forked from PAWPAW-Mirror/lib_xua
Merge branch 'DEV_ADAT_TX'
This commit is contained in:
@@ -19,9 +19,13 @@
|
||||
#ifdef SPDIF
|
||||
#include "SpdifTransmit.h"
|
||||
#endif
|
||||
#ifdef ADAT_TX
|
||||
#include "adat_tx.h"
|
||||
#endif
|
||||
#include "commands.h"
|
||||
#include "xc_ptr.h"
|
||||
|
||||
#include "print.h"
|
||||
|
||||
static unsigned samplesOut[NUM_USB_CHAN_OUT];
|
||||
|
||||
@@ -76,6 +80,10 @@ extern port p_mclk_in;
|
||||
extern buffered out port:32 p_spdif_tx;
|
||||
#endif
|
||||
|
||||
#ifdef ADAT_TX
|
||||
extern buffered out port:32 p_adat_tx;
|
||||
#endif
|
||||
|
||||
extern clock clk_audio_mclk;
|
||||
extern clock clk_audio_bclk;
|
||||
extern clock clk_mst_spd;
|
||||
@@ -153,6 +161,59 @@ static inline void doI2SClocks(unsigned divide)
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned adatCounter = 0;
|
||||
unsigned adatSamples[8];
|
||||
|
||||
#pragma unsafe arrays
|
||||
static inline void TransferAdatTxSamples(chanend c_adat_out, const unsigned samplesFromHost[], int smux, int handshake)
|
||||
{
|
||||
|
||||
/* Do some re-arranging for SMUX.. */
|
||||
unsafe
|
||||
{
|
||||
unsigned * unsafe samplesFromHostAdat = &samplesFromHost[ADAT_TX_INDEX];
|
||||
|
||||
/* Note, when smux == 1 this loop just does a straight 1:1 copy */
|
||||
//if(smux != 1)
|
||||
{
|
||||
int adatSampleIndex = adatCounter;
|
||||
for(int i = 0; i < (8/smux); i++)
|
||||
{
|
||||
adatSamples[adatSampleIndex] = samplesFromHostAdat[i];
|
||||
adatSampleIndex += smux;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
adatCounter++;
|
||||
|
||||
if(adatCounter == smux)
|
||||
{
|
||||
|
||||
#ifdef ADAT_TX_USE_SHARED_BUFF
|
||||
unsafe
|
||||
{
|
||||
/* Wait for ADAT core to be done with buffer */
|
||||
/* Note, we are "running ahead" of the ADAT core */
|
||||
inuint(c_adat_out);
|
||||
|
||||
/* Send buffer pointer over to ADAT core */
|
||||
volatile unsigned * unsafe samplePtr = &adatSamples;
|
||||
outuint(c_adat_out, (unsigned) samplePtr);
|
||||
}
|
||||
#else
|
||||
#pragma loop unroll
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
outuint(c_adat_out, samplesFromHost[ADAT_TX_INDEX + i]);
|
||||
}
|
||||
#endif
|
||||
adatCounter = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#pragma unsafe arrays
|
||||
static inline unsigned DoSampleTransfer(chanend c_out, int readBuffNo, unsigned underflowWord)
|
||||
{
|
||||
@@ -378,12 +439,18 @@ static inline void InitPorts(unsigned divide)
|
||||
|
||||
/* I2S delivery thread */
|
||||
#pragma unsafe arrays
|
||||
unsigned static deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, unsigned curSamFreq,
|
||||
#if(defined(SPDIF_RX) || defined(ADAT_RX))
|
||||
chanend c_dig_rx,
|
||||
unsigned static deliver(chanend c_out, chanend ?c_spd_out,
|
||||
#ifdef ADAT_TX
|
||||
chanend c_adat_out,
|
||||
unsigned adatSmuxMode,
|
||||
#endif
|
||||
chanend ?c_adc)
|
||||
unsigned divide, unsigned curSamFreq,
|
||||
#if(defined(SPDIF_RX) || defined(ADAT_RX))
|
||||
chanend c_dig_rx,
|
||||
#endif
|
||||
chanend ?c_adc)
|
||||
{
|
||||
|
||||
#if (I2S_CHANS_ADC != 0) || defined(SPDIF)
|
||||
unsigned sample;
|
||||
#endif
|
||||
@@ -413,6 +480,8 @@ chanend ?c_adc)
|
||||
|
||||
unsigned frameCount = 0;
|
||||
|
||||
adatCounter = 0;
|
||||
|
||||
#if(DSD_CHANS_DAC != 0)
|
||||
if(dsdMode == DSD_MODE_DOP)
|
||||
{
|
||||
@@ -424,15 +493,19 @@ chanend ?c_adc)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
unsigned command = DoSampleTransfer(c_out, readBuffNo, underflowWord);
|
||||
|
||||
#ifdef ADAT_TX
|
||||
unsafe{
|
||||
//TransferAdatTxSamples(c_adat_out, samplesOut, adatSmuxMode, 0);
|
||||
volatile unsigned * unsafe samplePtr = &samplesOut[ADAT_TX_INDEX];
|
||||
outuint(c_adat_out, (unsigned) samplePtr);
|
||||
}
|
||||
#endif
|
||||
if(command)
|
||||
{
|
||||
return command;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
InitPorts(divide);
|
||||
|
||||
/* TODO In master mode, the i/o loop assumes L/RCLK = 32bit clocks. We should check this every interation
|
||||
@@ -577,6 +650,9 @@ chanend ?c_adc)
|
||||
/* Clock out the LR Clock, the DAC data and Clock in the next sample into ADC */
|
||||
doI2SClocks(divide);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if (I2S_CHANS_ADC != 0)
|
||||
/* Input previous L sample into L in buffer */
|
||||
@@ -599,6 +675,10 @@ chanend ?c_adc)
|
||||
samplesIn_0[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line.
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ADAT_TX
|
||||
TransferAdatTxSamples(c_adat_out, samplesOut, adatSmuxMode, 1);
|
||||
#endif
|
||||
|
||||
if(frameCount == 0)
|
||||
{
|
||||
@@ -661,7 +741,7 @@ chanend ?c_adc)
|
||||
#ifndef CODEC_MASTER
|
||||
doI2SClocks(divide);
|
||||
#endif
|
||||
|
||||
|
||||
#if (I2S_CHANS_ADC != 0)
|
||||
index = 0;
|
||||
/* Channels 0, 2, 4.. on each line */
|
||||
@@ -824,6 +904,12 @@ chanend ?c_config, chanend ?c)
|
||||
#ifdef SPDIF
|
||||
chan c_spdif_out;
|
||||
#endif
|
||||
#ifdef ADAT_TX
|
||||
chan c_adat_out;
|
||||
unsigned adatSmuxMode = 0;
|
||||
unsigned adatMultiple = 0;
|
||||
#endif
|
||||
|
||||
unsigned curSamFreq = DEFAULT_FREQ;
|
||||
unsigned curSamRes_DAC = STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS; /* Default to something reasonable */
|
||||
unsigned curSamRes_ADC = STREAM_FORMAT_INPUT_1_RESOLUTION_BITS; /* Default to something reasonable - note, currently this never changes*/
|
||||
@@ -878,11 +964,21 @@ chanend ?c_config, chanend ?c)
|
||||
EnableBufferedPort(p_dsd_dac[i], 32);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ADAT_TX
|
||||
/* Share SPDIF clk blk */
|
||||
configure_clock_src(clk_mst_spd, p_mclk_in);
|
||||
configure_out_port_no_ready(p_adat_tx, clk_mst_spd, 0);
|
||||
set_clock_fall_delay(clk_mst_spd, 7);
|
||||
#ifndef SPDIF
|
||||
start_clock(clk_mst_spd);
|
||||
#endif
|
||||
#endif
|
||||
/* Configure ADAT/SPDIF tx ports */
|
||||
#ifdef SPDIF
|
||||
SpdifTransmitPortConfig(p_spdif_tx, clk_mst_spd, p_mclk_in);
|
||||
#endif
|
||||
|
||||
|
||||
/* Perform required CODEC/ADC/DAC initialisation */
|
||||
AudioHwInit(c_config);
|
||||
|
||||
@@ -892,10 +988,20 @@ chanend ?c_config, chanend ?c)
|
||||
if ((MCLK_441 % curSamFreq) == 0)
|
||||
{
|
||||
mClk = MCLK_441;
|
||||
#ifdef ADAT_TX
|
||||
/* Calculate ADAT SMUX mode (1, 2, 4) */
|
||||
adatSmuxMode = curSamFreq / 44100;
|
||||
adatMultiple = mClk / 44100;
|
||||
#endif
|
||||
}
|
||||
else if ((MCLK_48 % curSamFreq) == 0)
|
||||
{
|
||||
mClk = MCLK_48;
|
||||
#ifdef ADAT_TX
|
||||
/* Calculate ADAT SMUX mode (1, 2, 4) */
|
||||
adatSmuxMode = curSamFreq / 48000;
|
||||
adatMultiple = mClk / 48000;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Calculate master clock to bit clock (or DSD clock) divide for current sample freq
|
||||
@@ -1011,8 +1117,6 @@ chanend ?c_config, chanend ?c)
|
||||
}
|
||||
firstRun = 0;
|
||||
|
||||
|
||||
|
||||
par
|
||||
{
|
||||
|
||||
@@ -1023,6 +1127,12 @@ chanend ?c_config, chanend ?c)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ADAT_TX
|
||||
{
|
||||
set_thread_fast_mode_on();
|
||||
adat_tx_port(c_adat_out, p_adat_tx);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
#ifdef SPDIF
|
||||
/* Communicate master clock and sample freq to S/PDIF thread */
|
||||
@@ -1030,11 +1140,28 @@ chanend ?c_config, chanend ?c)
|
||||
outuint(c_spdif_out, mClk);
|
||||
#endif
|
||||
|
||||
#ifdef ADAT_TX
|
||||
// Configure ADAT parameters ...
|
||||
//
|
||||
// adat_oversampling = 256 for MCLK = 12M288 or 11M2896
|
||||
// = 512 for MCLK = 24M576 or 22M5792
|
||||
// = 1024 for MCLK = 49M152 or 45M1584
|
||||
//
|
||||
// adatSmuxMode = 1 for FS = 44K1 or 48K0
|
||||
// = 2 for FS = 88K2 or 96K0
|
||||
// = 4 for FS = 176K4 or 192K0
|
||||
outuint(c_adat_out, adatMultiple);
|
||||
outuint(c_adat_out, adatSmuxMode);
|
||||
#endif
|
||||
command = deliver(c_mix_out,
|
||||
#ifdef SPDIF
|
||||
c_spdif_out,
|
||||
#else
|
||||
null,
|
||||
#endif
|
||||
#ifdef ADAT_TX
|
||||
c_adat_out,
|
||||
adatSmuxMode,
|
||||
#endif
|
||||
divide, curSamFreq,
|
||||
#if defined (ADAT_RX) || defined (SPDIF_RX)
|
||||
@@ -1074,10 +1201,17 @@ chanend ?c_config, chanend ?c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SPDIF
|
||||
/* Notify S/PDIF thread of impending new freq... */
|
||||
outct(c_spdif_out, XS1_CT_END);
|
||||
#endif
|
||||
#ifdef ADAT_TX
|
||||
#ifdef ADAT_TX_USE_SHARED_BUFF
|
||||
/* Take out-standing handshake from ADAT core */
|
||||
inuint(c_adat_out);
|
||||
#endif
|
||||
/* Notify ADAT Tx thread of impending new freq... */
|
||||
outct(c_adat_out, XS1_CT_END);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,13 +231,38 @@
|
||||
#undef SPDIF
|
||||
#endif
|
||||
|
||||
#ifdef SPDIF
|
||||
#define SPDIF_TX 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Defines which output channels (stereo) should be output on S/PDIF. Note, Output channels indexed from 0.
|
||||
*
|
||||
* Default: 0 (i.e. channels 0 & 1)
|
||||
* */
|
||||
#ifndef SPDIF_TX_INDEX
|
||||
#define SPDIF_TX_INDEX (0)
|
||||
#define SPDIF_TX_INDEX (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables ADAT Tx. Default: 0 (Disabled)
|
||||
*/
|
||||
#ifndef ADAT_TX
|
||||
#define ADAT_TX (0)
|
||||
#endif
|
||||
|
||||
/* Tidy up old SPDIF usage */
|
||||
#if defined(ADAT_TX) && (ADAT_TX == 0)
|
||||
#undef ADAT_TX
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Defines which output channels (8) should be output on ADAT. Note, Output channels indexed from 0.
|
||||
*
|
||||
* Default: 0 (i.e. channels [0:7])
|
||||
* */
|
||||
#ifndef ADAT_TX_INDEX
|
||||
#define ADAT_TX_INDEX (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
56
module_usb_audio/endpoint0/chanstringgen.py
Normal file
56
module_usb_audio/endpoint0/chanstringgen.py
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
|
||||
def genstrings(outputChanCount, chanString, portString, structureString, adc_dac):
|
||||
|
||||
for i in range(1,outputChanCount):
|
||||
|
||||
print "#if (NUM_USB_CHAN_{c} > {i}-1) \n\
|
||||
.{s}ChanStr_{i} = \"\"\n\
|
||||
#if ({i} < I2S_CHANS_{adcdac}+1) \n\
|
||||
\"Analogue {i}\" \n\
|
||||
#endif \n\
|
||||
#if (({i} < SPDIF_{p}_INDEX+2+1) && ({i} > SPDIF_{p}_INDEX)) && defined(SPDIF_{p}) \n\
|
||||
#if ({i} < I2S_CHANS_{adcdac}+1) \n\
|
||||
\"/\" \n\
|
||||
#endif \n\
|
||||
#if({i} - SPDIF_TX_INDEX == 1) \n\
|
||||
\"SPDIF 1\"\n\
|
||||
#elif({i} - SPDIF_TX_INDEX == 2) \n\
|
||||
\"SPDIF 2\"\n\
|
||||
#endif\n\
|
||||
#endif\n\
|
||||
#if (({i} < ADAT_{p}_INDEX+8+1) && ({i} > ADAT_{p}_INDEX)) && defined(ADAT_{p}) \n\
|
||||
#if (({i} < SPDIF_{p}_INDEX+2+1) && ({i} > SPDIF_{p}_INDEX)) && defined(SPDIF_{p}) || ({i} < I2S_CHANS_{adcdac}+1) \n\
|
||||
\"/\" \n\
|
||||
#endif \n\
|
||||
#if({i} - ADAT_TX_INDEX == 1) \n\
|
||||
\"ADAT 1\"\n\
|
||||
#elif({i} - ADAT_TX_INDEX == 2) \n\
|
||||
\"ADAT 2\"\n\
|
||||
#elif({i} - ADAT_TX_INDEX == 3) \n\
|
||||
\"ADAT 3\"\n\
|
||||
#elif({i} - ADAT_TX_INDEX == 4) \n\
|
||||
\"ADAT 4\"\n\
|
||||
#elif({i} - ADAT_TX_INDEX == 5) \n\
|
||||
\"ADAT 5\"\n\
|
||||
#elif({i} - ADAT_TX_INDEX == 6) \n\
|
||||
\"ADAT 6\"\n\
|
||||
#elif({i} - ADAT_TX_INDEX == 7) \n\
|
||||
\"ADAT 7\"\n\
|
||||
#elif({i} - ADAT_TX_INDEX == 8) \n\
|
||||
\"ADAT 8\"\n\
|
||||
#endif\n \
|
||||
#endif\n\
|
||||
, \n#endif \n".format(i=i, c=chanString, p=portString, s=structureString, adcdac=adc_dac);
|
||||
return;
|
||||
|
||||
print "/* AUTOGENERATED using chanstringgen.py */ \n"
|
||||
print "/* Not very nice looking but the standard preprocessor is not very powerful\n and we save some memory over doing this all at runtime */"
|
||||
|
||||
print "/* Output Strings */\n\n"
|
||||
|
||||
genstrings(32, "OUT", "TX", "output", "DAC");
|
||||
|
||||
print "/* Input Strings */\n\n"
|
||||
|
||||
genstrings(32, "IN", "RX", "input", "ADC");
|
||||
2490
module_usb_audio/endpoint0/chanstrings.h
Normal file
2490
module_usb_audio/endpoint0/chanstrings.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -119,6 +119,10 @@ on tile[XUD_TILE] : in port p_for_mclk_count = PORT_MCLK_COUNT;
|
||||
on tile[AUDIO_IO_TILE] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT;
|
||||
#endif
|
||||
|
||||
#ifdef ADAT_TX
|
||||
on stdcore[AUDIO_IO_TILE] : buffered out port:32 p_adat_tx = PORT_ADAT_OUT;
|
||||
#endif
|
||||
|
||||
#ifdef ADAT_RX
|
||||
on stdcore[XUD_TILE] : buffered in port:32 p_adat_rx = PORT_ADAT_IN;
|
||||
#endif
|
||||
@@ -147,9 +151,7 @@ on tile[AUDIO_IO_TILE] : buffered in port:1 p_midi_rx = PORT_MIDI_IN;
|
||||
on tile[AUDIO_IO_TILE] : clock clk_midi = CLKBLK_MIDI;
|
||||
#endif
|
||||
|
||||
#ifdef SPDIF
|
||||
on tile[AUDIO_IO_TILE] : clock clk_mst_spd = CLKBLK_SPDIF_TX;
|
||||
#endif
|
||||
|
||||
#ifdef SPDIF_RX
|
||||
on tile[XUD_TILE] : clock clk_spd_rx = CLKBLK_SPDIF_RX;
|
||||
|
||||
Reference in New Issue
Block a user