Commit 20f3af5b authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

softpll.c: added some codes, commenting still to be finished

parent bba1b564
/*
White Rabbit Softcore PLL (SoftPLL)
*/
#include <stdio.h>
#include <stdlib.h>
......@@ -8,38 +15,50 @@
#include "gpio.h"
/* Bit size of phase tags generated by the DMTDs. Used to sign-extend the tags. */
#define TAG_BITS 20
/* Helper PLL N divider (1/2**N is the frequency offset) */
#define HPLL_N 14
#define HPLL_DAC_BIAS 30000
/* Fractional bits in PI controller coefficients */
#define PI_FRACBITS 12
#define CHAN_FB 8
#define CHAN_REF 4
#define CHAN_PERIOD 2
#define CHAN_AUX 1
/* Channel enables in the CSR register: When the corresponding bit is set,
the corresponding channel is enabled */
#define CHAN_FB 8 /* Main clock feedback (clk_ref_i) */
#define CHAN_REF 4 /* Reference clock (clk_rx_i) */
#define CHAN_PERIOD 2 /* (clk_rx_i - clk_dmtd_i) period error */
#define CHAN_AUX 1 /* Auxillary core clock (clk_aux_i) */
/* CSR reg "tag ready" flags: When the corresponding bit is set,
the corresponding TAG_xxx register constains a fresh value of phase/frequency tag */
#define READY_FB (8<<4)
#define READY_REF (4<<4)
#define READY_PERIOD (2<<4)
#define READY_AUX (1<<4)
/* number of fractional cycles in the phase setpoint, used to control the speed of the phase shifter
(which affects the stability of the PLL) */
#define SETPOINT_FRACBITS 1
static volatile struct SPLL_WB *SPLL = (volatile struct SPLL_WB *) BASE_SOFTPLL;
/* PI regulator state */
typedef struct {
int ki, kp;
int integrator;
int bias;
int anti_windup;
int y_min;
int y_max;
int x,y;
int ki, kp; /* integral and proportional gains (1<<PI_FRACBITS == 1.0f) */
int integrator; /* current integrator value */
int bias; /* DC offset always added to the output */
int anti_windup; /* when non-zero, anti-windup is enabled */
int y_min; /* min/max output range, used by claming and antiwindup algorithms */
int y_max;
int x,y; /* Current input and output value */
} spll_pi_t;
/* Processes a single sample (x) using PI controller (pi). Returns the value (y) which should
be used to drive the actuator. */
static inline int pi_update(spll_pi_t *pi, int x)
{
int i_new, y;
......@@ -48,6 +67,9 @@ static inline int pi_update(spll_pi_t *pi, int x)
y = ((i_new * pi->ki + x * pi->kp) >> PI_FRACBITS) + pi->bias;
/* clamping (output has to be in <y_min, y_max>) and anti-windup:
stop the integretor if the output is already out of range and the output
is going further away from y_min/y_max. */
if(y < pi->y_min)
{
y = pi->y_min;
......@@ -65,11 +87,13 @@ static inline int pi_update(spll_pi_t *pi, int x)
}
/* initializes the PI controller state. Currently almost a stub. */
static inline void pi_init(spll_pi_t *pi)
{
pi->integrator = 0;
}
/* lock detector state */
typedef struct {
int lock_cnt;
int lock_samples;
......@@ -79,6 +103,9 @@ typedef struct {
} spll_lock_det_t;
/* Lock detector state machine. Takes an error sample (y) and checks if it's withing an acceptable range
(i.e. <-ld.threshold, ld.threshold>. If it has been inside the range for (ld.lock_samples) cyckes, the
FSM assumes the PLL is locked. */
static inline int ld_update(spll_lock_det_t *ld, int y)
{
if (abs(y) <= ld->threshold)
......@@ -107,8 +134,11 @@ static void ld_init(spll_lock_det_t *ld)
ld->lock_cnt = 0;
}
/* State of the Helper PLL, producing a clock (clk_dmtd_i) which is
slightly offset in frequency from the recovered/reference clock (clk_rx_i or clk_ref_i), so the
Main PLL can use it to perform linear phase measurements */
struct spll_helper_state {
spll_pi_t pi_freq, pi_phase;
spll_pi_t pi_freq, pi_phase;
spll_lock_det_t ld_freq, ld_phase;
int f_setpoint;
int p_setpoint;
......@@ -130,39 +160,6 @@ struct spll_dmpll_state {
int phase_shift;
};
struct softpll_config {
int hpll_f_kp;
int hpll_f_ki;
int hpll_f_setpoint;
int hpll_ld_f_samples;
int hpll_ld_f_threshold;
int hpll_p_kp;
int hpll_p_ki;
int hpll_ld_p_samples;
int hpll_ld_p_threshold;
int hpll_delock_threshold;
int hpll_dac_bias;
int dpll_f_kp;
int dpll_f_ki;
int dpll_p_kp;
int dpll_p_ki;
int dpll_ld_samples;
int dpll_ld_threshold;
int dpll_delock_threshold;
int dpll_dac_bias;
int dpll_deglitcher_threshold;
};
void helper_init(struct spll_helper_state *s)
{
......@@ -439,13 +436,13 @@ int softpll_check_lock()
int softpll_busy(int channel)
{
// mprintf("busy?");
return main.setpoint != main.phase_shift;
}
void softpll_set_phase(int channel, int ps)
void softpll_set_phase( int ps)
{
main.phase_shift = -(int32_t) ((int64_t)ps * 16384LL / 8000LL) << SETPOINT_FRACBITS;
mprintf("PSSet: %d\n", main.phase_shift);
main.phase_shift = (-(int32_t) ((int64_t)ps * 16384LL / 8000LL)) << SETPOINT_FRACBITS;
}
void softpll_disable()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment