diff --git a/examples/xua_lite_example/src/app_xua_lite.xc b/examples/xua_lite_example/src/app_xua_lite.xc index d1be770d..934666aa 100644 --- a/examples/xua_lite_example/src/app_xua_lite.xc +++ b/examples/xua_lite_example/src/app_xua_lite.xc @@ -53,6 +53,8 @@ void XUA_Buffer_lite(chanend c_aud_out, chanend c_feedback, chanend c_aud_in, ch [[distributable]] void AudioHub(server i2s_frame_callback_if i2s, chanend c_aud, client i2c_master_if ?i2c, client output_gpio_if dac_reset); void AudioHwConfigure(unsigned samFreq, client i2c_master_if i_i2c); +void XUA_Endpoint0_select(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, + chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, ?dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_); int main() { @@ -103,7 +105,8 @@ int main() // Endpoint 0 core from lib_xua // Note, since we are not using many features we pass in null for quite a few params.. - XUA_Endpoint0(c_ep_out[0], c_ep_in[0], c_aud_ctl, null, null, null, null); + // XUA_Endpoint0(c_ep_out[0], c_ep_in[0], c_aud_ctl, null, null, null, null); + XUA_Endpoint0_select(c_ep_out[0], c_ep_in[0], c_aud_ctl, null, null, null, null); // Buffering cores - handles audio data to/from EP's and gives/gets data to/from the audio I/O core XUA_Buffer_lite(c_ep_out[1], c_ep_in[1], c_ep_in[2], c_sof, c_aud_ctl, p_for_mclk_count, c_audio); diff --git a/examples/xua_lite_example/src/xua_buffer.xc b/examples/xua_lite_example/src/xua_buffer.xc index 3d4a17fd..b6750a84 100644 --- a/examples/xua_lite_example/src/xua_buffer.xc +++ b/examples/xua_lite_example/src/xua_buffer.xc @@ -301,7 +301,7 @@ void XUA_Buffer_lite(chanend c_aud_out, chanend c_feedback, chanend c_aud_in, ch // for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio_hub <: samples_out[1]; int out_samps[NUM_USB_CHAN_OUT]; fifo_ret_t ret = fifo_block_pop(host_to_device_fifo_ptr, out_samps, NUM_USB_CHAN_OUT); - if (ret != FIFO_SUCCESS) debug_printf("empty\n"); + //if (ret != FIFO_SUCCESS) debug_printf("empty\n"); for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio_hub <: out_samps[i]; break; } diff --git a/lib_xua/src/core/endpoint0/xua_endpoint0.c b/lib_xua/src/core/endpoint0/xua_endpoint0.c index eef8323e..3bb36f55 100755 --- a/lib_xua/src/core/endpoint0/xua_endpoint0.c +++ b/lib_xua/src/core/endpoint0/xua_endpoint0.c @@ -200,13 +200,14 @@ const unsigned g_chanCount_In_HS[INPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_I #endif }; -/* Endpoint 0 function. Handles all requests to the device */ -void XUA_Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, +XUD_ep ep0_out; +XUD_ep ep0_in; + +void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_) { - USB_SetupPacket_t sp; - XUD_ep ep0_out = XUD_InitEp(c_ep0_out); - XUD_ep ep0_in = XUD_InitEp(c_ep0_in); + ep0_out = XUD_InitEp(c_ep0_out); + ep0_in = XUD_InitEp(c_ep0_in); #if 0 /* Dont need to init globals.. */ @@ -295,6 +296,520 @@ void XUA_Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, } #endif +} + +void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, + chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_) +{ + if (result == XUD_RES_OKAY) + { + result = XUD_RES_ERR; + + /* Inspect Request type and Receipient and direction */ + switch( (sp.bmRequestType.Direction << 7) | (sp.bmRequestType.Recipient ) | (sp.bmRequestType.Type << 5) ) + { + case USB_BMREQ_H2D_STANDARD_INT: + + /* Over-riding USB_StandardRequests implementation */ + if(sp.bRequest == USB_SET_INTERFACE) + { + switch (sp.wIndex) + { + /* Check for audio stream from host start/stop */ +#if (NUM_USB_CHAN_OUT > 0) && (AUDIO_CLASS == 2) + case INTERFACE_NUMBER_AUDIO_OUTPUT: + /* Check the alt is in range */ + if(sp.wValue <= OUTPUT_FORMAT_COUNT) + { + /* Alt 0 is stream stop */ + /* Only send change if we need to */ + if((sp.wValue > 0) && (g_curStreamAlt_Out != sp.wValue)) + { + g_curStreamAlt_Out = sp.wValue; + + /* Send format of data onto buffering */ + outuint(c_audioControl, SET_STREAM_FORMAT_OUT); + outuint(c_audioControl, g_dataFormat_Out[sp.wValue-1]); /* Data format (PCM/DSD) */ + + if(g_curUsbSpeed == XUD_SPEED_HS) + { + outuint(c_audioControl, NUM_USB_CHAN_OUT); /* Channel count */ + outuint(c_audioControl, g_subSlot_Out_HS[sp.wValue-1]); /* Subslot */ + outuint(c_audioControl, g_sampRes_Out_HS[sp.wValue-1]); /* Resolution */ + } + else + { + outuint(c_audioControl, NUM_USB_CHAN_OUT_FS); /* Channel count */ + outuint(c_audioControl, g_subSlot_Out_FS[sp.wValue-1]); /* Subslot */ + outuint(c_audioControl, g_sampRes_Out_FS[sp.wValue-1]); /* Resolution */ + } + + /* Handshake */ + chkct(c_audioControl, XS1_CT_END); + } + } + break; +#endif + +#if (NUM_USB_CHAN_IN > 0) && (AUDIO_CLASS == 2) + case INTERFACE_NUMBER_AUDIO_INPUT: + /* Check the alt is in range */ + if(sp.wValue <= INPUT_FORMAT_COUNT) + { + /* Alt 0 is stream stop */ + /* Only send change if we need to */ + if((sp.wValue > 0) && (g_curStreamAlt_In != sp.wValue)) + { + g_curStreamAlt_In = sp.wValue; + + /* Send format of data onto buffering */ + outuint(c_audioControl, SET_STREAM_FORMAT_IN); + outuint(c_audioControl, g_dataFormat_In[sp.wValue-1]); /* Data format (PCM/DSD) */ + + if(g_curUsbSpeed == XUD_SPEED_HS) + { + outuint(c_audioControl, g_chanCount_In_HS[sp.wValue-1]); /* Channel count */ + outuint(c_audioControl, g_subSlot_In_HS[sp.wValue-1]); /* Subslot */ + outuint(c_audioControl, g_sampRes_In_HS[sp.wValue-1]); /* Resolution */ + } + else + { + outuint(c_audioControl, NUM_USB_CHAN_IN_FS); /* Channel count */ + outuint(c_audioControl, g_subSlot_In_FS[sp.wValue-1]); /* Subslot */ + outuint(c_audioControl, g_sampRes_In_FS[sp.wValue-1]); /* Resolution */ + } + + /* Wait for handshake */ + chkct(c_audioControl, XS1_CT_END); + } + } + break; +#endif + +#ifdef IAP_EA_NATIVE_TRANS + case INTERFACE_NUMBER_IAP_EA_NATIVE_TRANS: + /* Check the alt is in range */ + if (sp.wValue <= IAP_EA_NATIVE_TRANS_ALT_COUNT) + { + /* Reset all state of endpoints associated with this interface + * when changing an alternative setting. See USB 2.0 Spec 9.1.1.5 */ + XUD_ResetEpStateByAddr(ENDPOINT_ADDRESS_IN_IAP_EA_NATIVE_TRANS); + XUD_ResetEpStateByAddr(ENDPOINT_ADDRESS_OUT_IAP_EA_NATIVE_TRANS); + + /* Send selected Alt interface number onto EA Native EP manager */ + outuint(c_EANativeTransport_ctrl, (unsigned)sp.wValue); + + /* Wait for handshake */ + chkct(c_EANativeTransport_ctrl, XS1_CT_END); + } + break; +#endif + default: + /* Unhandled interface */ + break; + } + +#if (NUM_USB_CHAN_OUT > 0) && (NUM_USB_CHAN_IN > 0) + if ((sp.wIndex == INTERFACE_NUMBER_AUDIO_OUTPUT) || (sp.wIndex == INTERFACE_NUMBER_AUDIO_INPUT)) + { + /* Check for stream start stop on output and input audio interfaces */ + if(sp.wValue && !g_interfaceAlt[INTERFACE_NUMBER_AUDIO_OUTPUT] && !g_interfaceAlt[INTERFACE_NUMBER_AUDIO_INPUT]) + { + /* If start and input AND output not currently running */ + UserAudioStreamStart(); + } + else if(((sp.wIndex == 1) && (!sp.wValue)) && g_interfaceAlt[INTERFACE_NUMBER_AUDIO_OUTPUT] && (!g_interfaceAlt[INTERFACE_NUMBER_AUDIO_INPUT])) + { + /* if output stop and output running and input not running */ + UserAudioStreamStop(); + } + else if(((sp.wIndex == 2) && (!sp.wValue)) && g_interfaceAlt[INTERFACE_NUMBER_AUDIO_INPUT] && (!g_interfaceAlt[INTERFACE_NUMBER_AUDIO_OUTPUT])) + { + /* if input stop and input running and output not running */ + UserAudioStreamStop(); + } + } +#elif (NUM_USB_CHAN_OUT > 0) + if(sp.wIndex == INTERFACE_NUMBER_AUDIO_OUTPUT) + { + if(sp.wValue && (!g_interfaceAlt[INTERFACE_NUMBER_AUDIO_OUTPUT])) + { + /* if start and not currently running */ + UserAudioStreamStart(); + } + else if (!sp.wValue && g_interfaceAlt[INTERFACE_NUMBER_AUDIO_OUTPUT]) + { + /* if stop and currently running */ + UserAudioStreamStop(); + } + } +#elif (NUM_USB_CHAN_IN > 0) + if(sp.wIndex == INTERFACE_NUMBER_AUDIO_INPUT) + { + if(sp.wValue && (!g_interfaceAlt[INTERFACE_NUMBER_AUDIO_INPUT])) + { + /* if start and not currently running */ + UserAudioStreamStart(); + } + else if (!sp.wValue && g_interfaceAlt[INTERFACE_NUMBER_AUDIO_INPUT]) + { + /* if stop and currently running */ + UserAudioStreamStop(); + } + } +#endif + } /* if(sp.bRequest == SET_INTERFACE) */ + + break; /* BMREQ_H2D_STANDARD_INT */ + + case USB_BMREQ_D2H_STANDARD_INT: + + switch(sp.bRequest) + { +#ifdef HID_CONTROLS + case USB_GET_DESCRIPTOR: + + /* Check what inteface request is for */ + if(sp.wIndex == INTERFACE_NUMBER_HID) + { + /* High byte of wValue is descriptor type */ + unsigned descriptorType = sp.wValue & 0xff00; + + switch (descriptorType) + { + case HID_HID: + /* Return HID Descriptor */ + result = XUD_DoGetRequest(ep0_out, ep0_in, hidDescriptor, + sizeof(hidDescriptor), sp.wLength); + break; + case HID_REPORT: + /* Return HID report descriptor */ + result = XUD_DoGetRequest(ep0_out, ep0_in, hidReportDescriptor, + sizeof(hidReportDescriptor), sp.wLength); + break; + } + } + break; +#endif + default: + break; + } + break; + + /* Recipient: Device */ + case USB_BMREQ_H2D_STANDARD_DEV: + + /* Inspect for actual request */ + switch( sp.bRequest ) + { + /* Standard request: SetConfiguration */ + /* Overriding implementation in USB_StandardRequests */ + case USB_SET_CONFIGURATION: + + //if(g_current_config == 1) + { + /* Consider host active with valid driver at this point */ + UserHostActive(1); + } + + /* We want to run USB_StandardsRequests() implementation also. Don't modify result + * and don't call XUD_DoSetRequestStatus() */ + break; + + default: + //Unknown device request" + break; + } + break; + + /* Audio Class 1.0 Sampling Freqency Requests go to Endpoint */ + case USB_BMREQ_H2D_CLASS_EP: + case USB_BMREQ_D2H_CLASS_EP: + { + unsigned epNum = sp.wIndex & 0xff; + + if ((epNum == ENDPOINT_ADDRESS_OUT_AUDIO) || (epNum == ENDPOINT_ADDRESS_IN_AUDIO)) + { +#if (AUDIO_CLASS == 2) && (AUDIO_CLASS_FALLBACK) + if(g_curUsbSpeed == XUD_SPEED_FS) + { + result = AudioEndpointRequests_1(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); + } +#elif (AUDIO_CLASS==1) + result = AudioEndpointRequests_1(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); +#endif + } + + } + break; + + case USB_BMREQ_H2D_CLASS_INT: + case USB_BMREQ_D2H_CLASS_INT: + { + unsigned interfaceNum = sp.wIndex & 0xff; + //unsigned request = (sp.bmRequestType.Recipient ) | (sp.bmRequestType.Type << 5); + + /* TODO Check on return value retval = */ +#if (XUA_DFU_EN == 1) + unsigned DFU_IF = INTERFACE_NUMBER_DFU; + + /* DFU interface number changes based on which mode we are currently running in */ + if (DFU_mode_active) + { + DFU_IF = 0; + } + + if (interfaceNum == DFU_IF) + { + int reset = 0; + + /* If running in application mode stop audio */ + /* Don't interupt audio for save and restore cmds */ + if ((DFU_IF == INTERFACE_NUMBER_DFU) && (sp.bRequest != XMOS_DFU_SAVESTATE) && + (sp.bRequest != XMOS_DFU_RESTORESTATE)) + { + // Stop audio + outuint(c_audioControl, SET_SAMPLE_FREQ); + outuint(c_audioControl, AUDIO_STOP_FOR_DFU); + // Handshake + chkct(c_audioControl, XS1_CT_END); + } + + /* This will return 1 if reset requested */ + result = DFUDeviceRequests(ep0_out, &ep0_in, &sp, null, g_interfaceAlt[sp.wIndex], dfuInterface, &reset); + + if(reset) + { + DFUDelay(50000000); + device_reboot(); + } + } +#endif + /* Check for: - Audio CONTROL interface request - always 0, note we check for DFU first + * - Audio STREAMING interface request (In or Out) + * - Audio endpoint request (Audio 1.0 Sampling freq requests are sent to the endpoint) + */ + if(((interfaceNum == 0) || (interfaceNum == 1) || (interfaceNum == 2)) +#if (XUA_DFU_EN == 1) + && !DFU_mode_active +#endif + ) + { +#if (AUDIO_CLASS == 2) && (AUDIO_CLASS_FALLBACK) + if(g_curUsbSpeed == XUD_SPEED_HS) + { + result = AudioClassRequests_2(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); + } + else + { + result = AudioClassRequests_1(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); + } +#elif (AUDIO_CLASS==2) + result = AudioClassRequests_2(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); +#else + result = AudioClassRequests_1(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); +#endif + +#ifdef VENDOR_AUDIO_REQS + /* If result is ERR at this point, then request to audio interface not handled - handle vendor audio reqs */ + if(result == XUD_RES_ERR) + { + result = VendorAudioRequests(ep0_out, ep0_in, sp.bRequest, + sp.wValue >> 8, sp.wValue & 0xff, + sp.wIndex >> 8, sp.bmRequestType.Direction, + c_audioControl, c_mix_ctl, c_clk_ctl); + } +#endif + } + } + break; + + default: + break; + } + + } /* if(result == XUD_RES_OKAY) */ + + { + if(result == XUD_RES_ERR) + { + /* Run vendor defined parsing/processing */ + /* Note, an interface might seem ideal here but this *must* be executed on the same + * core sure to shared memory depandancy */ + result = VendorRequests(ep0_out, ep0_in, &sp VENDOR_REQUESTS_PARAMS_); + } + } + + if(result == XUD_RES_ERR) + { +#if (XUA_DFU_EN == 1) + if (!DFU_mode_active) + { +#endif +#if (AUDIO_CLASS_FALLBACK) && (AUDIO_CLASS != 1) + /* Return Audio 2.0 Descriptors with Audio 1.0 as fallback */ + result = USB_StandardRequests(ep0_out, ep0_in, + (unsigned char*)&devDesc_Audio2, sizeof(devDesc_Audio2), + (unsigned char*)&cfgDesc_Audio2, sizeof(cfgDesc_Audio2), + (unsigned char*)&devDesc_Audio1, sizeof(devDesc_Audio1), + cfgDesc_Audio1, sizeof(cfgDesc_Audio1), + (char**)&g_strTable, sizeof(g_strTable)/sizeof(char *), + &sp, g_curUsbSpeed); +#elif FULL_SPEED_AUDIO_2 + /* Return Audio 2.0 Descriptors for high_speed and full-speed */ + + /* Unfortunately we need to munge the descriptors a bit between full and high-speed */ + if(g_curUsbSpeed == XUD_SPEED_HS) + { + /* Modify Audio Class 2.0 Config descriptor for High-speed operation */ +#if (NUM_USB_CHAN_OUT > 0) + cfgDesc_Audio2.Audio_CS_Control_Int.Audio_Out_InputTerminal.bNrChannels = NUM_USB_CHAN_OUT; +#if (NUM_USB_CHAN_OUT > 0) + cfgDesc_Audio2.Audio_Out_Format.bSubslotSize = HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_Out_Format.bBitResolution = HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_Out_Endpoint.wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_Out_ClassStreamInterface.bNrChannels = NUM_USB_CHAN_OUT; +#endif +#if (OUTPUT_FORMAT_COUNT > 1) + cfgDesc_Audio2.Audio_Out_Format_2.bSubslotSize = HS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_Out_Format_2.bBitResolution = HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_Out_Endpoint_2.wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_2_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_Out_ClassStreamInterface_2.bNrChannels = NUM_USB_CHAN_OUT; +#endif + +#if (OUTPUT_FORMAT_COUNT > 2) + cfgDesc_Audio2.Audio_Out_Format_3.bSubslotSize = HS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_Out_Format_3.bBitResolution = HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_Out_Endpoint_3.wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_3_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_Out_ClassStreamInterface_3.bNrChannels = NUM_USB_CHAN_OUT; +#endif +#endif +#if (NUM_USB_CHAN_IN > 0) + cfgDesc_Audio2.Audio_CS_Control_Int.Audio_In_InputTerminal.bNrChannels = NUM_USB_CHAN_IN; + cfgDesc_Audio2.Audio_In_Format.bSubslotSize = HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_In_Format.bBitResolution = HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_In_Endpoint.wMaxPacketSize = HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_In_ClassStreamInterface.bNrChannels = NUM_USB_CHAN_IN; +#endif + } + else + { + /* Modify Audio Class 2.0 Config descriptor for Full-speed operation */ +#if (NUM_USB_CHAN_OUT > 0) + cfgDesc_Audio2.Audio_CS_Control_Int.Audio_Out_InputTerminal.bNrChannels = NUM_USB_CHAN_OUT_FS; +#if (NUM_USB_CHAN_OUT > 0) + cfgDesc_Audio2.Audio_Out_Format.bSubslotSize = FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_Out_Format.bBitResolution = FS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_Out_Endpoint.wMaxPacketSize = FS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_Out_ClassStreamInterface.bNrChannels = NUM_USB_CHAN_OUT_FS; +#endif +#if (OUTPUT_FORMAT_COUNT > 1) + cfgDesc_Audio2.Audio_Out_Format_2.bSubslotSize = FS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_Out_Format_2.bBitResolution = FS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_Out_Endpoint_2.wMaxPacketSize = FS_STREAM_FORMAT_OUTPUT_2_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_Out_ClassStreamInterface_2.bNrChannels = NUM_USB_CHAN_OUT_FS; +#endif + +#if (OUTPUT_FORMAT_COUNT > 2) + cfgDesc_Audio2.Audio_Out_Format_3.bSubslotSize = FS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_Out_Format_3.bBitResolution = FS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_Out_Endpoint_3.wMaxPacketSize = FS_STREAM_FORMAT_OUTPUT_3_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_Out_ClassStreamInterface_3.bNrChannels = NUM_USB_CHAN_OUT_FS; +#endif +#endif +#if (NUM_USB_CHAN_IN > 0) + cfgDesc_Audio2.Audio_CS_Control_Int.Audio_In_InputTerminal.bNrChannels = NUM_USB_CHAN_IN_FS; + cfgDesc_Audio2.Audio_In_Format.bSubslotSize = FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_In_Format.bBitResolution = FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_In_Endpoint.wMaxPacketSize = FS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_In_ClassStreamInterface.bNrChannels = NUM_USB_CHAN_IN_FS; +#endif + } + + result = USB_StandardRequests(ep0_out, ep0_in, + (unsigned char*)&devDesc_Audio2, sizeof(devDesc_Audio2), + (unsigned char*)&cfgDesc_Audio2, sizeof(cfgDesc_Audio2), + null, 0, + null, 0, +#ifdef __XC__ + g_strTable, sizeof(g_strTable), sp, null, g_curUsbSpeed); +#else + (char**)&g_strTable, sizeof(g_strTable)/sizeof(char *), &sp, g_curUsbSpeed); +#endif +#elif (AUDIO_CLASS == 1) + /* Return Audio 1.0 Descriptors in FS, should never be in HS! */ + result = USB_StandardRequests(ep0_out, ep0_in, + null, 0, + null, 0, + (unsigned char*)&devDesc_Audio1, sizeof(devDesc_Audio1), + cfgDesc_Audio1, sizeof(cfgDesc_Audio1), + (char**)&g_strTable, sizeof(g_strTable)/sizeof(char *), &sp, g_curUsbSpeed); +#else + /* Return Audio 2.0 Descriptors with Null device as fallback */ + result = USB_StandardRequests(ep0_out, ep0_in, + (unsigned char*)&devDesc_Audio2, sizeof(devDesc_Audio2), + (unsigned char*)&cfgDesc_Audio2, sizeof(cfgDesc_Audio2), + devDesc_Null, sizeof(devDesc_Null), + cfgDesc_Null, sizeof(cfgDesc_Null), + (char**)&g_strTable, sizeof(g_strTable)/sizeof(char *), &sp, g_curUsbSpeed); +#endif +#if (XUA_DFU_EN == 1) + } + + else + { + /* Running in DFU mode - always return same descs for DFU whether HS or FS */ + result = USB_StandardRequests(ep0_out, ep0_in, + DFUdevDesc, sizeof(DFUdevDesc), + DFUcfgDesc, sizeof(DFUcfgDesc), + null, 0, /* Used same descriptors for full and high-speed */ + null, 0, + (char**)&g_strTable, sizeof(g_strTable)/sizeof(char *), &sp, g_curUsbSpeed); + } +#endif + } + + if (result == XUD_RES_RST) + { +#ifdef __XC__ + g_curUsbSpeed = XUD_ResetEndpoint(ep0_out, ep0_in); +#else + g_curUsbSpeed = XUD_ResetEndpoint(ep0_out, &ep0_in); +#endif + g_currentConfig = 0; + g_curStreamAlt_Out = 0; + g_curStreamAlt_In = 0; + +#if (XUA_DFU_EN == 1) + if (DFUReportResetState(null)) + { + if (!DFU_mode_active) + { + DFU_mode_active = 1; + } + } + else + { + if (DFU_mode_active) + { + DFU_mode_active = 0; + + /* Send reboot command */ + DFUDelay(5000000); + device_reboot(); + } + } +#endif + } +} + +/* Endpoint 0 function. Handles all requests to the device */ +void XUA_Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, + chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_) +{ + USB_SetupPacket_t sp; + XUA_Endpoint0_init(c_ep0_out, c_ep0_in, c_audioControl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface); + while(1) { #if XUA_LITE @@ -318,506 +833,7 @@ void XUA_Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, /* Returns XUD_RES_OKAY for success, XUD_RES_RST for bus reset */ XUD_Result_t result = USB_GetSetupPacket(ep0_out, ep0_in, &sp); #endif - if (result == XUD_RES_OKAY) - { - result = XUD_RES_ERR; - - /* Inspect Request type and Receipient and direction */ - switch( (sp.bmRequestType.Direction << 7) | (sp.bmRequestType.Recipient ) | (sp.bmRequestType.Type << 5) ) - { - case USB_BMREQ_H2D_STANDARD_INT: - - /* Over-riding USB_StandardRequests implementation */ - if(sp.bRequest == USB_SET_INTERFACE) - { - switch (sp.wIndex) - { - /* Check for audio stream from host start/stop */ -#if (NUM_USB_CHAN_OUT > 0) && (AUDIO_CLASS == 2) - case INTERFACE_NUMBER_AUDIO_OUTPUT: - /* Check the alt is in range */ - if(sp.wValue <= OUTPUT_FORMAT_COUNT) - { - /* Alt 0 is stream stop */ - /* Only send change if we need to */ - if((sp.wValue > 0) && (g_curStreamAlt_Out != sp.wValue)) - { - g_curStreamAlt_Out = sp.wValue; - - /* Send format of data onto buffering */ - outuint(c_audioControl, SET_STREAM_FORMAT_OUT); - outuint(c_audioControl, g_dataFormat_Out[sp.wValue-1]); /* Data format (PCM/DSD) */ - - if(g_curUsbSpeed == XUD_SPEED_HS) - { - outuint(c_audioControl, NUM_USB_CHAN_OUT); /* Channel count */ - outuint(c_audioControl, g_subSlot_Out_HS[sp.wValue-1]); /* Subslot */ - outuint(c_audioControl, g_sampRes_Out_HS[sp.wValue-1]); /* Resolution */ - } - else - { - outuint(c_audioControl, NUM_USB_CHAN_OUT_FS); /* Channel count */ - outuint(c_audioControl, g_subSlot_Out_FS[sp.wValue-1]); /* Subslot */ - outuint(c_audioControl, g_sampRes_Out_FS[sp.wValue-1]); /* Resolution */ - } - - /* Handshake */ - chkct(c_audioControl, XS1_CT_END); - } - } - break; -#endif - -#if (NUM_USB_CHAN_IN > 0) && (AUDIO_CLASS == 2) - case INTERFACE_NUMBER_AUDIO_INPUT: - /* Check the alt is in range */ - if(sp.wValue <= INPUT_FORMAT_COUNT) - { - /* Alt 0 is stream stop */ - /* Only send change if we need to */ - if((sp.wValue > 0) && (g_curStreamAlt_In != sp.wValue)) - { - g_curStreamAlt_In = sp.wValue; - - /* Send format of data onto buffering */ - outuint(c_audioControl, SET_STREAM_FORMAT_IN); - outuint(c_audioControl, g_dataFormat_In[sp.wValue-1]); /* Data format (PCM/DSD) */ - - if(g_curUsbSpeed == XUD_SPEED_HS) - { - outuint(c_audioControl, g_chanCount_In_HS[sp.wValue-1]); /* Channel count */ - outuint(c_audioControl, g_subSlot_In_HS[sp.wValue-1]); /* Subslot */ - outuint(c_audioControl, g_sampRes_In_HS[sp.wValue-1]); /* Resolution */ - } - else - { - outuint(c_audioControl, NUM_USB_CHAN_IN_FS); /* Channel count */ - outuint(c_audioControl, g_subSlot_In_FS[sp.wValue-1]); /* Subslot */ - outuint(c_audioControl, g_sampRes_In_FS[sp.wValue-1]); /* Resolution */ - } - - /* Wait for handshake */ - chkct(c_audioControl, XS1_CT_END); - } - } - break; -#endif - -#ifdef IAP_EA_NATIVE_TRANS - case INTERFACE_NUMBER_IAP_EA_NATIVE_TRANS: - /* Check the alt is in range */ - if (sp.wValue <= IAP_EA_NATIVE_TRANS_ALT_COUNT) - { - /* Reset all state of endpoints associated with this interface - * when changing an alternative setting. See USB 2.0 Spec 9.1.1.5 */ - XUD_ResetEpStateByAddr(ENDPOINT_ADDRESS_IN_IAP_EA_NATIVE_TRANS); - XUD_ResetEpStateByAddr(ENDPOINT_ADDRESS_OUT_IAP_EA_NATIVE_TRANS); - - /* Send selected Alt interface number onto EA Native EP manager */ - outuint(c_EANativeTransport_ctrl, (unsigned)sp.wValue); - - /* Wait for handshake */ - chkct(c_EANativeTransport_ctrl, XS1_CT_END); - } - break; -#endif - default: - /* Unhandled interface */ - break; - } - -#if (NUM_USB_CHAN_OUT > 0) && (NUM_USB_CHAN_IN > 0) - if ((sp.wIndex == INTERFACE_NUMBER_AUDIO_OUTPUT) || (sp.wIndex == INTERFACE_NUMBER_AUDIO_INPUT)) - { - /* Check for stream start stop on output and input audio interfaces */ - if(sp.wValue && !g_interfaceAlt[INTERFACE_NUMBER_AUDIO_OUTPUT] && !g_interfaceAlt[INTERFACE_NUMBER_AUDIO_INPUT]) - { - /* If start and input AND output not currently running */ - UserAudioStreamStart(); - } - else if(((sp.wIndex == 1) && (!sp.wValue)) && g_interfaceAlt[INTERFACE_NUMBER_AUDIO_OUTPUT] && (!g_interfaceAlt[INTERFACE_NUMBER_AUDIO_INPUT])) - { - /* if output stop and output running and input not running */ - UserAudioStreamStop(); - } - else if(((sp.wIndex == 2) && (!sp.wValue)) && g_interfaceAlt[INTERFACE_NUMBER_AUDIO_INPUT] && (!g_interfaceAlt[INTERFACE_NUMBER_AUDIO_OUTPUT])) - { - /* if input stop and input running and output not running */ - UserAudioStreamStop(); - } - } -#elif (NUM_USB_CHAN_OUT > 0) - if(sp.wIndex == INTERFACE_NUMBER_AUDIO_OUTPUT) - { - if(sp.wValue && (!g_interfaceAlt[INTERFACE_NUMBER_AUDIO_OUTPUT])) - { - /* if start and not currently running */ - UserAudioStreamStart(); - } - else if (!sp.wValue && g_interfaceAlt[INTERFACE_NUMBER_AUDIO_OUTPUT]) - { - /* if stop and currently running */ - UserAudioStreamStop(); - } - } -#elif (NUM_USB_CHAN_IN > 0) - if(sp.wIndex == INTERFACE_NUMBER_AUDIO_INPUT) - { - if(sp.wValue && (!g_interfaceAlt[INTERFACE_NUMBER_AUDIO_INPUT])) - { - /* if start and not currently running */ - UserAudioStreamStart(); - } - else if (!sp.wValue && g_interfaceAlt[INTERFACE_NUMBER_AUDIO_INPUT]) - { - /* if stop and currently running */ - UserAudioStreamStop(); - } - } -#endif - } /* if(sp.bRequest == SET_INTERFACE) */ - - break; /* BMREQ_H2D_STANDARD_INT */ - - case USB_BMREQ_D2H_STANDARD_INT: - - switch(sp.bRequest) - { -#ifdef HID_CONTROLS - case USB_GET_DESCRIPTOR: - - /* Check what inteface request is for */ - if(sp.wIndex == INTERFACE_NUMBER_HID) - { - /* High byte of wValue is descriptor type */ - unsigned descriptorType = sp.wValue & 0xff00; - - switch (descriptorType) - { - case HID_HID: - /* Return HID Descriptor */ - result = XUD_DoGetRequest(ep0_out, ep0_in, hidDescriptor, - sizeof(hidDescriptor), sp.wLength); - break; - case HID_REPORT: - /* Return HID report descriptor */ - result = XUD_DoGetRequest(ep0_out, ep0_in, hidReportDescriptor, - sizeof(hidReportDescriptor), sp.wLength); - break; - } - } - break; -#endif - default: - break; - } - break; - - /* Recipient: Device */ - case USB_BMREQ_H2D_STANDARD_DEV: - - /* Inspect for actual request */ - switch( sp.bRequest ) - { - /* Standard request: SetConfiguration */ - /* Overriding implementation in USB_StandardRequests */ - case USB_SET_CONFIGURATION: - - //if(g_current_config == 1) - { - /* Consider host active with valid driver at this point */ - UserHostActive(1); - } - - /* We want to run USB_StandardsRequests() implementation also. Don't modify result - * and don't call XUD_DoSetRequestStatus() */ - break; - - default: - //Unknown device request" - break; - } - break; - - /* Audio Class 1.0 Sampling Freqency Requests go to Endpoint */ - case USB_BMREQ_H2D_CLASS_EP: - case USB_BMREQ_D2H_CLASS_EP: - { - unsigned epNum = sp.wIndex & 0xff; - - if ((epNum == ENDPOINT_ADDRESS_OUT_AUDIO) || (epNum == ENDPOINT_ADDRESS_IN_AUDIO)) - { -#if (AUDIO_CLASS == 2) && (AUDIO_CLASS_FALLBACK) - if(g_curUsbSpeed == XUD_SPEED_FS) - { - result = AudioEndpointRequests_1(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); - } -#elif (AUDIO_CLASS==1) - result = AudioEndpointRequests_1(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); -#endif - } - - } - break; - - case USB_BMREQ_H2D_CLASS_INT: - case USB_BMREQ_D2H_CLASS_INT: - { - unsigned interfaceNum = sp.wIndex & 0xff; - //unsigned request = (sp.bmRequestType.Recipient ) | (sp.bmRequestType.Type << 5); - - /* TODO Check on return value retval = */ -#if (XUA_DFU_EN == 1) - unsigned DFU_IF = INTERFACE_NUMBER_DFU; - - /* DFU interface number changes based on which mode we are currently running in */ - if (DFU_mode_active) - { - DFU_IF = 0; - } - - if (interfaceNum == DFU_IF) - { - int reset = 0; - - /* If running in application mode stop audio */ - /* Don't interupt audio for save and restore cmds */ - if ((DFU_IF == INTERFACE_NUMBER_DFU) && (sp.bRequest != XMOS_DFU_SAVESTATE) && - (sp.bRequest != XMOS_DFU_RESTORESTATE)) - { - // Stop audio - outuint(c_audioControl, SET_SAMPLE_FREQ); - outuint(c_audioControl, AUDIO_STOP_FOR_DFU); - // Handshake - chkct(c_audioControl, XS1_CT_END); - } - - /* This will return 1 if reset requested */ - result = DFUDeviceRequests(ep0_out, &ep0_in, &sp, null, g_interfaceAlt[sp.wIndex], dfuInterface, &reset); - - if(reset) - { - DFUDelay(50000000); - device_reboot(); - } - } -#endif - /* Check for: - Audio CONTROL interface request - always 0, note we check for DFU first - * - Audio STREAMING interface request (In or Out) - * - Audio endpoint request (Audio 1.0 Sampling freq requests are sent to the endpoint) - */ - if(((interfaceNum == 0) || (interfaceNum == 1) || (interfaceNum == 2)) -#if (XUA_DFU_EN == 1) - && !DFU_mode_active -#endif - ) - { -#if (AUDIO_CLASS == 2) && (AUDIO_CLASS_FALLBACK) - if(g_curUsbSpeed == XUD_SPEED_HS) - { - result = AudioClassRequests_2(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); - } - else - { - result = AudioClassRequests_1(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); - } -#elif (AUDIO_CLASS==2) - result = AudioClassRequests_2(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); -#else - result = AudioClassRequests_1(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); -#endif - -#ifdef VENDOR_AUDIO_REQS - /* If result is ERR at this point, then request to audio interface not handled - handle vendor audio reqs */ - if(result == XUD_RES_ERR) - { - result = VendorAudioRequests(ep0_out, ep0_in, sp.bRequest, - sp.wValue >> 8, sp.wValue & 0xff, - sp.wIndex >> 8, sp.bmRequestType.Direction, - c_audioControl, c_mix_ctl, c_clk_ctl); - } -#endif - } - } - break; - - default: - break; - } - - } /* if(result == XUD_RES_OKAY) */ - - { - if(result == XUD_RES_ERR) - { - /* Run vendor defined parsing/processing */ - /* Note, an interface might seem ideal here but this *must* be executed on the same - * core sure to shared memory depandancy */ - result = VendorRequests(ep0_out, ep0_in, &sp VENDOR_REQUESTS_PARAMS_); - } - } - - if(result == XUD_RES_ERR) - { -#if (XUA_DFU_EN == 1) - if (!DFU_mode_active) - { -#endif -#if (AUDIO_CLASS_FALLBACK) && (AUDIO_CLASS != 1) - /* Return Audio 2.0 Descriptors with Audio 1.0 as fallback */ - result = USB_StandardRequests(ep0_out, ep0_in, - (unsigned char*)&devDesc_Audio2, sizeof(devDesc_Audio2), - (unsigned char*)&cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - (unsigned char*)&devDesc_Audio1, sizeof(devDesc_Audio1), - cfgDesc_Audio1, sizeof(cfgDesc_Audio1), - (char**)&g_strTable, sizeof(g_strTable)/sizeof(char *), - &sp, g_curUsbSpeed); -#elif FULL_SPEED_AUDIO_2 - /* Return Audio 2.0 Descriptors for high_speed and full-speed */ - - /* Unfortunately we need to munge the descriptors a bit between full and high-speed */ - if(g_curUsbSpeed == XUD_SPEED_HS) - { - /* Modify Audio Class 2.0 Config descriptor for High-speed operation */ -#if (NUM_USB_CHAN_OUT > 0) - cfgDesc_Audio2.Audio_CS_Control_Int.Audio_Out_InputTerminal.bNrChannels = NUM_USB_CHAN_OUT; -#if (NUM_USB_CHAN_OUT > 0) - cfgDesc_Audio2.Audio_Out_Format.bSubslotSize = HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES; - cfgDesc_Audio2.Audio_Out_Format.bBitResolution = HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS; - cfgDesc_Audio2.Audio_Out_Endpoint.wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE; - cfgDesc_Audio2.Audio_Out_ClassStreamInterface.bNrChannels = NUM_USB_CHAN_OUT; -#endif -#if (OUTPUT_FORMAT_COUNT > 1) - cfgDesc_Audio2.Audio_Out_Format_2.bSubslotSize = HS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES; - cfgDesc_Audio2.Audio_Out_Format_2.bBitResolution = HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS; - cfgDesc_Audio2.Audio_Out_Endpoint_2.wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_2_MAXPACKETSIZE; - cfgDesc_Audio2.Audio_Out_ClassStreamInterface_2.bNrChannels = NUM_USB_CHAN_OUT; -#endif - -#if (OUTPUT_FORMAT_COUNT > 2) - cfgDesc_Audio2.Audio_Out_Format_3.bSubslotSize = HS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES; - cfgDesc_Audio2.Audio_Out_Format_3.bBitResolution = HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS; - cfgDesc_Audio2.Audio_Out_Endpoint_3.wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_3_MAXPACKETSIZE; - cfgDesc_Audio2.Audio_Out_ClassStreamInterface_3.bNrChannels = NUM_USB_CHAN_OUT; -#endif -#endif -#if (NUM_USB_CHAN_IN > 0) - cfgDesc_Audio2.Audio_CS_Control_Int.Audio_In_InputTerminal.bNrChannels = NUM_USB_CHAN_IN; - cfgDesc_Audio2.Audio_In_Format.bSubslotSize = HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES; - cfgDesc_Audio2.Audio_In_Format.bBitResolution = HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS; - cfgDesc_Audio2.Audio_In_Endpoint.wMaxPacketSize = HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE; - cfgDesc_Audio2.Audio_In_ClassStreamInterface.bNrChannels = NUM_USB_CHAN_IN; -#endif - } - else - { - /* Modify Audio Class 2.0 Config descriptor for Full-speed operation */ -#if (NUM_USB_CHAN_OUT > 0) - cfgDesc_Audio2.Audio_CS_Control_Int.Audio_Out_InputTerminal.bNrChannels = NUM_USB_CHAN_OUT_FS; -#if (NUM_USB_CHAN_OUT > 0) - cfgDesc_Audio2.Audio_Out_Format.bSubslotSize = FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES; - cfgDesc_Audio2.Audio_Out_Format.bBitResolution = FS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS; - cfgDesc_Audio2.Audio_Out_Endpoint.wMaxPacketSize = FS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE; - cfgDesc_Audio2.Audio_Out_ClassStreamInterface.bNrChannels = NUM_USB_CHAN_OUT_FS; -#endif -#if (OUTPUT_FORMAT_COUNT > 1) - cfgDesc_Audio2.Audio_Out_Format_2.bSubslotSize = FS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES; - cfgDesc_Audio2.Audio_Out_Format_2.bBitResolution = FS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS; - cfgDesc_Audio2.Audio_Out_Endpoint_2.wMaxPacketSize = FS_STREAM_FORMAT_OUTPUT_2_MAXPACKETSIZE; - cfgDesc_Audio2.Audio_Out_ClassStreamInterface_2.bNrChannels = NUM_USB_CHAN_OUT_FS; -#endif - -#if (OUTPUT_FORMAT_COUNT > 2) - cfgDesc_Audio2.Audio_Out_Format_3.bSubslotSize = FS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES; - cfgDesc_Audio2.Audio_Out_Format_3.bBitResolution = FS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS; - cfgDesc_Audio2.Audio_Out_Endpoint_3.wMaxPacketSize = FS_STREAM_FORMAT_OUTPUT_3_MAXPACKETSIZE; - cfgDesc_Audio2.Audio_Out_ClassStreamInterface_3.bNrChannels = NUM_USB_CHAN_OUT_FS; -#endif -#endif -#if (NUM_USB_CHAN_IN > 0) - cfgDesc_Audio2.Audio_CS_Control_Int.Audio_In_InputTerminal.bNrChannels = NUM_USB_CHAN_IN_FS; - cfgDesc_Audio2.Audio_In_Format.bSubslotSize = FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES; - cfgDesc_Audio2.Audio_In_Format.bBitResolution = FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS; - cfgDesc_Audio2.Audio_In_Endpoint.wMaxPacketSize = FS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE; - cfgDesc_Audio2.Audio_In_ClassStreamInterface.bNrChannels = NUM_USB_CHAN_IN_FS; -#endif - } - - result = USB_StandardRequests(ep0_out, ep0_in, - (unsigned char*)&devDesc_Audio2, sizeof(devDesc_Audio2), - (unsigned char*)&cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - null, 0, - null, 0, -#ifdef __XC__ - g_strTable, sizeof(g_strTable), sp, null, g_curUsbSpeed); -#else - (char**)&g_strTable, sizeof(g_strTable)/sizeof(char *), &sp, g_curUsbSpeed); -#endif -#elif (AUDIO_CLASS == 1) - /* Return Audio 1.0 Descriptors in FS, should never be in HS! */ - result = USB_StandardRequests(ep0_out, ep0_in, - null, 0, - null, 0, - (unsigned char*)&devDesc_Audio1, sizeof(devDesc_Audio1), - cfgDesc_Audio1, sizeof(cfgDesc_Audio1), - (char**)&g_strTable, sizeof(g_strTable)/sizeof(char *), &sp, g_curUsbSpeed); -#else - /* Return Audio 2.0 Descriptors with Null device as fallback */ - result = USB_StandardRequests(ep0_out, ep0_in, - (unsigned char*)&devDesc_Audio2, sizeof(devDesc_Audio2), - (unsigned char*)&cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - devDesc_Null, sizeof(devDesc_Null), - cfgDesc_Null, sizeof(cfgDesc_Null), - (char**)&g_strTable, sizeof(g_strTable)/sizeof(char *), &sp, g_curUsbSpeed); -#endif -#if (XUA_DFU_EN == 1) - } - - else - { - /* Running in DFU mode - always return same descs for DFU whether HS or FS */ - result = USB_StandardRequests(ep0_out, ep0_in, - DFUdevDesc, sizeof(DFUdevDesc), - DFUcfgDesc, sizeof(DFUcfgDesc), - null, 0, /* Used same descriptors for full and high-speed */ - null, 0, - (char**)&g_strTable, sizeof(g_strTable)/sizeof(char *), &sp, g_curUsbSpeed); - } -#endif - } - - if (result == XUD_RES_RST) - { -#ifdef __XC__ - g_curUsbSpeed = XUD_ResetEndpoint(ep0_out, ep0_in); -#else - g_curUsbSpeed = XUD_ResetEndpoint(ep0_out, &ep0_in); -#endif - g_currentConfig = 0; - g_curStreamAlt_Out = 0; - g_curStreamAlt_In = 0; - -#if (XUA_DFU_EN == 1) - if (DFUReportResetState(null)) - { - if (!DFU_mode_active) - { - DFU_mode_active = 1; - } - } - else - { - if (DFU_mode_active) - { - DFU_mode_active = 0; - - /* Send reboot command */ - DFUDelay(5000000); - device_reboot(); - } - } -#endif - } + XUA_Endpoint0_loop(result, sp, c_ep0_out, c_ep0_in, c_audioControl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface); } } #endif /* XUA_USB_EN*/ diff --git a/lib_xua/src/core/endpoint0/xua_ep0_wrapper.xc b/lib_xua/src/core/endpoint0/xua_ep0_wrapper.xc new file mode 100644 index 00000000..36152999 --- /dev/null +++ b/lib_xua/src/core/endpoint0/xua_ep0_wrapper.xc @@ -0,0 +1,55 @@ +#include +#include +#include +#include "xua.h" + +#define DEBUG_UNIT EP0_WRAPPER +#define DEBUG_PRINT_ENABLE_EP0_WRAPPER 1 +#include "debug_print.h" + +#if 1 +void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, + chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, ?dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_); +void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, + chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, ?dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_); +#pragma select handler +void XUD_GetSetupData_Select(chanend c, XUD_ep e_out, unsigned &length, XUD_Result_t &result); + +extern XUD_ep ep0_out; +extern XUD_ep ep0_in; + + +void XUA_Endpoint0_select(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, + chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_) +{ + + USB_SetupPacket_t sp; + XUA_Endpoint0_init(c_ep0_out, c_ep0_in, c_audioControl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface); + unsigned char sbuffer[120]; + XUD_SetReady_Out(ep0_out, sbuffer); + while(1){ + + XUD_Result_t result = XUD_RES_ERR; + unsigned length = 0; + + //XUD_Result_t result = XUD_GetSetupBuffer(ep0_out, sbuffer, &length); //Flattened from xud_device + // result = XUD_GetSetupData(ep0_out, sbuffer, length);//Flattened from XUD_EpFunctions.xc + + select{ + case XUD_GetSetupData_Select(c_ep0_out, ep0_out, length, result): + break; + } + + if (result == XUD_RES_OKAY) + { + /* Parse data buffer end populate SetupPacket struct */ + USB_ParseSetupPacket(sbuffer, sp); + } + debug_printf("ep0, result: %d, length: %d\n", result, length); //-1 reset, 0 ok, 1 error + + XUA_Endpoint0_loop(result, sp, c_ep0_out, c_ep0_in, c_audioControl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface); + XUD_SetReady_Out(ep0_out, sbuffer); + + } +} +#endif \ No newline at end of file