DoSampleTransfer now takes readBuffNo rather than actual buffer. Now two separate In buffers (was 2D array). Attempts to help compiler.

This commit is contained in:
Ross Owen
2014-11-27 12:44:39 +00:00
parent c05e1f05c2
commit 3ffbc99456

View File

@@ -23,6 +23,12 @@
#include "xc_ptr.h" #include "xc_ptr.h"
static unsigned samplesOut[NUM_USB_CHAN_OUT];
/* Two buffers for ADC data to allow for DAC and ADC ports being offset */
static unsigned samplesIn_0[NUM_USB_CHAN_IN];
static unsigned samplesIn_1[NUM_USB_CHAN_IN];
#ifdef I2S_MODE_TDM #ifdef I2S_MODE_TDM
#define I2S_CHANS_PER_FRAME 8 #define I2S_CHANS_PER_FRAME 8
#else #else
@@ -160,11 +166,7 @@ static inline void doI2SClocks(unsigned divide)
#endif #endif
#pragma unsafe arrays #pragma unsafe arrays
static inline unsigned DoSampleTransfer(chanend c_out, unsigned samplesOut[], static inline unsigned DoSampleTransfer(chanend c_out, int readBuffNo, unsigned underflowWord)
#if NUM_USB_CHAN_IN > 0
unsigned samplesIn[],
#endif
unsigned underflowWord)
{ {
unsigned command; unsigned command;
unsigned underflow; unsigned underflow;
@@ -245,7 +247,10 @@ unsigned underflowWord)
#pragma loop unroll #pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_IN; i++) for(int i = 0; i < NUM_USB_CHAN_IN; i++)
{ {
outuint(c_out, samplesIn[i]); if(readBuffNo)
outuint(c_out, samplesIn_1[i]);
else
outuint(c_out, samplesIn_0[i]);
} }
#endif #endif
#endif #endif
@@ -372,11 +377,9 @@ chanend ?c_adc)
#endif #endif
unsigned underflow = 0; unsigned underflow = 0;
#if NUM_USB_CHAN_OUT > 0 #if NUM_USB_CHAN_OUT > 0
unsigned samplesOut[NUM_USB_CHAN_OUT];
#endif #endif
//#if NUM_USB_CHAN_IN > 0 //#if NUM_USB_CHAN_IN > 0
/* Since DAC and ADC buffered ports off by one sample we buffer previous ADC frame */ /* Since DAC and ADC buffered ports off by one sample we buffer previous ADC frame */
unsigned samplesIn[2][NUM_USB_CHAN_IN];
unsigned readBuffNo = 0; unsigned readBuffNo = 0;
//#endif //#endif
unsigned tmp; unsigned tmp;
@@ -398,15 +401,6 @@ chanend ?c_adc)
unsigned frameCount = 0; unsigned frameCount = 0;
#if NUM_USB_CHAN_IN > 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++)
{
samplesIn[0][i] = 0;
samplesIn[1][i] = 0;
}
#endif
#if(DSD_CHANS_DAC != 0) #if(DSD_CHANS_DAC != 0)
if(dsdMode == DSD_MODE_DOP) if(dsdMode == DSD_MODE_DOP)
{ {
@@ -418,16 +412,14 @@ chanend ?c_adc)
} }
#endif #endif
unsigned command = DoSampleTransfer(c_out, samplesOut, #if 1
#if NUM_USB_CHAN_IN > 0 unsigned command = DoSampleTransfer(c_out, readBuffNo, underflowWord);
samplesIn[0],
#endif
underflowWord);
if(command) if(command)
{ {
return command; return command;
} }
#endif
InitPorts(divide); InitPorts(divide);
@@ -545,7 +537,6 @@ chanend ?c_adc)
else else
#endif #endif
{ {
#ifndef CODEC_MASTER #ifndef CODEC_MASTER
/* LR clock delayed by one clock, This is so MSB is output on the falling edge of BCLK /* 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) */ * after the falling edge on which LRCLK was toggled. (see I2S spec) */
@@ -575,26 +566,30 @@ chanend ?c_adc)
} }
#endif #endif
#endif #endif
/* Clock out the LR Clock, the DAC data and Clock in the next sample into ADC */ /* Clock out the LR Clock, the DAC data and Clock in the next sample into ADC */
doI2SClocks(divide); doI2SClocks(divide);
#if (I2S_CHANS_ADC != 0) #if (I2S_CHANS_ADC != 0)
/* Input previous L sample into L in buffer */ /* Input previous L sample into L in buffer */
index = 0; index = 0;
#pragma loop unroll
#ifdef I2S_MODE_TDM #ifdef I2S_MODE_TDM
/* First input (i.e. frameCoint == 0) we read last ADC channel of previous frame.. */ /* First input (i.e. frameCoint == 0) we read last ADC channel of previous frame.. */
unsigned buffIndex = frameCount ? !readBuffNo : readBuffNo; unsigned buffIndex = frameCount ? !readBuffNo : readBuffNo;
#pragma loop unroll
/* 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+=I2S_CHANS_PER_FRAME) 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++]));
/* Note the use of readBuffNo changes based on frameCount */ /* 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. if(buffIndex)
samplesIn_1[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line.
else
samplesIn_0[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line.
} }
#else #else
#pragma loop unroll
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) */
@@ -636,6 +631,8 @@ chanend ?c_adc)
outuint(c_spd_out, sample); /* Forward sample to S/PDIF Tx thread */ outuint(c_spd_out, sample); /* Forward sample to S/PDIF Tx thread */
#endif #endif
#ifndef CODEC_MASTER #ifndef CODEC_MASTER
#ifdef I2S_MODE_TDM #ifdef I2S_MODE_TDM
if(frameCount == (I2S_CHANS_PER_FRAME-2)) if(frameCount == (I2S_CHANS_PER_FRAME-2))
@@ -668,13 +665,16 @@ chanend ?c_adc)
#if (I2S_CHANS_ADC != 0) #if (I2S_CHANS_ADC != 0)
index = 0; index = 0;
#pragma loop unroll
#ifdef I2S_MODE_TDM #ifdef I2S_MODE_TDM
/* Channels 0, 2, 4.. on each line */ /* Channels 0, 2, 4.. on each line */
#pragma loop unroll
for(int i = 0; i < I2S_CHANS_ADC; i += I2S_CHANS_PER_FRAME) 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][frameCount+i] = bitrev(sample); if(readBuffNo)
samplesIn_0[frameCount+i] = bitrev(sample);
else
samplesIn_1[frameCount+i] = bitrev(sample);
} }
#else #else
/* Input previous right ADC sample */ /* Input previous right ADC sample */
@@ -696,8 +696,6 @@ chanend ?c_adc)
#endif #endif
#endif #endif
} // !dsdMode } // !dsdMode
#if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0) #if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0)
/* Check for DSD - note we only move into DoP mode if valid DoP Freq */ /* Check for DSD - note we only move into DoP mode if valid DoP Freq */
@@ -752,11 +750,13 @@ chanend ?c_adc)
#endif #endif
{ {
/* Do samples transfer */ /* Do samples transfer */
unsigned command = DoSampleTransfer(c_out, samplesOut, /* The below looks a bit odd but forces the compiler to inline twice */
#if NUM_USB_CHAN_IN > 0 unsigned command;
samplesIn[readBuffNo], if(readBuffNo)
#endif command = DoSampleTransfer(c_out, 1, underflowWord);
underflowWord); else
command = DoSampleTransfer(c_out, 0, underflowWord);
if(command) if(command)
{ {