This commit is contained in:
Ross Owen
2012-11-16 12:16:31 +00:00
parent 79e10023d8
commit c1c7e0b097
3 changed files with 287 additions and 311 deletions

View File

@@ -153,35 +153,6 @@ unsigned char DFUdevQualDesc[] =
int DFUReportResetState(chanend ?c_user_cmd); int DFUReportResetState(chanend ?c_user_cmd);
int DFUDeviceRequests(XUD_ep c_ep0_out, XUD_ep &?ep0_in, SetupPacket &sp, chanend ?c_user_cmd, unsigned int altInterface, unsigned int user_reset); int DFUDeviceRequests(XUD_ep c_ep0_out, XUD_ep &?ep0_in, SetupPacket &sp, chanend ?c_user_cmd, unsigned int altInterface, unsigned int user_reset);
// Overload the USB user command handler if present
extern unsigned int flash_programmer(unsigned int cmd, unsigned int request_data[16]);
void user_cmd_handler(unsigned int cmd, chanend ?c_user_cmd) {
if (!isnull(c_user_cmd)) {
unsigned int request_data_len = 0;
unsigned int request_data[16];
unsigned int return_data_len = 0;
int i = 0;
// Read request data length
request_data_len = inuint(c_user_cmd);
// Read request data
for (i = 0; i < request_data_len; i++) {
request_data[i] = inuint(c_user_cmd);
}
return_data_len = flash_programmer(cmd, request_data);
outuint(c_user_cmd, return_data_len);
if (return_data_len) {
for (i = 0; i < return_data_len/4; i++) {
outuint(c_user_cmd, request_data[i]);
}
}
}
}

View File

