serial string removal and dfu changes for su1

This commit is contained in:
Ross Owen
2012-07-31 15:43:52 +01:00
parent 71885fcdb7
commit 69fb8e42d5
13 changed files with 1848 additions and 54 deletions

View File

@@ -1 +1,3 @@
Code providing firmware upgrade over USB.
./host provides an example of a host application for DFU. This is written and tested for OSX. LibUSB is used to aid cross-platform porting.

View File

@@ -0,0 +1,2 @@
all:
g++ -g -o xmosdfu xmosdfu.cpp -I. -IOSX libusb-1.0.0.dylib -m32

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
export DYLD_LIBRARY_PATH=$PWD:$DYLD_LIBRARY_PATH

View File

@@ -0,0 +1,45 @@
#! /bin/bash
################################################################################
#find out were we are running from so we only exec this programs
PROGDIR=`dirname $0`
#setup environment
export DYLD_LIBRARY_PATH=$PWD:$DYLD_LIBRARY_PATH
#check if we were given a binary name, otherwise use the default one
updatebin=testbin
if [ "$1" != "" ]; then
updatebin=$1
fi
#basic check for binary
if [ ! -f $updatebin ]; then
echo "FATAL: can't find update binary named $updatebin"
exit 1
else
using $updatebin
fi
#-------------------------------------------------------------------------------
for i in 1 2 3 4 5 6 7 8 9 10; do
echo ""
echo DFU test iteration $i
echo ---------------------
echo ""
echo "*** DFU revert to factory ***"
$PROGDIR/xmosdfu --revertfactory
sleep 2
echo ""
echo "*** DFU download new firmware ***"
$PROGDIR/xmosdfu --download $updatebin
sleep 2
echo ""
echo "*** DFU upload existing firmware ***"
$PROGDIR/xmosdfu --upload $updatebin
sleep 2
echo ""
done
echo DFU Test Complete!

View File

