forked from PAWPAW-Mirror/lib_xua
TDM code made a bit more generic. Fixed issue with multiple TDM input lines missing channels.
This commit is contained in:
@@ -23,6 +23,13 @@
|
|||||||
#include "xc_ptr.h"
|
#include "xc_ptr.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef I2S_MODE_TDM
|
||||||
|
#define I2S_CHANS_PER_FRAME 8
|
||||||
|
#else
|
||||||
|
#error
|
||||||
|
#define I2S_CHANS_PER_FRAME 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
unsigned testsamples[100];
|
unsigned testsamples[100];
|
||||||
int p = 0;
|
int p = 0;
|
||||||
@@ -300,7 +307,7 @@ static inline void InitPorts(unsigned divide)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else /* Divide != 1 */
|
||||||
{
|
{
|
||||||
#if (I2S_CHANS_DAC != 0)
|
#if (I2S_CHANS_DAC != 0)
|
||||||
/* Pre-fill the DAC ports */
|
/* Pre-fill the DAC ports */
|
||||||
@@ -309,8 +316,11 @@ static inline void InitPorts(unsigned divide)
|
|||||||
p_i2s_dac[i] <: 0;
|
p_i2s_dac[i] <: 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Pre-fill the LR clock output port */
|
||||||
p_lrclk <: 0x0;
|
p_lrclk <: 0x0;
|
||||||
|
|
||||||
doI2SClocks(divide);
|
doI2SClocks(divide);
|
||||||
|
|
||||||
}
|
}
|
||||||
#if (DSD_CHANS_DAC > 0)
|
#if (DSD_CHANS_DAC > 0)
|
||||||
} /* if (!dsdMode) */
|
} /* if (!dsdMode) */
|
||||||
@@ -345,7 +355,6 @@ static inline void InitPorts(unsigned divide)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -366,13 +375,13 @@ chanend ?c_adc)
|
|||||||
unsigned samplesOut[NUM_USB_CHAN_OUT];
|
unsigned samplesOut[NUM_USB_CHAN_OUT];
|
||||||
#endif
|
#endif
|
||||||
//#if NUM_USB_CHAN_IN > 0
|
//#if NUM_USB_CHAN_IN > 0
|
||||||
//unsigned samplesIn[NUM_USB_CHAN_IN];
|
/* Since DAC and ADC buffered ports off by one sample we buffer previous ADC frame */
|
||||||
unsigned samplesIn[2][NUM_USB_CHAN_IN];
|
unsigned samplesIn[2][NUM_USB_CHAN_IN];
|
||||||
unsigned readBuffNo = 0;
|
unsigned readBuffNo = 0;
|
||||||
//unsigned samplesInPrev[NUM_USB_CHAN_IN]; /* Since DAC and ADC buffered ports off by one sample we buffer previous ADC frame */
|
|
||||||
//#endif
|
//#endif
|
||||||
unsigned tmp;
|
unsigned tmp;
|
||||||
unsigned index;
|
unsigned index;
|
||||||
|
|
||||||
#ifdef RAMP_CHECK
|
#ifdef RAMP_CHECK
|
||||||
unsigned prev=0;
|
unsigned prev=0;
|
||||||
int started = 0;
|
int started = 0;
|
||||||
@@ -387,13 +396,12 @@ chanend ?c_adc)
|
|||||||
#endif
|
#endif
|
||||||
unsigned underflowWord = 0;
|
unsigned underflowWord = 0;
|
||||||
|
|
||||||
unsigned tdmCount = 0;
|
unsigned frameCount = 0;
|
||||||
|
|
||||||
#if NUM_USB_CHAN_IN > 0
|
#if NUM_USB_CHAN_IN > 0
|
||||||
/* Initialise buffers to 0 */
|
/* Initialise input buffers. Note two buffers due to offset between ADC and DAC ports */
|
||||||
for (int i=0;i<NUM_USB_CHAN_IN;i++)
|
for (int i=0;i<NUM_USB_CHAN_IN;i++)
|
||||||
{
|
{
|
||||||
//samplesIn[i] = 0;
|
|
||||||
samplesIn[0][i] = 0;
|
samplesIn[0][i] = 0;
|
||||||
samplesIn[1][i] = 0;
|
samplesIn[1][i] = 0;
|
||||||
}
|
}
|
||||||
@@ -430,7 +438,6 @@ chanend ?c_adc)
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
#if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0)
|
#if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0)
|
||||||
if(dsdMode == DSD_MODE_NATIVE)
|
if(dsdMode == DSD_MODE_NATIVE)
|
||||||
{
|
{
|
||||||
@@ -559,7 +566,7 @@ chanend ?c_adc)
|
|||||||
#ifdef I2S_MODE_TDM
|
#ifdef I2S_MODE_TDM
|
||||||
for(int i = 0; i < I2S_CHANS_DAC; i+=8)
|
for(int i = 0; i < I2S_CHANS_DAC; i+=8)
|
||||||
{
|
{
|
||||||
p_i2s_dac[index++] <: bitrev(samplesOut[(2*tdmCount)+i]);
|
p_i2s_dac[index++] <: bitrev(samplesOut[(frameCount)+i]);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for(int i = 0; i < I2S_CHANS_DAC; i+=2)
|
for(int i = 0; i < I2S_CHANS_DAC; i+=2)
|
||||||
@@ -576,29 +583,22 @@ chanend ?c_adc)
|
|||||||
index = 0;
|
index = 0;
|
||||||
#pragma loop unroll
|
#pragma loop unroll
|
||||||
#ifdef I2S_MODE_TDM
|
#ifdef I2S_MODE_TDM
|
||||||
if(tdmCount == 0)
|
/* First input (i.e. frameCoint == 0) we read last ADC channel of previous frame.. */
|
||||||
{
|
unsigned buffIndex = frameCount ? !readBuffNo : readBuffNo;
|
||||||
|
|
||||||
/* First time around we get channel 7 of TDM8 */
|
/* First time around we get channel 7 of TDM8 */
|
||||||
for(int i = 0; i < I2S_CHANS_ADC; i += 8)
|
for(int i = 0; i < I2S_CHANS_ADC; i+=I2S_CHANS_PER_FRAME)
|
||||||
{
|
{
|
||||||
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
|
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
|
||||||
samplesIn[readBuffNo][7] = bitrev(sample);
|
|
||||||
}
|
/* Note the use of readBuffNo changes based on frameCount */
|
||||||
}
|
samplesIn[buffIndex][((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line.
|
||||||
else
|
|
||||||
{
|
|
||||||
for(int i = 0; i < I2S_CHANS_ADC; i += 8)
|
|
||||||
{
|
|
||||||
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
|
|
||||||
samplesIn[!readBuffNo][(2*tdmCount)+i-1] = bitrev(sample); // channels 1, 3, 5.. on each line.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for(int i = 0; i < I2S_CHANS_ADC; i += 2)
|
for(int i = 0; i < I2S_CHANS_ADC; i += 2)
|
||||||
{
|
{
|
||||||
// Manual IN instruction since compiler generates an extra setc per IN (bug #15256)
|
/* Manual IN instruction since compiler generates an extra setc per IN (bug #15256) */
|
||||||
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
|
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
|
||||||
|
|
||||||
samplesIn[i] = bitrev(sample);
|
samplesIn[i] = bitrev(sample);
|
||||||
samplesIn[i-1] = samplesInPrev[i];
|
samplesIn[i-1] = samplesInPrev[i];
|
||||||
}
|
}
|
||||||
@@ -638,7 +638,7 @@ chanend ?c_adc)
|
|||||||
|
|
||||||
#ifndef CODEC_MASTER
|
#ifndef CODEC_MASTER
|
||||||
#ifdef I2S_MODE_TDM
|
#ifdef I2S_MODE_TDM
|
||||||
if(tdmCount == 3)
|
if(frameCount == (I2S_CHANS_PER_FRAME-2))
|
||||||
p_lrclk <: 0x80000000;
|
p_lrclk <: 0x80000000;
|
||||||
else
|
else
|
||||||
p_lrclk <: 0x00000000;
|
p_lrclk <: 0x00000000;
|
||||||
@@ -652,9 +652,9 @@ chanend ?c_adc)
|
|||||||
#if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0)
|
#if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0)
|
||||||
#pragma loop unroll
|
#pragma loop unroll
|
||||||
#ifdef I2S_MODE_TDM
|
#ifdef I2S_MODE_TDM
|
||||||
for(int i = 0; i < I2S_CHANS_DAC; i+=8)
|
for(int i = 0; i < I2S_CHANS_DAC; i+=I2S_CHANS_PER_FRAME)
|
||||||
{
|
{
|
||||||
p_i2s_dac[index++] <: bitrev(samplesOut[(2*tdmCount)+1+i]);
|
p_i2s_dac[index++] <: bitrev(samplesOut[frameCount+1+i]);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for(int i = 1; i < I2S_CHANS_DAC; i+=2)
|
for(int i = 1; i < I2S_CHANS_DAC; i+=2)
|
||||||
@@ -667,21 +667,20 @@ chanend ?c_adc)
|
|||||||
doI2SClocks(divide);
|
doI2SClocks(divide);
|
||||||
|
|
||||||
#if (I2S_CHANS_ADC != 0)
|
#if (I2S_CHANS_ADC != 0)
|
||||||
/* Input previous right ADC sample */
|
|
||||||
index = 0;
|
index = 0;
|
||||||
#pragma loop unroll
|
#pragma loop unroll
|
||||||
#ifdef I2S_MODE_TDM
|
#ifdef I2S_MODE_TDM
|
||||||
for(int i = 0; i < I2S_CHANS_ADC; i += 8)
|
/* Channels 0, 2, 4.. on each line */
|
||||||
|
for(int i = 0; i < I2S_CHANS_ADC; i += I2S_CHANS_PER_FRAME)
|
||||||
{
|
{
|
||||||
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
|
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
|
||||||
//samplesIn[(2*tdmCount)+i+1] = bitrev(sample);
|
samplesIn[!readBuffNo][frameCount+i] = bitrev(sample);
|
||||||
samplesIn[!readBuffNo][2*tdmCount+i] = bitrev(sample); // Channels 0, 2, 4.. on each line.
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
/* Input previous right ADC sample */
|
||||||
for(int i = 0; i < I2S_CHANS_ADC; i += 2)
|
for(int i = 0; i < I2S_CHANS_ADC; i += 2)
|
||||||
{
|
{
|
||||||
// p_i2s_adc[index++] :> sample;
|
/* Manual IN instruction since compiler generates an extra setc per IN (bug #15256) */
|
||||||
// Manual IN instruction since compiler generates an extra setc per IN (bug #15256)
|
|
||||||
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
|
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
|
||||||
samplesInPrev[i] = bitrev(sample);
|
samplesInPrev[i] = bitrev(sample);
|
||||||
}
|
}
|
||||||
@@ -690,7 +689,6 @@ chanend ?c_adc)
|
|||||||
#ifdef SU1_ADC_ENABLE
|
#ifdef SU1_ADC_ENABLE
|
||||||
{
|
{
|
||||||
unsigned x;
|
unsigned x;
|
||||||
|
|
||||||
x = inuint(c_adc);
|
x = inuint(c_adc);
|
||||||
inct(c_adc);
|
inct(c_adc);
|
||||||
asm("stw %0, dp[g_adcVal]"::"r"(x));
|
asm("stw %0, dp[g_adcVal]"::"r"(x));
|
||||||
@@ -748,10 +746,12 @@ chanend ?c_adc)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef I2S_MODE_TDM
|
#ifdef I2S_MODE_TDM
|
||||||
tdmCount++;
|
/* Increase frameCount by 2 since we have output two channels (per data line) */
|
||||||
if(tdmCount == 4)
|
frameCount+=2;
|
||||||
|
if(frameCount == I2S_CHANS_PER_FRAME)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
/* Do samples transfer */
|
||||||
unsigned command = DoSampleTransfer(c_out, samplesOut,
|
unsigned command = DoSampleTransfer(c_out, samplesOut,
|
||||||
#if NUM_USB_CHAN_IN > 0
|
#if NUM_USB_CHAN_IN > 0
|
||||||
samplesIn[readBuffNo],
|
samplesIn[readBuffNo],
|
||||||
@@ -759,9 +759,12 @@ chanend ?c_adc)
|
|||||||
underflowWord);
|
underflowWord);
|
||||||
|
|
||||||
if(command)
|
if(command)
|
||||||
|
{
|
||||||
return command;
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
tdmCount = 0;
|
/* Reset frame counter and flip the ADC buffer */
|
||||||
|
frameCount = 0;
|
||||||
readBuffNo = !readBuffNo;
|
readBuffNo = !readBuffNo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user