From 56e79c0af94360241b4a616e5f81427fb297c305 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Mon, 8 Dec 2014 17:04:23 +0000 Subject: [PATCH 01/21] Explicit feedback endpoint removed from Audio Class 2.0 descriptors when input stream is available (or UAC_FORCE_FEEDBACK_EP is defined) --- module_usb_audio/endpoint0/descriptors.h | 44 +++++++++++++++++++++--- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/module_usb_audio/endpoint0/descriptors.h b/module_usb_audio/endpoint0/descriptors.h index ca50bbf3..06b27d1f 100644 --- a/module_usb_audio/endpoint0/descriptors.h +++ b/module_usb_audio/endpoint0/descriptors.h @@ -1267,24 +1267,30 @@ typedef struct USB_Descriptor_Audio_Format_Type1_t Audio_Out_Format; USB_Descriptor_Endpoint_t Audio_Out_Endpoint; USB_Descriptor_Audio_Class_AS_Endpoint_t Audio_Out_ClassEndpoint; +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) USB_Descriptor_Endpoint_t Audio_Out_Fb_Endpoint; +#endif #if (OUTPUT_FORMAT_COUNT > 1) USB_Descriptor_Interface_t Audio_Out_StreamInterface_Alt2; USB_Descriptor_Audio_Interface_AS_t Audio_Out_ClassStreamInterface_2; USB_Descriptor_Audio_Format_Type1_t Audio_Out_Format_2; USB_Descriptor_Endpoint_t Audio_Out_Endpoint_2; USB_Descriptor_Audio_Class_AS_Endpoint_t Audio_Out_ClassEndpoint_2; +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) USB_Descriptor_Endpoint_t Audio_Out_Fb_Endpoint_2; #endif +#endif #if (OUTPUT_FORMAT_COUNT > 2) USB_Descriptor_Interface_t Audio_Out_StreamInterface_Alt3; USB_Descriptor_Audio_Interface_AS_t Audio_Out_ClassStreamInterface_3; USB_Descriptor_Audio_Format_Type1_t Audio_Out_Format_3; USB_Descriptor_Endpoint_t Audio_Out_Endpoint_3; USB_Descriptor_Audio_Class_AS_Endpoint_t Audio_Out_ClassEndpoint_3; +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) USB_Descriptor_Endpoint_t Audio_Out_Fb_Endpoint_3; #endif #endif +#endif #if (NUM_USB_CHAN_IN > 0) /* Audio Streaming: Input stream */ USB_Descriptor_Interface_t Audio_In_StreamInterface_Alt0; /* Zero bandwith alternative */ @@ -1745,7 +1751,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= /* Output Terminal Descriptor (USB Streaming) */ .bLength = 0x0C, .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE, - .bDescriptorSubtype = UAC_CS_AC_INTERFACE_SUBTYPE_OUTPUT_TERMINAL, + .bDescriptorSubtype = UAC_CS_AC_INTERFACE_SUBTYPE_OUTPUT_TERMINAL, .bTerminalID = ID_OT_USB, .wTerminalType = USB_TERMTYPE_USB_STREAMING, .bAssocTerminal = 0x00, @@ -1893,7 +1899,11 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= USB_DESCTYPE_INTERFACE, /* 1 bDescriptorType: INTERFACE */ INTERFACE_NUMBER_AUDIO_OUTPUT, /* 2 bInterfaceNumber: Number of interface */ 1, /* 3 bAlternateSetting */ +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) 2, /* 4 bNumEndpoints */ +#else + 1, /* 4 bNumEndpoints */ +#endif USB_CLASS_AUDIO, /* 5 bInterfaceClass: AUDIO */ UAC_INT_SUBCLASS_AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ UAC_INT_PROTOCOL_IP_VERSION_02_00,/* 7 bInterfaceProtocol: IP_VERSION_02_00 */ @@ -1949,6 +1959,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= 0x0008, /* 6:7 bLockDelay */ }, +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) .Audio_Out_Fb_Endpoint = { 0x07, /* 0 bLength: 7 */ @@ -1958,6 +1969,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= 0x0004, /* 4 wMaxPacketSize */ 4, /* 6 bInterval. Only values <= 1 frame (4) supported by MS */ }, +#endif #if (OUTPUT_FORMAT_COUNT > 1) /* Standard AS Interface Descriptor (4.9.1) (Alt) */ .Audio_Out_StreamInterface_Alt2 = @@ -1966,7 +1978,11 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= USB_DESCTYPE_INTERFACE, /* 1 bDescriptorType: INTERFACE */ INTERFACE_NUMBER_AUDIO_OUTPUT, /* 2 bInterfaceNumber: Number of interface */ 2, /* 3 bAlternateSetting */ +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) 2, /* 4 bNumEndpoints */ +#else + 1, /* 4 bNumEndpoints */ +#endif USB_CLASS_AUDIO, /* 5 bInterfaceClass: AUDIO */ UAC_INT_SUBCLASS_AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ UAC_INT_PROTOCOL_IP_VERSION_02_00,/* 7 bInterfaceProtocol: IP_VERSION_02_00 */ @@ -2021,6 +2037,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= 0x0008, /* 6:7 bLockDelay */ }, +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) .Audio_Out_Fb_Endpoint_2 = { 0x07, /* 0 bLength: 7 */ @@ -2031,6 +2048,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= 4, /* 6 bInterval. Only values <= 1 frame (4) supported by MS */ }, #endif +#endif #if (OUTPUT_FORMAT_COUNT > 2) /* Standard AS Interface Descriptor (4.9.1) (Alt) */ .Audio_Out_StreamInterface_Alt3 = @@ -2039,7 +2057,11 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= USB_DESCTYPE_INTERFACE, /* 1 bDescriptorType: INTERFACE */ INTERFACE_NUMBER_AUDIO_OUTPUT, /* 2 bInterfaceNumber: Number of interface */ 3, /* 3 bAlternateSetting */ +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) 2, /* 4 bNumEndpoints */ +#else + 1, /* 4 bNumEndpoints */ +#endif USB_CLASS_AUDIO, /* 5 bInterfaceClass: AUDIO */ UAC_INT_SUBCLASS_AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ UAC_INT_PROTOCOL_IP_VERSION_02_00,/* 7 bInterfaceProtocol: IP_VERSION_02_00 */ @@ -2095,6 +2117,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= .wLockDelay = 0x0008, }, +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) .Audio_Out_Fb_Endpoint_3 = { .bLength = 0x07, @@ -2104,6 +2127,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= .wMaxPacketSize = 0x0004, .bInterval = 4, /* Only values <= 1 frame (4) supported by MS */ }, +#endif #endif /* OUTPUT_FORMAT_COUNT > 2 */ #endif /* OUTPUT */ #if (NUM_USB_CHAN_IN > 0) @@ -2169,7 +2193,11 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= .bLength = 0x07, .bDescriptorType = USB_DESCTYPE_ENDPOINT, .bEndpointAddress = 0x82, - .bmAttributes = 5, +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) + .bmAttributes = 0x05, /* Iso, async, data endpoint */ +#else + .bmAttributes = 0x25, /* Iso, async, implicit feedback data endpoint */ +#endif .wMaxPacketSize = HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE, .bInterval = 0x01, }, @@ -2233,7 +2261,11 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= .bLength = 0x07, .bDescriptorType = USB_DESCTYPE_ENDPOINT, .bEndpointAddress = 0x82, - .bmAttributes = 5, +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) + .bmAttributes = 0x05, /* Iso, async, data endpoint */ +#else + .bmAttributes = 0x25, /* Iso, async, implicit feedback data endpoint */ +#endif .wMaxPacketSize = HS_STREAM_FORMAT_INPUT_2_MAXPACKETSIZE, .bInterval = 0x01, }, @@ -2298,7 +2330,11 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= .bLength = 0x07, .bDescriptorType = USB_DESCTYPE_ENDPOINT, .bEndpointAddress = 0x82, - .bmAttributes = 5, +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) + .bmAttributes = 0x05, /* Iso, async, data endpoint */ +#else + .bmAttributes = 0x25, /* Iso, async, implicit feedback data endpoint */ +#endif .wMaxPacketSize = HS_STREAM_FORMAT_INPUT_3_MAXPACKETSIZE, .bInterval = 0x01, }, From 8d2b65127e062192d82f8c742190b677d10796b0 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Mon, 8 Dec 2014 18:19:56 +0000 Subject: [PATCH 02/21] First attempt at complete removal of feedback EP code when not required. --- module_usb_audio/devicedefines.h | 2 ++ module_usb_audio/endpoint0/descriptors.h | 44 +++++++++++------------ module_usb_audio/main.xc | 10 +++--- module_usb_audio/usb_buffer/usb_buffer.h | 2 ++ module_usb_audio/usb_buffer/usb_buffer.xc | 13 +++++-- 5 files changed, 42 insertions(+), 29 deletions(-) diff --git a/module_usb_audio/devicedefines.h b/module_usb_audio/devicedefines.h index 60e71691..ac0505a7 100644 --- a/module_usb_audio/devicedefines.h +++ b/module_usb_audio/devicedefines.h @@ -1044,7 +1044,9 @@ enum USBEndpointNumber_In { ENDPOINT_NUMBER_IN_CONTROL, /* Endpoint 0 */ +#if (NUM_USB_CHAN_IN == 0) || (defined UAC_FORCE_FEEDBACK_EP) ENDPOINT_NUMBER_IN_FEEDBACK, +#endif ENDPOINT_NUMBER_IN_AUDIO, #if defined(SPDIF_RX) || defined(ADAT_RX) ENDPOINT_NUMBER_IN_INTERRUPT, /* Audio interrupt/status EP */ diff --git a/module_usb_audio/endpoint0/descriptors.h b/module_usb_audio/endpoint0/descriptors.h index 06b27d1f..54da9fda 100644 --- a/module_usb_audio/endpoint0/descriptors.h +++ b/module_usb_audio/endpoint0/descriptors.h @@ -1928,12 +1928,12 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= /* Type 1 Format Type Descriptor */ .Audio_Out_Format = { - 0x06, /* 0 bLength (in bytes): 6 */ - UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType: 0x24 */ - UAC_CS_AS_INTERFACE_SUBTYPE_FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ - UAC_FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ - .bSubslotSize = HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES, - .bBitResolution = HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS, + .bLength = 0x06, + .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE, + .bDescriptorSubtype = UAC_CS_AS_INTERFACE_SUBTYPE_FORMAT_TYPE, + .bFormatType = UAC_FORMAT_TYPE_I, + .bSubslotSize = HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES, + .bBitResolution = HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS, }, /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ @@ -1941,7 +1941,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= { .bLength = sizeof(USB_Descriptor_Endpoint_t), .bDescriptorType = USB_DESCTYPE_ENDPOINT, - .bEndpointAddress = 0x01, /* (D7: 0:out, 1:in) */ + .bEndpointAddress = ENDPOINT_ADDRESS_OUT_AUDIO, .bmAttributes = 0x05, /* (bitmap) */ .wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE, .bInterval = 1, @@ -1962,12 +1962,12 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= #if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) .Audio_Out_Fb_Endpoint = { - 0x07, /* 0 bLength: 7 */ - USB_DESCTYPE_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ - 0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ - 17, /* 3 bmAttributes (bitmap) */ - 0x0004, /* 4 wMaxPacketSize */ - 4, /* 6 bInterval. Only values <= 1 frame (4) supported by MS */ + .bLength = 0x07, + .bDescriptorType = USB_DESCTYPE_ENDPOINT, + .bEndpointAddress = ENDPOINT_ADDRESS_IN_FEEDBACK, + .bmAttributes = 17, /* (bitmap) */ + .wMaxPacketSize = 0x0004, + .bInterval = 4, /* Only values <= 1 frame (4) supported by MS */ }, #endif #if (OUTPUT_FORMAT_COUNT > 1) @@ -2019,7 +2019,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= { .bLength = sizeof(USB_Descriptor_Endpoint_t), .bDescriptorType = USB_DESCTYPE_ENDPOINT, - .bEndpointAddress = 0x01, + .bEndpointAddress = ENDPOINT_ADDRESS_OUT_AUDIO, .bmAttributes = 0x05, .wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_2_MAXPACKETSIZE, .bInterval = 1, @@ -2042,7 +2042,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= { 0x07, /* 0 bLength: 7 */ USB_DESCTYPE_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ - 0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ + ENDPOINT_ADDRESS_IN_FEEDBACK, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 17, /* 3 bmAttributes (bitmap) */ 0x0004, /* 4 wMaxPacketSize */ 4, /* 6 bInterval. Only values <= 1 frame (4) supported by MS */ @@ -2099,7 +2099,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= { .bLength = 0x07, .bDescriptorType = USB_DESCTYPE_ENDPOINT, - .bEndpointAddress = 0x01, + .bEndpointAddress = ENDPOINT_ADDRESS_OUT_AUDIO, .bmAttributes = 0x05, .wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_3_MAXPACKETSIZE, .bInterval = 1, @@ -2122,7 +2122,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= { .bLength = 0x07, .bDescriptorType = USB_DESCTYPE_ENDPOINT, - .bEndpointAddress = 0x81, + .bEndpointAddress = ENDPOINT_ADDRESS_IN_FEEDBACK, .bmAttributes = 17, /* (bitmap) */ .wMaxPacketSize = 0x0004, .bInterval = 4, /* Only values <= 1 frame (4) supported by MS */ @@ -2192,7 +2192,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= { .bLength = 0x07, .bDescriptorType = USB_DESCTYPE_ENDPOINT, - .bEndpointAddress = 0x82, + .bEndpointAddress = ENDPOINT_ADDRESS_IN_AUDIO, #if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) .bmAttributes = 0x05, /* Iso, async, data endpoint */ #else @@ -2260,7 +2260,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= { .bLength = 0x07, .bDescriptorType = USB_DESCTYPE_ENDPOINT, - .bEndpointAddress = 0x82, + .bEndpointAddress = ENDPOINT_ADDRESS_IN_AUDIO, #if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) .bmAttributes = 0x05, /* Iso, async, data endpoint */ #else @@ -2329,7 +2329,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= { .bLength = 0x07, .bDescriptorType = USB_DESCTYPE_ENDPOINT, - .bEndpointAddress = 0x82, + .bEndpointAddress = ENDPOINT_ADDRESS_IN_AUDIO, #if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) .bmAttributes = 0x05, /* Iso, async, data endpoint */ #else @@ -2927,7 +2927,7 @@ unsigned char cfgDesc_Audio1[] = /* Feedback EP */ 0x09, 0x05, /* bDescriptorType: ENDPOINT */ - 0x81, /* bEndpointAddress (D3:0 - EP no. D6:4 - reserved 0. D7 - 0:out, 1:in) */ + ENDPOINT_ADDRESS_IN_FEEDBACK, /* bEndpointAddress (D3:0 - EP no. D6:4 - reserved 0. D7 - 0:out, 1:in) */ 0x01, /* bmAttributes (bitmap) */ 0x03,0x0, /* wMaxPacketSize */ 0x01, /* bInterval - Must be 1 for compliance */ @@ -2994,7 +2994,7 @@ unsigned char cfgDesc_Audio1[] = /* Standard Endpoint Descriptor */ 0x09, 0x05, /* ENDPOINT */ - 0x82, /* EndpointAddress */ + ENDPOINT_ADDRESS_IN_AUDIO, /* EndpointAddress */ 0x05, /* Attributes - isochronous async */ FS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE&0xff, /* 4 wMaxPacketSize (Typically 294 bytes)*/ (FS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE&0xff00)>>8, /* 5 wMaxPacketSize */ diff --git a/module_usb_audio/main.xc b/module_usb_audio/main.xc index fe609211..9b46c2e2 100755 --- a/module_usb_audio/main.xc +++ b/module_usb_audio/main.xc @@ -332,12 +332,14 @@ void usb_audio_core(chanend c_mix_out asm("setclk res[%0], %1"::"r"(p_for_mclk_count), "r"(x)); #endif //:buffer - buffer(c_xud_out[ENDPOINT_NUMBER_OUT_AUDIO],/* Audio Out*/ - c_xud_in[ENDPOINT_NUMBER_IN_AUDIO], /* Audio In */ + buffer(c_xud_out[ENDPOINT_NUMBER_OUT_AUDIO], /* Audio Out*/ + c_xud_in[ENDPOINT_NUMBER_IN_AUDIO], /* Audio In */ +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) c_xud_in[ENDPOINT_NUMBER_IN_FEEDBACK], /* Audio FB */ +#endif #ifdef MIDI - c_xud_out[ENDPOINT_NUMBER_OUT_MIDI], /* MIDI Out */ // 2 - c_xud_in[ENDPOINT_NUMBER_IN_MIDI], /* MIDI In */ // 4 + c_xud_out[ENDPOINT_NUMBER_OUT_MIDI], /* MIDI Out */ // 2 + c_xud_in[ENDPOINT_NUMBER_IN_MIDI], /* MIDI In */ // 4 c_midi, #endif #ifdef IAP diff --git a/module_usb_audio/usb_buffer/usb_buffer.h b/module_usb_audio/usb_buffer/usb_buffer.h index ff405347..3541cf22 100644 --- a/module_usb_audio/usb_buffer/usb_buffer.h +++ b/module_usb_audio/usb_buffer/usb_buffer.h @@ -19,7 +19,9 @@ */ void buffer(chanend c_aud_out, chanend c_aud_in, +#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_ENDPOINT) chanend c_aud_fb, +#endif #ifdef MIDI chanend c_midi_from_host, chanend c_midi_to_host, diff --git a/module_usb_audio/usb_buffer/usb_buffer.xc b/module_usb_audio/usb_buffer/usb_buffer.xc index e6671aee..af84386f 100644 --- a/module_usb_audio/usb_buffer/usb_buffer.xc +++ b/module_usb_audio/usb_buffer/usb_buffer.xc @@ -94,7 +94,10 @@ unsigned char fb_clocks[16]; * @param c_aud_fb chanend for feeback to xud * @return void */ -void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud_fb, +void buffer(register chanend c_aud_out, register chanend c_aud_in, +#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_ENDPOINT) + chanend c_aud_fb, +#endif #ifdef MIDI chanend c_midi_from_host, chanend c_midi_to_host, @@ -131,7 +134,9 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud { XUD_ep ep_aud_out = XUD_InitEp(c_aud_out); XUD_ep ep_aud_in = XUD_InitEp(c_aud_in); +#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_ENDPOINT) XUD_ep ep_aud_fb = XUD_InitEp(c_aud_fb); +#endif #ifdef MIDI XUD_ep ep_midi_from_host = XUD_InitEp(c_midi_from_host); XUD_ep ep_midi_to_host = XUD_InitEp(c_midi_to_host); @@ -344,6 +349,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud SET_SHARED_GLOBAL(g_formatChange_DataFormat, formatChange_DataFormat); SET_SHARED_GLOBAL(g_formatChange_SampRes, formatChange_SampRes); +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) /* Host is starting up the output stream. Setup (or potentially resize) feedback packet based on bus-speed * This is only really important on inital start up (when bus-speed was unknown) and when changing bus-speeds */ @@ -357,7 +363,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud { XUD_SetReady_In(ep_aud_fb, fb_clocks, 3); } - +#endif } /* Pass on sample freq change to decouple() via global flag (saves a chanend) */ /* Note: freqChange flags now used to communicate other commands also */ @@ -460,6 +466,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud #endif #if (NUM_USB_CHAN_OUT > 0) +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) /* Feedback Pipe */ case XUD_SetData_Select(c_aud_fb, ep_aud_fb, result): { @@ -477,7 +484,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud } } break; - +#endif /* Received Audio packet HOST -> DEVICE. Datalength written to length */ case XUD_GetData_Select(c_aud_out, ep_aud_out, length, result): { From 129c9390cf852f636823a541ec1bf7788c018265 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Mon, 12 Jan 2015 18:12:59 +0000 Subject: [PATCH 03/21] UAC1 descriptors now use implicit feedback when sensible --- module_usb_audio/endpoint0/descriptors.h | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/module_usb_audio/endpoint0/descriptors.h b/module_usb_audio/endpoint0/descriptors.h index 922f94d2..77a0278d 100644 --- a/module_usb_audio/endpoint0/descriptors.h +++ b/module_usb_audio/endpoint0/descriptors.h @@ -3399,7 +3399,11 @@ unsigned char cfgDesc_Null[] = /* Note, this is different that INTERFACE_COUNT since we dont support items such as MIDI, iAP etc in UAC1 mode */ #define NUM_INTERFACES_A1 (1+INPUT_INTERFACES_A1 + OUTPUT_INTERFACES_A1) +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) #define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * 61) + (OUTPUT_INTERFACES_A1 * 70)) +#else +#define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * 61) + (OUTPUT_INTERFACES_A1 * 61)) +#endif /* In UAC1 supported sample rates are listed in descriptor */ /* Note, we always report 4 freqs, doing otherwise seems to cause an enumeration issue on Windows */ @@ -3537,7 +3541,11 @@ unsigned char cfgDesc_Audio1[] = 0x04, /* INTERFACE */ 0x01, /* Interface no */ 0x01, /* AlternateSetting */ - 0x02, /* num endpoints 2: audio EP and feedback EP */ +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) + 0x02, /* bNumEndpoints 2: audio EP and feedback EP */ +#else + 0x01, /* bNumEndpoints */ +#endif 0x01, /* Interface class - AUDIO */ 0x02, /* subclass - AUDIO_STREAMING */ 0x00, /* Unused */ @@ -3587,7 +3595,11 @@ unsigned char cfgDesc_Audio1[] = (FS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE&0xff00)>>8, /* 5 wMaxPacketSize */ 0x01, /* bInterval */ 0x00, /* bRefresh */ - 0x81, /* bSynchAdddress - address of EP used to communicate sync info */ +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) + ENDPOINT_ADDRESS_IN_FEEDBACK, /* bSynchAdddress - address of EP used to communicate sync info */ +#else + ENDPOINT_ADDRESS_IN_AUDIO, +#endif /* CS_Endpoint Descriptor ?? */ 0x07, @@ -3597,6 +3609,7 @@ unsigned char cfgDesc_Audio1[] = 0x02, /* bLockDelayUnits */ 0x00, 0x00, /* bLockDelay */ +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) /* Feedback EP */ 0x09, 0x05, /* bDescriptorType: ENDPOINT */ @@ -3607,6 +3620,7 @@ unsigned char cfgDesc_Audio1[] = 0x04, /* bRefresh 2^x */ 0x0, /* bSynchAddress */ #endif +#endif #if (NUM_USB_CHAN_IN > 0) /* Standard Interface Descriptor - Audio streaming IN */ @@ -3668,7 +3682,11 @@ unsigned char cfgDesc_Audio1[] = 0x09, 0x05, /* ENDPOINT */ ENDPOINT_ADDRESS_IN_AUDIO, /* EndpointAddress */ - 0x05, /* Attributes - isochronous async */ +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) + 0x05, /* Iso, async, data endpoint */ +#else + 0x25, /* Iso, async, implicit feedback data endpoint */ +#endif FS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE&0xff, /* 4 wMaxPacketSize (Typically 294 bytes)*/ (FS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE&0xff00)>>8, /* 5 wMaxPacketSize */ 0x01, /* bInterval */ From b36a7ab5556ad0384457c24678dcc04962087d76 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Mon, 12 Jan 2015 18:13:38 +0000 Subject: [PATCH 04/21] Audio Class endpoint checks now use ENDPOIN_ADDRESS defines --- module_usb_audio/endpoint0/endpoint0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module_usb_audio/endpoint0/endpoint0.c b/module_usb_audio/endpoint0/endpoint0.c index fd546cad..3b89073c 100755 --- a/module_usb_audio/endpoint0/endpoint0.c +++ b/module_usb_audio/endpoint0/endpoint0.c @@ -529,7 +529,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, { unsigned epNum = sp.wIndex & 0xff; - if ((epNum == 0x82) || (epNum == 0x01)) + if ((epNum == ENDPOINT_ADDRESS_OUT_AUDIO) || (epNum == ENDPOINT_ADDRESS_IN_AUDIO)) { #if (AUDIO_CLASS == 2) && defined(AUDIO_CLASS_FALLBACK) if(g_curUsbSpeed == XUD_SPEED_FS) From cfca7b347e1abb87fda387cb2467e47192dc092c Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Mon, 12 Jan 2015 18:14:07 +0000 Subject: [PATCH 05/21] Fixed build issue due to bad define name (EP vs ENDPOINT) --- module_usb_audio/usb_buffer/usb_buffer.h | 2 +- module_usb_audio/usb_buffer/usb_buffer.xc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/module_usb_audio/usb_buffer/usb_buffer.h b/module_usb_audio/usb_buffer/usb_buffer.h index 3541cf22..038bbdbc 100644 --- a/module_usb_audio/usb_buffer/usb_buffer.h +++ b/module_usb_audio/usb_buffer/usb_buffer.h @@ -19,7 +19,7 @@ */ void buffer(chanend c_aud_out, chanend c_aud_in, -#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_ENDPOINT) +#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP) chanend c_aud_fb, #endif #ifdef MIDI diff --git a/module_usb_audio/usb_buffer/usb_buffer.xc b/module_usb_audio/usb_buffer/usb_buffer.xc index af84386f..2201b1fc 100644 --- a/module_usb_audio/usb_buffer/usb_buffer.xc +++ b/module_usb_audio/usb_buffer/usb_buffer.xc @@ -95,7 +95,7 @@ unsigned char fb_clocks[16]; * @return void */ void buffer(register chanend c_aud_out, register chanend c_aud_in, -#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_ENDPOINT) +#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP) chanend c_aud_fb, #endif #ifdef MIDI @@ -134,7 +134,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, { XUD_ep ep_aud_out = XUD_InitEp(c_aud_out); XUD_ep ep_aud_in = XUD_InitEp(c_aud_in); -#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_ENDPOINT) +#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP) XUD_ep ep_aud_fb = XUD_InitEp(c_aud_fb); #endif #ifdef MIDI From cc14679d53aba8fd519ca5d90265cd6808befb76 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Fri, 4 Sep 2015 12:56:14 +0100 Subject: [PATCH 06/21] Fixed build issue due to undeclared var when DFU disabled. --- module_usb_audio/endpoint0/endpoint0.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/module_usb_audio/endpoint0/endpoint0.c b/module_usb_audio/endpoint0/endpoint0.c index 7cdc9a3a..b4bf4764 100755 --- a/module_usb_audio/endpoint0/endpoint0.c +++ b/module_usb_audio/endpoint0/endpoint0.c @@ -586,8 +586,12 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, * - 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)) && !DFU_mode_active) - { + if(((interfaceNum == 0) || (interfaceNum == 1) || (interfaceNum == 2)) +#ifdef DFU + && !DFU_mode_active +#endif + ) + { #if (AUDIO_CLASS == 2) && defined(AUDIO_CLASS_FALLBACK) if(g_curUsbSpeed == XUD_SPEED_HS) { From 9bf8075bd33ca3701288d762682b6c9271e8cb60 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Fri, 4 Sep 2015 13:11:49 +0100 Subject: [PATCH 07/21] Build error is I2S_CHANS_ADC/DAC set to zero and CODEC_MASTER enabled. --- module_usb_audio/ports/audioports.xc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/module_usb_audio/ports/audioports.xc b/module_usb_audio/ports/audioports.xc index 66f77641..5aa14366 100644 --- a/module_usb_audio/ports/audioports.xc +++ b/module_usb_audio/ports/audioports.xc @@ -110,17 +110,21 @@ unsigned int divide) /* Clock bclk clock-block from bclk pin */ configure_clock_src(clk_audio_bclk, p_bclk); +#if (I2S_CHANS_DAC != 0) /* Clock I2S output data ports from b-clock clock block */ for(int i = 0; i < I2S_WIRES_DAC; i++) { configure_out_port_no_ready(p_i2s_dac[i], clk_audio_bclk, 0); } +#endif +#if (I2S_CHANS_ADC != 0) /* Clock I2S input data ports from clock block */ for(int i = 0; i < I2S_WIRES_ADC; i++) { configure_in_port_no_ready(p_i2s_adc[i], clk_audio_bclk); } +#endif configure_in_port_no_ready(p_lrclk, clk_audio_bclk); From 7f96ce36e495179bbe0a970fc0bdcd8827f01249 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Mon, 7 Sep 2015 10:19:32 +0100 Subject: [PATCH 08/21] Fixed build issue when DFU is disabled (and DFU distributed into EP0) --- module_usb_audio/main.xc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/module_usb_audio/main.xc b/module_usb_audio/main.xc index 623b5686..1eeb6f63 100755 --- a/module_usb_audio/main.xc +++ b/module_usb_audio/main.xc @@ -278,7 +278,7 @@ void usb_audio_core(chanend c_mix_out #endif , chanend ?c_clk_int , chanend ?c_clk_ctl -, client interface i_dfu dfuInterface +, client interface i_dfu ?dfuInterface ) { chan c_sof; @@ -536,8 +536,10 @@ int main() { #if (XUD_TILE == 0) /* Check if USB is on the flash tile (tile 0) */ +#ifdef DFU [[distribute]] DFUHandler(dfuInterface, null); +#endif #endif usb_audio_core(c_mix_out #ifdef MIDI From 520677ffea906b7df9deb917d55e3fcd3978edbb Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Mon, 7 Sep 2015 16:08:52 +0100 Subject: [PATCH 09/21] Mixer and non-mixer chan comms (decouple->audio path) now the same scheme. --- module_usb_audio/audio.xc | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/module_usb_audio/audio.xc b/module_usb_audio/audio.xc index a91ca4a1..64b0d6f2 100755 --- a/module_usb_audio/audio.xc +++ b/module_usb_audio/audio.xc @@ -256,33 +256,6 @@ static inline unsigned DoSampleTransfer(chanend c_out, int readBuffNo, unsigned } else { -#ifndef MIXER // Interfaces straight to decouple() - inuint(c_out); -#if NUM_USB_CHAN_IN > 0 -#pragma loop unroll - for(int i = 0; i < I2S_CHANS_ADC; i++) - { - if(readBuffNo) - outuint(c_out, samplesIn_1[i]); - else - outuint(c_out, samplesIn_0[i]); - } - /* Send over the digi channels - no odd buffering required */ -#pragma loop unroll - for(int i = I2S_CHANS_ADC; i < NUM_USB_CHAN_IN; i++) - { - outuint(c_out, samplesIn_0[i]); - } -#endif - -#if NUM_USB_CHAN_OUT > 0 -#pragma loop unroll - for(int i = 0; i < NUM_USB_CHAN_OUT; i++) - { - samplesOut[i] = inuint(c_out); - } -#endif -#else /* ifndef MIXER */ #if NUM_USB_CHAN_OUT > 0 #pragma loop unroll for(int i = 0; i < NUM_USB_CHAN_OUT; i++) @@ -290,6 +263,8 @@ static inline unsigned DoSampleTransfer(chanend c_out, int readBuffNo, unsigned int tmp = inuint(c_out); samplesOut[i] = tmp; } +#else + inuint(c_out); #endif #if NUM_USB_CHAN_IN > 0 #pragma loop unroll @@ -310,7 +285,6 @@ static inline unsigned DoSampleTransfer(chanend c_out, int readBuffNo, unsigned { outuint(c_out, samplesIn_0[i]); } -#endif #endif } @@ -465,10 +439,8 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, #if (I2S_CHANS_ADC != 0) || defined(SPDIF_TX) unsigned sample; #endif -//#if NUM_USB_CHAN_IN > 0 /* Since DAC and ADC buffered ports off by one sample we buffer previous ADC frame */ unsigned readBuffNo = 0; -//#endif unsigned index; #ifdef RAMP_CHECK @@ -1097,7 +1069,7 @@ chanend ?c_config, chanend ?c { /* Configure audio ports */ ConfigAudioPortsWrapper( -#if (I2S_CHANS_DAC != 0) +#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0) p_dsd_dac, DSD_CHANS_DAC, #endif From f5da75fa4678a5a3c434ef88c3521dedd6fcadd7 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Mon, 7 Sep 2015 16:09:13 +0100 Subject: [PATCH 10/21] Mixer and non-mixer chan comms (decouple->audio path) now the same scheme. --- module_usb_audio/usb_buffer/decouple.xc | 314 ++++++++++++------------ 1 file changed, 160 insertions(+), 154 deletions(-) diff --git a/module_usb_audio/usb_buffer/decouple.xc b/module_usb_audio/usb_buffer/decouple.xc index 5cfafc9e..d63498e8 100644 --- a/module_usb_audio/usb_buffer/decouple.xc +++ b/module_usb_audio/usb_buffer/decouple.xc @@ -131,161 +131,9 @@ void handle_audio_request(chanend c_mix_out) /* Input word that triggered interrupt and handshake back */ unsigned underflowSample = inuint(c_mix_out); +#if (NUM_USB_CHAN_OUT == 0) outuint(c_mix_out, 0); - - /* If in overflow condition then receive samples and throw away */ - if(inOverflow || sampsToWrite == 0) - { -#pragma loop unroll - for(int i = 0; i < NUM_USB_CHAN_IN; i++) - { - (void) inuint(c_mix_out); - } - - /* Calculate how much space left in buffer */ - space_left = g_aud_to_host_rdptr - g_aud_to_host_wrptr; - - if (space_left <= 0) - { - space_left += BUFF_SIZE_IN*4; - } - - /* Check if we can come out of overflow */ - if (space_left > (BUFF_SIZE_IN*4/2)) - { - inOverflow = 0; - } - } - else - { - /* Not in overflow, store samples from mixer into sample buffer */ - switch(g_curSubSlot_In) - { - case 2: -#if (STREAM_FORMAT_INPUT_SUBSLOT_2_USED == 0) -__builtin_unreachable(); -#endif - for(int i = 0; i < g_numUsbChan_In; i++) - { - /* Receive sample */ - int sample = inuint(c_mix_out); -#if (INPUT_VOLUME_CONTROL == 1) -#if !defined(IN_VOLUME_IN_MIXER) - /* Apply volume */ - int mult; - int h; - unsigned l; - asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i)); - {h, l} = macs(mult, sample, 0, 0); - sample = h << 3; - - /* Note, in 2 byte sub slot - ignore lower bits of macs */ -#elif defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX) - sample = sample << 3; -#endif -#endif - write_short_via_xc_ptr(g_aud_to_host_dptr, sample>>16); - g_aud_to_host_dptr+=2; - } - break; - - case 4: - { -#if (STREAM_FORMAT_INPUT_SUBSLOT_4_USED == 0) -__builtin_unreachable(); -#endif - unsigned ptr = g_aud_to_host_dptr; - - for(int i = 0; i < g_numUsbChan_In; i++) - { - /* Receive sample */ - int sample = inuint(c_mix_out); -#if(INPUT_VOLUME_CONTROL == 1) -#if !defined(IN_VOLUME_IN_MIXER) - /* Apply volume */ - int mult; - int h; - unsigned l; - asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i)); - {h, l} = macs(mult, sample, 0, 0); - sample = h << 3; -#if (STREAM_FORMAT_INPUT_RESOLUTION_32BIT_USED == 1) - sample |= (l >> 29) & 0x7; // Note, this step is not required if we assume sample depth is 24 (rather than 32) -#endif -#elif defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX) - sample = sample << 3; -#endif -#endif - /* Write into fifo */ - write_via_xc_ptr(ptr, sample); - ptr+=4; - } - - /* Update global pointer */ - g_aud_to_host_dptr = ptr; - break; - } - - case 3: -#if (STREAM_FORMAT_INPUT_SUBSLOT_3_USED == 0) -__builtin_unreachable(); -#endif - for(int i = 0; i < g_numUsbChan_In; i++) - { - /* Receive sample */ - int sample = inuint(c_mix_out); -#if (INPUT_VOLUME_CONTROL) && !defined(IN_VOLUME_IN_MIXER) - /* Apply volume */ - int mult; - int h; - unsigned l; - asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i)); - {h, l} = macs(mult, sample, 0, 0); - sample = h << 3; -#endif - /* Pack 3 byte samples */ - switch (packState&0x3) - { - case 0: - packData = sample; - break; - case 1: - packData = (packData >> 8) | ((sample & 0xff00)<<16); - write_via_xc_ptr(g_aud_to_host_dptr, packData); - g_aud_to_host_dptr+=4; - write_via_xc_ptr(g_aud_to_host_dptr, sample>>16); - packData = sample; - break; - case 2: - packData = (packData>>16) | ((sample & 0xffff00) << 8); - write_via_xc_ptr(g_aud_to_host_dptr, packData); - g_aud_to_host_dptr+=4; - packData = sample; - break; - case 3: - packData = (packData >> 24) | (sample & 0xffffff00); - write_via_xc_ptr(g_aud_to_host_dptr, packData); - g_aud_to_host_dptr+=4; - break; - } - packState++; - } - break; - - default: - __builtin_unreachable(); - break; - } - - /* Input any remaining channels - past this thread we always operate on max channel count */ - for(int i = 0; i < NUM_USB_CHAN_IN - g_numUsbChan_In; i++) - { - inuint(c_mix_out); - } - - sampsToWrite--; - } - +#else if(outUnderflow) { #pragma xta endpoint "out_underflow" @@ -443,6 +291,164 @@ __builtin_unreachable(); aud_data_remaining_to_device -= (g_numUsbChan_Out * g_curSubSlot_Out); } + + +#endif + + /* If in overflow condition then receive samples and throw away */ + if(inOverflow || sampsToWrite == 0) + { +#pragma loop unroll + for(int i = 0; i < NUM_USB_CHAN_IN; i++) + { + (void) inuint(c_mix_out); + } + + /* Calculate how much space left in buffer */ + space_left = g_aud_to_host_rdptr - g_aud_to_host_wrptr; + + if (space_left <= 0) + { + space_left += BUFF_SIZE_IN*4; + } + + /* Check if we can come out of overflow */ + if (space_left > (BUFF_SIZE_IN*4/2)) + { + inOverflow = 0; + } + } + else + { + /* Not in overflow, store samples from mixer into sample buffer */ + switch(g_curSubSlot_In) + { + case 2: +#if (STREAM_FORMAT_INPUT_SUBSLOT_2_USED == 0) +__builtin_unreachable(); +#endif + for(int i = 0; i < g_numUsbChan_In; i++) + { + /* Receive sample */ + int sample = inuint(c_mix_out); +#if (INPUT_VOLUME_CONTROL == 1) +#if !defined(IN_VOLUME_IN_MIXER) + /* Apply volume */ + int mult; + int h; + unsigned l; + asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i)); + {h, l} = macs(mult, sample, 0, 0); + sample = h << 3; + + /* Note, in 2 byte sub slot - ignore lower bits of macs */ +#elif defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX) + sample = sample << 3; +#endif +#endif + write_short_via_xc_ptr(g_aud_to_host_dptr, sample>>16); + g_aud_to_host_dptr+=2; + } + break; + + case 4: + { +#if (STREAM_FORMAT_INPUT_SUBSLOT_4_USED == 0) +__builtin_unreachable(); +#endif + unsigned ptr = g_aud_to_host_dptr; + + for(int i = 0; i < g_numUsbChan_In; i++) + { + /* Receive sample */ + int sample = inuint(c_mix_out); +#if(INPUT_VOLUME_CONTROL == 1) +#if !defined(IN_VOLUME_IN_MIXER) + /* Apply volume */ + int mult; + int h; + unsigned l; + asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i)); + {h, l} = macs(mult, sample, 0, 0); + sample = h << 3; +#if (STREAM_FORMAT_INPUT_RESOLUTION_32BIT_USED == 1) + sample |= (l >> 29) & 0x7; // Note, this step is not required if we assume sample depth is 24 (rather than 32) +#endif +#elif defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX) + sample = sample << 3; +#endif +#endif + /* Write into fifo */ + write_via_xc_ptr(ptr, sample); + ptr+=4; + } + + /* Update global pointer */ + g_aud_to_host_dptr = ptr; + break; + } + + case 3: +#if (STREAM_FORMAT_INPUT_SUBSLOT_3_USED == 0) +__builtin_unreachable(); +#endif + for(int i = 0; i < g_numUsbChan_In; i++) + { + /* Receive sample */ + int sample = inuint(c_mix_out); +#if (INPUT_VOLUME_CONTROL) && !defined(IN_VOLUME_IN_MIXER) + /* Apply volume */ + int mult; + int h; + unsigned l; + asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i)); + {h, l} = macs(mult, sample, 0, 0); + sample = h << 3; +#endif + /* Pack 3 byte samples */ + switch (packState&0x3) + { + case 0: + packData = sample; + break; + case 1: + packData = (packData >> 8) | ((sample & 0xff00)<<16); + write_via_xc_ptr(g_aud_to_host_dptr, packData); + g_aud_to_host_dptr+=4; + write_via_xc_ptr(g_aud_to_host_dptr, sample>>16); + packData = sample; + break; + case 2: + packData = (packData>>16) | ((sample & 0xffff00) << 8); + write_via_xc_ptr(g_aud_to_host_dptr, packData); + g_aud_to_host_dptr+=4; + packData = sample; + break; + case 3: + packData = (packData >> 24) | (sample & 0xffffff00); + write_via_xc_ptr(g_aud_to_host_dptr, packData); + g_aud_to_host_dptr+=4; + break; + } + packState++; + } + break; + + default: + __builtin_unreachable(); + break; + } + + /* Input any remaining channels - past this thread we always operate on max channel count */ + for(int i = 0; i < NUM_USB_CHAN_IN - g_numUsbChan_In; i++) + { + inuint(c_mix_out); + } + + sampsToWrite--; + } + + if (!inOverflow) { if (sampsToWrite == 0) From 5f7d11d2fb873432717ce2b5be83162200c45695 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Mon, 7 Sep 2015 16:09:57 +0100 Subject: [PATCH 11/21] Fixing some build issues when I2S_CHANS_DAC = 0 but DSD_CHANS_DAC != 0 --- module_usb_audio/ports/audioports.c | 4 ++-- module_usb_audio/ports/audioports.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/module_usb_audio/ports/audioports.c b/module_usb_audio/ports/audioports.c index d121e711..d5e72b03 100644 --- a/module_usb_audio/ports/audioports.c +++ b/module_usb_audio/ports/audioports.c @@ -31,7 +31,7 @@ void EnableBufferedPort(port p, unsigned transferWidth) /* C wrapper for ConfigAudioPorts() to handle DSD ports */ void ConfigAudioPortsWrapper( -#if (I2S_CHANS_DAC != 0) +#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0) port p_dac[], int numPortsDac, #endif @@ -46,7 +46,7 @@ void ConfigAudioPortsWrapper( unsigned int divide, unsigned int dsdMode) { ConfigAudioPorts( -#if (I2S_CHANS_DAC != 0) +#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0) p_dac, numPortsDac, #endif diff --git a/module_usb_audio/ports/audioports.h b/module_usb_audio/ports/audioports.h index 09e59b35..153b28e5 100644 --- a/module_usb_audio/ports/audioports.h +++ b/module_usb_audio/ports/audioports.h @@ -57,7 +57,7 @@ void ConfigAudioPorts( #ifdef __XC__ void ConfigAudioPortsWrapper( -#if (I2S_CHANS_DAC != 0) +#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0) buffered out port:32 p_i2s_dac[], int numPortsDAC, #endif @@ -78,7 +78,7 @@ void ConfigAudioPortsWrapper( #else void ConfigAudioPortsWrapper( -#if (I2S_CHANS_DAC != 0) +#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0) port p_i2s_dac[], int numPortsDAC, #endif From 71adeaac9193a39e41cdf550dbcbe4b109c0cc39 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Mon, 7 Sep 2015 16:10:29 +0100 Subject: [PATCH 12/21] ADC only build with mixer failed to start up properly - channel comms mismatch. --- module_usb_audio/mixer/mixer.xc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/module_usb_audio/mixer/mixer.xc b/module_usb_audio/mixer/mixer.xc index cffbb0f9..85a6282d 100644 --- a/module_usb_audio/mixer/mixer.xc +++ b/module_usb_audio/mixer/mixer.xc @@ -598,6 +598,9 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) } #else /* IF MAX_MIX_COUNT > 0 */ /* No mixes, this thread runs on its own doing just volume */ +#if(NUM_USB_CHAN_OUT == 0) + outuint(c_mixer2, 0); +#endif GiveSamplesToDevice(c_mixer2, samples_to_device_map, multOut); GetSamplesFromDevice(c_mixer2); GiveSamplesToHost(c_host, samples_to_host_map, multIn); From 6867bd09236fe7f8aae3c5bcb83c0e4ee095988b Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Mon, 7 Sep 2015 16:30:16 +0100 Subject: [PATCH 13/21] Fixed bad guard on var dec --- module_usb_audio/audio.xc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/module_usb_audio/audio.xc b/module_usb_audio/audio.xc index 64b0d6f2..6b1dd261 100755 --- a/module_usb_audio/audio.xc +++ b/module_usb_audio/audio.xc @@ -436,9 +436,6 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, chanend ?c_adc) { -#if (I2S_CHANS_ADC != 0) || defined(SPDIF_TX) - unsigned sample; -#endif /* Since DAC and ADC buffered ports off by one sample we buffer previous ADC frame */ unsigned readBuffNo = 0; unsigned index; @@ -691,7 +688,7 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, #endif #if defined(SPDIF_TX) && (NUM_USB_CHAN_OUT > 0) outuint(c_spd_out, samplesOut[SPDIF_TX_INDEX]); /* Forward sample to S/PDIF Tx thread */ - sample = samplesOut[SPDIF_TX_INDEX + 1]; + unsigned sample = samplesOut[SPDIF_TX_INDEX + 1]; outuint(c_spd_out, sample); /* Forward sample to S/PDIF Tx thread */ #endif } From fd5806cab9f831df747fd2927bc5b6b6efd0d41f Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Mon, 7 Sep 2015 16:40:14 +0100 Subject: [PATCH 14/21] Fixed build issue - undeclared var. --- module_usb_audio/audio.xc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/module_usb_audio/audio.xc b/module_usb_audio/audio.xc index 6b1dd261..7a784416 100755 --- a/module_usb_audio/audio.xc +++ b/module_usb_audio/audio.xc @@ -611,6 +611,7 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, { // p_i2s_adc[index++] :> sample; // Manual IN instruction since compiler generates an extra setc per IN (bug #15256) + unsigned sample; asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++])); /* Note the use of readBuffNo changes based on frameCount */ @@ -701,7 +702,9 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, for(int i = 0; i < I2S_CHANS_ADC; i += I2S_CHANS_PER_FRAME) { /* Manual IN instruction since compiler generates an extra setc per IN (bug #15256) */ + unsigned sample; asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++])); + if(buffIndex) samplesIn_1[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line. else From 86e0423226b839fc9f28841bf48aaac09c85caca Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Tue, 8 Sep 2015 11:37:03 +0100 Subject: [PATCH 15/21] Changelog updates. --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 65a9c53a..740a9b0e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,11 @@ sc_usb_audio Change Log ======================= +6.12.6 +------ + - RESOLVED: Build error when DFU is disabled + - RESOLVED: Build error when I2S_CHANS_ADC or I2S_CHANS_DAC set to 0 and CODEC_MASTER enabled + 6.12.5 ------ - RESOLVED: Stream issue when NUM_USB_CHAN_IN < I2S_CHANS_ADC From 2ee8faf3efef90df49e7fec7043ce632d4333429 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Tue, 8 Sep 2015 11:47:09 +0100 Subject: [PATCH 16/21] Added implicit FB to changelog. --- CHANGELOG.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 740a9b0e..ac29e3b5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,12 @@ sc_usb_audio Change Log ======================= +6.12.7 +------ + - ADDED: Device now uses implicit feedback when input stream is available (previously explicit + feedback pipe always used). This saves chanend/EP resources and means less processing + burden for the host. + 6.12.6 ------ - RESOLVED: Build error when DFU is disabled From 7c1c5499f84f0d2fc5487d4115a54684f9cda42c Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Wed, 9 Sep 2015 11:14:19 +0100 Subject: [PATCH 17/21] Fixed up dummy deliver for shared mixer/non-mixer channel comms scheme --- module_usb_audio/audio.xc | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/module_usb_audio/audio.xc b/module_usb_audio/audio.xc index 7a784416..30e705ee 100755 --- a/module_usb_audio/audio.xc +++ b/module_usb_audio/audio.xc @@ -881,35 +881,28 @@ static void dummy_deliver(chanend c_out, unsigned &command) } else { -#ifndef MIXER // Interfaces straight to decouple() - (void) inuint(c_out); + +#if NUM_USB_CHAN_OUT > 0 +#pragma loop unroll + for(int i = 0; i < NUM_USB_CHAN_OUT; i++) + { + int tmp = inuint(c_out); + samplesOut[i] = tmp; + } +#else + inuint(c_out); +#endif + +#if NUM_USB_CHAN_IN > 0 #pragma loop unroll for(int i = 0; i < NUM_USB_CHAN_IN; i++) { outuint(c_out, 0); } - -#pragma loop unroll - for(int i = 0; i < NUM_USB_CHAN_OUT; i++) - { - (void) inuint(c_out); - } -#else -#pragma loop unroll - for(int i = 0; i < NUM_USB_CHAN_OUT; i++) - { - (void) inuint(c_out); - } - -#pragma loop unroll - for(int i = 0; i < NUM_USB_CHAN_IN; i++) - { - outuint(c_out, 0); - } #endif - } + } - outuint(c_out, 0); + outuint(c_out, 0); break; } } From 9036bac9323fd9f1d1e09b1eb35bac9da81cda8a Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Wed, 9 Sep 2015 11:15:06 +0100 Subject: [PATCH 18/21] Fixed up mixer channel comms scheme --- module_usb_audio/mixer/mixer.xc | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/module_usb_audio/mixer/mixer.xc b/module_usb_audio/mixer/mixer.xc index 85a6282d..d593655a 100644 --- a/module_usb_audio/mixer/mixer.xc +++ b/module_usb_audio/mixer/mixer.xc @@ -203,6 +203,9 @@ static inline void GiveSamplesToHost(chanend c, xc_ptr ptr, xc_ptr multIn) #pragma unsafe arrays static inline void GetSamplesFromHost(chanend c) { +#if (NUM_USB_CHAN_OUT == 0) + inuint(c); +#else { #pragma loop unroll for (int i=0; i 0 outuint(c_mixer2, 0); GiveSamplesToHost(c_host, samples_to_host_map, multIn); @@ -543,7 +548,7 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) inuint(c_mixer2); #ifdef FAST_MIXER mixed = doMix0(samples, mix_mult_slice(0)); -#else +NN#else mixed = doMix(samples, mix_map_slice(0),mix_mult_slice(0)); #endif write_via_xc_ptr_indexed(samples_array, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 0), mixed); @@ -559,11 +564,11 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) #if MAX_MIX_COUNT > 2 #ifdef FAST_MIXER - mixed = doMix2(samples, mix_mult_slice(2)); + mixed = doMix2(samples, mix_mult_slice(2)); #else - mixed = doMix(samples, mix_map_slice(2),mix_mult_slice(2)); + mixed = doMix(samples, mix_map_slice(2),mix_mult_slice(2)); #endif - write_via_xc_ptr_indexed(samples_array, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 2), mixed); + write_via_xc_ptr_indexed(samples_array, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 2), mixed); #if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS) ComputeMixerLevel(mixed, 2); @@ -603,8 +608,8 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) #endif GiveSamplesToDevice(c_mixer2, samples_to_device_map, multOut); GetSamplesFromDevice(c_mixer2); - GiveSamplesToHost(c_host, samples_to_host_map, multIn); GetSamplesFromHost(c_host); + GiveSamplesToHost(c_host, samples_to_host_map, multIn); #endif } } From 4d599e44f5c28433fe71196cb80f9dcf22856fca Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Wed, 9 Sep 2015 11:15:29 +0100 Subject: [PATCH 19/21] Changelog update --- CHANGELOG.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ac29e3b5..028c42b5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,7 +5,9 @@ sc_usb_audio Change Log ------ - ADDED: Device now uses implicit feedback when input stream is available (previously explicit feedback pipe always used). This saves chanend/EP resources and means less processing - burden for the host. + burden for the host. Previous behaviour available by enabling UAC_FORCE_FEEDBACK_EP + - CHANGE: Mixer and non-mixer channel comms scheme (decouple <-> audio path) now the identical + 6.12.6 ------ From 728f3700f653081731cff275afbe700b6f2277a5 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Fri, 11 Sep 2015 10:23:41 +0100 Subject: [PATCH 20/21] Fixed accidental character addition causing build error. --- module_usb_audio/mixer/mixer.xc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module_usb_audio/mixer/mixer.xc b/module_usb_audio/mixer/mixer.xc index d593655a..e882f71c 100644 --- a/module_usb_audio/mixer/mixer.xc +++ b/module_usb_audio/mixer/mixer.xc @@ -548,7 +548,7 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) inuint(c_mixer2); #ifdef FAST_MIXER mixed = doMix0(samples, mix_mult_slice(0)); -NN#else +#else mixed = doMix(samples, mix_map_slice(0),mix_mult_slice(0)); #endif write_via_xc_ptr_indexed(samples_array, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 0), mixed); From c45f91ff399fa422ea527e58ad1e53fed5d65b71 Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Tue, 15 Sep 2015 15:33:02 +0100 Subject: [PATCH 21/21] Fixed endpoint type table (due to removal of explicit feedback EP) --- module_usb_audio/main.xc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/module_usb_audio/main.xc b/module_usb_audio/main.xc index a73b8150..63190444 100755 --- a/module_usb_audio/main.xc +++ b/module_usb_audio/main.xc @@ -212,16 +212,19 @@ XUD_EpType epTypeTableOut[ENDPOINT_COUNT_OUT] = { XUD_EPTYPE_CTL | XUD_STATUS_EN XUD_EPTYPE_BUL, /* MIDI */ #endif #ifdef IAP - XUD_EPTYPE_BUL, /* iAP */ + XUD_EPTYPE_BUL, /* iAP */ #ifdef IAP_EA_NATIVE_TRANS - XUD_EPTYPE_BUL, /* EA Native Transport */ + XUD_EPTYPE_BUL, /* EA Native Transport */ #endif #endif }; XUD_EpType epTypeTableIn[ENDPOINT_COUNT_IN] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, XUD_EPTYPE_ISO, - XUD_EPTYPE_ISO, + +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) + XUD_EPTYPE_ISO, /* Async feedback endpoint */ +#endif #if defined (SPDIF_RX) || defined (ADAT_RX) XUD_EPTYPE_BUL, #endif