@@ -0,0 +1,415 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libusb.h"
/* the device's vendor and product id */
#define XMOS_VID 0x20b1
#define XMOS_L1_AUDIO2_PID 0x0002
#define XMOS_L1_AUDIO1_PID 0x0003
#define XMOS_L2_AUDIO2_PID 0x0004
unsigned int XMOS_DFU_IF = 0;
#define DFU_REQUEST_TO_DEV 0x21
#define DFU_REQUEST_FROM_DEV 0xa1
// Standard DFU requests
#define DFU_DETACH 0
#define DFU_DNLOAD 1
#define DFU_UPLOAD 2
#define DFU_GETSTATUS 3
#define DFU_CLRSTATUS 4
#define DFU_GETSTATE 5
#define DFU_ABORT 6
// XMOS alternate setting requests
#define XMOS_DFU_RESETDEVICE 0xf0
#define XMOS_DFU_REVERTFACTORY 0xf1
#define XMOS_DFU_RESETINTODFU 0xf2
#define XMOS_DFU_RESETFROMDFU 0xf3
#define XMOS_DFU_SAVESTATE 0xf5
#define XMOS_DFU_RESTORESTATE 0xf6
static libusb_device_handle *devh = NULL;
static int find_xmos_device(unsigned int id)
{
libusb_device *dev;
libusb_device **devs;
int i = 0;
int found = 0;
libusb_get_device_list(NULL, &devs);
while ((dev = devs[i++]) != NULL)
{
struct libusb_device_descriptor desc;
libusb_get_device_descriptor(dev, &desc);
printf("VID = 0x%x, PID = 0x%x\n", desc.idVendor, desc.idProduct);
if (desc.idVendor == XMOS_VID &&
((desc.idProduct == XMOS_L1_AUDIO1_PID) ||
(desc.idProduct == XMOS_L1_AUDIO2_PID) ||
(desc.idProduct == XMOS_L2_AUDIO2_PID)))
{
if (found == id)
{
if (libusb_open(dev, &devh) < 0)
{
return -1;
}
else
{
libusb_config_descriptor *config_desc = NULL;
libusb_get_active_config_descriptor(dev, &config_desc);
if (config_desc != NULL)
{
for (int j = 0; j < config_desc->bNumInterfaces; j++)
{
const libusb_interface_descriptor *inter_desc = ((libusb_interface *)&config_desc->interface[j])->altsetting;
if (inter_desc->bInterfaceClass == 0xFE && inter_desc->bInterfaceSubClass == 0x1)
{
XMOS_DFU_IF = j;
}
}
}
else
{
XMOS_DFU_IF = 0;
}
}
break;
}
found++;
}
}
libusb_free_device_list(devs, 1);
return devh ? 0 : -1;
}
int xmos_dfu_resetdevice(void) {
libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_RESETDEVICE, 0, 0, NULL, 0, 0);
}
int xmos_dfu_revertfactory(void) {
libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_REVERTFACTORY, 0, 0, NULL, 0, 0);
}
int xmos_dfu_resetintodfu(unsigned int interface) {
libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_RESETINTODFU, 0, interface, NULL, 0, 0);
}
int xmos_dfu_resetfromdfu(unsigned int interface) {
libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_RESETFROMDFU, 0, interface, NULL, 0, 0);
}
int dfu_detach(unsigned int interface, unsigned int timeout) {
libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, DFU_DETACH, timeout, interface, NULL, 0, 0);
return 0;
}
int dfu_getState(unsigned int interface, unsigned char *state) {
libusb_control_transfer(devh, DFU_REQUEST_FROM_DEV, DFU_GETSTATE, 0, interface, state, 1, 0);
return 0;
}
int dfu_getStatus(unsigned int interface, unsigned char *state, unsigned int *timeout,
unsigned char *nextState, unsigned char *strIndex) {
unsigned int data[2];
libusb_control_transfer(devh, DFU_REQUEST_FROM_DEV, DFU_GETSTATUS, 0, interface, (unsigned char *)data, 6, 0);
*state = data[0] & 0xff;
*timeout = (data[0] >> 8) & 0xffffff;
*nextState = data[1] & 0xff;
*strIndex = (data[1] >> 8) & 0xff;
return 0;
}
int dfu_clrStatus(unsigned int interface) {
libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, DFU_CLRSTATUS, 0, interface, NULL, 0, 0);
return 0;
}
int dfu_abort(unsigned int interface) {
libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, DFU_ABORT, 0, interface, NULL, 0, 0);
return 0;
}
int xmos_dfu_save_state(unsigned int interface) {
libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_SAVESTATE, 0, interface, NULL, 0, 0);
printf("Save state command sent\n");
return 0;
}
int xmos_dfu_restore_state(unsigned int interface) {
libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, XMOS_DFU_RESTORESTATE, 0, interface, NULL, 0, 0);
printf("Restore state command sent\n");
return 0;
}
int dfu_download(unsigned int interface, unsigned int block_num, unsigned int size, unsigned char *data) {
//printf("... Downloading block number %d size %d\r", block_num, size);
libusb_control_transfer(devh, DFU_REQUEST_TO_DEV, DFU_DNLOAD, block_num, interface, data, size, 0);
return 0;
}
int dfu_upload(unsigned int interface, unsigned int block_num, unsigned int size, unsigned char*data) {
unsigned int numBytes = 0;
numBytes = libusb_control_transfer(devh, DFU_REQUEST_FROM_DEV, DFU_UPLOAD, block_num, interface, (unsigned char *)data, size, 0);
return numBytes;
}
int write_dfu_image(char *file) {
int i = 0;
FILE* inFile = NULL;
int image_size = 0;
unsigned int num_blocks = 0;
unsigned int block_size = 64;
unsigned int remainder = 0;
unsigned char block_data[256];
unsigned char dfuState = 0;
unsigned char nextDfuState = 0;
unsigned int timeout = 0;
unsigned char strIndex = 0;
unsigned int dfuBlockCount = 0;
inFile = fopen( file, "rb" );
if( inFile == NULL ) {
fprintf(stderr,"Error: Failed to open input data file.\n");
return -1;
}
/* Discover the size of the image. */
if( 0 != fseek( inFile, 0, SEEK_END ) ) {
fprintf(stderr,"Error: Failed to discover input data file size.\n");
return -1;
}
image_size = (int)ftell( inFile );
if( 0 != fseek( inFile, 0, SEEK_SET ) ) {
fprintf(stderr,"Error: Failed to input file pointer.\n");
return -1;
}
num_blocks = image_size/block_size;
remainder = image_size - (num_blocks * block_size);
printf("... Downloading image (%s) to device\n", file);
dfuBlockCount = 0;
for (i = 0; i < num_blocks; i++) {
memset(block_data, 0x0, block_size);
fread(block_data, 1, block_size, inFile);
dfu_download(0, dfuBlockCount, block_size, block_data);
dfu_getStatus(0, &dfuState, &timeout, &nextDfuState, &strIndex);
dfuBlockCount++;
}
if (remainder) {
memset(block_data, 0x0, block_size);
fread(block_data, 1, remainder, inFile);
dfu_download(0, dfuBlockCount, block_size, block_data);
dfu_getStatus(0, &dfuState, &timeout, &nextDfuState, &strIndex);
}
// 0 length download terminates
dfu_download(0, 0, 0, NULL);
dfu_getStatus(0, &dfuState, &timeout, &nextDfuState, &strIndex);
printf("... Download complete\n");
return 0;
}
int read_dfu_image(char *file) {
FILE *outFile = NULL;
unsigned int block_count = 0;
unsigned int block_size = 64;
unsigned char block_data[64];
outFile = fopen( file, "wb" );
if( outFile == NULL ) {
fprintf(stderr,"Error: Failed to open output data file.\n");
return -1;
}
printf("... Uploading image (%s) from device\n", file);
while (1) {
unsigned int numBytes = 0;
numBytes = dfu_upload(0, block_count, 64, block_data);
if (numBytes == 0)
break;
fwrite(block_data, 1, block_size, outFile);
block_count++;
}
fclose(outFile);
}
int main(int argc, char **argv) {
int r = 1;
unsigned char dfuState = 0;
unsigned char nextDfuState = 0;
unsigned int timeout = 0;
unsigned char strIndex = 0;
unsigned int download = 0;
unsigned int upload = 0;
unsigned int revert = 0;
unsigned int save = 0;
unsigned int restore = 0;
char *firmware_filename = NULL;
if (argc < 2) {
fprintf(stderr, "No options passed to dfu application\n");
return -1;
}
if (strcmp(argv[1], "--download") == 0) {
if (argv[2]) {
firmware_filename = argv[2];
} else {
fprintf(stderr, "No filename specified for download option\n");
return -1;
}
download = 1;
} else if (strcmp(argv[1], "--upload") == 0) {
if (argv[2]) {
firmware_filename = argv[2];
} else {
fprintf(stderr, "No filename specified for upload option\n");
return -1;
}
upload = 1;
} else if (strcmp(argv[1], "--revertfactory") == 0) {
revert = 1;
}
else if(strcmp(argv[1], "--savecustomstate") == 0)
{
save = 1;
}
else if(strcmp(argv[1], "--restorecustomstate") == 0)
{
restore = 1;
}
else {
fprintf(stderr, "Invalid option passed to dfu application\n");
return -1;
}
r = libusb_init(NULL);
if (r < 0) {
fprintf(stderr, "failed to initialise libusb\n");
return -1;
}
r = find_xmos_device(0);
if (r < 0) {
fprintf(stderr, "Could not find/open device\n");
return -1;
}
r = libusb_claim_interface(devh, XMOS_DFU_IF);
if (r < 0) {
fprintf(stderr, "Error claiming interface %d %d\n", XMOS_DFU_IF, r);
return -1;
}
printf("XMOS DFU application started - Interface %d claimed\n", XMOS_DFU_IF);
/* Dont go into DFU mode for save/restore */
if(save)
{
xmos_dfu_save_state(XMOS_DFU_IF);
}
else if(restore)
{
xmos_dfu_restore_state(XMOS_DFU_IF);
}
else
{
printf("Detaching device from application mode.\n");
xmos_dfu_resetintodfu(XMOS_DFU_IF);
libusb_release_interface(devh, XMOS_DFU_IF);
libusb_close(devh);
printf("Waiting for device to restart and enter DFU mode...\n");
// Wait for device to enter dfu mode and restart
system("sleep 20");
// NOW IN DFU APPLICATION MODE
r = find_xmos_device(0);
if (r < 0) {
fprintf(stderr, "Could not find/open device\n");
return -1;
}
r = libusb_claim_interface(devh, 0);
if (r != 0)
{
fprintf(stderr, "Error claiming interface 0\n");
switch(r)
{
case LIBUSB_ERROR_NOT_FOUND:
printf("The requested interface does not exist'n");
break;
case LIBUSB_ERROR_BUSY:
printf("Another program or driver has claimed the interface\n");
break;
case LIBUSB_ERROR_NO_DEVICE:
printf("The device has been disconnected\n");
break;
case LIBUSB_ERROR_ACCESS:
printf("Access denied\n");
break;
default:
printf("Unknown error code: %d\n", r);
break;
}
return -1;
}
printf("... DFU firmware upgrade device opened\n");
if (download) {
write_dfu_image(firmware_filename);
xmos_dfu_resetfromdfu(XMOS_DFU_IF);
} else if (upload) {
read_dfu_image(firmware_filename);
xmos_dfu_resetfromdfu(XMOS_DFU_IF);
} else if (revert) {
printf("... Reverting device to factory image\n");
xmos_dfu_revertfactory();
// Give device time to revert firmware
system("sleep 2");
xmos_dfu_resetfromdfu(XMOS_DFU_IF);
}
else{
xmos_dfu_resetfromdfu(XMOS_DFU_IF);
}
printf("... Returning device to application mode\n");
}
// END OF DFU APPLICATION MODE
libusb_release_interface(devh, 0);
libusb_close(devh);
libusb_exit(NULL);
return true;
}

