diff --git a/lib_xua/api/xua_conf_default.h b/lib_xua/api/xua_conf_default.h index 8b6242cd..17379e94 100644 --- a/lib_xua/api/xua_conf_default.h +++ b/lib_xua/api/xua_conf_default.h @@ -193,6 +193,16 @@ #define I2S_DOWNSAMPLE_CHANS_IN I2S_CHANS_ADC #endif +/** + * @Brief Number of bits per channel for I2S/TDM + * + * Default: 32 bits + */ +#ifndef XUA_I2S_N_BITS +#define XUA_I2S_N_BITS (32) +#endif + + /** * @brief Max supported sample frequency for device (Hz). Default: 192000 */ diff --git a/lib_xua/src/core/audiohub/audiohub_initport.xc b/lib_xua/src/core/audiohub/audiohub_initport.xc index 89fa82c0..2d44b233 100644 --- a/lib_xua/src/core/audiohub/audiohub_initport.xc +++ b/lib_xua/src/core/audiohub/audiohub_initport.xc @@ -39,11 +39,12 @@ void InitPorts_master(buffered _XUA_CLK_DIR port:32 p_lrclk, buffered _XUA_CLK_D #endif unsigned tmp; - #ifdef N_BITS_I2S - tmp = partout_timestamped(p_lrclk, N_BITS_I2S, 0); - #else - p_lrclk <: 0 @ tmp; - #endif + + if(XUA_I2S_N_BITS == 32) + p_lrclk <: 0 @ tmp; + else + tmp = partout_timestamped(p_lrclk, XUA_I2S_N_BITS, 0); + tmp += 100; /* Since BCLK is free-running, setup outputs/inputs at a known point in the future */ @@ -51,11 +52,10 @@ void InitPorts_master(buffered _XUA_CLK_DIR port:32 p_lrclk, buffered _XUA_CLK_D #pragma loop unroll for(int i = 0; i < I2S_WIRES_DAC; i++) { - #ifdef N_BITS_I2S - partout_timed(p_i2s_dac[i], N_BITS_I2S, 0, tmp); - #else - p_i2s_dac[i] @ tmp <: 0; - #endif + if(XUA_I2S_N_BITS == 32) + p_i2s_dac[i] @ tmp <: 0; + else + partout_timed(p_i2s_dac[i], XUA_I2S_N_BITS, 0, tmp); } #endif unsigned lrClkVal = 0x7FFFFFFF; @@ -64,19 +64,18 @@ void InitPorts_master(buffered _XUA_CLK_DIR port:32 p_lrclk, buffered _XUA_CLK_D lrClkVal = 0x80000000; } - #ifdef N_BITS_I2S - partout_timed(p_lrclk, N_BITS_I2S, lrClkVal, tmp); - #else - p_lrclk @ tmp <: lrClkVal; - #endif + if(XUA_I2S_N_BITS == 32) + p_lrclk @ tmp <: lrClkVal; + else + partout_timed(p_lrclk, XUA_I2S_N_BITS, lrClkVal, tmp); #if (I2S_CHANS_ADC != 0) for(int i = 0; i < I2S_WIRES_ADC; i++) { asm("setpt res[%0], %1"::"r"(p_i2s_adc[i]),"r"(tmp-1)); - #ifdef N_BITS_I2S - set_port_shift_count(p_i2s_adc[i], N_BITS_I2S); - #endif + + if(XUA_I2S_N_BITS != 32) + set_port_shift_count(p_i2s_adc[i], XUA_I2S_N_BITS); } #endif #endif /* (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0) */ @@ -109,11 +108,7 @@ void InitPorts_slave(buffered _XUA_CLK_DIR port:32 p_lrclk, buffered _XUA_CLK_DI p_lrclk when pinseq(0) :> void @ tmp; #endif - #ifdef N_BITS_I2S - tmp += (I2S_CHANS_PER_FRAME * N_BITS_I2S) - N_BITS_I2S + 1 ; - #else - tmp += (I2S_CHANS_PER_FRAME * 32) - 32 + 1 ; - #endif + tmp += (I2S_CHANS_PER_FRAME * XUA_I2S_N_BITS) - XUA_I2S_N_BITS + 1 ; /* E.g. 2 * 32 - 32 + 1 = 33 for stereo */ /* E.g. 8 * 32 - 32 + 1 = 225 for 8 chan TDM */ @@ -121,11 +116,10 @@ void InitPorts_slave(buffered _XUA_CLK_DIR port:32 p_lrclk, buffered _XUA_CLK_DI #pragma loop unroll for(int i = 0; i < I2S_WIRES_DAC; i++) { - #ifdef N_BITS_I2S - partout_timed(p_i2s_dac[i], N_BITS_I2S, 0, tmp-1); - #else - p_i2s_dac[i] @ tmp <: 0; - #endif + if(XUA_I2S_N_BITS == 32) + p_i2s_dac[i] @ tmp <: 0; + else + partout_timed(p_i2s_dac[i], XUA_I2S_N_BITS, 0, tmp-1); } #endif @@ -133,17 +127,15 @@ void InitPorts_slave(buffered _XUA_CLK_DIR port:32 p_lrclk, buffered _XUA_CLK_DI #pragma loop unroll for(int i = 0; i < I2S_WIRES_ADC; i++) { - asm("setpt res[%0], %1"::"r"(p_i2s_adc[i]),"r"(tmp-1)); - #ifdef N_BITS_I2S - set_port_shift_count(p_i2s_adc[i], N_BITS_I2S); - #endif + asm("setpt res[%0], %1"::"r"(p_i2s_adc[i]),"r"(tmp-1)); + if(XUA_I2S_N_BITS != 32) + set_port_shift_count(p_i2s_adc[i], XUA_I2S_N_BITS); } #endif asm("setpt res[%0], %1"::"r"(p_lrclk),"r"(tmp-1)); - #ifdef N_BITS_I2S - set_port_shift_count(p_lrclk, N_BITS_I2S); - #endif + if(XUA_I2S_N_BITS != 32) + set_port_shift_count(p_lrclk, XUA_I2S_N_BITS); #endif /* (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0) */ } #endif diff --git a/lib_xua/src/core/audiohub/xua_audiohub.xc b/lib_xua/src/core/audiohub/xua_audiohub.xc index aedae4f5..97b387dc 100755 --- a/lib_xua/src/core/audiohub/xua_audiohub.xc +++ b/lib_xua/src/core/audiohub/xua_audiohub.xc @@ -85,14 +85,18 @@ static inline int HandleSampleClock(int frameCount, buffered _XUA_CLK_DIR port:3 #if CODEC_MASTER unsigned syncError = 0; unsigned lrval = 0; - - #ifdef N_BITS_I2S - const unsigned lrval_mask = (0xffffffff << (32 - N_BITS_I2S)); - asm volatile("in %0, res[%1]":"=r"(lrval):"r"(p_lrclk):"memory"); - set_port_shift_count(p_lrclk, N_BITS_I2S); - #else - p_lrclk :> lrval; - #endif + const unsigned lrval_mask = 0; + + if(XUA_I2S_N_BITS != 32) + { + lrval_mask = (0xffffffff << (32 - XUA_I2S_N_BITS)); + asm volatile("in %0, res[%1]":"=r"(lrval):"r"(p_lrclk):"memory"); + set_port_shift_count(p_lrclk, XUA_I2S_N_BITS); + } + else + { + p_lrclk :> lrval; + } if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM) { @@ -110,60 +114,46 @@ static inline int HandleSampleClock(int frameCount, buffered _XUA_CLK_DIR port:3 } else { - if(frameCount == 0) + if(XUA_I2S_N_BITS == 32) { - #ifdef N_BITS_I2S - if ((lrval & lrval_mask) != 0x80000000) - { - syncError = 1; - } - #else - syncError += (lrval != 0x80000000); + if(frameCount == 0) + syncError = (lrval != 0x80000000); + else + syncError = (lrval != 0x7FFFFFFF); } - #endif else { - #ifdef N_BITS_I2S - if ((lrval | (~lrval_mask)) != 0x7FFFFFFF) - { - syncError = 1; - } - #else - syncError += (lrval != 0x7FFFFFFF); - #endif + if(frameCount == 0) + syncError = ((lrval & lrval_mask) != 0x80000000) + else + syncError = ((lrval | (~lrval_mask)) != 0x7FFFFFFF) } } return syncError; #else + unsigned clkVal; if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM) { if(frameCount == (I2S_CHANS_PER_FRAME-1)) - p_lrclk <: 0x80000000; + clkVal = 0x80000000; else - p_lrclk <: 0x00000000; + clkVal = 0x00000000; } else { if(frameCount == 0) - { - #ifdef N_BITS_I2S - partout(p_lrclk, N_BITS_I2S, 0x80000000 >> (32 - N_BITS_I2S)); - #else - p_lrclk <: 0x80000000; - #endif - } + clkVal = 0x80000000; else - { - #ifdef N_BITS_I2S - partout(p_lrclk, N_BITS_I2S, 0x7fffffff >> (32 - N_BITS_I2S)); - #else - p_lrclk <: 0x7fffffff; - #endif - } + clkVal = 0x7fffffff; } + if(XUA_I2S_N_BITS == 32) + p_lrclk <: clkVal; + else + partout(p_lrclk, XUA_I2S_N_BITS, clkVal >> (32 - XUA_I2S_N_BITS)); + return 0; #endif @@ -317,16 +307,16 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out // 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])); - #ifdef N_BITS_I2S - set_port_shift_count(p_i2s_adc[index], N_BITS_I2S); - sample = bitrev(sample) << (32 - N_BITS_I2S); - #else - sample = bitrev(sample); - #endif + sample = bitrev(sample); + if(XUA_I2S_N_BITS != 32) + { + set_port_shift_count(p_i2s_adc[index], XUA_I2S_N_BITS); + sample <<= (32 - XUA_I2S_N_BITS); + } index++; - int chanIndex = ((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i; // channels 0, 2, 4.. on each line. + int chanIndex = ((frameCount-2) & (I2S_CHANS_PER_FRAME-1)) + i; // channels 0, 2, 4.. on each line. #if (AUD_TO_USB_RATIO > 1) if ((AUD_TO_USB_RATIO - 1) == audioToUsbRatioCounter) @@ -378,12 +368,10 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out src_ff3v_fir_coefs[2-audioToUsbRatioCounter]); } #endif /* (AUD_TO_USB_RATIO > 1) */ - #ifdef N_BITS_I2S - partout(p_i2s_dac[index++], N_BITS_I2S, bitrev(samplesOut[frameCount +i])); - #else - p_i2s_dac[index++] <: bitrev(samplesOut[frameCount +i]); - #endif - + if(XUA_I2S_N_BITS == 32) + p_i2s_dac[index++] <: bitrev(samplesOut[frameCount +i]); + else + partout(p_i2s_dac[index++], XUA_I2S_N_BITS, bitrev(samplesOut[frameCount +i])); } #endif // (I2S_CHANS_DAC != 0) @@ -457,13 +445,12 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out /* 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])); - #ifdef N_BITS_I2S - set_port_shift_count(p_i2s_adc[index], N_BITS_I2S); - sample = bitrev(sample) << (32 - N_BITS_I2S); - #else sample = bitrev(sample); - #endif - + if(XUA_I2S_N_BITS != 32) + { + set_port_shift_count(p_i2s_adc[index], XUA_I2S_N_BITS); + sample = bitrev(sample) << (32 - XUA_I2S_N_BITS); + } index++; int chanIndex = ((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i; // channels 1, 3, 5.. on each line. @@ -515,12 +502,10 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out src_ff3v_fir_coefs[2-audioToUsbRatioCounter]); } #endif /* (AUD_TO_USB_RATIO > 1) */ - #ifdef N_BITS_I2S - partout(p_i2s_dac[index++], N_BITS_I2S, bitrev(samplesOut[frameCount + i])); - #else - p_i2s_dac[index++] <: bitrev(samplesOut[frameCount + i]); - #endif - + if(XUA_I2S_N_BITS == 32) + p_i2s_dac[index++] <: bitrev(samplesOut[frameCount + i]); + else + partout(p_i2s_dac[index++], XUA_I2S_N_BITS, bitrev(samplesOut[frameCount + i])); } #endif // (I2S_CHANS_DAC != 0) @@ -731,22 +716,13 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk, /* Calculate master clock to bit clock (or DSD clock) divide for current sample freq * e.g. 11.289600 / (176400 * 64) = 1 */ { -#if (XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM) - /* I2S has 32 bits per sample. *8 as 8 channels */ - unsigned numBits = 256; + unsigned numBits = XUA_I2S_N_BITS * 2; -#if N_BITS_I2S != 32 -#error TDM mode only supports 32 bclks per sample -#endif - -#else - #ifndef N_BITS_I2S - /* I2S has 32 bits per sample. *2 as 2 channels */ - unsigned numBits = 2 * 32; - #else - unsigned numBits = 2 * N_BITS_I2S; - #endif -#endif + if(XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM) + { + /* TDM has 8 channels */ + numBits *= 4; + } #if (DSD_CHANS_DAC > 0) if(dsdMode == DSD_MODE_DOP)