Add mclk change logic

This commit is contained in:
Ed
2024-01-04 15:32:44 +00:00
parent d644775e4c
commit 61f17f3fe9
5 changed files with 78 additions and 29 deletions

View File

@@ -38,6 +38,8 @@
*
* \param c_dig Channel connected to the clockGen() thread for
* receiving/transmitting samples
*
* \param c_mclk_change Channel notifying clockgen of an mclk frequency change
*/
void XUA_AudioHub(chanend ?c_aud,
clock ?clk_audio_mclk,
@@ -52,6 +54,7 @@ void XUA_AudioHub(chanend ?c_aud,
#endif
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN || defined(__DOXYGEN__))
, chanend c_dig
, chanend c_mclk_change
#endif
#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1)
, server interface i_dfu ?dfuInterface

View File

@@ -27,6 +27,8 @@ void PllRefPinTask(server interface pll_ref_if i_pll_ref, out port p_sync);
* \param c_clk_int channel connected to the decouple() thread for clock
* interrupts
* \param p_for_mclk_count_aud port used for counting mclk and providing a timestamp
*
* \param c_mclk_change channel to notify of master clock change
*/
void clockGen( streaming chanend ?c_spdif_rx,
chanend ?c_adat_rx,
@@ -34,6 +36,7 @@ void clockGen( streaming chanend ?c_spdif_rx,
chanend c_audio,
chanend c_clk_ctl,
chanend c_clk_int,
port ?p_for_mclk_count_aud);
port p_for_mclk_count_aud,
chanend c_mclk_change);
#endif

View File

@@ -640,6 +640,7 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
#endif
#if (XUA_ADAT_RX_EN || XUA_SPDIF_RX_EN)
, chanend c_dig_rx
, chanend c_mclk_change
#endif
#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1)
, server interface i_dfu ?dfuInterface
@@ -800,6 +801,10 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
#endif
/* Configure Clocking/CODEC/DAC/ADC for SampleFreq/MClk */
AudioHwConfig(curFreq, mClk, dsdMode, curSamRes_DAC, curSamRes_ADC);
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
/* Notify clockgen of new mCLk */
c_mclk_change <: mClk;
#endif
}
if(!firstRun)

View File

