Add I2S resync to LRCLK logic when CODEC_MASTER=1

In CODEC master mode, the I/O loop assumes L/RCLK = 32bit clocks.
Check this every iteration and resync if we get a bclk glitch.
This commit is contained in:
Sam Chesney
2016-12-21 16:23:27 +00:00
parent c422ca5181
commit 1bd7dcf168

View File

@@ -472,6 +472,10 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
int started = 0; int started = 0;
#endif #endif
#ifdef CODEC_MASTER
int firstIteration = 1;
#endif
#if (DSD_CHANS_DAC != 0) #if (DSD_CHANS_DAC != 0)
unsigned dsdMarker = DSD_MARKER_2; /* This alternates between DSD_MARKER_1 and DSD_MARKER_2 */ unsigned dsdMarker = DSD_MARKER_2; /* This alternates between DSD_MARKER_1 and DSD_MARKER_2 */
int dsdCount = 0; int dsdCount = 0;
@@ -519,12 +523,27 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
InitPorts(divide); InitPorts(divide);
/* TODO In master mode, the i/o loop assumes L/RCLK = 32bit clocks. We should check this every interation
* and resync if we got a bclk glitch */
/* Main Audio I/O loop */ /* Main Audio I/O loop */
while (1) while (1)
{ {
#ifdef CODEC_MASTER
/* In CODEC master mode, the I/O loop assumes L/RCLK = 32bit clocks.
* Check this every iteration and resync if we get a bclk glitch.
*/
int syncError = 0;
if (!firstIteration)
{
InitPorts(divide);
}
else
{
firstIteration = 0;
}
while (!syncError)
#endif // CODEC_MASTER
{
#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)
{ {
@@ -652,6 +671,15 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
// 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)
unsigned sample; unsigned sample;
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++]));
#ifdef CODEC_MASTER
unsigned lrval;
p_lrclk :> lrval;
#ifdef I2S_MODE_TDM
syncError += (lrval != 0x00000000);
#else
syncError += (lrval != 0x80000000);
#endif // I2S_MODE_TDM
#endif // CODEC_MASTER
/* Note the use of readBuffNo changes based on frameCount */ /* Note the use of readBuffNo changes based on frameCount */
samplesIn[buffIndex][((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 0, 2, 4.. on each line. samplesIn[buffIndex][((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 0, 2, 4.. on each line.
@@ -773,6 +801,22 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
/* 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) */
unsigned sample; unsigned sample;
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++]));
#ifdef CODEC_MASTER
unsigned lrval;
p_lrclk :> lrval;
#ifdef I2S_MODE_TDM
if (frameCount == (I2S_CHANS_PER_FRAME-2))
{
syncError += (lrval != 0x80000000);
}
else
{
syncError += (lrval != 0x00000000);
}
#else
syncError += (lrval != 0x7FFFFFFF);
#endif // I2S_MODE_TDM
#endif // CODEC_MASTER
samplesIn[buffIndex][((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line. samplesIn[buffIndex][((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line.
#if ((I2S_DOWNSAMPLE_FACTOR > 1) && !I2S_DOWNSAMPLE_MONO) #if ((I2S_DOWNSAMPLE_FACTOR > 1) && !I2S_DOWNSAMPLE_MONO)
@@ -906,6 +950,7 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
} }
} }
} }
}
#pragma xta endpoint "deliver_return" #pragma xta endpoint "deliver_return"
return 0; return 0;