@@ -39,7 +39,6 @@ static int DFU_OpenFlash(chanend ?c_user_cmd)
{ {
unsigned int cmd_data[16]; unsigned int cmd_data[16];
DFUCustomFlashEnable(); DFUCustomFlashEnable();
//HandleUserDeviceRequest(FLASH_CMD_INIT, 1, 0, cmd_data);
flash_cmd_init(); flash_cmd_init();
DFU_flash_connected = 1; DFU_flash_connected = 1;
} }
@@ -53,7 +52,6 @@ static int DFU_CloseFlash(chanend ?c_user_cmd)
{ {
unsigned int cmd_data[16]; unsigned int cmd_data[16];
DFUCustomFlashDisable(); DFUCustomFlashDisable();
//HandleUserDeviceRequest(FLASH_CMD_DEINIT, 1, 0, cmd_data);
flash_cmd_deinit(); flash_cmd_deinit();
DFU_flash_connected = 0; DFU_flash_connected = 0;
} }
@@ -82,7 +80,8 @@ static int DFU_Detach(unsigned int timeout, chanend ?c_user_cmd)
return 0; return 0;
} }
static int DFU_Dnload(unsigned int request_len, unsigned int block_num, unsigned int request_data[16], chanend ?c_user_cmd) { static int DFU_Dnload(unsigned int request_len, unsigned int block_num, unsigned int request_data[16], chanend ?c_user_cmd)
{
unsigned int fromDfuIdle = 0; unsigned int fromDfuIdle = 0;
// Get DFU packets here, sequence is // Get DFU packets here, sequence is
@@ -92,7 +91,8 @@ static int DFU_Dnload(unsigned int request_len, unsigned int block_num, unsigned
DFU_OpenFlash(c_user_cmd); DFU_OpenFlash(c_user_cmd);
switch (DFU_state) { switch (DFU_state)
{
case STATE_DFU_IDLE: case STATE_DFU_IDLE:
case STATE_DFU_DOWNLOAD_IDLE: case STATE_DFU_DOWNLOAD_IDLE:
break; break;
@@ -101,34 +101,41 @@ static int DFU_Dnload(unsigned int request_len, unsigned int block_num, unsigned
return 0; return 0;
} }
if ((DFU_state == STATE_DFU_IDLE) && (request_len == 0)) { if ((DFU_state == STATE_DFU_IDLE) && (request_len == 0))
{
DFU_state = STATE_DFU_ERROR; DFU_state = STATE_DFU_ERROR;
return 0; return 0;
} else if (DFU_state == STATE_DFU_IDLE) { }
else if (DFU_state == STATE_DFU_IDLE)
{
fromDfuIdle = 1; fromDfuIdle = 1;
} else { }
else
{
fromDfuIdle = 0; fromDfuIdle = 0;
} }
if (request_len == 0) { if (request_len == 0)
{
// Host signalling complete download // Host signalling complete download
int i = 0; int i = 0;
unsigned int cmd_data[16]; unsigned int cmd_data[16];
if (subPagesLeft) { if (subPagesLeft)
{
unsigned int subPagePad[16] = {0}; unsigned int subPagePad[16] = {0};
for (i = 0; i < subPagesLeft; i++) for (i = 0; i < subPagesLeft; i++)
{ {
//HandleUserDeviceRequest(FLASH_CMD_WRITE_PAGE_DATA, 1, 64, subPagePad);
flash_cmd_write_page_data((subPagePad, unsigned char[64])); flash_cmd_write_page_data((subPagePad, unsigned char[64]));
} }
} }
cmd_data[0] = 2; // Terminate write cmd_data[0] = 2; // Terminate write
//HandleUserDeviceRequest(FLASH_CMD_WRITE_PAGE, 1, 4, cmd_data);
flash_cmd_write_page((cmd_data, unsigned char[])); flash_cmd_write_page((cmd_data, unsigned char[]));
DFU_state = STATE_DFU_MANIFEST_SYNC; DFU_state = STATE_DFU_MANIFEST_SYNC;
} else { }
else
{
unsigned int i = 0; unsigned int i = 0;
unsigned int flash_cmd = 0; unsigned int flash_cmd = 0;
unsigned int flash_page_index = 0; unsigned int flash_page_index = 0;
@@ -139,26 +146,22 @@ static int DFU_Dnload(unsigned int request_len, unsigned int block_num, unsigned
unsigned s = 0; unsigned s = 0;
// Erase flash on first block // Erase flash on first block
//HandleUserDeviceRequest(FLASH_CMD_ERASE_ALL, 1, 0, cmd_data);
flash_cmd_erase_all(); flash_cmd_erase_all();
} }
// Program firmware, STATE_DFU_DOWNLOAD_BUSY not currently used // Program firmware, STATE_DFU_DOWNLOAD_BUSY not currently used
if (!(block_num % 4)) if (!(block_num % 4))
{ {
cmd_data[0] = !fromDfuIdle; // 0 for first page, 1 for other pages. cmd_data[0] = !fromDfuIdle; // 0 for first page, 1 for other pages.
//HandleUserDeviceRequest(FLASH_CMD_WRITE_PAGE, 1, 4, cmd_data);
flash_cmd_write_page((cmd_data, unsigned char[64])); flash_cmd_write_page((cmd_data, unsigned char[64]));
subPagesLeft = 4; subPagesLeft = 4;
} }
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++)
{
cmd_data[i] = request_data[i]; cmd_data[i] = request_data[i];
} }
//HandleUserDeviceRequest(FLASH_CMD_WRITE_PAGE_DATA, 1, 64, cmd_data);
flash_cmd_write_page_data((cmd_data, unsigned char[64])); flash_cmd_write_page_data((cmd_data, unsigned char[64]));
subPagesLeft--; subPagesLeft--;
@@ -177,7 +180,6 @@ static int DFU_Upload(unsigned int request_len, unsigned int block_num, unsigned
// Start at flash address 0 // Start at flash address 0
// Keep reading flash pages until read_page returns 1 (address out of range) // Keep reading flash pages until read_page returns 1 (address out of range)
// Return terminating upload packet at this point // Return terminating upload packet at this point
DFU_OpenFlash(c_user_cmd); DFU_OpenFlash(c_user_cmd);
switch (DFU_state) switch (DFU_state)
@@ -206,7 +208,6 @@ static int DFU_Upload(unsigned int request_len, unsigned int block_num, unsigned
cmd_data[0] = !firstRead; cmd_data[0] = !firstRead;
// Read page // Read page
// HandleUserDeviceRequest(FLASH_CMD_READ_PAGE, 0, 4, cmd_data);
flash_cmd_read_page((cmd_data, unsigned char[64])); flash_cmd_read_page((cmd_data, unsigned char[64]));
subPagesLeft = 4; subPagesLeft = 4;
@@ -221,7 +222,6 @@ static int DFU_Upload(unsigned int request_len, unsigned int block_num, unsigned
} }
// Read page data // Read page data
// HandleUserDeviceRequest(FLASH_CMD_READ_PAGE_DATA, 0, 0, request_data);
flash_cmd_write_page_data((request_data, unsigned char[64])); flash_cmd_write_page_data((request_data, unsigned char[64]));
subPagesLeft--; subPagesLeft--;
@@ -325,8 +325,6 @@ int DFUReportResetState(chanend ?c_user_cmd)
if (currentTime - DFUTimerStart > DFUResetTimeout) if (currentTime - DFUTimerStart > DFUResetTimeout)
{ {
DFU_state = STATE_APP_IDLE; DFU_state = STATE_APP_IDLE;
//printintln(currentTime - DFUTimerStart);
//printintln(DFUResetTimeout);
inDFU = 0; inDFU = 0;
} }
else else
@@ -352,7 +350,8 @@ int DFUReportResetState(chanend ?c_user_cmd)
break; break;
} }
if (!inDFU) { if (!inDFU)
{
DFU_CloseFlash(c_user_cmd); DFU_CloseFlash(c_user_cmd);
} }
@@ -366,7 +365,6 @@ int XMOS_DFU_RevertFactory(chanend ?c_user_cmd)
DFU_OpenFlash(c_user_cmd); DFU_OpenFlash(c_user_cmd);
//HandleUserDeviceRequest(FLASH_CMD_ERASE_ALL, 1, 0, cmd_data);
flash_cmd_erase_all(); flash_cmd_erase_all();
DFUTimer :> s; DFUTimer :> s;
@@ -375,12 +373,11 @@ int XMOS_DFU_RevertFactory(chanend ?c_user_cmd)
return 0; return 0;
} }
int XMOS_DFU_SelectImage(unsigned int index, chanend ?c_user_cmd) { int XMOS_DFU_SelectImage(unsigned int index, chanend ?c_user_cmd)
{
// Select the image index for firmware update // Select the image index for firmware update
// Currently not used or implemented
return 0; return 0;
} }
@@ -394,14 +391,16 @@ int XMOS_DFU_LoadState()
return 0; return 0;
} }
int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, SetupPacket &sp, chanend ?c_user_cmd, unsigned int altInterface, unsigned int user_reset) { int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, SetupPacket &sp, chanend ?c_user_cmd, unsigned int altInterface, unsigned int user_reset)
{
unsigned int return_data_len = 0; unsigned int return_data_len = 0;
unsigned int data_buffer_len = 0; unsigned int data_buffer_len = 0;
unsigned int data_buffer[17]; unsigned int data_buffer[17];
unsigned int reset_device_after_ack = 0; unsigned int reset_device_after_ack = 0;
if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_OUT) if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_OUT)
{ // Host to device {
// Host to device
if (sp.wLength) if (sp.wLength)
#ifdef ARCH_G #ifdef ARCH_G
data_buffer_len = XUD_GetBuffer_(ep0_out, 0, (data_buffer, unsigned char[])); data_buffer_len = XUD_GetBuffer_(ep0_out, 0, (data_buffer, unsigned char[]));
@@ -411,7 +410,8 @@ int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, SetupPacket &sp, chanend
} }
// Map Standard DFU commands onto device level firmware upgrade mechanism // Map Standard DFU commands onto device level firmware upgrade mechanism
switch (sp.bRequest) { switch (sp.bRequest)
{
case DFU_DETACH: case DFU_DETACH:
return_data_len = DFU_Detach(sp.wValue, c_user_cmd); return_data_len = DFU_Detach(sp.wValue, c_user_cmd);
break; break;
@@ -466,13 +466,17 @@ int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, SetupPacket &sp, chanend
break; break;
} }
if (sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_IN && sp.wLength != 0) { // Device to host if (sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_IN && sp.wLength != 0)
{
// Device to host
#ifdef ARCH_G #ifdef ARCH_G
XUD_DoGetRequest(ep0_out, 0, (data_buffer, unsigned char[]), return_data_len, return_data_len); XUD_DoGetRequest(ep0_out, 0, (data_buffer, unsigned char[]), return_data_len, return_data_len);
#else #else
XUD_DoGetRequest(ep0_out, ep0_in, (data_buffer, unsigned char[]), return_data_len, return_data_len); XUD_DoGetRequest(ep0_out, ep0_in, (data_buffer, unsigned char[]), return_data_len, return_data_len);
#endif #endif
} else { }
else
{
#ifdef ARCH_G #ifdef ARCH_G
XUD_DoSetRequestStatus(ep0_out, 0); XUD_DoSetRequestStatus(ep0_out, 0);
#else #else
@@ -483,13 +487,7 @@ int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, SetupPacket &sp, chanend
// If device reset requested, handle after command acknowledgement // If device reset requested, handle after command acknowledgement
if (reset_device_after_ack) if (reset_device_after_ack)
{ {
if (!user_reset) if (user_reset)
{
unsigned int cmd_data[16];
//HandleUserDeviceRequest(FLASH_CMD_REBOOT, 1, 0, cmd_data);
flash_cmd_reboot();
}
else
{ {
return 1; return 1;
} }

View File

@@ -9,16 +9,11 @@
#ifdef ARCH_G #ifdef ARCH_G
#define FLASH_MAX_UPGRADE_SIZE 128 * 1024 // 128K default #define FLASH_MAX_UPGRADE_SIZE 128 * 1024 // 128K default
#else #else
//#define FLASH_MAX_UPGRADE_SIZE 64 * 1024 // 64K default #define FLASH_MAX_UPGRADE_SIZE 128 * 1024 // 128K default
#define FLASH_MAX_UPGRADE_SIZE 128 * 1024 // 64K default
#endif #endif
#endif #endif
#if 1
#define FLASH_ERROR() do { printstr("Error: line: "); printintln(__LINE__); __builtin_trap(); } while(0)
#else
#define FLASH_ERROR() do {} while(0) #define FLASH_ERROR() do {} while(0)
#endif
static int flash_device_open = 0; static int flash_device_open = 0;
static fl_BootImageInfo factory_image; static fl_BootImageInfo factory_image;
@@ -50,7 +45,6 @@ void DFUCustomFlashDisable()
return; return;
} }
int flash_cmd_init(void) int flash_cmd_init(void)
{ {
fl_BootImageInfo image; fl_BootImageInfo image;
@@ -93,24 +87,34 @@ int flash_cmd_deinit(void)
return 0; return 0;
} }
int flash_cmd_read_page(unsigned char *data) { int flash_cmd_read_page(unsigned char *data)
if (!upgrade_image_valid) { {
if (!upgrade_image_valid)
{
*(unsigned int *)data = 1; *(unsigned int *)data = 1;
return 4; return 4;
} }
if (*(unsigned int *)data == 0) {
if (*(unsigned int *)data == 0)
{
fl_startImageRead(&upgrade_image); fl_startImageRead(&upgrade_image);
} }
current_flash_subpage_index = 0; current_flash_subpage_index = 0;
if (fl_readImageRead(current_flash_page_data) == 0) {
if (fl_readImageRead(current_flash_page_data) == 0)
{
*(unsigned int *)data = 0; *(unsigned int *)data = 0;
} else { }
else
{
*(unsigned int *)data = 1; *(unsigned int *)data = 1;
} }
return 4; return 4;
} }
int flash_cmd_read_page_data(unsigned char *data) { int flash_cmd_read_page_data(unsigned char *data)
{
unsigned char *page_data_ptr = &current_flash_page_data[current_flash_subpage_index * 64]; unsigned char *page_data_ptr = &current_flash_page_data[current_flash_subpage_index * 64];
memcpy(data, page_data_ptr, 64); memcpy(data, page_data_ptr, 64);
@@ -125,26 +129,28 @@ static void begin_write()
// TODO this will take a long time. To minimise the amount of time spent // TODO this will take a long time. To minimise the amount of time spent
// paused on this operation it would be preferable to move to this to a // paused on this operation it would be preferable to move to this to a
// seperate command, e.g. start_write. // seperate command, e.g. start_write.
do { do
{
result = fl_startImageAdd(&factory_image, FLASH_MAX_UPGRADE_SIZE, 0); result = fl_startImageAdd(&factory_image, FLASH_MAX_UPGRADE_SIZE, 0);
} while (result > 0); } while (result > 0);
if (result < 0) if (result < 0)
FLASH_ERROR(); FLASH_ERROR();
} }
static int pages_written = 0; static int pages_written = 0;
int flash_cmd_write_page(unsigned char *data) { int flash_cmd_write_page(unsigned char *data)
{
unsigned int flag = *(unsigned int *)data; unsigned int flag = *(unsigned int *)data;
//printstr("flash_cmd_write_page(");
//printint(flag);
//printstr(")\n");
if (upgrade_image_valid) { if (upgrade_image_valid)
{
return 0; return 0;
} }
switch (flag) { switch (flag)
{
case 0: case 0:
// First page. // First page.
begin_write(); begin_write();
@@ -157,6 +163,7 @@ int flash_cmd_write_page(unsigned char *data) {
// Termination. // Termination.
if (fl_endWriteImage() != 0) if (fl_endWriteImage() != 0)
FLASH_ERROR(); FLASH_ERROR();
// Sanity check // Sanity check
fl_BootImageInfo image = factory_image; fl_BootImageInfo image = factory_image;
if (fl_getNextBootImage(&image) != 0) if (fl_getNextBootImage(&image) != 0)
@@ -171,22 +178,25 @@ int flash_cmd_write_page(unsigned char *data) {
static int isAllOnes(unsigned char page[256]) static int isAllOnes(unsigned char page[256])
{ {
unsigned i; unsigned i;
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++)
{
if (page[i] != 0xff) if (page[i] != 0xff)
return 0; return 0;
} }
return 1; return 1;
} }
int flash_cmd_write_page_data(unsigned char *data) { int flash_cmd_write_page_data(unsigned char *data)
{
unsigned char *page_data_ptr = &current_flash_page_data[current_flash_subpage_index * 64]; unsigned char *page_data_ptr = &current_flash_page_data[current_flash_subpage_index * 64];
//printstr("flash_cmd_write_page_data()\n");
if (upgrade_image_valid) { if (upgrade_image_valid)
{
return 0; return 0;
} }
if (current_flash_subpage_index >= 4) { if (current_flash_subpage_index >= 4)
{
return 0; return 0;
} }
@@ -194,7 +204,8 @@ int flash_cmd_write_page_data(unsigned char *data) {
current_flash_subpage_index++; current_flash_subpage_index++;
if (current_flash_subpage_index == 4) { if (current_flash_subpage_index == 4)
{
if (isAllOnes(data)) if (isAllOnes(data))
FLASH_ERROR(); FLASH_ERROR();
if (fl_writeImagePage(current_flash_page_data) != 0) if (fl_writeImagePage(current_flash_page_data) != 0)
@@ -205,8 +216,10 @@ int flash_cmd_write_page_data(unsigned char *data) {
return 0; return 0;
} }
int flash_cmd_erase_all(void) { int flash_cmd_erase_all(void)
if (upgrade_image_valid) { {
if (upgrade_image_valid)
{
if (fl_deleteImage(&upgrade_image) != 0) if (fl_deleteImage(&upgrade_image) != 0)
FLASH_ERROR(); FLASH_ERROR();
upgrade_image_valid = 0; upgrade_image_valid = 0;
@@ -214,9 +227,3 @@ int flash_cmd_erase_all(void) {
return 0; return 0;
} }
int flash_cmd_reboot(void) {
//unsigned int pllVal;
//read_sswitch_reg(0, 6, &pllVal);
//write_sswitch_reg(0, 6, pllVal);
return 0;
}