diff --git a/module_usb_audio/audio.xc b/module_usb_audio/audio.xc index f4f4bde4..26155835 100755 --- a/module_usb_audio/audio.xc +++ b/module_usb_audio/audio.xc @@ -150,8 +150,12 @@ static inline void doI2SClocks(unsigned divide) } #endif - -static inline unsigned DoSampleTransfer(chanend c_out, unsigned samplesOut[], unsigned samplesIn[], unsigned underflowWord) +#pragma unsafe arrays +static inline unsigned DoSampleTransfer(chanend c_out, unsigned samplesOut[], +#if NUM_USB_CHAN_IN > 0 + unsigned samplesIn[], +#endif +unsigned underflowWord) { unsigned command; unsigned underflow; @@ -373,9 +377,7 @@ chanend ?c_adc) unsigned samplesInPrev[NUM_USB_CHAN_IN]; #endif unsigned tmp; -#if (I2S_CHANS_ADC != 0) unsigned index; -#endif #ifdef RAMP_CHECK unsigned prev=0; int started = 0; @@ -390,6 +392,8 @@ chanend ?c_adc) #endif unsigned underflowWord = 0; + unsigned tdmCount = 0; + #if NUM_USB_CHAN_IN > 0 for (int i=0;i 0 + samplesIn, +#endif + underflowWord); if(command) { @@ -422,10 +430,17 @@ chanend ?c_adc) /* Main Audio I/O loop */ while (1) { - unsigned command = DoSampleTransfer(c_out, samplesOut, samplesIn, underflowWord); + if(tdmCount == 0) + { + unsigned command = DoSampleTransfer(c_out, samplesOut, +#if NUM_USB_CHAN_IN > 0 + samplesIn, +#endif + underflowWord); - if(command) - return command; + if(command) + return command; + } #if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0) if(dsdMode == DSD_MODE_NATIVE) @@ -554,7 +569,12 @@ chanend ?c_adc) /* LR clock delayed by one clock, This is so MSB is output on the falling edge of BCLK * after the falling edge on which LRCLK was toggled. (see I2S spec) */ /* Generate clocks LR Clock low - LEFT */ +#ifdef I2S_MODE_TDM + p_lrclk <: 0x00000000; +#else p_lrclk <: 0x80000000; + +#endif #endif #pragma xta endpoint "i2s_output_l" @@ -562,10 +582,17 @@ chanend ?c_adc) #if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0) index = 0; #pragma loop unroll +#ifdef I2S_MODE_TDM + for(int i = 0; i < I2S_CHANS_DAC; i+=8) + { + p_i2s_dac[index++] <: bitrev(samplesOut[(2*tdmCount)+i]); + } +#else for(int i = 0; i < I2S_CHANS_DAC; i+=2) { p_i2s_dac[index++] <: bitrev(samplesOut[i]); /* Output Left sample to DAC */ } +#endif #endif /* Clock out the LR Clock, the DAC data and Clock in the next sample into ADC */ @@ -628,17 +655,31 @@ chanend ?c_adc) #endif #ifndef CODEC_MASTER +#ifdef I2S_MODE_TDM + if(tdmCount == 3) + p_lrclk <: 0x80000000; + else + p_lrclk <: 0x00000000; +#else p_lrclk <: 0x7FFFFFFF; +#endif #endif index = 0; #pragma xta endpoint "i2s_output_r" #if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0) #pragma loop unroll +#ifdef I2S_MODE_TDM + for(int i = 0; i < I2S_CHANS_DAC; i+=8) + { + p_i2s_dac[index++] <: bitrev(samplesOut[(2*tdmCount)+1+i]); + } +#else for(int i = 1; i < I2S_CHANS_DAC; i+=2) { p_i2s_dac[index++] <: bitrev(samplesOut[i]); /* Output Right sample to DAC */ } +#endif #endif doI2SClocks(divide); @@ -688,6 +729,13 @@ chanend ?c_adc) } } #endif + +#ifdef I2S_MODE_TDM + tdmCount++; + //tdmCount &= 0b11; /* if(tdmCount == 4) tdmCount = 0) */ + if(tdmCount == 4) + tdmCount = 0; +#endif } #pragma xta endpoint "deliver_return" @@ -746,7 +794,6 @@ unsigned static dummy_deliver(chanend c_out) #define NUMBER_WORDS ((NUMBER_SAMPLES * NUMBER_CHANNELS+1)/2) #define SAMPLES_PER_PRINT 1 - void audio(chanend c_mix_out, #if (defined(ADAT_RX) || defined(SPDIF_RX)) chanend c_dig_rx, @@ -848,7 +895,15 @@ chanend ?c_config, chanend ?c) numBits = 32; } #endif - divide = mClk / ( curSamFreq * numBits ); + unsigned tdmDiv = 1; +#if I2S_MODE_TDM + if(dsdMode == DSD_MODE_OFF) + { + tdmDiv = 4; + } +#endif + + divide = mClk / ( curSamFreq * numBits * tdmDiv); } diff --git a/module_usb_audio/devicedefines.h b/module_usb_audio/devicedefines.h index 60e71691..c37631db 100644 --- a/module_usb_audio/devicedefines.h +++ b/module_usb_audio/devicedefines.h @@ -76,8 +76,13 @@ #error I2S_CHANS_DAC not defined #define I2S_CHANS_DAC 2 /* Define anyway for doxygen */ #else + +#ifdef I2S_MODE_TDM +#define I2S_WIRES_DAC (I2S_CHANS_DAC >> 3) +#else #define I2S_WIRES_DAC (I2S_CHANS_DAC >> 1) #endif +#endif /** * @brief Number of I2S channels from ADC/CODEC. Must be a multiple of 2. @@ -88,8 +93,13 @@ #error I2S_CHANS_ADC not defined #define I2S_CHANS_ADC 2 /* Define anyway for doxygen */ #else + +#ifdef I2S_MODE_TDM +#define I2S_WIRES_ADC (I2S_CHANS_ADC >> 3) +#else #define I2S_WIRES_ADC (I2S_CHANS_ADC >> 1) #endif +#endif /** * @brief Max supported sample frequency for device (Hz). Default: 192000 diff --git a/module_usb_audio/endpoint0/descriptors.h b/module_usb_audio/endpoint0/descriptors.h index ca50bbf3..d4675a1d 100644 --- a/module_usb_audio/endpoint0/descriptors.h +++ b/module_usb_audio/endpoint0/descriptors.h @@ -115,7 +115,50 @@ typedef struct STR_TABLE_ENTRY(outputChanStr_18); #endif #if (NUM_USB_CHAN_OUT > 18) -#error NUM_USB_CHAN > 18 + STR_TABLE_ENTRY(outputChanStr_19); +#endif +#if (NUM_USB_CHAN_OUT > 19) + STR_TABLE_ENTRY(outputChanStr_20); +#endif +#if (NUM_USB_CHAN_OUT > 20) + STR_TABLE_ENTRY(outputChanStr_21); +#endif +#if (NUM_USB_CHAN_OUT > 21) + STR_TABLE_ENTRY(outputChanStr_22); +#endif +#if (NUM_USB_CHAN_OUT > 22) + STR_TABLE_ENTRY(outputChanStr_23); +#endif +#if (NUM_USB_CHAN_OUT > 23) + STR_TABLE_ENTRY(outputChanStr_24); +#endif +#if (NUM_USB_CHAN_OUT > 24) + STR_TABLE_ENTRY(outputChanStr_25); +#endif +#if (NUM_USB_CHAN_OUT > 25) + STR_TABLE_ENTRY(outputChanStr_26); +#endif +#if (NUM_USB_CHAN_OUT > 26) + STR_TABLE_ENTRY(outputChanStr_27); +#endif +#if (NUM_USB_CHAN_OUT > 27) + STR_TABLE_ENTRY(outputChanStr_28); +#endif +#if (NUM_USB_CHAN_OUT > 28) + STR_TABLE_ENTRY(outputChanStr_29); +#endif +#if (NUM_USB_CHAN_OUT > 29) + STR_TABLE_ENTRY(outputChanStr_30); +#endif +#if (NUM_USB_CHAN_OUT > 30) + STR_TABLE_ENTRY(outputChanStr_31); +#endif +#if (NUM_USB_CHAN_OUT > 31) + STR_TABLE_ENTRY(outputChanStr_32); +#endif + +#if (NUM_USB_CHAN_OUT > 32) +#error NUM_USB_CHAN > 32 #endif #if (NUM_USB_CHAN_IN > 0) @@ -557,7 +600,115 @@ StringDescTable_t g_strTable = #endif #if (NUM_USB_CHAN_OUT > 18) -#error NUM_USB_CHAN_OUT > 18 +#if defined(SPDIF) && (SPDIF_TX_INDEX == 18) + #if(SPDIF_TX_INDEX < I2S_CHANS_DAC) + .outputChanStr_19 = "Analogue 19/SPDIF 1", + #else + .outputChanStr_19 = "S/PDIF 1", + #endif +#elif defined(SPDIF) && (SPDIF_TX_INDEX == 17) + #if(SPDIF_TX_INDEX < I2S_CHANS_DAC) + .outputChanStr_19 = "Analogue 19/SPDIF 2", + #else + .outputChanStr_19 = "S/PDIF 2", + #endif +#else + .outputChanStr_19 = "Analogue 19", +#endif +#endif + +#if (NUM_USB_CHAN_OUT > 19) +#if defined(SPDIF) && (SPDIF_TX_INDEX == 19) + #if(SPDIF_TX_INDEX < I2S_CHANS_DAC) + .outputChanStr_20 = "Analogue 20/SPDIF 1", + #else + .outputChanStr_20 = "S/PDIF 1", + #endif +#elif defined(SPDIF) && (SPDIF_TX_INDEX == 18) + #if(SPDIF_TX_INDEX < I2S_CHANS_DAC) + .outputChanStr_20 = "Analogue 20/SPDIF 2", + #else + .outputChanStr_20 = "S/PDIF 2", + #endif +#else + .outputChanStr_20 = "Analogue 20", +#endif +#endif + +#if (NUM_USB_CHAN_OUT > 20) +#if defined(SPDIF) && (SPDIF_TX_INDEX == 20) + #if(SPDIF_TX_INDEX < I2S_CHANS_DAC) + .outputChanStr_21 = "Analogue 21/SPDIF 1", + #else + .outputChanStr_21 = "S/PDIF 1", + #endif +#elif defined(SPDIF) && (SPDIF_TX_INDEX == 19) + #if(SPDIF_TX_INDEX < I2S_CHANS_DAC) + .outputChanStr_21 = "Analogue 21/SPDIF 2", + #else + .outputChanStr_21 = "S/PDIF 2", + #endif +#else + .outputChanStr_21 = "Analogue 21", +#endif +#endif + +#if (NUM_USB_CHAN_OUT > 21) +#if defined(SPDIF) && (SPDIF_TX_INDEX == 21) + #if(SPDIF_TX_INDEX < I2S_CHANS_DAC) + .outputChanStr_22 = "Analogue 22/SPDIF 1", + #else + .outputChanStr_22 = "S/PDIF 1", + #endif +#elif defined(SPDIF) && (SPDIF_TX_INDEX == 20) + #if(SPDIF_TX_INDEX < I2S_CHANS_DAC) + .outputChanStr_22 = "Analogue 22/SPDIF 2", + #else + .outputChanStr_22 = "S/PDIF 2", + #endif +#else + .outputChanStr_22 = "Analogue 22", +#endif +#endif + +#if (NUM_USB_CHAN_OUT > 22) +#if defined(SPDIF) && (SPDIF_TX_INDEX == 22) + #if(SPDIF_TX_INDEX < I2S_CHANS_DAC) + .outputChanStr_23 = "Analogue 23/SPDIF 1", + #else + .outputChanStr_23 = "S/PDIF 1", + #endif +#elif defined(SPDIF) && (SPDIF_TX_INDEX == 21) + #if(SPDIF_TX_INDEX < I2S_CHANS_DAC) + .outputChanStr_23 = "Analogue 23/SPDIF 2", + #else + .outputChanStr_23 = "S/PDIF 2", + #endif +#else + .outputChanStr_23 = "Analogue 23", +#endif +#endif + +#if (NUM_USB_CHAN_OUT > 23) +#if defined(SPDIF) && (SPDIF_TX_INDEX == 23) + #if(SPDIF_TX_INDEX < I2S_CHANS_DAC) + .outputChanStr_24 = "Analogue 24/SPDIF 1", + #else + .outputChanStr_24 = "S/PDIF 1", + #endif +#elif defined(SPDIF) && (SPDIF_TX_INDEX == 22) + #if(SPDIF_TX_INDEX < I2S_CHANS_DAC) + .outputChanStr_24 = "Analogue 24/SPDIF 2", + #else + .outputChanStr_24 = "S/PDIF 2", + #endif +#else + .outputChanStr_24 = "Analogue 24", +#endif +#endif + +#if (NUM_USB_CHAN_OUT > 24) +#error NUM_USB_CHAN > 24 #endif /*** INPUT CHANNEL STRINGS ***/ @@ -1600,7 +1751,25 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= 0x0000000F, /* bmaControls(18) */ #endif #if (NUM_USB_CHAN_OUT > 18) -#error NUM_USB_CHAN_OUT > 18 + 0x0000000F, /* bmaControls(19) */ +#endif +#if (NUM_USB_CHAN_OUT > 19) + 0x0000000F, /* bmaControls(20) */ +#endif +#if (NUM_USB_CHAN_OUT > 20) + 0x0000000F, /* bmaControls(21) */ +#endif +#if (NUM_USB_CHAN_OUT > 21) + 0x0000000F, /* bmaControls(22) */ +#endif +#if (NUM_USB_CHAN_OUT > 22) + 0x0000000F, /* bmaControls(23) */ +#endif +#if (NUM_USB_CHAN_OUT > 23) + 0x0000000F, /* bmaControls(24) */ +#endif +#if (NUM_USB_CHAN_OUT > 24) +#error NUM_USB_CHAN_OUT > 24 #endif }, 0, /* 60 iFeature */