From c1c7e0b0979705a0392a08935efef85104a6258e Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Fri, 16 Nov 2012 12:16:31 +0000 Subject: [PATCH] DFU tidy --- module_dfu/src/dfu.h | 29 --- module_dfu/src/dfu.xc | 348 +++++++++++++++---------------- module_dfu/src/flash_interface.c | 221 ++++++++++---------- 3 files changed, 287 insertions(+), 311 deletions(-) diff --git a/module_dfu/src/dfu.h b/module_dfu/src/dfu.h index 296ce84a..5dc57e05 100644 --- a/module_dfu/src/dfu.h +++ b/module_dfu/src/dfu.h @@ -153,35 +153,6 @@ unsigned char DFUdevQualDesc[] = 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); -// 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]); - } - } - } -} diff --git a/module_dfu/src/dfu.xc b/module_dfu/src/dfu.xc index f157dd05..be1765e8 100644 --- a/module_dfu/src/dfu.xc +++ b/module_dfu/src/dfu.xc @@ -39,7 +39,6 @@ static int DFU_OpenFlash(chanend ?c_user_cmd) { unsigned int cmd_data[16]; DFUCustomFlashEnable(); - //HandleUserDeviceRequest(FLASH_CMD_INIT, 1, 0, cmd_data); flash_cmd_init(); DFU_flash_connected = 1; } @@ -53,7 +52,6 @@ static int DFU_CloseFlash(chanend ?c_user_cmd) { unsigned int cmd_data[16]; DFUCustomFlashDisable(); - //HandleUserDeviceRequest(FLASH_CMD_DEINIT, 1, 0, cmd_data); flash_cmd_deinit(); DFU_flash_connected = 0; } @@ -82,90 +80,95 @@ static int DFU_Detach(unsigned int timeout, chanend ?c_user_cmd) return 0; } -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; +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; - // Get DFU packets here, sequence is - // DFU_DOWNLOAD -> DFU_DOWNLOAD_SYNC - // GET_STATUS -> DFU_DOWNLOAD_SYNC (flash busy) || DFU_DOWNLOAD_IDLE - // REPEAT UNTIL DFU_DOWNLOAD with 0 length -> DFU_MANIFEST_SYNC + // Get DFU packets here, sequence is + // DFU_DOWNLOAD -> DFU_DOWNLOAD_SYNC + // GET_STATUS -> DFU_DOWNLOAD_SYNC (flash busy) || DFU_DOWNLOAD_IDLE + // REPEAT UNTIL DFU_DOWNLOAD with 0 length -> DFU_MANIFEST_SYNC - DFU_OpenFlash(c_user_cmd); + DFU_OpenFlash(c_user_cmd); - switch (DFU_state) { - case STATE_DFU_IDLE: - case STATE_DFU_DOWNLOAD_IDLE: - break; - default: - DFU_state = STATE_DFU_ERROR; - return 0; - } - - if ((DFU_state == STATE_DFU_IDLE) && (request_len == 0)) { - DFU_state = STATE_DFU_ERROR; - return 0; - } else if (DFU_state == STATE_DFU_IDLE) { - fromDfuIdle = 1; - } else { - fromDfuIdle = 0; - } - - if (request_len == 0) { - // Host signalling complete download - int i = 0; - unsigned int cmd_data[16]; - if (subPagesLeft) { - unsigned int subPagePad[16] = {0}; - for (i = 0; i < subPagesLeft; i++) - { - //HandleUserDeviceRequest(FLASH_CMD_WRITE_PAGE_DATA, 1, 64, subPagePad); - flash_cmd_write_page_data((subPagePad, unsigned char[64])); - } - } - - cmd_data[0] = 2; // Terminate write - //HandleUserDeviceRequest(FLASH_CMD_WRITE_PAGE, 1, 4, cmd_data); - flash_cmd_write_page((cmd_data, unsigned char[])); - - DFU_state = STATE_DFU_MANIFEST_SYNC; - } else { - unsigned int i = 0; - unsigned int flash_cmd = 0; - unsigned int flash_page_index = 0; - unsigned int cmd_data[16]; - - if (fromDfuIdle) - { - unsigned s = 0; - - // Erase flash on first block - //HandleUserDeviceRequest(FLASH_CMD_ERASE_ALL, 1, 0, cmd_data); - flash_cmd_erase_all(); - - - } - - // Program firmware, STATE_DFU_DOWNLOAD_BUSY not currently used - if (!(block_num % 4)) + switch (DFU_state) { - 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])); - subPagesLeft = 4; + case STATE_DFU_IDLE: + case STATE_DFU_DOWNLOAD_IDLE: + break; + default: + DFU_state = STATE_DFU_ERROR; + return 0; } + + if ((DFU_state == STATE_DFU_IDLE) && (request_len == 0)) + { + DFU_state = STATE_DFU_ERROR; + return 0; + } + else if (DFU_state == STATE_DFU_IDLE) + { + fromDfuIdle = 1; + } + else + { + fromDfuIdle = 0; + } + + if (request_len == 0) + { + // Host signalling complete download + int i = 0; + unsigned int cmd_data[16]; + if (subPagesLeft) + { + unsigned int subPagePad[16] = {0}; + for (i = 0; i < subPagesLeft; i++) + { + flash_cmd_write_page_data((subPagePad, unsigned char[64])); + } + } + + cmd_data[0] = 2; // Terminate write + flash_cmd_write_page((cmd_data, unsigned char[])); + + DFU_state = STATE_DFU_MANIFEST_SYNC; + } + else + { + unsigned int i = 0; + unsigned int flash_cmd = 0; + unsigned int flash_page_index = 0; + unsigned int cmd_data[16]; + + if (fromDfuIdle) + { + unsigned s = 0; + + // Erase flash on first block + flash_cmd_erase_all(); + } + + // Program firmware, STATE_DFU_DOWNLOAD_BUSY not currently used + if (!(block_num % 4)) + { + cmd_data[0] = !fromDfuIdle; // 0 for first page, 1 for other pages. + flash_cmd_write_page((cmd_data, unsigned char[64])); + subPagesLeft = 4; + } - for (i = 0; i < 16; i++) { - cmd_data[i] = request_data[i]; + for (i = 0; i < 16; i++) + { + cmd_data[i] = request_data[i]; + } + + flash_cmd_write_page_data((cmd_data, unsigned char[64])); + subPagesLeft--; + + DFU_state = STATE_DFU_DOWNLOAD_SYNC; } - //HandleUserDeviceRequest(FLASH_CMD_WRITE_PAGE_DATA, 1, 64, cmd_data); - flash_cmd_write_page_data((cmd_data, unsigned char[64])); - subPagesLeft--; - - DFU_state = STATE_DFU_DOWNLOAD_SYNC; - } - - return 0; + return 0; } @@ -177,7 +180,6 @@ static int DFU_Upload(unsigned int request_len, unsigned int block_num, unsigned // Start at flash address 0 // Keep reading flash pages until read_page returns 1 (address out of range) // Return terminating upload packet at this point - DFU_OpenFlash(c_user_cmd); switch (DFU_state) @@ -206,7 +208,6 @@ static int DFU_Upload(unsigned int request_len, unsigned int block_num, unsigned cmd_data[0] = !firstRead; // Read page - // HandleUserDeviceRequest(FLASH_CMD_READ_PAGE, 0, 4, cmd_data); flash_cmd_read_page((cmd_data, unsigned char[64])); subPagesLeft = 4; @@ -221,7 +222,6 @@ static int DFU_Upload(unsigned int request_len, unsigned int block_num, unsigned } // Read page data - // HandleUserDeviceRequest(FLASH_CMD_READ_PAGE_DATA, 0, 0, request_data); flash_cmd_write_page_data((request_data, unsigned char[64])); subPagesLeft--; @@ -325,8 +325,6 @@ int DFUReportResetState(chanend ?c_user_cmd) if (currentTime - DFUTimerStart > DFUResetTimeout) { DFU_state = STATE_APP_IDLE; - //printintln(currentTime - DFUTimerStart); - //printintln(DFUResetTimeout); inDFU = 0; } else @@ -350,13 +348,14 @@ int DFUReportResetState(chanend ?c_user_cmd) DFU_state = STATE_DFU_ERROR; inDFU = 1; break; - } + } - if (!inDFU) { - DFU_CloseFlash(c_user_cmd); - } + if (!inDFU) + { + DFU_CloseFlash(c_user_cmd); + } - return inDFU; + return inDFU; } int XMOS_DFU_RevertFactory(chanend ?c_user_cmd) @@ -366,7 +365,6 @@ int XMOS_DFU_RevertFactory(chanend ?c_user_cmd) DFU_OpenFlash(c_user_cmd); - //HandleUserDeviceRequest(FLASH_CMD_ERASE_ALL, 1, 0, cmd_data); flash_cmd_erase_all(); DFUTimer :> s; @@ -375,12 +373,11 @@ int XMOS_DFU_RevertFactory(chanend ?c_user_cmd) return 0; } -int XMOS_DFU_SelectImage(unsigned int index, chanend ?c_user_cmd) { - - // Select the image index for firmware update - - return 0; - +int XMOS_DFU_SelectImage(unsigned int index, chanend ?c_user_cmd) +{ + // Select the image index for firmware update + // Currently not used or implemented + return 0; } @@ -394,102 +391,103 @@ int XMOS_DFU_LoadState() 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) { - unsigned int return_data_len = 0; - unsigned int data_buffer_len = 0; - unsigned int data_buffer[17]; - unsigned int reset_device_after_ack = 0; +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 data_buffer_len = 0; + unsigned int data_buffer[17]; + unsigned int reset_device_after_ack = 0; - if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_OUT) - { // Host to device - if (sp.wLength) + if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_OUT) + { + // Host to device + if (sp.wLength) #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[])); #else - data_buffer_len = XUD_GetBuffer(ep0_out, (data_buffer, unsigned char[])); + data_buffer_len = XUD_GetBuffer(ep0_out, (data_buffer, unsigned char[])); #endif - } + } - // Map Standard DFU commands onto device level firmware upgrade mechanism - switch (sp.bRequest) { - case DFU_DETACH: - return_data_len = DFU_Detach(sp.wValue, c_user_cmd); - break; - case DFU_DNLOAD: - return_data_len = DFU_Dnload(sp.wLength, sp.wValue, data_buffer, c_user_cmd); - break; - case DFU_UPLOAD: - return_data_len = DFU_Upload(sp.wLength, sp.wValue, data_buffer, c_user_cmd); - break; - case DFU_GETSTATUS: - return_data_len = DFU_GetStatus(sp.wLength, data_buffer, c_user_cmd); - break; - case DFU_CLRSTATUS: - return_data_len = DFU_ClrStatus(); - break; - case DFU_GETSTATE: - return_data_len = DFU_GetState(sp.wLength, data_buffer, c_user_cmd); - break; - case DFU_ABORT: - return_data_len = DFU_Abort(); - break; - /* XMOS Custom DFU requests */ - case XMOS_DFU_RESETDEVICE: - reset_device_after_ack = 1; - return_data_len = 0; - break; - case XMOS_DFU_REVERTFACTORY: - return_data_len = XMOS_DFU_RevertFactory(c_user_cmd); - break; - case XMOS_DFU_RESETINTODFU: - reset_device_after_ack = 1; - DFU_reset_override = 0x11042011; - return_data_len = 0; - break; - case XMOS_DFU_RESETFROMDFU: - reset_device_after_ack = 1; - DFU_reset_override = 0; - return_data_len = 0; - break; - case XMOS_DFU_SELECTIMAGE: - return_data_len = XMOS_DFU_SelectImage(sp.wValue, c_user_cmd); - break; - case XMOS_DFU_SAVESTATE: - /* Save passed state to flash */ - return_data_len = XMOS_DFU_SaveState(); - break; - case XMOS_DFU_RESTORESTATE: - /* Restore saved state from flash */ - return_data_len = XMOS_DFU_LoadState(); - break; - default: - break; - } + // Map Standard DFU commands onto device level firmware upgrade mechanism + switch (sp.bRequest) + { + case DFU_DETACH: + return_data_len = DFU_Detach(sp.wValue, c_user_cmd); + break; + case DFU_DNLOAD: + return_data_len = DFU_Dnload(sp.wLength, sp.wValue, data_buffer, c_user_cmd); + break; + case DFU_UPLOAD: + return_data_len = DFU_Upload(sp.wLength, sp.wValue, data_buffer, c_user_cmd); + break; + case DFU_GETSTATUS: + return_data_len = DFU_GetStatus(sp.wLength, data_buffer, c_user_cmd); + break; + case DFU_CLRSTATUS: + return_data_len = DFU_ClrStatus(); + break; + case DFU_GETSTATE: + return_data_len = DFU_GetState(sp.wLength, data_buffer, c_user_cmd); + break; + case DFU_ABORT: + return_data_len = DFU_Abort(); + break; + /* XMOS Custom DFU requests */ + case XMOS_DFU_RESETDEVICE: + reset_device_after_ack = 1; + return_data_len = 0; + break; + case XMOS_DFU_REVERTFACTORY: + return_data_len = XMOS_DFU_RevertFactory(c_user_cmd); + break; + case XMOS_DFU_RESETINTODFU: + reset_device_after_ack = 1; + DFU_reset_override = 0x11042011; + return_data_len = 0; + break; + case XMOS_DFU_RESETFROMDFU: + reset_device_after_ack = 1; + DFU_reset_override = 0; + return_data_len = 0; + break; + case XMOS_DFU_SELECTIMAGE: + return_data_len = XMOS_DFU_SelectImage(sp.wValue, c_user_cmd); + break; + case XMOS_DFU_SAVESTATE: + /* Save passed state to flash */ + return_data_len = XMOS_DFU_SaveState(); + break; + case XMOS_DFU_RESTORESTATE: + /* Restore saved state from flash */ + return_data_len = XMOS_DFU_LoadState(); + break; + default: + 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 - 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 - 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 - } else { + } + else + { #ifdef ARCH_G - XUD_DoSetRequestStatus(ep0_out, 0); + XUD_DoSetRequestStatus(ep0_out, 0); #else - XUD_DoSetRequestStatus(ep0_in, 0); + XUD_DoSetRequestStatus(ep0_in, 0); #endif - } + } // If device reset requested, handle after command acknowledgement if (reset_device_after_ack) { - if (!user_reset) - { - unsigned int cmd_data[16]; - //HandleUserDeviceRequest(FLASH_CMD_REBOOT, 1, 0, cmd_data); - flash_cmd_reboot(); - } - else + if (user_reset) { return 1; } diff --git a/module_dfu/src/flash_interface.c b/module_dfu/src/flash_interface.c index 3cccf96d..d768c167 100755 --- a/module_dfu/src/flash_interface.c +++ b/module_dfu/src/flash_interface.c @@ -9,16 +9,11 @@ #ifdef ARCH_G #define FLASH_MAX_UPGRADE_SIZE 128 * 1024 // 128K default #else -//#define FLASH_MAX_UPGRADE_SIZE 64 * 1024 // 64K default -#define FLASH_MAX_UPGRADE_SIZE 128 * 1024 // 64K default +#define FLASH_MAX_UPGRADE_SIZE 128 * 1024 // 128K default #endif #endif -#if 1 -#define FLASH_ERROR() do { printstr("Error: line: "); printintln(__LINE__); __builtin_trap(); } while(0) -#else #define FLASH_ERROR() do {} while(0) -#endif static int flash_device_open = 0; static fl_BootImageInfo factory_image; @@ -50,7 +45,6 @@ void DFUCustomFlashDisable() return; } - int flash_cmd_init(void) { fl_BootImageInfo image; @@ -93,130 +87,143 @@ int flash_cmd_deinit(void) return 0; } -int flash_cmd_read_page(unsigned char *data) { - if (!upgrade_image_valid) { - *(unsigned int *)data = 1; +int flash_cmd_read_page(unsigned char *data) +{ + if (!upgrade_image_valid) + { + *(unsigned int *)data = 1; + return 4; + } + + if (*(unsigned int *)data == 0) + { + fl_startImageRead(&upgrade_image); + } + + current_flash_subpage_index = 0; + + if (fl_readImageRead(current_flash_page_data) == 0) + { + *(unsigned int *)data = 0; + } + else + { + *(unsigned int *)data = 1; + } return 4; - } - if (*(unsigned int *)data == 0) { - fl_startImageRead(&upgrade_image); - } - current_flash_subpage_index = 0; - if (fl_readImageRead(current_flash_page_data) == 0) { - *(unsigned int *)data = 0; - } else { - *(unsigned int *)data = 1; - } - return 4; } -int flash_cmd_read_page_data(unsigned char *data) { - unsigned char *page_data_ptr = ¤t_flash_page_data[current_flash_subpage_index * 64]; - memcpy(data, page_data_ptr, 64); +int flash_cmd_read_page_data(unsigned char *data) +{ + unsigned char *page_data_ptr = ¤t_flash_page_data[current_flash_subpage_index * 64]; + memcpy(data, page_data_ptr, 64); - current_flash_subpage_index++; + current_flash_subpage_index++; - return 64; + return 64; } static void begin_write() { - int result; - // 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 - // seperate command, e.g. start_write. - do { - result = fl_startImageAdd(&factory_image, FLASH_MAX_UPGRADE_SIZE, 0); - } while (result > 0); - if (result < 0) - FLASH_ERROR(); + int result; + // 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 + // seperate command, e.g. start_write. + do + { + result = fl_startImageAdd(&factory_image, FLASH_MAX_UPGRADE_SIZE, 0); + } while (result > 0); + + if (result < 0) + FLASH_ERROR(); } static int pages_written = 0; -int flash_cmd_write_page(unsigned char *data) { - unsigned int flag = *(unsigned int *)data; - //printstr("flash_cmd_write_page("); - //printint(flag); - //printstr(")\n"); +int flash_cmd_write_page(unsigned char *data) +{ + unsigned int flag = *(unsigned int *)data; + + if (upgrade_image_valid) + { + return 0; + } + + switch (flag) + { + case 0: + // First page. + begin_write(); + pages_written = 0; + // fallthrough + case 1: + // Do nothing. + break; + case 2: + // Termination. + if (fl_endWriteImage() != 0) + FLASH_ERROR(); + + // Sanity check + fl_BootImageInfo image = factory_image; + if (fl_getNextBootImage(&image) != 0) + FLASH_ERROR(); + break; + } + current_flash_subpage_index = 0; - if (upgrade_image_valid) { return 0; - } - - switch (flag) { - case 0: - // First page. - begin_write(); - pages_written = 0; - // fallthrough - case 1: - // Do nothing. - break; - case 2: - // Termination. - if (fl_endWriteImage() != 0) - FLASH_ERROR(); - // Sanity check - fl_BootImageInfo image = factory_image; - if (fl_getNextBootImage(&image) != 0) - FLASH_ERROR(); - break; - } - current_flash_subpage_index = 0; - - return 0; } static int isAllOnes(unsigned char page[256]) { - unsigned i; - for (i = 0; i < 256; i++) { - if (page[i] != 0xff) - return 0; - } - return 1; + unsigned i; + for (i = 0; i < 256; i++) + { + if (page[i] != 0xff) + return 0; + } + return 1; } -int flash_cmd_write_page_data(unsigned char *data) { - unsigned char *page_data_ptr = ¤t_flash_page_data[current_flash_subpage_index * 64]; - //printstr("flash_cmd_write_page_data()\n"); +int flash_cmd_write_page_data(unsigned char *data) +{ + unsigned char *page_data_ptr = ¤t_flash_page_data[current_flash_subpage_index * 64]; + + if (upgrade_image_valid) + { + return 0; + } + + if (current_flash_subpage_index >= 4) + { + return 0; + } + + memcpy(page_data_ptr, data, 64); + + current_flash_subpage_index++; + + if (current_flash_subpage_index == 4) + { + if (isAllOnes(data)) + FLASH_ERROR(); + if (fl_writeImagePage(current_flash_page_data) != 0) + FLASH_ERROR(); + pages_written++; + } - if (upgrade_image_valid) { return 0; - } +} - if (current_flash_subpage_index >= 4) { +int flash_cmd_erase_all(void) +{ + if (upgrade_image_valid) + { + if (fl_deleteImage(&upgrade_image) != 0) + FLASH_ERROR(); + upgrade_image_valid = 0; + } return 0; - } - - memcpy(page_data_ptr, data, 64); - - current_flash_subpage_index++; - - if (current_flash_subpage_index == 4) { - if (isAllOnes(data)) - FLASH_ERROR(); - if (fl_writeImagePage(current_flash_page_data) != 0) - FLASH_ERROR(); - pages_written++; - } - - return 0; } -int flash_cmd_erase_all(void) { - if (upgrade_image_valid) { - if (fl_deleteImage(&upgrade_image) != 0) - FLASH_ERROR(); - upgrade_image_valid = 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; -}