diff --git a/lib_xua/api/xua_audiohub.h b/lib_xua/api/xua_audiohub.h index 90856ec4..6682676f 100644 --- a/lib_xua/api/xua_audiohub.h +++ b/lib_xua/api/xua_audiohub.h @@ -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 diff --git a/lib_xua/api/xua_clocking.h b/lib_xua/api/xua_clocking.h index c41d130f..b3a74ab7 100644 --- a/lib_xua/api/xua_clocking.h +++ b/lib_xua/api/xua_clocking.h @@ -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 diff --git a/lib_xua/src/core/audiohub/xua_audiohub.xc b/lib_xua/src/core/audiohub/xua_audiohub.xc index 1a9ae947..b8c5e472 100755 --- a/lib_xua/src/core/audiohub/xua_audiohub.xc +++ b/lib_xua/src/core/audiohub/xua_audiohub.xc @@ -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) diff --git a/lib_xua/src/core/clocking/clockgen.xc b/lib_xua/src/core/clocking/clockgen.xc index a49b2356..27bd85ba 100644 --- a/lib_xua/src/core/clocking/clockgen.xc +++ b/lib_xua/src/core/clocking/clockgen.xc @@ -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: diff --git a/lib_xua/src/core/main.xc b/lib_xua/src/core/main.xc index d46b6026..3a82d1d3 100755 --- a/lib_xua/src/core/main.xc +++ b/lib_xua/src/core/main.xc @@ -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