forked from PAWPAW-Mirror/lib_xua
Audiohub now takes some resources as params (prev was global)
This commit is contained in:
@@ -15,14 +15,24 @@
|
||||
* This function drives I2S ports and handles samples to/from other digital
|
||||
* I/O threads.
|
||||
*
|
||||
* \param c_aud Audio sample channel connected to the mixer() thread or the
|
||||
* decouple() thread
|
||||
* \param c_dig channel connected to the clockGen() thread for
|
||||
* receiving/transmitting samples
|
||||
* \param c_config An optional channel that will be passed on to the
|
||||
* CODEC configuration functions.
|
||||
* \param c_aud Audio sample channel connected to the mixer() thread or the
|
||||
* decouple() thread
|
||||
*
|
||||
* \param clk_audio_mclk Nullable clockblock to be clocked from master clock
|
||||
*
|
||||
* \param clk_audio_mclk Nullable clockblock to be clocked from i2s clock
|
||||
*
|
||||
* \param p_mclk_in Master clock inport port (must be 1-bit)
|
||||
*
|
||||
* \param c_dig channel connected to the clockGen() thread for
|
||||
* receiving/transmitting samples
|
||||
*/
|
||||
void XUA_AudioHub(chanend ?c_aud
|
||||
void XUA_AudioHub(chanend ?c_aud,
|
||||
clock ?clk_audio_mclk,
|
||||
clock ?clk_audio_bclk,
|
||||
in port p_mclk_in,
|
||||
buffered _XUA_CLK_DIR port:32 ?p_lrclk,
|
||||
buffered _XUA_CLK_DIR port:32 ?p_bclk
|
||||
#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
|
||||
, chanend c_spdif_tx
|
||||
#endif
|
||||
|
||||
@@ -8,4 +8,10 @@
|
||||
|
||||
#include "xua_conf_default.h"
|
||||
|
||||
#if CODEC_MASTER
|
||||
#define _XUA_CLK_DIR in
|
||||
#else
|
||||
#define _XUA_CLK_DIR out
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,11 +21,11 @@ The code is split into several directories.
|
||||
- Device Firmware Upgrade code
|
||||
|
||||
|
||||
Note, the midi and dfu directories are potential canditates for separate libs in their own right.
|
||||
Note, the midi and dfu directories are potential candidates for separate libs in their own right.
|
||||
|
||||
|
||||
Including in a project
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
All `lib_xua` functions can be accessed via the ``xud.h`` header filer::
|
||||
|
||||
@@ -34,4 +34,101 @@ All `lib_xua` functions can be accessed via the ``xud.h`` header filer::
|
||||
It is also requited to to add ``lib_xua`` to the ``USED_MODULES`` field of your application Makefile.
|
||||
|
||||
|
||||
Core hardware resources
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Currently all hardware resources used by `lib_xua` are simply declared globally.
|
||||
|
||||
As an absolute minimum the following resources are required
|
||||
|
||||
- A 1-bit port for audio master clock input
|
||||
- A n-bit port for internal feedback calculation (typically a free, unused port is used e.g. `16B`)
|
||||
- A clock-block, which will be clocked from the master clock input port
|
||||
|
||||
.. note::
|
||||
|
||||
Since these resources are accessed globally naming is of importance
|
||||
|
||||
Example declaration of these resources might look as follows::
|
||||
|
||||
in port p_mclk_in = PORT_MCLK_IN;
|
||||
in port p_for_mclk_count = PORT_MCLK_COUNT; /* Extra port for counting master clock ticks */
|
||||
clock clk_audio_mclk = on tile[0]: XS1_CLKBLK_5; /* Master clock */
|
||||
|
||||
|
||||
If the ``XUD_AudioHub()`` and ``XUD_Buffer()`` cores reside on separate tiles a separate master clock input port must be provided to each, for example::
|
||||
|
||||
/* Master clock for the audio IO tile */
|
||||
in port p_mclk_in = PORT_MCLK_IN;
|
||||
|
||||
/* Resources for USB feedback */
|
||||
in port p_mclk_in_usb = PORT_MCLK_IN_USB; /* Extra master clock input for the USB tile */
|
||||
|
||||
Whilst this satisfies the basic requirements for the operation of `lib_xua` projects typically also needs some additional audio I/O, I2S or SPDIF for example.
|
||||
These should be passed into the various cores as required (see API section)
|
||||
|
||||
Running the core components
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In their most basic form the core components can be run as follows::
|
||||
|
||||
par
|
||||
{
|
||||
/* Endpoint 0 core from lib_xua */
|
||||
XUA_Endpoint0(c_ep_out[0], c_ep_in[0], c_aud_ctl, null, null, null, null);
|
||||
|
||||
/* Buffering cores - handles audio data to/from EP's and gives/gets data to/from the audio I/O core */
|
||||
/* Note, this spawns two cores */
|
||||
XUA_Buffer(c_ep_out[1], c_ep_in[1], c_sof, c_aud_ctl, p_for_mclk_count, c_aud);
|
||||
|
||||
/* AudioHub/IO core does most of the audio IO i.e. I2S (also serves as a hub for all audio) */
|
||||
XUA_AudioHub(c_aud);
|
||||
}
|
||||
|
||||
``XUA_Buffer()`` expects its ``p_for_mclk_count`` argument to be clocked from the audio master clock
|
||||
The following code satisfies this requirement::
|
||||
|
||||
{
|
||||
/* Connect master-clock clock-block to clock-block pin */
|
||||
set_clock_src(clk_audio_mclk_usb, p_mclk_in_usb); /* Clock clock-block from mclk pin */
|
||||
set_port_clock(p_for_mclk_count, clk_audio_mclk_usb); /* Clock the "count" port from the clock block */
|
||||
start_clock(clk_audio_mclk_usb); /* Set the clock off running */
|
||||
|
||||
XUA_Buffer(c_ep_out[1], c_ep_in[1], c_sof, c_aud_ctl, p_for_mclk_count, c_aud);
|
||||
|
||||
}
|
||||
|
||||
.. note:: By keeping this configuraiton outside of the ``XUA_Buffer()`` function allow the possiblity to share the ``p_mclk_in_usb`` port with additional components
|
||||
|
||||
To produce a fully operating device a call to ``XUD_Main()`` (from ``lib_xud``) must also be made for USB connectivity::
|
||||
|
||||
/* Low level USB device layer core */
|
||||
on tile[1]: XUD_Main(c_ep_out, 2, c_ep_in, 2, c_sof, epTypeTableOut, epTypeTableIn, null, null, -1, XUD_SPEED_HS, XUD_PWR_SELF);
|
||||
|
||||
Additionally the required communication channels must also be declared::
|
||||
|
||||
/* Channel arrays for lib_xud */
|
||||
chan c_ep_out[2];
|
||||
chan c_ep_in[2];
|
||||
|
||||
/* Channel for communicating SOF notifications from XUD to the Buffering cores */
|
||||
chan c_sof;
|
||||
|
||||
/* Channel for audio data between buffering cores and AudioHub/IO core */
|
||||
chan c_aud;
|
||||
|
||||
/* Channel for communicating control messages from EP0 to the rest of the device (via the buffering cores) */
|
||||
chan c_aud_ctl;
|
||||
|
||||
|
||||
|
||||
Configuring XUA
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Built in main()
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Enabling Additional Features
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This sections describes only the basic feature set of ``lib_xua`` details on enabling additional features e.g. S/PDIF can be found later in this document.
|
||||
|
||||
106
lib_xua/src/core/audiohub/init_ports.h
Normal file
106
lib_xua/src/core/audiohub/init_ports.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#if !CODEC_MASTER
|
||||
static inline void InitPorts_master(unsigned divide, buffered out port:32 p_lrclk, buffered out port:32 p_bclk)
|
||||
{
|
||||
#if (DSD_CHANS_DAC > 0)
|
||||
if(dsdMode == DSD_MODE_OFF)
|
||||
{
|
||||
#endif
|
||||
|
||||
#if (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0)
|
||||
|
||||
/* Clear I2S port buffers */
|
||||
clearbuf(p_lrclk);
|
||||
|
||||
#if (I2S_CHANS_DAC != 0)
|
||||
for(int i = 0; i < I2S_WIRES_DAC; i++)
|
||||
{
|
||||
clearbuf(p_i2s_dac[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (I2S_CHANS_ADC != 0)
|
||||
for(int i = 0; i < I2S_WIRES_ADC; i++)
|
||||
{
|
||||
clearbuf(p_i2s_adc[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma xta endpoint "divide_1"
|
||||
unsigned tmp;
|
||||
p_lrclk <: 0 @ tmp;
|
||||
tmp += 100;
|
||||
|
||||
/* Since BCLK is free-running, setup outputs/inputs at a known point in the future */
|
||||
#if (I2S_CHANS_DAC != 0)
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < I2S_WIRES_DAC; i++)
|
||||
{
|
||||
p_i2s_dac[i] @ tmp <: 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
p_lrclk @ tmp <: 0x7FFFFFFF;
|
||||
|
||||
#if (I2S_CHANS_ADC != 0)
|
||||
for(int i = 0; i < I2S_WIRES_ADC; i++)
|
||||
{
|
||||
asm("setpt res[%0], %1"::"r"(p_i2s_adc[i]),"r"(tmp-1));
|
||||
}
|
||||
#endif
|
||||
#endif /* (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0) */
|
||||
|
||||
|
||||
#if (DSD_CHANS_DAC > 0)
|
||||
} /* if (!dsdMode) */
|
||||
else
|
||||
{
|
||||
/* p_dsd_clk must start high */
|
||||
p_dsd_clk <: 0x80000000;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CODEC_MASTER
|
||||
static inline void InitPorts_slave(unsigned divide, buffered in port:32 p_lrclk, buffered in port:32 p_bclk)
|
||||
{
|
||||
#if (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0)
|
||||
unsigned tmp;
|
||||
|
||||
/* Wait for LRCLK edge (in I2S LRCLK = 0 is left, TDM rising edge is start of frame) */
|
||||
p_lrclk when pinseq(0) :> void;
|
||||
p_lrclk when pinseq(1) :> void;
|
||||
p_lrclk when pinseq(0) :> void;
|
||||
p_lrclk when pinseq(1) :> void;
|
||||
#if I2S_MODE_TDM
|
||||
p_lrclk when pinseq(0) :> void;
|
||||
p_lrclk when pinseq(1) :> void @ tmp;
|
||||
#else
|
||||
p_lrclk when pinseq(0) :> void @ tmp;
|
||||
#endif
|
||||
|
||||
tmp += (I2S_CHANS_PER_FRAME * 32) - 32 + 1 ;
|
||||
/* E.g. 2 * 32 - 32 + 1 = 33 for stereo */
|
||||
/* E.g. 8 * 32 - 32 + 1 = 225 for 8 chan TDM */
|
||||
|
||||
#if (I2S_CHANS_DAC != 0)
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < I2S_WIRES_DAC; i++)
|
||||
{
|
||||
p_i2s_dac[i] @ tmp <: 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (I2S_CHANS_ADC != 0)
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < I2S_WIRES_ADC; i++)
|
||||
{
|
||||
asm("setpt res[%0], %1"::"r"(p_i2s_adc[i]),"r"(tmp-1));
|
||||
}
|
||||
#endif
|
||||
|
||||
asm("setpt res[%0], %1"::"r"(p_lrclk),"r"(tmp-1));
|
||||
#endif /* (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0) */
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -76,21 +76,9 @@ extern buffered out port:32 p_i2s_dac[I2S_WIRES_DAC];
|
||||
extern buffered in port:32 p_i2s_adc[I2S_WIRES_ADC];
|
||||
#endif
|
||||
|
||||
/* I2S LR/Bit clock I/O */
|
||||
#if CODEC_MASTER
|
||||
extern buffered in port:32 p_lrclk;
|
||||
extern buffered in port:32 p_bclk;
|
||||
#else
|
||||
extern buffered out port:32 p_lrclk;
|
||||
extern buffered out port:32 p_bclk;
|
||||
#endif
|
||||
|
||||
unsigned dsdMode = DSD_MODE_OFF;
|
||||
|
||||
/* Master clock input */
|
||||
extern in port p_mclk_in;
|
||||
extern in port p_mclk_in2;
|
||||
|
||||
#if (XUA_SPDIF_TX_EN)
|
||||
extern buffered out port:32 p_spdif_tx;
|
||||
#endif
|
||||
@@ -99,15 +87,10 @@ extern buffered out port:32 p_spdif_tx;
|
||||
extern buffered out port:32 p_adat_tx;
|
||||
#endif
|
||||
|
||||
extern clock clk_audio_mclk;
|
||||
extern clock clk_audio_bclk;
|
||||
|
||||
#if XUA_SPDIF_TX_EN || defined(ADAT_TX)
|
||||
extern clock clk_mst_spd;
|
||||
#endif
|
||||
|
||||
//extern void device_reboot(void);
|
||||
|
||||
#define MAX_DIVIDE_48 (MCLK_48/MIN_FREQ_48/64)
|
||||
#define MAX_DIVIDE_44 (MCLK_44/MIN_FREQ_44/64)
|
||||
#if (MAX_DIVIDE_44 > MAX_DIVIDE_48)
|
||||
@@ -116,10 +99,14 @@ extern clock clk_mst_spd;
|
||||
#define MAX_DIVIDE (MAX_DIVIDE_48)
|
||||
#endif
|
||||
|
||||
|
||||
#include "init_ports.h"
|
||||
|
||||
#ifdef ADAT_TX
|
||||
unsigned adatCounter = 0;
|
||||
unsigned adatSamples[8];
|
||||
|
||||
|
||||
#pragma unsafe arrays
|
||||
static inline void TransferAdatTxSamples(chanend c_adat_out, const unsigned samplesFromHost[], int smux, int handshake)
|
||||
{
|
||||
@@ -182,9 +169,11 @@ static inline unsigned DoSampleTransfer(chanend c_out, const int readBuffNo, con
|
||||
#ifndef CODEC_MASTER
|
||||
if(dsdMode == DSD_MODE_OFF)
|
||||
{
|
||||
// Set clocks low
|
||||
#if (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0)
|
||||
/* Set clocks low */
|
||||
p_lrclk <: 0;
|
||||
p_bclk <: 0;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -293,9 +282,11 @@ static inline int DoDsdDopCheck(unsigned &dsdMode, int &dsdCount, unsigned curSa
|
||||
dsdCount = 0;
|
||||
dsdMarker = DSD_MARKER_2;
|
||||
|
||||
#if (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0)
|
||||
// Set clocks low
|
||||
p_lrclk <: 0;
|
||||
p_bclk <: 0;
|
||||
#endif
|
||||
p_dsd_clk <: 0;
|
||||
return 0;
|
||||
}
|
||||
@@ -315,8 +306,10 @@ static inline int DoDsdDopCheck(unsigned &dsdMode, int &dsdCount, unsigned curSa
|
||||
{
|
||||
dsdMode = DSD_MODE_OFF;
|
||||
// Set clocks low
|
||||
#if (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0)
|
||||
p_lrclk <: 0;
|
||||
p_bclk <: 0;
|
||||
#endif
|
||||
p_dsd_clk <: 0;
|
||||
return 0;
|
||||
}
|
||||
@@ -327,104 +320,6 @@ static inline int DoDsdDopCheck(unsigned &dsdMode, int &dsdCount, unsigned curSa
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !CODEC_MASTER
|
||||
static inline void InitPorts_master(unsigned divide)
|
||||
{
|
||||
unsigned tmp;
|
||||
#if (DSD_CHANS_DAC > 0)
|
||||
if(dsdMode == DSD_MODE_OFF)
|
||||
{
|
||||
#endif
|
||||
/* Clear I2S port buffers */
|
||||
clearbuf(p_lrclk);
|
||||
|
||||
#if (I2S_CHANS_DAC != 0)
|
||||
for(int i = 0; i < I2S_WIRES_DAC; i++)
|
||||
{
|
||||
clearbuf(p_i2s_dac[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (I2S_CHANS_ADC != 0)
|
||||
for(int i = 0; i < I2S_WIRES_ADC; i++)
|
||||
{
|
||||
clearbuf(p_i2s_adc[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma xta endpoint "divide_1"
|
||||
p_lrclk <: 0 @ tmp;
|
||||
tmp += 100;
|
||||
|
||||
/* Since BCLK is free-running, setup outputs/inputs at a known point in the future */
|
||||
#if (I2S_CHANS_DAC != 0)
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < I2S_WIRES_DAC; i++)
|
||||
{
|
||||
p_i2s_dac[i] @ tmp <: 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
p_lrclk @ tmp <: 0x7FFFFFFF;
|
||||
|
||||
#if (I2S_CHANS_ADC != 0)
|
||||
for(int i = 0; i < I2S_WIRES_ADC; i++)
|
||||
{
|
||||
asm("setpt res[%0], %1"::"r"(p_i2s_adc[i]),"r"(tmp-1));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (DSD_CHANS_DAC > 0)
|
||||
} /* if (!dsdMode) */
|
||||
else
|
||||
{
|
||||
/* p_dsd_clk must start high */
|
||||
p_dsd_clk <: 0x80000000;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CODEC_MASTER
|
||||
static inline void InitPorts_slave(unsigned divide)
|
||||
{
|
||||
unsigned tmp;
|
||||
|
||||
/* Wait for LRCLK edge (in I2S LRCLK = 0 is left, TDM rising edge is start of frame) */
|
||||
p_lrclk when pinseq(0) :> void;
|
||||
p_lrclk when pinseq(1) :> void;
|
||||
p_lrclk when pinseq(0) :> void;
|
||||
p_lrclk when pinseq(1) :> void;
|
||||
#if I2S_MODE_TDM
|
||||
p_lrclk when pinseq(0) :> void;
|
||||
p_lrclk when pinseq(1) :> void @ tmp;
|
||||
#else
|
||||
p_lrclk when pinseq(0) :> void @ tmp;
|
||||
#endif
|
||||
|
||||
tmp += (I2S_CHANS_PER_FRAME * 32) - 32 + 1 ;
|
||||
/* E.g. 2 * 32 - 32 + 1 = 33 for stereo */
|
||||
/* E.g. 8 * 32 - 32 + 1 = 225 for 8 chan TDM */
|
||||
|
||||
#if (I2S_CHANS_DAC != 0)
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < I2S_WIRES_DAC; i++)
|
||||
{
|
||||
p_i2s_dac[i] @ tmp <: 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (I2S_CHANS_ADC != 0)
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < I2S_WIRES_ADC; i++)
|
||||
{
|
||||
asm("setpt res[%0], %1"::"r"(p_i2s_adc[i]),"r"(tmp-1));
|
||||
}
|
||||
#endif
|
||||
|
||||
asm("setpt res[%0], %1"::"r"(p_lrclk),"r"(tmp-1));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -442,6 +337,7 @@ unsigned static deliver_master(chanend ?c_out, chanend ?c_spd_out
|
||||
#if (NUM_PDM_MICS > 0)
|
||||
, chanend c_pdm_pcm
|
||||
#endif
|
||||
, buffered out port:32 p_lrclk, buffered out port:32 p_bclk
|
||||
)
|
||||
{
|
||||
/* Since DAC and ADC buffered ports off by one sample we buffer previous ADC frame */
|
||||
@@ -533,7 +429,7 @@ unsigned static deliver_master(chanend ?c_out, chanend ?c_spd_out
|
||||
return command;
|
||||
}
|
||||
|
||||
InitPorts_master(divide);
|
||||
InitPorts_master(divide, p_lrclk, p_bclk);
|
||||
|
||||
/* Main Audio I/O loop */
|
||||
while (1)
|
||||
@@ -598,11 +494,13 @@ unsigned static deliver_master(chanend ?c_out, chanend ?c_spd_out
|
||||
/* 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) */
|
||||
/* Generate clocks LR Clock low - LEFT */
|
||||
#if I2S_MODE_TDM
|
||||
#if (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0)
|
||||
#if I2S_MODE_TDM
|
||||
p_lrclk <: 0x00000000;
|
||||
#else
|
||||
p_lrclk <: 0x80000000;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#pragma xta endpoint "i2s_output_l"
|
||||
|
||||
@@ -725,6 +623,7 @@ unsigned static deliver_master(chanend ?c_out, chanend ?c_spd_out
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0)
|
||||
#if I2S_MODE_TDM
|
||||
if(frameCount == (I2S_CHANS_PER_FRAME-2))
|
||||
p_lrclk <: 0x80000000;
|
||||
@@ -732,6 +631,7 @@ unsigned static deliver_master(chanend ?c_out, chanend ?c_spd_out
|
||||
p_lrclk <: 0x00000000;
|
||||
#else
|
||||
p_lrclk <: 0x7FFFFFFF;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
index = 0;
|
||||
@@ -821,6 +721,7 @@ unsigned static deliver_slave(chanend ?c_out, chanend ?c_spd_out
|
||||
#if (NUM_PDM_MICS > 0)
|
||||
, chanend c_pdm_pcm
|
||||
#endif
|
||||
, buffered in port:32 p_lrclk, buffered in port:32 p_bclk
|
||||
)
|
||||
{
|
||||
/* Since DAC and ADC buffered ports off by one sample we buffer previous ADC frame */
|
||||
@@ -903,7 +804,7 @@ unsigned static deliver_slave(chanend ?c_out, chanend ?c_spd_out
|
||||
unsigned lrval;
|
||||
unsigned syncError = 0;
|
||||
|
||||
InitPorts_slave(divide);
|
||||
InitPorts_slave(divide, p_lrclk, p_bclk);
|
||||
|
||||
while (!syncError)
|
||||
{
|
||||
@@ -956,8 +857,10 @@ unsigned static deliver_slave(chanend ?c_out, chanend ?c_spd_out
|
||||
}
|
||||
#endif //(I2S_CHANS_ADC != 0)
|
||||
|
||||
#if (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0)
|
||||
/* LR Clock sync check */
|
||||
p_lrclk :> lrval;
|
||||
#endif
|
||||
|
||||
if(I2S_MODE_TDM)
|
||||
{
|
||||
@@ -1094,9 +997,10 @@ unsigned static deliver_slave(chanend ?c_out, chanend ?c_spd_out
|
||||
}
|
||||
#endif //(I2S_CHANS_ADC != 0)
|
||||
|
||||
#if (I2S_CHANS_ADC != 0 || I2S_CHANS_DAC != 0)
|
||||
/* LR Clock sync check */
|
||||
p_lrclk :> lrval;
|
||||
|
||||
#endif
|
||||
if(I2S_MODE_TDM)
|
||||
{
|
||||
/* Do nothing */
|
||||
@@ -1179,7 +1083,7 @@ void SpdifTxWrapper(chanend c_spdif_tx)
|
||||
|
||||
// TODO could share clock block here..
|
||||
// NOTE, Assuming SPDIF tile == USB tile here..
|
||||
asm("ldw %0, dp[p_mclk_in2]":"=r"(portId));
|
||||
asm("ldw %0, dp[p_mclk_in_usb]":"=r"(portId));
|
||||
asm("setclk res[%0], %1"::"r"(clk_mst_spd), "r"(portId));
|
||||
configure_out_port_no_ready(p_spdif_tx, clk_mst_spd, 0);
|
||||
set_clock_fall_delay(clk_mst_spd, 7);
|
||||
@@ -1261,7 +1165,10 @@ static void dummy_deliver(chanend ?c_out, unsigned &command)
|
||||
void DFUHandler(server interface i_dfu i, chanend ?c_user_cmd);
|
||||
#endif
|
||||
|
||||
void XUA_AudioHub(chanend ?c_mix_out
|
||||
void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
|
||||
in port p_mclk_in,
|
||||
buffered _XUA_CLK_DIR port:32 ?p_lrclk,
|
||||
buffered _XUA_CLK_DIR port:32 ?p_bclk
|
||||
#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
|
||||
, chanend c_spdif_out
|
||||
#endif
|
||||
@@ -1457,7 +1364,7 @@ void XUA_AudioHub(chanend ?c_mix_out
|
||||
#endif
|
||||
/* Handshake back */
|
||||
#ifndef NO_USB
|
||||
outct(c_mix_out, XS1_CT_END);
|
||||
outct(c_aud, XS1_CT_END);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1505,9 +1412,9 @@ void XUA_AudioHub(chanend ?c_mix_out
|
||||
outuint(c_adat_out, adatSmuxMode);
|
||||
#endif
|
||||
#if CODEC_MASTER
|
||||
command = deliver_slave(c_mix_out
|
||||
command = deliver_slave(c_aud
|
||||
#else
|
||||
command = deliver_master(c_mix_out
|
||||
command = deliver_master(c_aud
|
||||
#endif
|
||||
#if (XUA_SPDIF_TX_EN)
|
||||
, c_spdif_out
|
||||
@@ -1525,12 +1432,14 @@ void XUA_AudioHub(chanend ?c_mix_out
|
||||
#if (NUM_PDM_MICS > 0)
|
||||
, c_pdm_in
|
||||
#endif
|
||||
, p_lrclk,
|
||||
p_bclk
|
||||
);
|
||||
|
||||
#ifndef NO_USB
|
||||
if(command == SET_SAMPLE_FREQ)
|
||||
{
|
||||
curSamFreq = inuint(c_mix_out) * AUD_TO_USB_RATIO;
|
||||
curSamFreq = inuint(c_aud) * AUD_TO_USB_RATIO;
|
||||
}
|
||||
else if(command == SET_STREAM_FORMAT_OUT)
|
||||
{
|
||||
@@ -1538,17 +1447,17 @@ void XUA_AudioHub(chanend ?c_mix_out
|
||||
* DOP = 1
|
||||
* Native = 2
|
||||
*/
|
||||
dsdMode = inuint(c_mix_out);
|
||||
curSamRes_DAC = inuint(c_mix_out);
|
||||
dsdMode = inuint(c_aud);
|
||||
curSamRes_DAC = inuint(c_aud);
|
||||
}
|
||||
|
||||
#if (XUA_DFU_EN == 1)
|
||||
/* Currently no more audio will happen after this point */
|
||||
if ((curSamFreq / AUD_TO_USB_RATIO) == AUDIO_STOP_FOR_DFU)
|
||||
{
|
||||
outct(c_mix_out, XS1_CT_END);
|
||||
outct(c_aud, XS1_CT_END);
|
||||
|
||||
outuint(c_mix_out, 0);
|
||||
outuint(c_aud, 0);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
@@ -219,7 +219,7 @@ int main(void)
|
||||
{
|
||||
par
|
||||
{
|
||||
XUA_AudioHub(c_out);
|
||||
XUA_AudioHub(c_out, clk_audio_mclk, clk_audio_bclk, p_mclk_in, p_lrclk, p_bclk);
|
||||
generator(c_checker, c_out);
|
||||
checker(c_checker, 0);
|
||||
#ifdef SIMULATION
|
||||
|
||||
Reference in New Issue
Block a user