Initial loop closed

This commit is contained in:
Ed
2024-01-05 10:59:32 +00:00
parent 780a407519
commit 702e8d14b9

View File

@@ -232,6 +232,12 @@ static inline int validSamples(Counter &counter, int clockIndex)
#endif
#if USE_SW_PLL
/* Pointer to sw_pll struct to allow it to be used in separate SDM thread */
unsafe
{
sw_pll_state_t * unsafe sw_pll_ptr = NULL;
}
unsigned InitSWPLL(sw_pll_state_t &sw_pll, unsigned mClk)
{
/* Autogenerated SDM App PLL setup by dco_model.py using 22.5792_1M profile */
@@ -294,30 +300,27 @@ unsigned InitSWPLL(sw_pll_state_t &sw_pll, unsigned mClk)
return (XS1_TIMER_HZ / sw_pll_sdm_rate[clkIndex]);
}
void do_sw_pll_control( sw_pll_state_t sw_pll,
void do_sw_pll_phase_frequency_detector( sw_pll_state_t sw_pll,
unsigned short mclk_time_stamp,
unsigned mclks_per_sample,
chanend c_sigma_delta,
int receivedSamples)
{
/* Keep a store of the last mclk time stamp so we can work out the increment */
static unsigned short last_mclk_time_stamp = 0;
static unsigned count = 0;
count++;
const unsigned expected_mclk_inc = mclks_per_sample * receivedSamples;
const unsigned short expected_mclk_count = (last_mclk_time_stamp + expected_mclk_inc) & 0xffff;
/* Calculate what the zero-error mclk count increment should be for this many samples */
const unsigned expected_mclk_inc = mclks_per_sample * receivedSamples / 2; /* divide by 2 because this fn is called per edge */
short f_error = (int)mclk_time_stamp - (int)expected_mclk_count;
/* Calculate actualy time-stamped mclk count increment is */
const unsigned short actual_mclk_inc = mclk_time_stamp - last_mclk_time_stamp;
/* The difference is the raw error in terms of mclk counts */
short f_error = (int)actual_mclk_inc - (int)expected_mclk_inc;
if(count == 30)
{
//calc mclk inc
outuint(c_sigma_delta, (unsigned) (1000000 + f_error));
count = 0;
}
/* send PFD output to the sigma delta thread */
outuint(c_sigma_delta, (unsigned) (1000000 + f_error));
last_mclk_time_stamp = mclk_time_stamp;
}
@@ -326,9 +329,15 @@ void SigmaDeltaTask(chanend c_sigma_delta, unsigned sdm_interval){
the first control value has been received. This avoids issues with
channel lockup if two tasks (eg. init and SDM) try to write at the same time. */
int dco_setting = 0;
sw_pll_sdm_state_t sdm_state;
sw_pll_init_sigma_delta(&sdm_state);
/* To be extra safe, spin on sw_pll_ptr until it has been initialised */
while(sw_pll_ptr == NULL);
int f_error = 0;
int dco_setting = SW_PLL_SDM_CTRL_MID_24; // TODO FIX ME
unsafe
{
sw_pll_init_sigma_delta(&sw_pll_ptr->sdm_state);
}
tileref_t this_tile = get_local_tile_id();
@@ -344,8 +353,13 @@ void SigmaDeltaTask(chanend c_sigma_delta, unsigned sdm_interval){
select
{
case inuint_byref(c_sigma_delta, tmp):
dco_setting = (int32_t)tmp;
printstr("sigma-delta got: "); printintln(dco_setting);
f_error = (int32_t)tmp;
printstr("sigma-delta got: "); printintln(f_error);
unsafe
{
sw_pll_sdm_do_control_from_error(sw_pll_ptr, -f_error + 1000000);
dco_setting = sw_pll_ptr->sdm_state.current_ctrl_val;
}
break;
// Do nothing & fall-through
@@ -367,9 +381,9 @@ void SigmaDeltaTask(chanend c_sigma_delta, unsigned sdm_interval){
control value. This will avoid the writing of the
frac reg from two different threads which may cause
a channel deadlock. */
if(dco_setting != 0)
{
sw_pll_do_sigma_delta(&sdm_state, this_tile, dco_setting);
if(f_error != 0)
unsafe {
sw_pll_do_sigma_delta(&sw_pll_ptr->sdm_state, this_tile, dco_setting);
send_ack_once = 1;
}
else if(send_ack_once)
@@ -524,6 +538,13 @@ void clockGen ( streaming chanend ?c_spdif_rx,
#if USE_SW_PLL
chan c_sigma_delta;
sw_pll_state_t sw_pll;
/* Initialise before we par off the SDM task */
unsafe
{
sw_pll_ptr = &sw_pll;
}
unsigned sdm_interval = InitSWPLL(sw_pll, MCLK_48);
par
@@ -708,7 +729,7 @@ void clockGen ( streaming chanend ?c_spdif_rx,
printstr("c_mclk_change: "); printuintln(selected_mclk_rate);
disable_sigma_delta(c_sigma_delta); /* Blocks until SDM is idle */
InitSWPLL(sw_pll, selected_mclk_rate);
outuint(c_sigma_delta, sw_pll.sdm_state.ctrl_mid_point); /* Send ctrl mid point to enable SDM */
outuint(c_sigma_delta, sw_pll.sdm_state.ctrl_mid_point); /* Send ctrl mid point to re-enable SDM and set to nominal mclk */
printstr("swpll int'd\n");
#endif
break;
@@ -792,7 +813,7 @@ void clockGen ( streaming chanend ?c_spdif_rx,
timeNextEdge = spdifRxTime + LOCAL_CLOCK_INCREMENT + LOCAL_CLOCK_MARGIN;
#if USE_SW_PLL
do_sw_pll_control(sw_pll, mclk_time_stamp, mclks_per_sample, c_sigma_delta, spdifCounters.receivedSamples);
do_sw_pll_phase_frequency_detector(sw_pll, mclk_time_stamp, mclks_per_sample, c_sigma_delta, spdifCounters.receivedSamples);
#else
/* Toggle edge */
i_pll_ref.toggle_timed(1);
@@ -902,7 +923,7 @@ void clockGen ( streaming chanend ?c_spdif_rx,
timeNextEdge = adatReceivedTime + LOCAL_CLOCK_INCREMENT + LOCAL_CLOCK_MARGIN;
#if USE_SW_PLL
do_sw_pll_control(sw_pll, mclk_time_stamp, mclks_per_sample, c_sigma_delta, adatCounters.receivedSamples);
do_sw_pll_phase_frequency_detector(sw_pll, mclk_time_stamp, mclks_per_sample, c_sigma_delta, adatCounters.receivedSamples);
#else
/* Toggle edge */
i_pll_ref.toggle_timed(1);