View File

@@ -17,8 +17,8 @@
#endif
#ifndef DFU_SERIAL_STR_INDEX
#error DFU_SERIAL_STR_INDEX NOT DEFINED!
//#define DFU_SERIAL_STR_INDEX 0x00
/* By default no serial string */
#define DFU_SERIAL_STR_INDEX 0x00
#endif
#ifndef DFU_PRODUCT_INDEX

View File

@@ -272,48 +272,54 @@ static int DFU_Abort(void) {
}
// Tell the DFU state machine that a USB reset has occured
int DFUReportResetState(chanend ?c_user_cmd) {
unsigned int inDFU = 0;
unsigned int currentTime = 0;
int DFUReportResetState(chanend ?c_user_cmd)
{
unsigned int inDFU = 0;
unsigned int currentTime = 0;
if (DFU_reset_override == 0x11042011) {
unsigned int cmd_data[16];
inDFU = 1;
DFU_state = STATE_DFU_IDLE;
return inDFU;
}
switch(DFU_state) {
case STATE_APP_DETACH:
case STATE_DFU_IDLE:
DFU_state = STATE_DFU_IDLE;
DFUTimer :> currentTime;
if (currentTime - DFUTimerStart > DFUResetTimeout) {
DFU_state = STATE_APP_IDLE;
//printintln(currentTime - DFUTimerStart);
//printintln(DFUResetTimeout);
inDFU = 0;
} else {
if (DFU_reset_override == 0x11042011)
{
unsigned int cmd_data[16];
inDFU = 1;
}
break;
case STATE_APP_IDLE:
case STATE_DFU_DOWNLOAD_SYNC:
case STATE_DFU_DOWNLOAD_BUSY:
case STATE_DFU_DOWNLOAD_IDLE:
case STATE_DFU_MANIFEST_SYNC:
case STATE_DFU_MANIFEST:
case STATE_DFU_MANIFEST_WAIT_RESET:
case STATE_DFU_UPLOAD_IDLE:
case STATE_DFU_ERROR:
inDFU = 0;
DFU_state = STATE_APP_IDLE;
break;
default:
DFU_state = STATE_DFU_ERROR;
inDFU = 1;
break;
DFU_state = STATE_DFU_IDLE;
return inDFU;
}
switch(DFU_state)
{
case STATE_APP_DETACH:
case STATE_DFU_IDLE:
DFU_state = STATE_DFU_IDLE;
DFUTimer :> currentTime;
if (currentTime - DFUTimerStart > DFUResetTimeout)
{
DFU_state = STATE_APP_IDLE;
//printintln(currentTime - DFUTimerStart);
//printintln(DFUResetTimeout);
inDFU = 0;
}
else
{
inDFU = 1;
}
break;
case STATE_APP_IDLE:
case STATE_DFU_DOWNLOAD_SYNC:
case STATE_DFU_DOWNLOAD_BUSY:
case STATE_DFU_DOWNLOAD_IDLE:
case STATE_DFU_MANIFEST_SYNC:
case STATE_DFU_MANIFEST:
case STATE_DFU_MANIFEST_WAIT_RESET:
case STATE_DFU_UPLOAD_IDLE:
case STATE_DFU_ERROR:
inDFU = 0;
DFU_state = STATE_APP_IDLE;
break;
default:
DFU_state = STATE_DFU_ERROR;
inDFU = 1;
break;
}
if (!inDFU) {

View File

@@ -292,11 +292,6 @@
#define ID_MIXER_1 60
#ifndef SERIAL_STR
#define SERIAL_STR "0000" /* Serial number string */
#endif
#define SERIAL_STR_INDEX 0x03
#define MANUFACTURER_STR_INDEX 0x01
#define PRODUCT_STR_INDEX 0x02

View File

@@ -36,7 +36,7 @@ unsigned char devDesc_Audio1[] =
(BCD_DEVICE >> 8), /* 13 bcdDevice : Device release number */
MANUFACTURER_STR_INDEX, /* 14 iManufacturer : Index of manufacturer string */
PRODUCT_STR_INDEX, /* 15 iProduct : Index of product string descriptor */
SERIAL_STR_INDEX, /* 16 iSerialNumber : Index of serial number decriptor */
0,//SERIAL_STR_INDEX, /* 16 iSerialNumber : Index of serial number decriptor */
0x01 /* 17 bNumConfigurations : Number of possible configs. */
};
#endif
@@ -60,7 +60,7 @@ unsigned char devDesc_Audio2[] =
(BCD_DEVICE >> 8), /* 13 bcdDevice : Device release number */
MANUFACTURER_STR_INDEX, /* 14 iManufacturer : Index of manufacturer string */
PRODUCT_STR_INDEX, /* 15 iProduct : Index of product string descriptor */
SERIAL_STR_INDEX, /* 16 iSerialNumber : Index of serial number decriptor */
0,// SERIAL_STR_INDEX, /* 16 iSerialNumber : Index of serial number decriptor */
0x02 /* 17 bNumConfigurations : Number of possible configs. Set to 2 so that Windows
does not load Composite driver. */
};
@@ -84,7 +84,7 @@ unsigned char devDesc_Null[] =
(BCD_DEVICE >> 8), /* 13 bcdDevice : Device release number */
MANUFACTURER_STR_INDEX, /* 14 iManufacturer : Index of manufacturer string */
PRODUCT_STR_INDEX, /* 15 iProduct : Index of product string descriptor */
SERIAL_STR_INDEX, /* 16 iSerialNumber : Index of serial number decriptor */
0,//SERIAL_STR_INDEX, /* 16 iSerialNumber : Index of serial number decriptor */
0x01 /* 17 bNumConfigurations : Number of possible configs */
};
@@ -1338,7 +1338,7 @@ static unsigned char strDescs_Audio2[][40] =
"Langids", /* String 0 (LangIDs) place holder */
APPEND_VENDOR_STR( ), // 1 iManufacturer (at MANUFACTURER_STRING_INDEX)
APPEND_VENDOR_STR(USB Audio 2.0), // 2 iProduct and iInterface for control interface (at PRODUCT_STR_INDEX)
SERIAL_STR, // 3 iSerialNumber (at SERIAL_STR_INDEX)
"",//SERIAL_STR, // 3 iSerialNumber (at SERIAL_STR_INDEX)
APPEND_VENDOR_STR(USB 2.0 Audio Out), // 4 iInterface for Streaming interaces
APPEND_VENDOR_STR(USB 2.0 Audio In), // 5
@@ -1576,7 +1576,7 @@ unsigned char oSpeedCfgDesc[] =
#define STREAMING_INTERFACES (INPUT_INTERFACES + OUTPUT_INTERFACES)
#define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES * 61) + (OUTPUT_INTERFACES * 70) + (DFU_INTERFACES * 18))
#define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES * 61) + (OUTPUT_INTERFACES * 70))
#ifdef AUDIO_CLASS_FALLBACK
unsigned char cfgDesc_Audio1[] =
{
@@ -1876,6 +1876,7 @@ unsigned char cfgDesc_Audio1[] =
0x40,
0x00
#else
#if 0
/* DFU 1.1 Run-Time DFU Functional Descriptor */
0x09, /* 0 Size */
0x21, /* 1 bDescriptorType : DFU FUNCTIONAL */
@@ -1886,7 +1887,7 @@ unsigned char cfgDesc_Audio1[] =
0x00, /* 6 wTransferSize */
0x10, /* 7 bcdDFUVersion */
0x01, /* 7 bcdDFUVersion */
#endif
#endif
};
@@ -1899,7 +1900,7 @@ static unsigned char strDescs_Audio1[][40] =
"Langids", /* String 0 (LangIDs) place holder */
APPEND_VENDOR_STR(), // 1 iManufacturer
APPEND_VENDOR_STR(USB Audio 1.0), // 2 iProduct and iInterface for control interface
SERIAL_STR, // 3 iSerialNumber
"",//SERIAL_STR, // 3 iSerialNumber
APPEND_VENDOR_STR(USB 1.0 Audio Out), // 4 iInterface for Streaming interaces
APPEND_VENDOR_STR(USB 1.0 Audio In), // 5

View File

@@ -24,6 +24,20 @@
#include "hid.h"
#endif
#define GLXID 0x0001
#define PLL_CTRL_VAL ((1<<23) | (499<<8) | (2<<0))
void glx_link_setup(unsigned myid, unsigned glxid);
void glx_link_setup_with(unsigned myid, unsigned glxid, unsigned link_setup_val);
int write_glx_periph_word(unsigned destId, unsigned periphAddress, unsigned destRegAddr, unsigned data);
int read_glx_periph_word(unsigned dest_id, unsigned periph_addr, unsigned dest_reg_addr, unsigned &rd_data);
int read_glx_periph_reg(unsigned dest_id, unsigned periph_addr, unsigned dest_reg_addr, unsigned bad_format, unsigned data_size, char buf[]);
int write_glx_periph_reg(unsigned dest_id, unsigned periph_addr, unsigned dest_reg_addr, unsigned bad_packet, unsigned data_size, char buf[]);
void read_sswitch_reg_verify(unsigned coreid, unsigned reg, unsigned &data, unsigned failval);
void write_sswitch_reg_verify(unsigned coreid, unsigned reg, unsigned data, unsigned failval);
#define XS1_GLX_PERIPH_SCTH_ID 0x3
/* Windows does not have a built in DFU driver (windows will prompt), so warn that DFU will not be functional in Audio 1.0 mode.Udi
* Of course, OSX is unaffected.
*/
@@ -267,6 +281,24 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
VendorAudioRequestsInit(c_audioControl, c_mix_ctl, c_clk_ctl);
#endif
#if 0
{
char rdata[1];
char wdata[1];
//wdata[0] = 77;
//write_glx_periph_reg(GLXID, XS1_GLX_PERIPH_SCTH_ID, 0x0, 0, 1, wdata);
read_glx_periph_reg(GLXID, XS1_GLX_PERIPH_SCTH_ID, 0x1, 0, 1, rdata);
if(rdata[0] != 0)
{
while(1);
}
// printintln(rdata[0]);
#endif
#ifdef DFU
/* Check if device has started in DFU mode */
if (DFUReportResetState(null))
@@ -867,6 +899,13 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
// Restart audio
//outuint(c_audioControl, AUDIO_START_FROM_DFU);
DFU_mode_active = 0;
{
unsigned char wdata[1];
wdata[0] = 77;
write_glx_periph_reg(GLXID, XS1_GLX_PERIPH_SCTH_ID, 0x0, 0, 1, wdata);
}
// Send reboot command
//outuint(c_audioControl, SET_SAMPLE_FREQ);
//outuint(c_audioControl, AUDIO_REBOOT_FROM_DFU);

View File

@@ -1,11 +1,63 @@
#include <xs1.h>
#include <print.h>
#define GLXID 0x0001
#define XS1_GLX_PERIPH_USB_ID 0x1
#define XS1_GLX_CFG_RST_MISC_ADRS 0x50
#define XS1_UIFM_PHY_CONTROL_REG 0x3c
#define XS1_UIFM_PHY_CONTROL_FORCERESET 0x0
#define XS1_GLX_CFG_USB_CLK_EN_BASE 0x3
#define XS1_GLX_CFG_USB_EN_BASE 0x2
#define XS1_GLX_PERIPH_SCTH_ID 0x3
#define XS1_UIFM_FUNC_CONTROL_REG 0xc
#define XS1_UIFM_FUNC_CONTROL_XCVRSELECT 0x0
#define XS1_UIFM_FUNC_CONTROL_TERMSELECT 0x1
int write_sswitch_reg_blind(unsigned coreid, unsigned reg, unsigned data);
void write_sswitch_reg_verify(unsigned coreid, unsigned reg, unsigned data, unsigned failval);
int write_glx_periph_word(unsigned destId, unsigned periphAddress, unsigned destRegAddr, unsigned data);
int write_glx_periph_reg(unsigned dest_id, unsigned periph_addr, unsigned dest_reg_addr, unsigned bad_packet, unsigned data_size, char buf[]);
void read_sswitch_reg_verify(unsigned coreid, unsigned reg, unsigned &data, unsigned failval);
/* Reboots XMOS device by writing to the PLL config register */
void device_reboot_implementation(chanend spare)
{
//#ifdef ARCH_S
#if 1
unsigned wdata;
char wdatac[1];
write_glx_periph_word(GLXID, XS1_GLX_PERIPH_USB_ID, XS1_UIFM_FUNC_CONTROL_REG, 4);
// (0<<XS1_UIFM_FUNC_CONTROL_XCVRSELECT)
// | (0<<XS1_UIFM_FUNC_CONTROL_TERMSELECT));
// Turn off All term resistors and d+ pullup
// Term select and opmode
#if 0
/* Write to glx scratch reg so we know rebooting into DFU mode */
wdatac[0] = 0x77;
write_glx_periph_reg(GLXID, XS1_GLX_PERIPH_SCTH_ID, 0x1, 0, 1, wdatac);
// Issue soft boot
wdata = 0x000c0001;
write_sswitch_reg_verify(GLXID, XS1_GLX_CFG_RST_MISC_ADRS, wdata, 2);
while(1); // Should reset before it executes this.
#endif
/* Keep usb clock active, enter active mode */
//rite_sswitch_reg(GLXID, XS1_GLX_CFG_RST_MISC_ADRS, (0 << XS1_GLX_CFG_USB_CLK_EN_BASE) | (0<<XS1_GLX_CFG_USB_EN_BASE) );
/* Now reset the phy */
// write_glx_periph_word(GLXID, XS1_GLX_PERIPH_USB_ID, XS1_UIFM_PHY_CONTROL_REG, (1<<XS1_UIFM_PHY_CONTROL_FORCERESET));
/* Enable the USB clock */
//write_sswitch_reg(GLXID, XS1_GLX_CFG_RST_MISC_ADRS, ( ( 0 << XS1_GLX_CFG_USB_CLK_EN_BASE ) ) );
#endif
#if 1
outct(spare, XS1_CT_END); // have to do this before freeing the chanend
inct(spare); // Receive end ct from usb_buffer to close down in both directions
// Need a spare chanend so we can talk to the pll register
@@ -17,4 +69,7 @@ void device_reboot_implementation(chanend spare)
write_sswitch_reg_blind(core_id^0x8000, 6, pllVal);
write_sswitch_reg_blind(core_id, 6, pllVal);
}
#endif
}