forked from PAWPAW-Mirror/lib_xua
Initial loop closed
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user