diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 68789a60..288ebdaa 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,25 @@ sc_usb_audio Change Log ======================= +6.9.0 +----- + - ADDED: ADAT S-MUX II functionality (i.e. 2 channels at 192kHz) - Previously only S-MUX + supported (4 channels at 96kHz). + - ADDED: Explicit build warnings if sample rate/depth & channel combination exceeds + available USB bus bandwidth. + - RESOLVED: (Major) Reinstated ADAT input functionality, including descriptors and clock + generation/control and stream configuration defines/tables. + - RESOLVED: (Major) S/PDIF/ADAT sample transfer code in audio() (from ClockGen()) moved to + aid timing. + - CHANGE: Modifying mix map now only affects specified mix, previous was applied to all + mixes. CS_XU_MIXSEL control selector now takes values 0 to MAX_MIX_COUNT + 1 + (with 0 affecting all mixes). + - CHANGE: Channel c_dig_rx is no longer nullable, assists with timing due to removal of + null checks inserted by compiler. + - CHANGE: ADAT SMUX selection now based on device sample frequency rather than selected + stream format - Endpoint 0 now configures clockgen() on a sample-rate change + rather than stream start. + 6.8.0 ----- - ADDED: Evaluation support for iAP EA Native Transport endpoints diff --git a/README.rst b/README.rst index b1c3de00..b69e3079 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ USB Audio Shared ................ -:Latest release: 6.8.0alpha2 +:Latest release: 6.9.0alpha0 :Maintainer: xross :Description: USB Audio Shared Components. For use in the XMOS USB Audio Refererence Designs. diff --git a/module_usb_audio/audio.h b/module_usb_audio/audio.h index 38cb7970..bef4d5d5 100644 --- a/module_usb_audio/audio.h +++ b/module_usb_audio/audio.h @@ -1,6 +1,7 @@ #ifndef __audio_h__ #define __audio_h__ +#include "devicedefines.h" /** The audio driver thread. * * This function drives I2S ports and handles samples to/from other digital @@ -13,6 +14,10 @@ * \param c_config An optional channel that will be passed on to the * CODEC configuration functions. */ -void audio(chanend c_in, chanend ?c_dig, chanend ?c_config, chanend ?c_adc); +void audio(chanend c_in, +#if (defined(SPDIF_RX) || defined(ADAT_RX)) + chanend c_dig, +#endif + chanend ?c_config, chanend ?c_adc); #endif // __audio_h__ diff --git a/module_usb_audio/audio.xc b/module_usb_audio/audio.xc index 755ce13e..eab75996 100755 --- a/module_usb_audio/audio.xc +++ b/module_usb_audio/audio.xc @@ -144,7 +144,11 @@ static inline void doI2SClocks(unsigned divide) /* I2S delivery thread */ #pragma unsafe arrays -unsigned static deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, unsigned curSamFreq, chanend ?c_dig_rx, chanend ?c_adc) +unsigned static deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, unsigned curSamFreq, +#if(defined(SPDIF_RX) || defined(ADAT_RX)) +chanend c_dig_rx, +#endif +chanend ?c_adc) { #if (I2S_CHANS_ADC != 0) || defined(SPDIF) unsigned sample; @@ -461,30 +465,7 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, unsi #endif } -#if defined(SPDIF_RX) || defined(ADAT_RX) - /* Sync with clockgen */ - inuint(c_dig_rx); -#endif -#ifdef SPDIF_RX - asm("ldw %0, dp[g_digData]":"=r"(samplesIn[SPDIF_RX_INDEX + 0])); - asm("ldw %0, dp[g_digData+4]":"=r"(samplesIn[SPDIF_RX_INDEX + 1])); -#endif -#ifdef ADAT_RX - asm("ldw %0, dp[g_digData+8]":"=r"(samplesIn[ADAT_RX_INDEX + 0])); - asm("ldw %0, dp[g_digData+12]":"=r"(samplesIn[ADAT_RX_INDEX+ 1])); - asm("ldw %0, dp[g_digData+16]":"=r"(samplesIn[ADAT_RX_INDEX + 2])); - asm("ldw %0, dp[g_digData+20]":"=r"(samplesIn[ADAT_RX_INDEX + 3])); - asm("ldw %0, dp[g_digData+24]":"=r"(samplesIn[ADAT_RX_INDEX + 4])); - asm("ldw %0, dp[g_digData+28]":"=r"(samplesIn[ADAT_RX_INDEX + 5])); - asm("ldw %0, dp[g_digData+32]":"=r"(samplesIn[ADAT_RX_INDEX + 6])); - asm("ldw %0, dp[g_digData+36]":"=r"(samplesIn[ADAT_RX_INDEX + 7])); -#endif - -#if defined(SPDIF_RX) || defined(ADAT_RX) - /* Request digital data (with prefill) */ - outuint(c_dig_rx, 0); -#endif tmp = 0; #if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0) @@ -629,7 +610,30 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, unsi #endif } #endif +#if defined(SPDIF_RX) || defined(ADAT_RX) + /* Sync with clockgen */ + inuint(c_dig_rx); +#endif +#ifdef SPDIF_RX + asm("ldw %0, dp[g_digData]":"=r"(samplesIn[SPDIF_RX_INDEX + 0])); + asm("ldw %0, dp[g_digData+4]":"=r"(samplesIn[SPDIF_RX_INDEX + 1])); +#endif +#ifdef ADAT_RX + asm("ldw %0, dp[g_digData+8]":"=r"(samplesIn[ADAT_RX_INDEX])); + asm("ldw %0, dp[g_digData+12]":"=r"(samplesIn[ADAT_RX_INDEX + 1])); + asm("ldw %0, dp[g_digData+16]":"=r"(samplesIn[ADAT_RX_INDEX + 2])); + asm("ldw %0, dp[g_digData+20]":"=r"(samplesIn[ADAT_RX_INDEX + 3])); + asm("ldw %0, dp[g_digData+24]":"=r"(samplesIn[ADAT_RX_INDEX + 4])); + asm("ldw %0, dp[g_digData+28]":"=r"(samplesIn[ADAT_RX_INDEX + 5])); + asm("ldw %0, dp[g_digData+32]":"=r"(samplesIn[ADAT_RX_INDEX + 6])); + asm("ldw %0, dp[g_digData+36]":"=r"(samplesIn[ADAT_RX_INDEX + 7])); +#endif + +#if defined(SPDIF_RX) || defined(ADAT_RX) + /* Request digital data (with prefill) */ + outuint(c_dig_rx, 0); +#endif #if defined(SPDIF) && (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]; @@ -779,7 +783,11 @@ unsigned static dummy_deliver(chanend c_out) #define SAMPLES_PER_PRINT 1 -void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c) +void audio(chanend c_mix_out, +#if (defined(ADAT_RX) || defined(SPDIF_RX)) +chanend c_dig_rx, +#endif +chanend ?c_config, chanend ?c) { #ifdef SPDIF chan c_spdif_out; @@ -989,7 +997,11 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c) #else null, #endif - divide, curSamFreq, c_dig_rx, c); + divide, curSamFreq, +#if defined (ADAT_RX) || defined (SPDIF_RX) + c_dig_rx, +#endif + c); if(command == SET_SAMPLE_FREQ) { diff --git a/module_usb_audio/clocking.h b/module_usb_audio/clocking.h index b1b85f57..72237236 100644 --- a/module_usb_audio/clocking.h +++ b/module_usb_audio/clocking.h @@ -13,6 +13,6 @@ * \param c_clk_int channel connected to the decouple() thread for clock interrupts */ -void clockGen (streaming chanend c_spdif_rx, chanend ?c_adat_rx, out port p, chanend c_audio, chanend c_clk_ctl, chanend c_clk_int); +void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, out port p, chanend c_audio, chanend c_clk_ctl, chanend c_clk_int); #endif diff --git a/module_usb_audio/clocking/clockgen.xc b/module_usb_audio/clocking/clockgen.xc index 4046e328..e7cc288b 100644 --- a/module_usb_audio/clocking/clockgen.xc +++ b/module_usb_audio/clocking/clockgen.xc @@ -200,7 +200,7 @@ extern int samples_to_host_inputs_buff[NUM_USB_CHAN_IN]; int VendorAudCoreReqs(unsigned cmd, chanend c); #pragma unsafe arrays -void clockGen (streaming chanend c_spdif_rx, chanend ?c_adat_rx, out port p, chanend c_dig_rx, chanend c_clk_ctl, chanend c_clk_int) +void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, out port p, chanend c_dig_rx, chanend c_clk_ctl, chanend c_clk_int) { timer t_local; unsigned timeNextEdge, timeLastEdge, timeNextClockDetection; @@ -604,16 +604,28 @@ void clockGen (streaming chanend c_spdif_rx, chanend ?c_adat_rx, out port p, cha /* only store left samples if not in overflow and stream is reasonably valid */ if (!adatOverflow && clockValid[CLOCK_ADAT_INDEX]) { - if(smux) + /* Unpick the SMUX.. */ + if(smux == 2) + { + adatSamples[adatWr + 0] = adatFrame[0]; + adatSamples[adatWr + 1] = adatFrame[4]; + adatSamples[adatWr + 2] = adatFrame[1]; + adatSamples[adatWr + 3] = adatFrame[5]; + adatSamples[adatWr + 4] = adatFrame[2]; + adatSamples[adatWr + 5] = adatFrame[6]; + adatSamples[adatWr + 6] = adatFrame[3]; + adatSamples[adatWr + 7] = adatFrame[7]; + } + else if(smux) { adatSamples[adatWr + 0] = adatFrame[0]; - adatSamples[adatWr + 4] = adatFrame[1]; adatSamples[adatWr + 1] = adatFrame[2]; - adatSamples[adatWr + 5] = adatFrame[3]; adatSamples[adatWr + 2] = adatFrame[4]; - adatSamples[adatWr + 6] = adatFrame[5]; adatSamples[adatWr + 3] = adatFrame[6]; + adatSamples[adatWr + 4] = adatFrame[1]; + adatSamples[adatWr + 5] = adatFrame[3]; + adatSamples[adatWr + 6] = adatFrame[5]; adatSamples[adatWr + 7] = adatFrame[7]; } else @@ -741,10 +753,25 @@ void clockGen (streaming chanend c_spdif_rx, chanend ?c_adat_rx, out port p, cha } else { - /* TODO SMUX II mode */ /* read out samples from the ADAT buffer and send */ /* always return 8 samples */ - if (smux) + /* SMUX II mode */ + if (smux == 2) + { + /* SMUX2 mode - 2 samples from fifo and 4 zero samples */ + g_digData[2] = adatSamples[adatRd + 0]; + g_digData[3] = adatSamples[adatRd + 1]; + + g_digData[4] = 0; + g_digData[5] = 0; + g_digData[6] = 0; + g_digData[7] = 0; + g_digData[8] = 0; + g_digData[9] = 0; + adatRd = (adatRd + 2) & (MAX_ADAT_SAMPLES - 1); + adatSamps -= 2; + } + else if(smux) { /* SMUX mode - 4 samples from fifo and 4 zero samples */ g_digData[2] = adatSamples[adatRd + 0]; diff --git a/module_usb_audio/devicedefines.h b/module_usb_audio/devicedefines.h index 766d7a9c..18dd7fff 100644 --- a/module_usb_audio/devicedefines.h +++ b/module_usb_audio/devicedefines.h @@ -263,6 +263,26 @@ #error ADAT_RX_INDEX not defined and ADAT_RX defined #define ADAT_RX_INDEX (0) /* Default define for doxygen */ #endif + +#if (ADAT_RX_INDEX + 8 > NUM_USB_CHAN_IN) + #error Not enough channels for ADAT +#endif +#endif + +#ifdef ADAT_RX + +/* Setup input stream formats for ADAT */ +#if(MAX_FREQ > 96000) +#define INPUT_FORMAT_COUNT 3 +#elif(MAX_FREQ > 48000) +#define INPUT_FORMAT_COUNT 2 +#else +#define INPUT_FORMAT_COUNT 1 +#endif + +#define HS_STREAM_FORMAT_INPUT_1_CHAN_COUNT NUM_USB_CHAN_IN +#define HS_STREAM_FORMAT_INPUT_2_CHAN_COUNT (NUM_USB_CHAN_IN - 4) +#define HS_STREAM_FORMAT_INPUT_3_CHAN_COUNT (NUM_USB_CHAN_IN - 6) #endif /** @@ -386,7 +406,7 @@ * @brief Device firmware version number in Binary Coded Decimal format: 0xJJMN where JJ: major, M: minor, N: sub-minor version number. */ #ifndef BCD_DEVICE_M -#define BCD_DEVICE_M 8 +#define BCD_DEVICE_M 9 #endif /** @@ -644,22 +664,16 @@ #endif #endif +/***** INPUT STREAMS FORMAT ******/ + /** * @brief Number of supported input stream formats. - * - * Currenly only 1 supported - * * Default: 1 */ #ifndef INPUT_FORMAT_COUNT #define INPUT_FORMAT_COUNT 1 #endif -#if (INPUT_FORMAT_COUNT > 1) - /* Only 1 supported */ - #error -#endif - /** * @brief Sample resolution (bits) of input stream Alternate 1. * @@ -669,16 +683,59 @@ #define STREAM_FORMAT_INPUT_1_RESOLUTION_BITS 24 #endif +#ifndef STREAM_FORMAT_INPUT_2_RESOLUTION_BITS + #define STREAM_FORMAT_INPUT_2_RESOLUTION_BITS 24 +#endif + +#ifndef STREAM_FORMAT_INPUT_3_RESOLUTION_BITS + #define STREAM_FORMAT_INPUT_3_RESOLUTION_BITS 24 +#endif + + + /* Default resolutions for HS */ #ifndef HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS #define HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS STREAM_FORMAT_INPUT_1_RESOLUTION_BITS #endif +#ifndef HS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS + #define HS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS STREAM_FORMAT_INPUT_2_RESOLUTION_BITS +#endif + +#ifndef HS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS + #define HS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS STREAM_FORMAT_INPUT_3_RESOLUTION_BITS +#endif + + /* Default resolutions for FS (same as HS) */ #ifndef FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS #define FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS STREAM_FORMAT_INPUT_1_RESOLUTION_BITS #endif +#ifndef FS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS + #define FS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS STREAM_FORMAT_INPUT_2_RESOLUTION_BITS +#endif + +#ifndef FS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS + #define FS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS STREAM_FORMAT_INPUT_3_RESOLUTION_BITS +#endif + + +/* Channel count defines for input streams */ +#ifndef HS_STREAM_FORMAT_INPUT_1_CHAN_COUNT + #define HS_STREAM_FORMAT_INPUT_1_CHAN_COUNT NUM_USB_CHAN_IN +#endif + +#ifndef HS_STREAM_FORMAT_INPUT_2_CHAN_COUNT + #define HS_STREAM_FORMAT_INPUT_2_CHAN_COUNT NUM_USB_CHAN_IN +#endif + +#ifndef HS_STREAM_FORMAT_INPUT_3_CHAN_COUNT + #define HS_STREAM_FORMAT_INPUT_3_CHAN_COUNT NUM_USB_CHAN_IN +#endif + + + /** * @brief Sample sub-slot size (bytes) of input stream Alternate 1 when running in high-speed * @@ -696,6 +753,22 @@ #endif #endif +#ifndef HS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES + #if (HS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS == 24) + #define HS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES 4 /* 4 byte subslot is nicer for our 32 bit machine to unpack.. */ + #else + #define HS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES (HS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS/8) + #endif +#endif + +#ifndef HS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES + #if (HS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS == 24) + #define HS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES 4 /* 4 byte subslot is nicer for our 32 bit machine to unpack.. */ + #else + #define HS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES (HS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS/8) + #endif +#endif + /** * @brief Sample sub-slot size (bytes) of input stream Alternate 1 when running in full-speed * @@ -705,7 +778,15 @@ * Default: STREAM_FORMAT_INPUT_1_RESOLUTION_BITS / 8 */ #ifndef FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES - #define FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES (FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS/8) + #define FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES (FS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS/8) +#endif + +#ifndef FS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES + #define FS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES (FS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS/8) +#endif + +#ifndef FS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES + #define FS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES (FS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS/8) #endif /** @@ -717,6 +798,18 @@ #define STREAM_FORMAT_INPUT_1_DATAFORMAT UAC_FORMAT_TYPEI_PCM #endif +#ifndef STREAM_FORMAT_INPUT_2_DATAFORMAT + #define STREAM_FORMAT_INPUT_2_DATAFORMAT UAC_FORMAT_TYPEI_PCM +#endif + +#ifndef STREAM_FORMAT_INPUT_3_DATAFORMAT + #define STREAM_FORMAT_INPUT_3_DATAFORMAT UAC_FORMAT_TYPEI_PCM +#endif + + +/****** END INPUT STREAMS FORMAT *****/ + + /** * @brief Enable/disable output volume control including all processing and descriptor support * diff --git a/module_usb_audio/endpoint0/audiorequests.xc b/module_usb_audio/endpoint0/audiorequests.xc index 42a8b079..39452110 100644 --- a/module_usb_audio/endpoint0/audiorequests.xc +++ b/module_usb_audio/endpoint0/audiorequests.xc @@ -40,7 +40,7 @@ extern unsigned char channelMapAud[NUM_USB_CHAN_OUT]; extern unsigned char channelMapUsb[NUM_USB_CHAN_IN]; /* Mixer input mapping */ -extern unsigned char mixSel[MIX_INPUTS]; +extern unsigned char mixSel[MAX_MIX_COUNT][MIX_INPUTS]; #endif /* Global var for current frequency, set to default freq */ @@ -320,7 +320,26 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c } setG_curSamFreqMultiplier(g_curSamFreq/(i_tmp/512)); - +#ifdef ADAT_RX + /* Configure ADAT SMUX based on sample rate */ + outuint(c_clk_ctl, SET_SMUX); + if(g_curSamFreq < 88200) + { + /* No SMUX */ + outuint(c_clk_ctl, 0); + } + else if(g_curSamFreq < 176400) + { + /* SMUX */ + outuint(c_clk_ctl, 1); + } + else + { + /* SMUX II */ + outuint(c_clk_ctl, 2); + } + outct(c_clk_ctl, XS1_CT_END); +#endif outuint(c_audioControl, SET_SAMPLE_FREQ); outuint(c_audioControl, g_curSamFreq); @@ -687,23 +706,42 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c /* cn bounds check for safety..*/ if(cn < MIX_INPUTS) { - if(cs == CS_XU_MIXSEL) + //if(cs == CS_XU_MIXSEL) + /* cs now contains mix number */ + if(cs < (MAX_MIX_COUNT + 1)) { /* Check for "off" - update local state */ if(buffer[0] == 0xFF) - mixSel[cn] = (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT); - else - mixSel[cn] = buffer[0]; - - /* Update all mix maps */ - for (int i = 0; i < MAX_MIX_COUNT; i++) { - outuint(c_mix_ctl, SET_MIX_MAP); - outuint(c_mix_ctl, i); /* Mix bus */ - outuint(c_mix_ctl, cn); /* Mixer input */ - outuint(c_mix_ctl, (int) mixSel[cn]); /* Source */ - outct(c_mix_ctl, XS1_CT_END); + mixSel[cs][cn] = (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT); } + else + { + mixSel[cs][cn] = buffer[0]; + } + + if(cs == 0) + { + /* Update all mix maps */ + for (int i = 0; i < MAX_MIX_COUNT; i++) + { + outuint(c_mix_ctl, SET_MIX_MAP); + outuint(c_mix_ctl, i); /* Mix bus */ + outuint(c_mix_ctl, cn); /* Mixer input */ + outuint(c_mix_ctl, (int) mixSel[cn]); /* Source */ + outct(c_mix_ctl, XS1_CT_END); + } + } + else + { + /* Update relevant mix map */ + outuint(c_mix_ctl, SET_MIX_MAP); /* Command */ + outuint(c_mix_ctl, (cs-1)); /* Mix bus */ + outuint(c_mix_ctl, cn); /* Mixer input */ + outuint(c_mix_ctl, (int) mixSel[cs][cn]); /* Source */ + outct(c_mix_ctl, XS1_CT_END); /* Wait for handshake back */ + } + return XUD_DoSetRequestStatus(ep0_in); } } @@ -718,9 +756,10 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c if(cn < MIX_INPUTS) { /* Inspect control selector */ - if(cs == CS_XU_MIXSEL) + /* TODO ideally have a return for cs = 0. I.e all mix maps */ + if((cs > 0) && (cs < (MAX_MIX_COUNT+1))) { - buffer[0] = mixSel[cn]; + buffer[0] = mixSel[cs-1][cn]; return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 1, 1 ); } } diff --git a/module_usb_audio/endpoint0/descriptors.h b/module_usb_audio/endpoint0/descriptors.h index dd5b38bd..7bf0ee20 100644 --- a/module_usb_audio/endpoint0/descriptors.h +++ b/module_usb_audio/endpoint0/descriptors.h @@ -14,7 +14,7 @@ #ifdef IAP_EA_NATIVE_TRANS /* - * FIXME currently this will not build if IAP_EA_NATIVE_TRANS_PROTOCOL_NAME is not defined in iap_conf.h, + * NOTE, currently this will not build if IAP_EA_NATIVE_TRANS_PROTOCOL_NAME is not defined in iap_conf.h, * would be nice if a default string was used instead, and a warning issued. * * Could get a default define by including the following line, but iap2.h cannot currently be included from C @@ -1153,21 +1153,55 @@ unsigned char hidReportDescriptor[] = * Samples per channel. e.g (192000+7999/8000) = 24 * Must allow 1 sample extra per chan (24 + 1) = 25 * Multiply by number of channels and bytes 25 * 2 * 4 = 200 bytes + * TODO Output doesn't get modified by channel count */ #define MAX_PACKET_SIZE_MULT_OUT_HS ((((MAX_FREQ+7999)/8000)+1) * NUM_USB_CHAN_OUT) #define MAX_PACKET_SIZE_MULT_OUT_FS ((((MAX_FREQ_FS+999)/1000)+1) * NUM_USB_CHAN_OUT_FS) -#define MAX_PACKET_SIZE_MULT_IN_HS ((((MAX_FREQ+7999)/8000)+1) * NUM_USB_CHAN_IN) -#define MAX_PACKET_SIZE_MULT_IN_FS ((((MAX_FREQ_FS+999)/1000)+1) * NUM_USB_CHAN_IN_FS) #define HS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_OUT_HS * HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES) #define HS_STREAM_FORMAT_OUTPUT_2_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_OUT_HS * HS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES) #define HS_STREAM_FORMAT_OUTPUT_3_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_OUT_HS * HS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES) +#if (HS_STEAM_FORMAT_OUPUT_1_MAXPACKETSIZE > 1024) || (HS_STEAM_FORMAT_OUPUT_2_MAXPACKETSIZE > 1024) \ + || (HS_STEAM_FORMAT_OUPUT_3_MAXPACKETSIZE > 1024) +#error +#endif + #define FS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_OUT_FS * FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES) #define FS_STREAM_FORMAT_OUTPUT_2_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_OUT_FS * FS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES) #define FS_STREAM_FORMAT_OUTPUT_3_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_OUT_FS * FS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES) -#define HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_IN_HS * HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES) +/* Input Packet Sizes: high-speed */ + +#define MAX_PACKET_SIZE_MULT_INPUT_1_HS ((((MAX_FREQ+7999)/8000)+1) * HS_STREAM_FORMAT_INPUT_1_CHAN_COUNT) +#define MAX_PACKET_SIZE_MULT_INPUT_2_HS ((((MAX_FREQ+7999)/8000)+1) * HS_STREAM_FORMAT_INPUT_2_CHAN_COUNT) +#define MAX_PACKET_SIZE_MULT_INPUT_3_HS ((((MAX_FREQ+7999)/8000)+1) * HS_STREAM_FORMAT_INPUT_3_CHAN_COUNT) + +/* TODO SUBSLOT_BYTES shared */ +#define HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_INPUT_1_HS * HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES) +#define HS_STREAM_FORMAT_INPUT_2_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_INPUT_1_HS * HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES) +#define HS_STREAM_FORMAT_INPUT_3_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_INPUT_1_HS * HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES) + +#if (HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE > 1024) +#warning HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE > 1024 +#undef HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE +#define HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE 1024 +#endif + +#if (HS_STREAM_FORMAT_INPUT_2_MAXPACKETSIZE > 1024) +#warning HS_STREAM_FORMAT_INPUT_2_MAXPACKETSIZE > 1024 +#undef HS_STREAM_FORMAT_INPUT_2_MAXPACKETSIZE +#define HS_STREAM_FORMAT_INPUT_2_MAXPACKETSIZE 1024 +#endif + +#if (HS_STREAM_FORMAT_INPUT_3_MAXPACKETSIZE > 1024) +#warning HS_STREAM_FORMAT_INPUT_3_MAXPACKETSIZE > 1024 +#undef HS_STREAM_FORMAT_INPUT_3_MAXPACKETSIZE +#define HS_STREAM_FORMAT_INPUT_3_MAXPACKETSIZE 1024 +#endif + +/* Input Packet Sizes: full-speed */ +#define MAX_PACKET_SIZE_MULT_IN_FS ((((MAX_FREQ_FS+999)/1000)+1) * NUM_USB_CHAN_IN_FS) #define FS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_IN_FS * FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES) #if (NUM_CLOCKS == 1) @@ -1268,8 +1302,21 @@ typedef struct USB_Descriptor_Audio_Format_Type1_t Audio_In_Format; USB_Descriptor_Endpoint_t Audio_In_Endpoint; USB_Descriptor_Audio_Class_AS_Endpoint_t Audio_In_ClassEndpoint; +#if (INPUT_FORMAT_COUNT > 1) + USB_Descriptor_Interface_t Audio_In_StreamInterface_Alt2; + USB_Descriptor_Audio_Interface_AS_t Audio_In_ClassStreamInterface_2; + USB_Descriptor_Audio_Format_Type1_t Audio_In_Format_2; + USB_Descriptor_Endpoint_t Audio_In_Endpoint_2; + USB_Descriptor_Audio_Class_AS_Endpoint_t Audio_In_ClassEndpoint_2; +#endif +#if (INPUT_FORMAT_COUNT > 2) + USB_Descriptor_Interface_t Audio_In_StreamInterface_Alt3; + USB_Descriptor_Audio_Interface_AS_t Audio_In_ClassStreamInterface_3; + USB_Descriptor_Audio_Format_Type1_t Audio_In_Format_3; + USB_Descriptor_Endpoint_t Audio_In_Endpoint_3; + USB_Descriptor_Audio_Class_AS_Endpoint_t Audio_In_ClassEndpoint_3; +#endif #endif - #ifdef MIDI /* MIDI descriptors currently handled as a single block */ unsigned char configDesc_Midi[MIDI_LENGTH]; @@ -2069,70 +2116,69 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= #endif /* OUTPUT_FORMAT_COUNT > 2 */ #endif /* OUTPUT */ #if (NUM_USB_CHAN_IN > 0) - /* Zero bandwith alternative 0 */ /* Standard AS Interface Descriptor (4.9.1) */ .Audio_In_StreamInterface_Alt0 = { - 0x09, /* 0 bLength: (in bytes, 9) */ - USB_DESCTYPE_INTERFACE, /* 1 bDescriptorType: INTERFACE */ - INTERFACE_NUMBER_AUDIO_INPUT, /* 2 bInterfaceNumber: Number of interface */ - 0, /* 3 bAlternateSetting */ - 0, /* 4 bNumEndpoints */ - USB_CLASS_AUDIO, /* 5 bInterfaceClass: AUDIO */ - UAC_INT_SUBCLASS_AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ - 0x20, /* 7 bInterfaceProtocol: IP_VERSION_02_00 */ - 5, /* 8 iInterface: (Sting index) */ + .bLength = 0x09, + .bDescriptorType = USB_DESCTYPE_INTERFACE, + .bInterfaceNumber = INTERFACE_NUMBER_AUDIO_INPUT, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = UAC_INT_SUBCLASS_AUDIOSTREAMING, + .bInterfaceProtocol = 0x20, + .iInterface = 5, /* (String index) */ }, /* Alternative 1 */ /* Standard AS Interface Descriptor (4.9.1) (Alt) */ .Audio_In_StreamInterface_Alt1 = { - 0x09, /* 0 bLength: (in bytes, 9) */ - USB_DESCTYPE_INTERFACE, /* 1 bDescriptorType: INTERFACE */ - INTERFACE_NUMBER_AUDIO_INPUT, /* 2 bInterfaceNumber: Number of interface */ - 1, /* 3 bAlternateSetting */ - 1, /* 4 bNumEndpoints */ - 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 */ - 5, /* 8 iInterface: (Sting index) */ + .bLength = 0x09, + .bDescriptorType = USB_DESCTYPE_INTERFACE, + .bInterfaceNumber = INTERFACE_NUMBER_AUDIO_INPUT, + .bAlternateSetting = 1, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = UAC_INT_SUBCLASS_AUDIOSTREAMING, + .bInterfaceProtocol = UAC_INT_PROTOCOL_IP_VERSION_02_00, + .iInterface = 5, /* (String index) */ }, /* Class Specific AS Interface Descriptor */ .Audio_In_ClassStreamInterface = { - 0x10, /* 0 bLength: 16 */ - UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType: 0x24 */ - UAC_CS_AS_INTERFACE_SUBTYPE_AS_GENERAL, /* 2 bDescriptorSubType */ - ID_OT_USB, /* 3 bTerminalLink */ - 0x00, /* 4 bmControls */ - 0x01, /* 5 bFormatType */ - UAC_FORMAT_TYPEI_PCM, /* 6:10 bmFormats (note this is a bitmap) */ - NUM_USB_CHAN_IN, /* 11 bNrChannels */ - 0x00000000, /* 12:14: bmChannelConfig */ + .bLength = 0x10, + .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE, + .bDescriptorSubType = UAC_CS_AS_INTERFACE_SUBTYPE_AS_GENERAL, + .bTerminalLink = ID_OT_USB, + .bmControls = 0x00, + .bFormatType = 0x01, + .bmFormats = UAC_FORMAT_TYPEI_PCM, + .bNrChannels = HS_STREAM_FORMAT_INPUT_1_CHAN_COUNT, + .bmChannelConfig = 0x00000000, .iChannelNames = offsetof(StringDescTable_t, inputChanStr_1)/sizeof(char *), }, /* Type 1 Format Type Descriptor */ .Audio_In_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_INPUT_1_SUBSLOT_BYTES, /* 4 bSubslotSize (Number of bytes per subslot) */ + .bLength = 6, + .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE, + .bDescriptorSubtype = UAC_CS_AS_INTERFACE_SUBTYPE_FORMAT_TYPE, + .bFormatType = UAC_FORMAT_TYPE_I, + .bSubslotSize = HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES, /* Number of bytes per subslot */ .bBitResolution = HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS, }, /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ .Audio_In_Endpoint = { - 0x07, /* 0 bLength: 7 */ - USB_DESCTYPE_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ - 0x82, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ - 5, /* 3 bmAttributes (bitmap) */ + .bLength = 0x07, + .bDescriptorType = USB_DESCTYPE_ENDPOINT, + .bEndpointAddress = 0x82, + .bmAttributes = 5, .wMaxPacketSize = HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE, .bInterval = 0x01, }, @@ -2148,7 +2194,138 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= .bLockDelayUnits = 0x02, .wLockDelay = 0x0008, }, +#if (INPUT_FORMAT_COUNT > 1) + /* Alternative 2 */ + /* Standard AS Interface Descriptor (4.9.1) (Alt) */ + .Audio_In_StreamInterface_Alt2 = + { + .bLength = 0x09, + .bDescriptorType = USB_DESCTYPE_INTERFACE, + .bInterfaceNumber = INTERFACE_NUMBER_AUDIO_INPUT, + .bAlternateSetting = 2, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = UAC_INT_SUBCLASS_AUDIOSTREAMING, + .bInterfaceProtocol = UAC_INT_PROTOCOL_IP_VERSION_02_00, + .iInterface = 5, /* (String index) */ + }, + + /* Class Specific AS Interface Descriptor */ + .Audio_In_ClassStreamInterface_2 = + { + .bLength = 0x10, + .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE, + .bDescriptorSubType = UAC_CS_AS_INTERFACE_SUBTYPE_AS_GENERAL, + .bTerminalLink = ID_OT_USB, + .bmControls = 0x00, + .bFormatType = 0x01, + .bmFormats = UAC_FORMAT_TYPEI_PCM, + .bNrChannels = HS_STREAM_FORMAT_INPUT_2_CHAN_COUNT, + .bmChannelConfig = 0x00000000, + .iChannelNames = offsetof(StringDescTable_t, inputChanStr_1)/sizeof(char *), + }, + + /* Type 1 Format Type Descriptor */ + .Audio_In_Format_2 = + { + .bLength = 6, + .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE, + .bDescriptorSubtype = UAC_CS_AS_INTERFACE_SUBTYPE_FORMAT_TYPE, + .bFormatType = UAC_FORMAT_TYPE_I, + .bSubslotSize = HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES, /* TODO SUBSLOT_BYTES currently shared */ + .bBitResolution = HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS, /* TODO RESOLUTION_BITS currently shared */ + }, + + /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ + .Audio_In_Endpoint_2 = + { + .bLength = 0x07, + .bDescriptorType = USB_DESCTYPE_ENDPOINT, + .bEndpointAddress = 0x82, + .bmAttributes = 5, + .wMaxPacketSize = HS_STREAM_FORMAT_INPUT_2_MAXPACKETSIZE, + .bInterval = 0x01, + }, + + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */ + .Audio_In_ClassEndpoint_2 = + { + .bLength = sizeof(USB_Descriptor_Audio_Class_AS_Endpoint_t), + .bDescriptorType = UAC_CS_DESCTYPE_ENDPOINT, + .bDescriptorSubtype = UAC_CS_ENDPOINT_SUBTYPE_EP_GENERAL, + .bmAttributes = 0x00, + .bmControls = 0x00, + .bLockDelayUnits = 0x02, + .wLockDelay = 0x0008, + }, #endif +#if (INPUT_FORMAT_COUNT > 2) + /* Alternative 3 */ + /* Standard AS Interface Descriptor (4.9.1) (Alt) */ + .Audio_In_StreamInterface_Alt3 = + { + .bLength = 0x09, + .bDescriptorType = USB_DESCTYPE_INTERFACE, + .bInterfaceNumber = INTERFACE_NUMBER_AUDIO_INPUT, + .bAlternateSetting = 3, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = UAC_INT_SUBCLASS_AUDIOSTREAMING, + .bInterfaceProtocol = UAC_INT_PROTOCOL_IP_VERSION_02_00, + .iInterface = 5, /* (String index) */ + }, + + /* Class Specific AS Interface Descriptor */ + .Audio_In_ClassStreamInterface_3 = + { + .bLength = 0x10, + .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE, + .bDescriptorSubType = UAC_CS_AS_INTERFACE_SUBTYPE_AS_GENERAL, + .bTerminalLink = ID_OT_USB, + .bmControls = 0x00, + .bFormatType = 0x01, + .bmFormats = UAC_FORMAT_TYPEI_PCM, + .bNrChannels = HS_STREAM_FORMAT_INPUT_3_CHAN_COUNT, + .bmChannelConfig = 0x00000000, + .iChannelNames = offsetof(StringDescTable_t, inputChanStr_1)/sizeof(char *), + }, + + /* Type 1 Format Type Descriptor */ + .Audio_In_Format_3 = + { + .bLength = 6, + .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE, + .bDescriptorSubtype = UAC_CS_AS_INTERFACE_SUBTYPE_FORMAT_TYPE, + .bFormatType = UAC_FORMAT_TYPE_I, + .bSubslotSize = HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES, /* TODO SUBSLOT_BYTES currently shared */ + .bBitResolution = HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS, /* TODO RESOLUTION_BITS currently shared */ + }, + + /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ + .Audio_In_Endpoint_3 = + { + .bLength = 0x07, + .bDescriptorType = USB_DESCTYPE_ENDPOINT, + .bEndpointAddress = 0x82, + .bmAttributes = 5, + .wMaxPacketSize = HS_STREAM_FORMAT_INPUT_3_MAXPACKETSIZE, + .bInterval = 0x01, + }, + + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */ + .Audio_In_ClassEndpoint_3 = + { + .bLength = sizeof(USB_Descriptor_Audio_Class_AS_Endpoint_t), + .bDescriptorType = UAC_CS_DESCTYPE_ENDPOINT, + .bDescriptorSubtype = UAC_CS_ENDPOINT_SUBTYPE_EP_GENERAL, + .bmAttributes = 0x00, + .bmControls = 0x00, + .bLockDelayUnits = 0x02, + .wLockDelay = 0x0008, + }, +#endif + +#endif /* #if(NUM_USB_CHAN_IN > 0) */ #ifdef MIDI /* MIDI Descriptors */ /* Table B-3: MIDI Adapter Standard AC Interface Descriptor */ diff --git a/module_usb_audio/endpoint0/endpoint0.c b/module_usb_audio/endpoint0/endpoint0.c index 016468c0..fd546cad 100755 --- a/module_usb_audio/endpoint0/endpoint0.c +++ b/module_usb_audio/endpoint0/endpoint0.c @@ -78,7 +78,7 @@ short mixer1Weights[18*8]; unsigned char channelMap[NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT]; unsigned char channelMapAud[NUM_USB_CHAN_OUT]; unsigned char channelMapUsb[NUM_USB_CHAN_IN]; -unsigned char mixSel[MIX_INPUTS]; +unsigned char mixSel[MAX_MIX_COUNT][MIX_INPUTS]; #endif int min(int x, int y); @@ -97,6 +97,8 @@ unsigned g_curStreamAlt_In = 0; /* Global variable for current USB bus speed (i.e. FS/HS) */ XUD_BusSpeed_t g_curUsbSpeed = 0; + +/* Subslot */ const unsigned g_subSlot_Out_HS[OUTPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES, #if(OUTPUT_FORMAT_COUNT > 1) HS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES, @@ -115,10 +117,25 @@ const unsigned g_subSlot_Out_FS[OUTPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_OUTP #endif }; -const unsigned g_subSlot_In_HS[INPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES}; +const unsigned g_subSlot_In_HS[INPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES, +#if(INPUT_FORMAT_COUNT > 1) + HS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES, +#endif +#if(INPUT_FORMAT_COUNT > 2) + HS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES +#endif +}; -const unsigned g_subSlot_In_FS[INPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES}; +const unsigned g_subSlot_In_FS[INPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES, +#if(INPUT_FORMAT_COUNT > 1) + FS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES, +#endif +#if(INPUT_FORMAT_COUNT > 2) + FS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES +#endif +}; +/* Sample Resolution */ const unsigned g_sampRes_Out_HS[OUTPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS, #if(OUTPUT_FORMAT_COUNT > 1) HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS, @@ -137,12 +154,26 @@ const unsigned g_sampRes_Out_FS[OUTPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_OUTP #endif }; -const unsigned g_sampRes_In_HS[OUTPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS}; +const unsigned g_sampRes_In_HS[INPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS, +#if(INPUT_FORMAT_COUNT > 1) + HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS, +#endif +#if(INPUT_FORMAT_COUNT > 2) + HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS +#endif +}; -const unsigned g_sampRes_In_FS[OUTPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS}; +const unsigned g_sampRes_In_FS[INPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS, +#if(INPUT_FORMAT_COUNT > 1) + FS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS, +#endif +#if(INPUT_FORMAT_COUNT > 2) + FS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS +#endif +}; +/* Data Format (Note, this is shared over HS and FS */ const unsigned g_dataFormat_Out[OUTPUT_FORMAT_COUNT] = {STREAM_FORMAT_OUTPUT_1_DATAFORMAT, - #if(OUTPUT_FORMAT_COUNT > 1) STREAM_FORMAT_OUTPUT_2_DATAFORMAT, #endif @@ -151,7 +182,25 @@ const unsigned g_dataFormat_Out[OUTPUT_FORMAT_COUNT] = {STREAM_FORMAT_OUTPUT_ #endif }; -const unsigned g_dataFormat_In[INPUT_FORMAT_COUNT] = {STREAM_FORMAT_INPUT_1_DATAFORMAT}; +const unsigned g_dataFormat_In[INPUT_FORMAT_COUNT] = {STREAM_FORMAT_INPUT_1_DATAFORMAT, +#if(INPUT_FORMAT_COUNT > 1) + STREAM_FORMAT_INPUT_2_DATAFORMAT, +#endif +#if(INPUT_FORMAT_COUNT > 2) + STREAM_FORMAT_INPUT_3_DATAFORMAT +#endif +}; + +/* Channel count */ +/* Note, currently only input changes.. */ +const unsigned g_chanCount_In_HS[INPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_INPUT_1_CHAN_COUNT, +#if(INPUT_FORMAT_COUNT > 1) + HS_STREAM_FORMAT_INPUT_2_CHAN_COUNT, +#endif +#if(INPUT_FORMAT_COUNT > 2) + HS_STREAM_FORMAT_INPUT_3_CHAN_COUNT +#endif +}; /* Endpoint 0 function. Handles all requests to the device */ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, @@ -221,9 +270,10 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, #endif /* Init mixer inputs */ + for(int j = 0; j < MAX_MIX_COUNT; j++) for(int i = 0; i < MIX_INPUTS; i++) { - mixSel[i] = i; + mixSel[j][i] = i; } #endif @@ -319,7 +369,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, if(g_curUsbSpeed == XUD_SPEED_HS) { - outuint(c_audioControl, NUM_USB_CHAN_IN); /* Channel count */ + 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 */ } diff --git a/module_usb_audio/main.xc b/module_usb_audio/main.xc index 393cdd6e..32fd88ce 100755 --- a/module_usb_audio/main.xc +++ b/module_usb_audio/main.xc @@ -34,9 +34,13 @@ #ifdef SPDIF_RX #include "SpdifReceive.h" -#include "clocking.h" #endif +#ifdef ADAT_RX +#include "adatreceiver.h" +#endif + +#include "clocking.h" /* Audio I/O - Port declarations */ #if I2S_WIRES_DAC > 0 @@ -109,6 +113,7 @@ on tile[AUDIO_IO_TILE] : buffered in port:32 p_i2s_adc[I2S_WIRES_ADC] = #else #define CLKBLK_MIDI XS1_CLKBLK_REF; #endif +#define CLKBLK_ADAT_RX XS1_CLKBLK_3 #define CLKBLK_SPDIF_TX XS1_CLKBLK_1 #define CLKBLK_SPDIF_RX XS1_CLKBLK_1 #define CLKBLK_MCLK XS1_CLKBLK_2 @@ -130,8 +135,16 @@ on tile[XUD_TILE] : in port p_for_mclk_count = PORT_MCLK_COUNT; on tile[AUDIO_IO_TILE] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT; #endif +#ifdef ADAT_RX +on stdcore[XUD_TILE] : buffered in port:32 p_adat_rx = PORT_ADAT_IN; +#endif + #ifdef SPDIF_RX -on tile[XUD_TILE] : buffered in port:4 p_spdif_rx = PORT_SPDIF_IN; /* K: coax, J: optical */ +on tile[XUD_TILE] : buffered in port:4 p_spdif_rx = PORT_SPDIF_IN; +#endif + +#if defined (SPDIF_RX) || defined (ADAT_RX) +/* Reference to external clock multiplier */ on tile[AUDIO_IO_TILE] : out port p_pll_clk = PORT_PLL_REF; #endif @@ -158,6 +171,11 @@ on tile[AUDIO_IO_TILE] : clock clk_mst_spd = CLKBLK_SPDIF_TX; on tile[XUD_TILE] : clock clk_spd_rx = CLKBLK_SPDIF_RX; #endif +#ifdef ADAT_RX +on tile[XUD_TILE] : clock clk_adat_rx = CLKBLK_ADAT_RX; +#endif + + on tile[AUDIO_IO_TILE] : clock clk_audio_mclk = CLKBLK_MCLK; /* Master clock */ #if(AUDIO_IO_TILE != XUD_TILE) @@ -355,7 +373,7 @@ 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, null, c_EANativeTransport_ctrl); + Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl); } /* Decoupling core */ @@ -377,6 +395,7 @@ chanend c_mix_ctl, #endif chanend ?c_aud_cfg, streaming chanend ?c_spdif_rx, +chanend ?c_adat_rx, chanend ?c_clk_ctl, chanend ?c_clk_int ) @@ -404,17 +423,25 @@ chanend ?c_clk_int { thread_speed(); #ifdef MIXER - audio(c_mix_out, c_dig_rx, c_aud_cfg, c_adc); + audio(c_mix_out, +#if defined(SPDIF_RX) || defined(ADAT_RX) + c_dig_rx, +#endif + c_aud_cfg, c_adc); #else - audio(c_aud_in, c_dig_rx, c_aud_cfg, c_adc); + audio(c_aud_in, +#if defined(SPDIF_RX) || defined(ADAT_RX) + c_dig_rx, +#endif + c_aud_cfg, c_adc); #endif } -#ifdef SPDIF_RX +#if defined(SPDIF_RX) || defined(ADAT_RX) { thread_speed(); - clockGen(c_spdif_rx, null, p_pll_clk, c_dig_rx, c_clk_ctl, c_clk_int); + clockGen(c_spdif_rx, c_adat_rx, p_pll_clk, c_dig_rx, c_clk_ctl, c_clk_int); } #endif @@ -462,12 +489,22 @@ int main() #ifdef SPDIF_RX streaming chan c_spdif_rx; +#else +#define c_spdif_rx null +#endif + +#ifdef ADAT_RX + chan c_adat_rx; +#else +#define c_adat_rx null +#endif + +#if (defined (SPDIF_RX) || defined (ADAT_RX)) chan c_clk_ctl; chan c_clk_int; #else #define c_clk_int null #define c_clk_ctl null -#define c_spdif_rx null #endif USER_MAIN_DECLARATIONS @@ -494,7 +531,7 @@ int main() #ifdef MIXER , c_mix_ctl #endif - ,c_aud_cfg, c_spdif_rx, c_clk_ctl, c_clk_int + ,c_aud_cfg, c_spdif_rx, c_adat_rx, c_clk_ctl, c_clk_int ); #if defined(MIDI) && defined(IAP) && (IAP_TILE == MIDI_TILE) @@ -529,6 +566,20 @@ int main() SpdifReceive(p_spdif_rx, c_spdif_rx, 1, clk_spd_rx); } #endif + +#ifdef ADAT_RX + on stdcore[0] : + { + set_thread_fast_mode_on(); + set_port_clock(p_adat_rx, clk_adat_rx); + start_clock(clk_adat_rx); + while (1) + { + adatReceiver48000(p_adat_rx, c_adat_rx); + adatReceiver44100(p_adat_rx, c_adat_rx); + } + } +#endif USER_MAIN_CORES } diff --git a/module_usb_audio/usb_buffer/decouple.xc b/module_usb_audio/usb_buffer/decouple.xc index 5a44a290..edb985e0 100644 --- a/module_usb_audio/usb_buffer/decouple.xc +++ b/module_usb_audio/usb_buffer/decouple.xc @@ -576,20 +576,23 @@ static inline void SetupZerosSendBuffer(XUD_ep aud_to_host_usb_ep, unsigned samp GetADCCounts(sampFreq, min, mid, max); // TODO, don't need to use speed. - if (usb_speed == XUD_SPEED_HS) - { - mid *= NUM_USB_CHAN_IN * slotSize; - } - else - { - mid *= NUM_USB_CHAN_IN_FS * slotSize; - } + //if (usb_speed == XUD_SPEED_HS) + //{ + // mid *= NUM_USB_CHAN_IN * slotSize; + // } + //else + //{ + // mid *= NUM_USB_CHAN_IN_FS * slotSize; + //} + + mid *= g_numUsbChan_In * slotSize; asm("stw %0, %1[0]"::"r"(mid),"r"(g_aud_to_host_zeros)); /* Mark EP ready with the zero buffer. Note this will simply update the packet size * if it is already ready */ GET_SHARED_GLOBAL(p, g_aud_to_host_buffer); + XUD_SetReady_InPtr(aud_to_host_usb_ep, p+4, mid); } @@ -962,7 +965,6 @@ void decouple(chanend c_mix_out { SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros); } - } else { diff --git a/module_usb_audio_adat/.cproject b/module_usb_audio_adat/.cproject index 252164f5..e72d2d69 100644 --- a/module_usb_audio_adat/.cproject +++ b/module_usb_audio_adat/.cproject @@ -156,7 +156,8 @@ @@ -269,7 +270,8 @@ @@ -388,7 +390,8 @@ - + + diff --git a/module_usb_audio_adat/README b/module_usb_audio_adat/README deleted file mode 100644 index 0035e6b2..00000000 --- a/module_usb_audio_adat/README +++ /dev/null @@ -1,2 +0,0 @@ -MODULE_ADAT_RX_V3 - diff --git a/xpd.xml b/xpd.xml index 5099f87f..3657cbb3 100644 --- a/xpd.xml +++ b/xpd.xml @@ -74,7 +74,8 @@ - + + XM-004720-SM XMOS