@@ -94,17 +94,6 @@ void PllRefPinTask(server interface pll_ref_if i_pll_ref, out port p_pll_ref)
}
}
void do_sw_pll_control(sw_pll_state_t sw_pll, unsigned short mclk_time_stamp, chanend c_sigma_delta)
{
static unsigned count = 0;
count++;
if(count == 30)
{
printuintln(mclk_time_stamp);
count = 0;
}
}
#if (XUA_SPDIF_RX_EN) || (XUA_ADAT_RX_EN)
static int abs(int x)
@@ -242,13 +231,6 @@ static inline int validSamples(Counter &counter, int clockIndex)
#endif
#if USE_SW_PLL
void SigmaDeltaTask(chanend c_sigma_delta){
while(1)
{
c_sigma_delta :> int _;
}
}
void InitSWPLL(sw_pll_state_t &sw_pll, unsigned mClk)
{
/* Autogenerated SDM App PLL setup by dco_model.py using 22.5792_1M profile */
@@ -303,8 +285,44 @@ void InitSWPLL(sw_pll_state_t &sw_pll, unsigned mClk)
app_pll_div_reg[clkIndex],
app_pll_frac_reg[clkIndex],
sw_pll_sdm_ctrl_mid[clkIndex],
3000 /* PPM_RANGE FOR PFD Don't care for this API*/ );
3000 /* PPM_RANGE (FOR PFD) Don't care for this API*/ );
printstr("Init sw_pll: "); printuintln(mClk);
}
void do_sw_pll_control(sw_pll_state_t sw_pll, unsigned short mclk_time_stamp, chanend c_sigma_delta)
{
static unsigned count = 0;
count++;
if(count == 30)
{
printuintln(mclk_time_stamp);
count = 0;
}
}
void SigmaDeltaTask(chanend c_sigma_delta){
int dco_setting = 0;
while(1)
{
c_sigma_delta :> dco_setting;
printstr("sigma-delta got: "); printintln(dco_setting);
if(dco_setting == 0)
{
c_sigma_delta <: 0; /* Send ACK */
}
}
}
void disable_sigma_delta(chanend c_sigma_delta)
{
c_sigma_delta <: 0; /* Stops SD */
c_sigma_delta :> int _; /* Wait for ACK so we know reg write is complete */
}
#endif
#ifdef LEVEL_METER_LEDS
@@ -323,7 +341,8 @@ void clockGen ( streaming chanend ?c_spdif_rx,
chanend c_dig_rx,
chanend c_clk_ctl,
chanend c_clk_int,
port ?p_for_mclk_count_aud)
port p_for_mclk_count_aud,
chanend c_mclk_change)
{
timer t_local;
unsigned timeNextEdge, timeLastEdge, timeNextClockDetection;
@@ -340,6 +359,7 @@ void clockGen ( streaming chanend ?c_spdif_rx,
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
timer t_external;
unsigned selected_mclk_rate = 0;
unsigned short mclk_time_stamp = 0;
/* Get MCLK count */
asm volatile(" getts %0, res[%1]" : "=r" (mclk_time_stamp) : "r" (p_for_mclk_count_aud));
@@ -447,8 +467,6 @@ void clockGen ( streaming chanend ?c_spdif_rx,
#endif
while(1)
{
// TMP
c_sigma_delta <: 0;
select
{
#ifdef LEVEL_METER_LEDS
@@ -564,11 +582,12 @@ void clockGen ( streaming chanend ?c_spdif_rx,
/* Generate local clock from timer */
case t_local when timerafter(timeNextEdge) :> void:
#if USE_SW_PLL
/* Do nothing - hold the most recent sw_pll setting */
#else
/* Setup next local clock edge */
i_pll_ref.toggle_timed(0);
printstr("d\n");
#endif
/* Record time of edge */
timeLastEdge = timeNextEdge;
@@ -614,6 +633,16 @@ void clockGen ( streaming chanend ?c_spdif_rx,
break;
#endif
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
case c_mclk_change :> selected_mclk_rate:
#if USE_SW_PLL
printstr("c_mclk_change: "); printuintln(selected_mclk_rate);
disable_sigma_delta(c_sigma_delta); /* Blocks until SD is idle */
InitSWPLL(sw_pll, selected_mclk_rate);
#endif
break;
#endif
#if (XUA_SPDIF_RX_EN)
/* Receive sample from S/PDIF RX thread (streaming chan) */
case c_spdif_rx :> spdifRxData:

View File

@@ -320,6 +320,8 @@ void usb_audio_io(chanend ?c_aud_in,
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
chan c_dig_rx;
chan c_mclk_change; /* Notification of new mclk freq to clockgen */
/* Connect p_for_mclk_count_aud to clk_audio_mclk so we can count mclks/timestamp in digital rx*/
unsigned x = 0;
@@ -373,6 +375,7 @@ void usb_audio_io(chanend ?c_aud_in,
#endif
#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
, c_dig_rx
, c_mclk_change
#endif
#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1)
, dfuInterface
@@ -393,12 +396,18 @@ void usb_audio_io(chanend ?c_aud_in,
* However, due to the use of an interface the pll reference signal port can be on another tile
*/
thread_speed();
clockGen(c_spdif_rx, c_adat_rx, i_pll_ref, c_dig_rx, c_clk_ctl, c_clk_int, p_for_mclk_count_aud);
clockGen( c_spdif_rx,
c_adat_rx,
i_pll_ref,
c_dig_rx,
c_clk_ctl,
c_clk_int,
p_for_mclk_count_aud,
c_mclk_change);
}
#endif
//:
}
} // par
}
#ifndef USER_MAIN_DECLARATIONS