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

@@ -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;
}