From 29c1f6cc14d6c99c7f3ce7e1b18dca209d114381 Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 29 Nov 2023 14:40:18 +0000 Subject: [PATCH] Vanilla sw_pll now called sw_pll_lut --- examples/i2s_slave_lut/src/i2s_slave_sw_pll.c | 28 ++--- examples/simple_lut/src/simple_sw_pll.c | 28 ++--- lib_sw_pll/api/sw_pll.h | 109 +++++++++--------- lib_sw_pll/src/sw_pll.c | 32 ++--- tests/test_app/main.c | 30 ++--- tests/test_app_low_level_api/main.c | 30 ++--- tests/test_app_sdm_ctrl/main.c | 2 +- tests/test_app_sdm_dco/main.c | 4 +- 8 files changed, 132 insertions(+), 131 deletions(-) diff --git a/examples/i2s_slave_lut/src/i2s_slave_sw_pll.c b/examples/i2s_slave_lut/src/i2s_slave_sw_pll.c index 62731b2f..a31d8e38 100644 --- a/examples/i2s_slave_lut/src/i2s_slave_sw_pll.c +++ b/examples/i2s_slave_lut/src/i2s_slave_sw_pll.c @@ -102,7 +102,7 @@ static i2s_restart_t i2s_restart_check(void *app_data){ old_mclk_pt = mclk_pt; old_bclk_pt = bclk_pt; - sw_pll_do_control(cb_args->sw_pll, mclk_pt, bclk_pt); + sw_pll_lut_do_control(cb_args->sw_pll, mclk_pt, bclk_pt); if(cb_args->sw_pll->lock_status != cb_args->curr_lock_status){ cb_args->curr_lock_status = cb_args->sw_pll->lock_status; @@ -175,19 +175,19 @@ void sw_pll_test(void){ printf("Initialising SW PLL\n"); sw_pll_state_t sw_pll; - sw_pll_init(&sw_pll, - SW_PLL_15Q16(0.0), - SW_PLL_15Q16(1.0), - SW_PLL_15Q16(0.0), - CONTROL_LOOP_COUNT, - PLL_RATIO, - BCLKS_PER_LRCLK, - frac_values_80, - SW_PLL_NUM_LUT_ENTRIES(frac_values_80), - APP_PLL_CTL_12288, - APP_PLL_DIV_12288, - APP_PLL_NOMINAL_INDEX_12288, - PPM_RANGE); + sw_pll_lut_init(&sw_pll, + SW_PLL_15Q16(0.0), + SW_PLL_15Q16(1.0), + SW_PLL_15Q16(0.0), + CONTROL_LOOP_COUNT, + PLL_RATIO, + BCLKS_PER_LRCLK, + frac_values_80, + SW_PLL_NUM_LUT_ENTRIES(frac_values_80), + APP_PLL_CTL_12288, + APP_PLL_DIV_12288, + APP_PLL_NOMINAL_INDEX_12288, + PPM_RANGE); printf("i_windup_limit: %ld\n", sw_pll.pi_state.i_windup_limit); diff --git a/examples/simple_lut/src/simple_sw_pll.c b/examples/simple_lut/src/simple_sw_pll.c index db9b1f4a..b3f19c71 100644 --- a/examples/simple_lut/src/simple_sw_pll.c +++ b/examples/simple_lut/src/simple_sw_pll.c @@ -38,19 +38,19 @@ void sw_pll_test(void){ setup_recovered_ref_clock_output(p_recovered_ref_clk, clk_recovered_ref_clk, p_mclk, PLL_RATIO); sw_pll_state_t sw_pll; - sw_pll_init(&sw_pll, - SW_PLL_15Q16(0.0), - SW_PLL_15Q16(1.0), - SW_PLL_15Q16(0.0), - CONTROL_LOOP_COUNT, - PLL_RATIO, - 0, - frac_values_80, - SW_PLL_NUM_LUT_ENTRIES(frac_values_80), - APP_PLL_CTL_12288, - APP_PLL_DIV_12288, - APP_PLL_NOMINAL_INDEX_12288, - PPM_RANGE); + sw_pll_lut_init(&sw_pll, + SW_PLL_15Q16(0.0), + SW_PLL_15Q16(1.0), + SW_PLL_15Q16(0.0), + CONTROL_LOOP_COUNT, + PLL_RATIO, + 0, + frac_values_80, + SW_PLL_NUM_LUT_ENTRIES(frac_values_80), + APP_PLL_CTL_12288, + APP_PLL_DIV_12288, + APP_PLL_NOMINAL_INDEX_12288, + PPM_RANGE); sw_pll_lock_status_t lock_status = SW_PLL_LOCKED; @@ -61,7 +61,7 @@ void sw_pll_test(void){ uint16_t mclk_pt = port_get_trigger_time(p_ref_clk);// Get the port timer val from p_ref_clk (which is running from MCLK). So this is basically a 16 bit free running counter running from MCLK. uint32_t t0 = get_reference_time(); - sw_pll_do_control(&sw_pll, mclk_pt, 0); + sw_pll_lut_do_control(&sw_pll, mclk_pt, 0); uint32_t t1 = get_reference_time(); if(t1 - t0 > max_time){ max_time = t1 - t0; diff --git a/lib_sw_pll/api/sw_pll.h b/lib_sw_pll/api/sw_pll.h index d00716a6..32145f00 100644 --- a/lib_sw_pll/api/sw_pll.h +++ b/lib_sw_pll/api/sw_pll.h @@ -24,52 +24,6 @@ * @{ */ - -/** - * sw_pll initialisation function. - * - * This must be called before use of sw_pll_do_control. - * Call this passing a pointer to the sw_pll_state_t stuct declared locally. - * - * \param sw_pll Pointer to the struct to be initialised. - * \param Kp Proportional PI constant. Use SW_PLL_15Q16() to convert from a float. - * \param Ki Integral PI constant. Use SW_PLL_15Q16() to convert from a float. - * \param Kii Double integral PI constant. Use SW_PLL_15Q16() to convert from a float. - * \param loop_rate_count How many counts of the call to sw_pll_do_control before control is done. - * Note this is only used by sw_pll_do_control. sw_pll_do_control_from_error - * calls the control loop every time so this is ignored. - * \param pll_ratio Integer ratio between input reference clock and the PLL output. - * Only used by sw_pll_do_control. Don't care otherwise. - * \param ref_clk_expected_inc Expected ref clock increment each time sw_pll_do_control is called. - * Pass in zero if you are sure the mclk sampling timing is precise. This - * will disable the scaling of the mclk count inside sw_pll_do_control. - * Only used by sw_pll_do_control. Don't care otherwise. - * \param lut_table_base Pointer to the base of the fractional PLL LUT used - * \param num_lut_entries Number of entries in the LUT (half sizeof since entries are 16b) - * \param app_pll_ctl_reg_val The setting of the app pll control register. - * \param app_pll_div_reg_val The setting of the app pll divider register. - * \param nominal_lut_idx The index into the LUT which gives the nominal output. Normally - * close to halfway to allow symmetrical range. - * \param ppm_range The pre-calculated PPM range. Used to determine the maximum deviation - * of counted mclk before the PLL resets its state. - * Note this is only used by sw_pll_do_control. sw_pll_do_control_from_error - * calls the control loop every time so this is ignored. - * - */ -void sw_pll_init( sw_pll_state_t * const sw_pll, - const sw_pll_15q16_t Kp, - const sw_pll_15q16_t Ki, - const sw_pll_15q16_t Kii, - const size_t loop_rate_count, - const size_t pll_ratio, - const uint32_t ref_clk_expected_inc, - const int16_t * const lut_table_base, - const size_t num_lut_entries, - const uint32_t app_pll_ctl_reg_val, - const uint32_t app_pll_div_reg_val, - const unsigned nominal_lut_idx, - const unsigned ppm_range); - /** * Helper to do a partial init of the PI controller at runtime without setting the physical PLL and LUT settings. * @@ -112,7 +66,54 @@ static inline void sw_pll_reset(sw_pll_state_t *sw_pll, sw_pll_15q16_t Kp, sw_pl */ /** - * sw_pll control function. + * sw_lut_pll initialisation function. + * + * This must be called before use of sw_pll_lut_do_control. + * Call this passing a pointer to the sw_pll_state_t stuct declared locally. + * + * \param sw_pll Pointer to the struct to be initialised. + * \param Kp Proportional PI constant. Use SW_PLL_15Q16() to convert from a float. + * \param Ki Integral PI constant. Use SW_PLL_15Q16() to convert from a float. + * \param Kii Double integral PI constant. Use SW_PLL_15Q16() to convert from a float. + * \param loop_rate_count How many counts of the call to sw_pll_lut_do_control before control is done. + * Note this is only used by sw_pll_lut_do_control. sw_pll_lut_do_control_from_error + * calls the control loop every time so this is ignored. + * \param pll_ratio Integer ratio between input reference clock and the PLL output. + * Only used by sw_pll_lut_do_control. Don't care otherwise. + * \param ref_clk_expected_inc Expected ref clock increment each time sw_pll_lut_do_control is called. + * Pass in zero if you are sure the mclk sampling timing is precise. This + * will disable the scaling of the mclk count inside sw_pll_lut_do_control. + * Only used by sw_pll_lut_do_control. Don't care otherwise. + * \param lut_table_base Pointer to the base of the fractional PLL LUT used + * \param num_lut_entries Number of entries in the LUT (half sizeof since entries are 16b) + * \param app_pll_ctl_reg_val The setting of the app pll control register. + * \param app_pll_div_reg_val The setting of the app pll divider register. + * \param nominal_lut_idx The index into the LUT which gives the nominal output. Normally + * close to halfway to allow symmetrical range. + * \param ppm_range The pre-calculated PPM range. Used to determine the maximum deviation + * of counted mclk before the PLL resets its state. + * Note this is only used by sw_pll_lut_do_control. sw_pll_lut_do_control_from_error + * calls the control loop every time so this is ignored. + * + */ +void sw_pll_lut_init( sw_pll_state_t * const sw_pll, + const sw_pll_15q16_t Kp, + const sw_pll_15q16_t Ki, + const sw_pll_15q16_t Kii, + const size_t loop_rate_count, + const size_t pll_ratio, + const uint32_t ref_clk_expected_inc, + const int16_t * const lut_table_base, + const size_t num_lut_entries, + const uint32_t app_pll_ctl_reg_val, + const uint32_t app_pll_div_reg_val, + const unsigned nominal_lut_idx, + const unsigned ppm_range); + + + +/** + * sw_pll LUT version control function. * * This must be called periodically for every reference clock transition. * Typically, in an audio system, this would be at the I2S or reference clock input rate. @@ -127,8 +128,8 @@ static inline void sw_pll_reset(sw_pll_state_t *sw_pll, sw_pll_15q16_t Kp, sw_pl * to output jitter being a PLL. * * \param sw_pll Pointer to the struct to be initialised. - * \param mclk_pt The 16b port timer count of mclk at the time of calling sw_pll_do_control. - * \param ref_pt The 16b port timer ref ount at the time of calling sw_pll_do_control. This value + * \param mclk_pt The 16b port timer count of mclk at the time of calling sw_pll_lut_do_control. + * \param ref_pt The 16b port timer ref ount at the time of calling sw_pll_lut_do_control. This value * is ignored when the pll is initialised with a zero ref_clk_expected_inc and the * control loop will assume that mclk_pt sample timing is precise. * @@ -136,7 +137,7 @@ static inline void sw_pll_reset(sw_pll_state_t *sw_pll, sw_pll_15q16_t Kp, sw_pl * this value is only updated when the control loop has run. * The type is sw_pll_lock_status_t. */ -sw_pll_lock_status_t sw_pll_do_control(sw_pll_state_t * const sw_pll, const uint16_t mclk_pt, const uint16_t ref_pt); +sw_pll_lock_status_t sw_pll_lut_do_control(sw_pll_state_t * const sw_pll, const uint16_t mclk_pt, const uint16_t ref_pt); /** * low level sw_pll control function for use as pure PLL control loop. @@ -152,7 +153,7 @@ sw_pll_lock_status_t sw_pll_do_control(sw_pll_state_t * const sw_pll, const uint * this value is only updated when the control loop is running. * The type is sw_pll_lock_status_t. */ -sw_pll_lock_status_t sw_pll_do_control_from_error(sw_pll_state_t * const sw_pll, int16_t error); +sw_pll_lock_status_t sw_pll_lut_do_control_from_error(sw_pll_state_t * const sw_pll, int16_t error); /**@}*/ // END: addtogroup sw_pll_lut @@ -179,7 +180,7 @@ sw_pll_lock_status_t sw_pll_do_control_from_error(sw_pll_state_t * const sw_pll, * calls the control loop every time so this is ignored. * \param pll_ratio Integer ratio between input reference clock and the PLL output. * Only used by sw_pll_sdm_do_control. Don't care otherwise. - * \param ref_clk_expected_inc Expected ref clock increment each time sw_pll_do_control is called. + * \param ref_clk_expected_inc Expected ref clock increment each time sw_pll_sdm_do_control is called. * Pass in zero if you are sure the mclk sampling timing is precise. This * will disable the scaling of the mclk count inside sw_pll_sdm_do_control. * Only used by sw_pll_sdm_do_control. Don't care otherwise. @@ -226,8 +227,8 @@ void sw_pll_sdm_init(sw_pll_state_t * const sw_pll, * to output jitter being a PLL. * * \param sw_pll Pointer to the struct to be initialised. - * \param mclk_pt The 16b port timer count of mclk at the time of calling sw_pll_do_control. - * \param ref_pt The 16b port timer ref ount at the time of calling sw_pll_do_control. This value + * \param mclk_pt The 16b port timer count of mclk at the time of calling sw_pll_sdm_do_control. + * \param ref_pt The 16b port timer ref ount at the time of calling sw_pll_sdm_do_control. This value * is ignored when the pll is initialised with a zero ref_clk_expected_inc and the * control loop will assume that mclk_pt sample timing is precise. * diff --git a/lib_sw_pll/src/sw_pll.c b/lib_sw_pll/src/sw_pll.c index 823018db..7abe9df0 100644 --- a/lib_sw_pll/src/sw_pll.c +++ b/lib_sw_pll/src/sw_pll.c @@ -72,19 +72,19 @@ static inline uint16_t lookup_pll_frac(sw_pll_state_t * const sw_pll, const int3 return sw_pll->lut_state.lut_table_base[frac_index]; } -void sw_pll_init( sw_pll_state_t * const sw_pll, - const sw_pll_15q16_t Kp, - const sw_pll_15q16_t Ki, - const sw_pll_15q16_t Kii, - const size_t loop_rate_count, - const size_t pll_ratio, - const uint32_t ref_clk_expected_inc, - const int16_t * const lut_table_base, - const size_t num_lut_entries, - const uint32_t app_pll_ctl_reg_val, - const uint32_t app_pll_div_reg_val, - const unsigned nominal_lut_idx, - const unsigned ppm_range) +void sw_pll_lut_init( sw_pll_state_t * const sw_pll, + const sw_pll_15q16_t Kp, + const sw_pll_15q16_t Ki, + const sw_pll_15q16_t Kii, + const size_t loop_rate_count, + const size_t pll_ratio, + const uint32_t ref_clk_expected_inc, + const int16_t * const lut_table_base, + const size_t num_lut_entries, + const uint32_t app_pll_ctl_reg_val, + const uint32_t app_pll_div_reg_val, + const unsigned nominal_lut_idx, + const unsigned ppm_range) { // Get PLL started and running at nominal sw_pll_app_pll_init(get_local_tile_id(), @@ -115,7 +115,7 @@ void sw_pll_init( sw_pll_state_t * const sw_pll, __attribute__((always_inline)) -inline sw_pll_lock_status_t sw_pll_do_control_from_error(sw_pll_state_t * const sw_pll, int16_t error) +inline sw_pll_lock_status_t sw_pll_lut_do_control_from_error(sw_pll_state_t * const sw_pll, int16_t error) { int32_t total_error = sw_pll_do_pi_ctrl(sw_pll, error); sw_pll->lut_state.current_reg_val = lookup_pll_frac(sw_pll, total_error); @@ -125,7 +125,7 @@ inline sw_pll_lock_status_t sw_pll_do_control_from_error(sw_pll_state_t * const return sw_pll->lock_status; } -sw_pll_lock_status_t sw_pll_do_control(sw_pll_state_t * const sw_pll, const uint16_t mclk_pt, const uint16_t ref_clk_pt) +sw_pll_lock_status_t sw_pll_lut_do_control(sw_pll_state_t * const sw_pll, const uint16_t mclk_pt, const uint16_t ref_clk_pt) { if (++sw_pll->loop_counter == sw_pll->loop_rate_count) { @@ -145,7 +145,7 @@ sw_pll_lock_status_t sw_pll_do_control(sw_pll_state_t * const sw_pll, const uint else { sw_pll_calc_error_from_port_timers(&sw_pll->pfd_state, &sw_pll->first_loop, mclk_pt, ref_clk_pt); - sw_pll_do_control_from_error(sw_pll, sw_pll->pfd_state.mclk_diff); + sw_pll_lut_do_control_from_error(sw_pll, sw_pll->pfd_state.mclk_diff); // Save for next iteration to calc diff sw_pll->pfd_state.mclk_pt_last = mclk_pt; diff --git a/tests/test_app/main.c b/tests/test_app/main.c index 94391904..219e694f 100644 --- a/tests/test_app/main.c +++ b/tests/test_app/main.c @@ -3,7 +3,7 @@ /// /// Application to call the control loop with the parameters fully /// controllable by an external application. This app expects the -/// sw_pll_init parameters on the commannd line. These will be integers +/// sw_pll_lut_init parameters on the commannd line. These will be integers /// for lut_table_base, skip the parameter in the list and append the whole /// lut to the command line /// @@ -66,19 +66,19 @@ int main(int argc, char** argv) { fprintf(stderr, "\n"); sw_pll_state_t sw_pll; - sw_pll_init( &sw_pll, - SW_PLL_15Q16(kp), - SW_PLL_15Q16(ki), - SW_PLL_15Q16(kii), - loop_rate_count, - pll_ratio, - ref_clk_expected_inc, - lut_table_base, - num_lut_entries, - app_pll_ctl_reg_val, - app_pll_div_reg_val, - nominal_lut_idx, - ppm_range); + sw_pll_lut_init( &sw_pll, + SW_PLL_15Q16(kp), + SW_PLL_15Q16(ki), + SW_PLL_15Q16(kii), + loop_rate_count, + pll_ratio, + ref_clk_expected_inc, + lut_table_base, + num_lut_entries, + app_pll_ctl_reg_val, + app_pll_div_reg_val, + nominal_lut_idx, + ppm_range); for(;;) { @@ -104,7 +104,7 @@ int main(int argc, char** argv) { sscanf(read_buf, "%hu %hu", &mclk_pt, &ref_pt); fprintf(stderr, "%hu %hu\n", mclk_pt, ref_pt); uint32_t t0 = get_reference_time(); - sw_pll_lock_status_t s = sw_pll_do_control(&sw_pll, mclk_pt, ref_pt); + sw_pll_lock_status_t s = sw_pll_lut_do_control(&sw_pll, mclk_pt, ref_pt); uint32_t t1 = get_reference_time(); // xsim doesn't support our register and the val that was set gets diff --git a/tests/test_app_low_level_api/main.c b/tests/test_app_low_level_api/main.c index 64cbc882..1cc2f77e 100644 --- a/tests/test_app_low_level_api/main.c +++ b/tests/test_app_low_level_api/main.c @@ -3,7 +3,7 @@ /// /// Application to call the control loop with the parameters fully /// controllable by an external application. This app expects the -/// sw_pll_init parameters on the commannd line. These will be integers +/// sw_pll_lut_init parameters on the commannd line. These will be integers /// for lut_table_base, skip the parameter in the list and append the whole /// lut to the command line /// @@ -66,19 +66,19 @@ int main(int argc, char** argv) { fprintf(stderr, "\n"); sw_pll_state_t sw_pll; - sw_pll_init( &sw_pll, - SW_PLL_15Q16(kp), - SW_PLL_15Q16(ki), - SW_PLL_15Q16(kii), - loop_rate_count, - pll_ratio, - ref_clk_expected_inc, - lut_table_base, - num_lut_entries, - app_pll_ctl_reg_val, - app_pll_div_reg_val, - nominal_lut_idx, - ppm_range); + sw_pll_lut_init( &sw_pll, + SW_PLL_15Q16(kp), + SW_PLL_15Q16(ki), + SW_PLL_15Q16(kii), + loop_rate_count, + pll_ratio, + ref_clk_expected_inc, + lut_table_base, + num_lut_entries, + app_pll_ctl_reg_val, + app_pll_div_reg_val, + nominal_lut_idx, + ppm_range); for(;;) { @@ -104,7 +104,7 @@ int main(int argc, char** argv) { fprintf(stderr, "%hu\n", error); uint32_t t0 = get_reference_time(); - sw_pll_lock_status_t s = sw_pll_do_control_from_error(&sw_pll, error); + sw_pll_lock_status_t s = sw_pll_lut_do_control_from_error(&sw_pll, error); uint32_t t1 = get_reference_time(); // xsim doesn't support our register and the val that was set gets diff --git a/tests/test_app_sdm_ctrl/main.c b/tests/test_app_sdm_ctrl/main.c index 202bae21..75bff034 100644 --- a/tests/test_app_sdm_ctrl/main.c +++ b/tests/test_app_sdm_ctrl/main.c @@ -98,7 +98,7 @@ void control_task(int argc, char** argv, chanend_t c_sdm_control) { sscanf(read_buf, "%hd", &mclk_diff); uint32_t t0 = get_reference_time(); - int32_t error = sw_pll_sdm_do_control_from_error(&sw_pll, -mclk_diff); + int32_t error = sw_pll_do_pi_ctrl(&sw_pll, -mclk_diff); int32_t dco_ctl = sw_pll_sdm_post_control_proc(&sw_pll, error); uint32_t t1 = get_reference_time(); diff --git a/tests/test_app_sdm_dco/main.c b/tests/test_app_sdm_dco/main.c index 563f2da1..b8ac6660 100644 --- a/tests/test_app_sdm_dco/main.c +++ b/tests/test_app_sdm_dco/main.c @@ -51,8 +51,8 @@ int main(int argc, char** argv) { // calc new ds_out and then wait to write uint32_t t0 = get_reference_time(); - int32_t ds_out = do_sigma_delta(&sdm_state, ds_in); - uint32_t frac_val = ds_out_to_frac_reg(ds_out); + int32_t ds_out = sw_pll_do_sigma_delta(&sdm_state, ds_in); + uint32_t frac_val = sw_pll_sdm_out_to_frac_reg(ds_out); uint32_t t1 = get_reference_time(); printf("%ld %lu %lu\n", ds_out, frac_val, t1 - t0);