Started looking as DOP detection

This commit is contained in:
Ross Owen
2013-03-19 19:27:52 +00:00
parent 42b2cecf5c
commit ff504c0657

View File

@@ -30,6 +30,18 @@ unsigned g_adcVal = 0;
//#pragma xta command "analyse path i2s_output_r i2s_output_l" //#pragma xta command "analyse path i2s_output_r i2s_output_l"
//#pragma xta command "set required - 2000 ns" //#pragma xta command "set required - 2000 ns"
#define DSD_OVER_PCM 1
#ifdef DSD_OVER_PCM
unsigned dopMarkerCount = 0;
#define DOP_MARKER_1 0x05
#define DOP_MARKER_2 0xFA
#define DOP_MARKER_XOR 0xFF
#define DOP_MARKER_THRESH 32 /* How many DSD markers we must see before switching to DSD mode */
#define DSD_MASK_IN(x) ((x & 0xFF000000) >> 24)
unsigned dopMarker = DOP_MARKER_1;
#endif
/* I2S Data I/O*/ /* I2S Data I/O*/
#if (I2S_CHANS_DAC != 0) #if (I2S_CHANS_DAC != 0)
extern buffered out port:32 p_i2s_dac[I2S_WIRES_DAC]; extern buffered out port:32 p_i2s_dac[I2S_WIRES_DAC];
@@ -63,7 +75,11 @@ extern void device_reboot(void);
/* I2S delivery thread */ /* I2S delivery thread */
#pragma unsafe arrays #pragma unsafe arrays
unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_dig_rx, chanend ?c_adc) unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_dig_rx, chanend ?c_adc
#ifdef DSD_OVER_PCM
, int dop
#endif
)
{ {
unsigned sample; unsigned sample;
#if NUM_USB_CHAN_OUT > 0 #if NUM_USB_CHAN_OUT > 0
@@ -82,6 +98,8 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
int started = 0; int started = 0;
#endif #endif
int dsdmode = 0;
#if NUM_USB_CHAN_IN > 0 #if NUM_USB_CHAN_IN > 0
for (int i=0;i<NUM_USB_CHAN_IN;i++) for (int i=0;i<NUM_USB_CHAN_IN;i++)
@@ -304,17 +322,57 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
asm("ldw %0, dp[g_digData+36]":"=r"(samplesIn[ADAT_RX_INDEX + 7])); asm("ldw %0, dp[g_digData+36]":"=r"(samplesIn[ADAT_RX_INDEX + 7]));
#endif #endif
#ifdef DSD_OVER_PCM
/* Inspect for DSD markers */
if((DSD_MASK_IN(samplesOut[0]) == dopMarker) && (DSD_MASK_IN(samplesOut[1]) == dopMarker))
{
dopMarker ^= DOP_MARKER_XOR;
dopMarkerCount++;
if(!dsdmode)
{
if(dopMarkerCount >= DOP_MARKER_THRESH)
{
dopMarkerCount=0;
dopMarker ^= DOP_MARKER_XOR;
printstr("DSD\n");
dsdmode = 1;
//return 0;
}
}
}
else
{
/* Reset DOP detect state */
dopMarkerCount = 0;
if(dsdmode)
{
//if(samplesOut[0] == 0)
//else
if(DSD_MASK_IN(samplesOut[0]) == (dopMarker ^ 0xff))
{
printstr("almost stopped");
//dopMarker ^= 0xff;
}
else
{
/* We were running in DOP mode, but it stopped... */
//return 0;
dsdmode = 0;
printstr("PCM\n");
}
}
}
#endif
#if defined(SPDIF_RX) || defined(ADAT_RX) #if defined(SPDIF_RX) || defined(ADAT_RX)
/* Request digital data (with prefill) */ /* Request digital data (with prefill) */
outuint(c_dig_rx, 0); outuint(c_dig_rx, 0);
#endif #endif
tmp = 0; tmp = 0;
#pragma xta endpoint "i2s_output_l" #pragma xta endpoint "i2s_output_l"
#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
for(int i = 0; i < I2S_CHANS_DAC; i+=2) for(int i = 0; i < I2S_CHANS_DAC; i+=2)
@@ -382,13 +440,12 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
} }
#endif #endif
#if defined(SPDIF) && (NUM_USB_CHAN_OUT > 0) #if defined(SPDIF) && (NUM_USB_CHAN_OUT > 0)
outuint(c_spd_out, samplesOut[SPDIF_TX_INDEX]); /* Forward sample to SPDIF txt thread */ if(!dop)
{ outuint(c_spd_out, samplesOut[SPDIF_TX_INDEX]); /* Forward sample to SPDIF txt thread */
sample = samplesOut[SPDIF_TX_INDEX + 1]; sample = samplesOut[SPDIF_TX_INDEX + 1];
outuint(c_spd_out, sample); /* Forward sample to SPDIF txt thread */ outuint(c_spd_out, sample); /* Forward sample to SPDIF txt thread */
}
#ifdef RAMP_CHECK #ifdef RAMP_CHECK
sample >>= 8; sample >>= 8;
if (started<10000) { if (started<10000) {
@@ -547,6 +604,9 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c)
unsigned mClk; unsigned mClk;
unsigned divide; unsigned divide;
unsigned firstRun = 1; unsigned firstRun = 1;
#ifdef DSD_OVER_PCM
unsigned dop = 0;
#endif
#ifdef SU1_ADC_ENABLE #ifdef SU1_ADC_ENABLE
/* Setup galaxian ADC */ /* Setup galaxian ADC */
@@ -593,61 +653,92 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c)
while(1) while(1)
{ {
if(curSamFreq)
{
/* Calculate what master clock we should be using */ /* Calculate what master clock we should be using */
if ((curSamFreq % 22050) == 0) if ((curSamFreq % 22050) == 0)
{
mClk = MCLK_441;
}
else if ((curSamFreq % 24000) == 0)
{
mClk = MCLK_48;
}
/* Calculate divide required for bit clock e.g. 11.289600 / (176400 * 64) = 1 */
divide = mClk / ( curSamFreq * 64 );
/* Configure clocking for required master clock */
ClockingConfig(mClk, c_config);
if(!firstRun)
{
/* TODO wait for good mclk instead of delay */
/* No delay for DFU modes */
if ((curSamFreq != AUDIO_REBOOT_FROM_DFU) && (curSamFreq != AUDIO_STOP_FOR_DFU))
{ {
timer t; mClk = MCLK_441;
unsigned time; }
t :> time; else if ((curSamFreq % 24000) == 0)
t when timerafter(time+AUDIO_PLL_LOCK_DELAY) :> void; {
mClk = MCLK_48;
/* Handshake back */
outct(c_mix_out, XS1_CT_END);
} }
}
firstRun = 0;
/* Configure CODEC/DAC/ADC for SampleFreq/MClk */
CodecConfig(curSamFreq, mClk, c_config);
/* Configure audio ports */ /* Calculate divide required for bit clock e.g. 11.289600 / (176400 * 64) = 1 */
ConfigAudioPorts(divide); divide = mClk / ( curSamFreq * 64 );
/* Configure clocking for required master clock */
ClockingConfig(mClk, c_config);
if(!firstRun)
{
/* TODO wait for good mclk instead of delay */
/* No delay for DFU modes */
if ((curSamFreq != AUDIO_REBOOT_FROM_DFU) && (curSamFreq != AUDIO_STOP_FOR_DFU))
{
timer t;
unsigned time;
t :> time;
t when timerafter(time+AUDIO_PLL_LOCK_DELAY) :> void;
/* Handshake back */
outct(c_mix_out, XS1_CT_END);
}
}
firstRun = 0;
/* Configure CODEC/DAC/ADC for SampleFreq/MClk */
CodecConfig(curSamFreq, mClk, c_config);
/* Configure audio ports */
ConfigAudioPorts(divide);
}
else
{
if(!dop)
{
/* DOP detected! */
printstrln("DOP Detect");
dop = 1;
/* TODO:
* Config ports for DSD
* Config CODEC for DSD
*/
}
else
{
/* DOP mode end */
printstrln("DOP end");
dop = 0;
}
}
par par
{ {
#ifdef SPDIF #ifdef SPDIF
{ {
set_thread_fast_mode_on(); if(!dop)
SpdifTransmit(p_spdif_tx, c_spdif_out); {
set_thread_fast_mode_on();
SpdifTransmit(p_spdif_tx, c_spdif_out);
}
} }
#endif #endif
{ {
#ifdef SPDIF #ifdef SPDIF
if(!dop)
{
/* Communicate master clock and sample freq to S/PDIF thread */ /* Communicate master clock and sample freq to S/PDIF thread */
outuint(c_spdif_out, curSamFreq); outuint(c_spdif_out, curSamFreq);
outuint(c_spdif_out, mClk); outuint(c_spdif_out, mClk);
}
#endif #endif
curSamFreq = deliver(c_mix_out, curSamFreq = deliver(c_mix_out,
@@ -656,7 +747,11 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c)
#else #else
null, null,
#endif #endif
divide, c_dig_rx, c); divide, c_dig_rx, c
#ifdef DSD_OVER_PCM
, dop
#endif
);
// Currently no more audio will happen after this point // Currently no more audio will happen after this point
if (curSamFreq == AUDIO_STOP_FOR_DFU) if (curSamFreq == AUDIO_STOP_FOR_DFU)
@@ -678,6 +773,7 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c)
#ifdef SPDIF #ifdef SPDIF
/* Notify S/PDIF thread of impending new freq... */ /* Notify S/PDIF thread of impending new freq... */
if(!dop)
outct(c_spdif_out, XS1_CT_END); outct(c_spdif_out, XS1_CT_END);
#endif #endif
} }