diff --git a/module_dfu/src/dfu.h b/module_dfu/src/dfu.h index 4ca6876b..10fb349c 100644 --- a/module_dfu/src/dfu.h +++ b/module_dfu/src/dfu.h @@ -88,7 +88,7 @@ unsigned char DFUcfgDesc[] = { int DFUReportResetState(NULLABLE_RESOURCE(chanend , c_user_cmd)); int DFUDeviceRequests(XUD_ep c_ep0_out, NULLABLE_REFERENCE_PARAM(XUD_ep, ep0_in), REFERENCE_PARAM(USB_SetupPacket_t, sp), - NULLABLE_RESOURCE(chanend, c_user_cmd), unsigned int altInterface, unsigned int user_reset); + NULLABLE_RESOURCE(chanend, c_user_cmd), unsigned int altInterface, CLIENT_INTERFACE(i_dfu, dfuInterface)); /* Helper function for C */ void DFUDelay(unsigned d); diff --git a/module_dfu/src/dfu.xc b/module_dfu/src/dfu.xc index a47632ee..c3170ba0 100644 --- a/module_dfu/src/dfu.xc +++ b/module_dfu/src/dfu.xc @@ -8,6 +8,8 @@ #include "dfu_types.h" #include "flash_interface.h" +#include + static int DFU_state = STATE_APP_IDLE; static int DFU_status = DFU_OK; static timer DFUTimer; @@ -84,7 +86,7 @@ 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) +static int DFU_Dnload(unsigned int request_len, unsigned int block_num, const unsigned request_data[16], chanend ?c_user_cmd) { unsigned int fromDfuIdle = 0; @@ -176,7 +178,7 @@ static int DFU_Dnload(unsigned int request_len, unsigned int block_num, unsigned } -static int DFU_Upload(unsigned int request_len, unsigned int block_num, unsigned int request_data[16], chanend ?c_user_cmd) +static int DFU_Upload(unsigned int request_len, unsigned int block_num, unsigned data_out[16], chanend ?c_user_cmd) { unsigned int cmd_data[16]; unsigned int firstRead = 0; @@ -226,7 +228,7 @@ static int DFU_Upload(unsigned int request_len, unsigned int block_num, unsigned } // Get 64 bytes of page data from memory - flash_cmd_read_page_data((request_data, unsigned char[64])); + flash_cmd_read_page_data((data_out, unsigned char[64])); subPagesLeft--; @@ -235,11 +237,11 @@ static int DFU_Upload(unsigned int request_len, unsigned int block_num, unsigned return 64; } -static int DFU_GetStatus(unsigned int request_len, unsigned int request_data[16], chanend ?c_user_cmd) +static int DFU_GetStatus(unsigned int request_len, unsigned data_buffer[16], chanend ?c_user_cmd) { unsigned int timeout = 0; - request_data[0] = timeout << 8 | (unsigned char)DFU_status; + data_buffer[0] = timeout << 8 | (unsigned char)DFU_status; switch (DFU_state) { @@ -262,9 +264,10 @@ static int DFU_GetStatus(unsigned int request_len, unsigned int request_data[16] break; } - request_data[1] = DFU_state; + data_buffer[1] = DFU_state; return 6; + } static int DFU_ClrStatus(void) @@ -383,7 +386,6 @@ static int XMOS_DFU_SelectImage(unsigned int index, chanend ?c_user_cmd) return 0; } - static int XMOS_DFU_SaveState() { return 0; @@ -394,13 +396,117 @@ static int XMOS_DFU_LoadState() return 0; } -int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, chanend ?c_user_cmd, unsigned int altInterface, unsigned int user_reset) +[[distributable]] +void DFUHandler(server interface i_dfu i, chanend ?c_user_cmd) +{ + while(1) + { + select + { + case i.HandleDfuRequest(USB_SetupPacket_t &sp, unsigned data_buffer[], unsigned data_buffer_length) + -> {unsigned reset_device_after_ack, int return_data_len, unsigned dfu_reset_override}: + + reset_device_after_ack = 0; + return_data_len = 0; + dfu_reset_override = 0; + + // 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: + unsigned data[16]; + for(int i = 0; i < 16; i++) + data[i] = data_buffer[i]; + return_data_len = DFU_Dnload(sp.wLength, sp.wValue, data, c_user_cmd); + break; + + case DFU_UPLOAD: + unsigned data_out[16]; + return_data_len = DFU_Upload(sp.wLength, sp.wValue, data_out, c_user_cmd); + for(int i = 0; i < 16; i++) + data_buffer[i] = data_out[i]; + break; + + case DFU_GETSTATUS: + unsigned data_out[16]; + return_data_len = DFU_GetStatus(sp.wLength, data_out, c_user_cmd); + for(int i = 0; i < 16; i++) + data_buffer[i] = data_out[i]; + break; + + case DFU_CLRSTATUS: + return_data_len = DFU_ClrStatus(); + break; + + case DFU_GETSTATE: + unsigned data_out[16]; + return_data_len = DFU_GetState(sp.wLength, data_out, c_user_cmd); + for(int i = 0; i < 16; i++) + data_buffer[i] = data_out[i]; + 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; + } + break; + + case i.finish(): + return; + } + } +} + +int DFUDeviceRequests_(client interface i_dfu i, XUD_ep ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, unsigned int altInterface) { 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 == USB_BM_REQTYPE_DIRECTION_H2D) { // Host to device @@ -408,62 +514,8 @@ int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, ch XUD_GetBuffer(ep0_out, (data_buffer, unsigned char[]), data_buffer_len); } - // 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; - } + /* Interface used here such that the handler can be on another tile */ + {reset_device_after_ack, return_data_len, DFU_reset_override} = i.HandleDfuRequest(sp, data_buffer, data_buffer_len); if (sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_D2H && sp.wLength != 0) { @@ -477,11 +529,28 @@ int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, ch // If device reset requested, handle after command acknowledgement if (reset_device_after_ack) { - if (user_reset) - { - return 1; - } + return 1; } return 0; } + +int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, chanend ?c_user_cmd, unsigned int altInterface, client interface i_dfu i) +{ + //interface i_dfu i; + int retVal; + + // par + // { +//#if XUD_TILE == 0 + // /* Flash is always on tile 0, USB may be used on a different tile */ + // [[distribute]] + // DFUHandler(i, c_user_cmd); +//#else +//#error +//#endif + retVal = DFUDeviceRequests_(i, ep0_out, ep0_in, sp, altInterface); + // } + + return retVal; +} diff --git a/module_dfu/src/dfu_interface.h b/module_dfu/src/dfu_interface.h new file mode 100644 index 00000000..60169833 --- /dev/null +++ b/module_dfu/src/dfu_interface.h @@ -0,0 +1,14 @@ + +#ifndef __DFU_INTERFACE_H__ +#define __DFU_INTERFACE_H__ + +#include "usb_std_requests.h" + +interface i_dfu +{ + {unsigned, int, unsigned} HandleDfuRequest(USB_SetupPacket_t &sp, unsigned data_buffer[], unsigned data_buffer_length); + void finish(); +}; +#endif + + diff --git a/module_usb_audio/endpoint0/endpoint0.c b/module_usb_audio/endpoint0/endpoint0.c index ee029edc..701c17a4 100755 --- a/module_usb_audio/endpoint0/endpoint0.c +++ b/module_usb_audio/endpoint0/endpoint0.c @@ -204,7 +204,7 @@ const unsigned g_chanCount_In_HS[INPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_I /* Endpoint 0 function. Handles all requests to the device */ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, - chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl) + chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface)) { USB_SetupPacket_t sp; XUD_ep ep0_out = XUD_InitEp(c_ep0_out); @@ -296,11 +296,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, while(1) { /* Returns XUD_RES_OKAY for success, XUD_RES_RST for bus reset */ -#if defined(__XC__) - XUD_Result_t result = USB_GetSetupPacket(ep0_out, ep0_in, sp); -#else XUD_Result_t result = USB_GetSetupPacket(ep0_out, ep0_in, &sp); -#endif if (result == XUD_RES_OKAY) { @@ -573,13 +569,9 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, // Handshake chkct(c_audioControl, XS1_CT_END); } -#ifdef __XC__ + /* This will return 1 if reset requested */ - if (DFUDeviceRequests(ep0_out, ep0_in, sp, null, g_interfaceAlt[sp.wIndex], 1)) -#else - /* This will return 1 if reset requested */ - if (DFUDeviceRequests(ep0_out, &ep0_in, &sp, null, g_interfaceAlt[sp.wIndex], 1)) -#endif + if (DFUDeviceRequests(ep0_out, &ep0_in, &sp, null, g_interfaceAlt[sp.wIndex], dfuInterface)) { DFUDelay(50000000); device_reboot(c_audioControl); diff --git a/module_usb_audio/endpoint0/endpoint0.h b/module_usb_audio/endpoint0/endpoint0.h index 778d0937..ef3afaa8 100644 --- a/module_usb_audio/endpoint0/endpoint0.h +++ b/module_usb_audio/endpoint0/endpoint0.h @@ -2,6 +2,8 @@ #ifndef _ENDPOINT0_H_ #define _ENDPOINT0_H_ +#include "dfu_interface.h" + /** Function implementing Endpoint 0 for enumeration, control and configuration * of USB audio devices. It uses the descriptors defined in ``descriptors_2.h``. * @@ -18,7 +20,7 @@ * \param c_EANativeTransport_ctrl Optional chanend to be connected to EA Native * endpoint manager if present */ -void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioCtrl, - chanend ?c_mix_ctl,chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctrl); +void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioCtrl, + chanend ?c_mix_ctl,chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctr, client interface i_dfu dfuInterface); #endif diff --git a/module_usb_audio/main.xc b/module_usb_audio/main.xc index 968c7baa..93308e2f 100755 --- a/module_usb_audio/main.xc +++ b/module_usb_audio/main.xc @@ -43,6 +43,9 @@ #include "clocking.h" +[[distributable]] +void DFUHandler(server interface i_dfu i, chanend ?c_user_cmd); + /* Audio I/O - Port declarations */ #if I2S_WIRES_DAC > 0 on tile[AUDIO_IO_TILE] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] = @@ -296,6 +299,12 @@ void usb_audio_core(chanend c_mix_out #define c_EANativeTransport_ctrl null #endif +#ifdef DFU + interface i_dfu dfuInterface; +#else + #define dfuInterface null +#endif + par { /* USB Interface Core */ @@ -367,7 +376,12 @@ void usb_audio_core(chanend c_mix_out /* Endpoint 0 Core */ { thread_speed(); - Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl); + par + { + [[distribute]] + DFUHandler(dfuInterface, null); + Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface); + } } /* Decoupling core */