diff --git a/module_dfu/src/dfu.xc b/module_dfu/src/dfu.xc index c6a64545..f2aba72d 100644 --- a/module_dfu/src/dfu.xc +++ b/module_dfu/src/dfu.xc @@ -10,6 +10,28 @@ #include +#if defined(ARCH_X200) && (ARCH_X200 == 1) +/* Note range 0x7FFC8 - 0x7FFFF guarenteed to be untouched by tools */ +#define FLAG_ADDRESS 0x7ffc4 +#else +/* Note range 0x1FFC8 - 0x1FFFF guarenteed to be untouched by tools */ +#define FLAG_ADDRESS 0x1ffc4 +#endif + +/* Store Flag to fixed address */ +static void SetDFUFlag(unsigned x) +{ + asm volatile("stw %0, %1[0]" :: "r"(x), "r"(FLAG_ADDRESS)); +} + +/* Load flag from fixed address */ +static unsigned GetDFUFlag() +{ + unsigned x; + asm volatile("ldw %0, %1[0]" : "=r"(x) : "r"(FLAG_ADDRESS)); + return x; +} + static int g_DFU_state = STATE_APP_IDLE; static int DFU_status = DFU_OK; static timer DFUTimer; @@ -19,8 +41,6 @@ static int DFU_flash_connected = 0; static unsigned int subPagesLeft = 0; -extern int DFU_reset_override; - extern void DFUCustomFlashEnable(); extern void DFUCustomFlashDisable(); @@ -32,13 +52,6 @@ void DFUDelay(unsigned d) tmr when timerafter(s + d) :> void; } - -void temp() -{ - asm(".linkset DFU_reset_override, _edp.bss"); - asm(".globl DFU_reset_override"); -} - /* Return non-zero on error */ static int DFU_OpenFlash() { @@ -321,8 +334,12 @@ int DFUReportResetState(chanend ?c_user_cmd) { unsigned int inDFU = 0; unsigned int currentTime = 0; + + unsigned flag; + flag = GetDFUFlag(); - if (DFU_reset_override == 0x11042011) + //if (DFU_reset_override == 0x11042011) + if (flag == 0x11042011) { unsigned int cmd_data[16]; inDFU = 1; @@ -412,7 +429,7 @@ void DFUHandler(server interface i_dfu i, chanend ?c_user_cmd) select { case i.HandleDfuRequest(USB_SetupPacket_t &sp, unsigned data_buffer[], unsigned data_buffer_length, unsigned dfuState) - -> {unsigned reset_device_after_ack, int return_data_len, unsigned dfu_reset_override, unsigned returnVal, unsigned newDfuState}: + -> {unsigned reset_device_after_ack, int return_data_len, int dfu_reset_override, int returnVal, unsigned newDfuState}: reset_device_after_ack = 0; return_data_len = 0; @@ -519,8 +536,9 @@ int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, ch unsigned int data_buffer_len = 0; unsigned int data_buffer[17]; unsigned int reset_device_after_ack = 0; - unsigned int returnVal = 0; + int returnVal = 0; unsigned int dfuState = g_DFU_state; + int dfuResetOverride; if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_H2D) { @@ -530,21 +548,23 @@ int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, ch } /* Interface used here such that the handler can be on another tile */ - {reset_device_after_ack, return_data_len, DFU_reset_override, returnVal, dfuState} = i.HandleDfuRequest(sp, data_buffer, data_buffer_len, g_DFU_state); + {reset_device_after_ack, return_data_len, dfuResetOverride, returnVal, dfuState} = i.HandleDfuRequest(sp, data_buffer, data_buffer_len, g_DFU_state); + + SetDFUFlag(dfuResetOverride); /* Update our version of dfuState */ g_DFU_state = dfuState; /* Check if the request was handled */ - if(!returnVal) + if(returnVal == 0) { if (sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_D2H && sp.wLength != 0) { - XUD_DoGetRequest(ep0_out, ep0_in, (data_buffer, unsigned char[]), return_data_len, return_data_len); + returnVal = XUD_DoGetRequest(ep0_out, ep0_in, (data_buffer, unsigned char[]), return_data_len, return_data_len); } else { - XUD_DoSetRequestStatus(ep0_in); + returnVal = XUD_DoSetRequestStatus(ep0_in); } // If device reset requested, handle after command acknowledgement diff --git a/module_dfu/src/dfu_interface.h b/module_dfu/src/dfu_interface.h index 1d3fc901..e535313c 100644 --- a/module_dfu/src/dfu_interface.h +++ b/module_dfu/src/dfu_interface.h @@ -6,7 +6,7 @@ interface i_dfu { - {unsigned, int, unsigned, unsigned, unsigned} HandleDfuRequest(USB_SetupPacket_t &sp, unsigned data_buffer[], unsigned data_buffer_length, unsigned dfuState); + {unsigned, int, int, int, unsigned} HandleDfuRequest(USB_SetupPacket_t &sp, unsigned data_buffer[], unsigned data_buffer_length, unsigned dfuState); void finish(); }; #endif diff --git a/module_usb_audio/endpoint0/endpoint0.c b/module_usb_audio/endpoint0/endpoint0.c index b6190ec4..7cdc9a3a 100755 --- a/module_usb_audio/endpoint0/endpoint0.c +++ b/module_usb_audio/endpoint0/endpoint0.c @@ -575,14 +575,11 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, /* This will return 1 if reset requested */ result = DFUDeviceRequests(ep0_out, &ep0_in, &sp, null, g_interfaceAlt[sp.wIndex], dfuInterface, &reset); - if(reset && result == XUD_RES_OKAY) + if(reset) { DFUDelay(50000000); device_reboot(c_audioControl); } - - /* TODO we should not make the assumption that all DFU requests are handled */ - //result = 0; } #endif /* Check for: - Audio CONTROL interface request - always 0, note we check for DFU first diff --git a/module_usb_audio/reboot.xc b/module_usb_audio/reboot.xc index 7d924bdd..14707daf 100644 --- a/module_usb_audio/reboot.xc +++ b/module_usb_audio/reboot.xc @@ -69,4 +69,6 @@ void device_reboot(chanend spare) asm("freer res[%0]"::"r"(spare)); #endif device_reboot_aux(); + + while(1); }