Classes | |
struct | aided_lf_state_t |
struct | aided_tl_state_t |
struct | comp_tl_state_t |
struct | simple_lf_state_t |
struct | simple_tl_state_t |
Functions | |
void | aided_lf_init (aided_lf_state_t *s, float y0, float pgain, float igain, float aiding_igain) |
float | aided_lf_update (aided_lf_state_t *s, float p_i_error, float aiding_error) |
void | aided_tl_init (aided_tl_state_t *s, float loop_freq, float code_freq, float code_bw, float code_zeta, float code_k, float carr_freq, float carr_bw, float carr_zeta, float carr_k, float carr_freq_igain) |
void | aided_tl_update (aided_tl_state_t *s, correlation_t cs[3]) |
void | calc_loop_gains (float bw, float zeta, float k, float loop_freq, float *pgain, float *igain) |
void | comp_tl_init (comp_tl_state_t *s, float loop_freq, float code_freq, float code_bw, float code_zeta, float code_k, float carr_freq, float carr_bw, float carr_zeta, float carr_k, float tau, float cpc, u32 sched) |
void | comp_tl_update (comp_tl_state_t *s, correlation_t cs[3]) |
float | costas_discriminator (float I, float Q) |
float | dll_discriminator (correlation_t cs[3]) |
float | frequency_discriminator (float I, float Q, float prev_I, float prev_Q) |
void | simple_lf_init (simple_lf_state_t *s, float y0, float pgain, float igain) |
float | simple_lf_update (simple_lf_state_t *s, float error) |
void | simple_tl_init (simple_tl_state_t *s, float loop_freq, float code_freq, float code_bw, float code_zeta, float code_k, float carr_freq, float carr_bw, float carr_zeta, float carr_k) |
void | simple_tl_update (simple_tl_state_t *s, correlation_t cs[3]) |
Functions used by the tracking loops.
void aided_lf_init | ( | aided_lf_state_t * | s, |
float | y0, | ||
float | pgain, | ||
float | igain, | ||
float | aiding_igain | ||
) |
Initialize an integral aided loop filter.
This initializes a feedback loop with a PI component, plus an extra independent I term.
s | The loop filter state struct to initialize. |
y0 | The initial value of the output variable, . |
pgain | The proportional gain of the PI error term, . |
igain | The integral gain of the PI error term, . |
aiding_igain | The integral gain of the aiding error term, . |
float aided_lf_update | ( | aided_lf_state_t * | s, |
float | p_i_error, | ||
float | aiding_error | ||
) |
Update step for the integral aided loop filter.
This updates a feedback loop with a PI component plus an extra independent I term.
s | The loop filter state struct. |
p_i_error | The error output from the discriminator used in both P and I terms. |
aiding_error | The error output from the discriminator use just in an I term. |
void aided_tl_init | ( | aided_tl_state_t * | s, |
float | loop_freq, | ||
float | code_freq, | ||
float | code_bw, | ||
float | code_zeta, | ||
float | code_k, | ||
float | carr_freq, | ||
float | carr_bw, | ||
float | carr_zeta, | ||
float | carr_k, | ||
float | carr_freq_igain | ||
) |
Initialise an aided tracking loop.
For a full description of the loop filter parameters, see calc_loop_gains().
TODO, add carrier aiding to the code loop.
s | The tracking loop state struct to initialise. |
code_freq | The initial code phase rate (i.e. frequency). |
code_bw | The code tracking loop noise bandwidth. |
code_zeta | The code tracking loop damping ratio. |
code_k | The code tracking loop gain. |
carr_freq | The initial carrier frequency. |
carr_bw | The carrier tracking loop noise bandwidth. |
carr_zeta | The carrier tracking loop damping ratio. |
carr_k | The carrier tracking loop gain. |
void aided_tl_update | ( | aided_tl_state_t * | s, |
correlation_t | cs[3] | ||
) |
Update step for the aided tracking loop.
Implements a basic second-order tracking loop. The code tracking loop is a second-order DLL using dll_discriminator() as its discriminator function. The carrier phase tracking loop is a second-order Costas loop using costas_discriminator(), aided by a frequency discriminator using frequency_discriminator().
TODO, add carrier aiding to the code loop.
The tracking loop output variables, i.e. code and carrier frequencies can be read out directly from the state struct.
s | The tracking loop state struct. |
cs | An array [E, P, L] of correlation_t structs for the Early, Prompt and Late correlations. |
void calc_loop_gains | ( | float | bw, |
float | zeta, | ||
float | k, | ||
float | loop_freq, | ||
float * | pgain, | ||
float * | igain | ||
) |
Calculate coefficients for a 2nd order digital PLL / DLL loop filter.
A second order digital PLL consists of a first-order filter and a Numerically Controlled Oscillator (NCO). A linearised model of a digital second order PLL is shown below:
Where is the discriminator gain and and are the loop filter and NCO transfer functions. The NCO is essentially an accumulator and hence has a transfer function:
The first-order loop filter is shown below:
and has transfer function:
It is useful to be able to calculate the loop filter coefficients, and by comparison to the parameters used in analog PLL design. By comparison between the digital and analog PLL transfer functions we can show the digital loop filter coefficients are related to the analog PLL natural frequency, and damping ratio, by:
Where is the loop update period and the overall loop gain, , is the product of the NCO and discriminator gains, . The natural frequency is related to the loop noise bandwidth, by the following relationship:
These coefficients are applicable to both the Carrier phase Costas loop and the Code phase DLL.
References:
bw | The loop noise bandwidth, . |
zeta | The damping ratio, . |
k | The loop gain, . |
loop_freq | The loop update frequency, . |
pgain | Where to store the calculated proportional gain, . |
igain | Where to store the calculated integral gain, . |
void comp_tl_init | ( | comp_tl_state_t * | s, |
float | loop_freq, | ||
float | code_freq, | ||
float | code_bw, | ||
float | code_zeta, | ||
float | code_k, | ||
float | carr_freq, | ||
float | carr_bw, | ||
float | carr_zeta, | ||
float | carr_k, | ||
float | tau, | ||
float | cpc, | ||
u32 | sched | ||
) |
Initialise a code/carrier phase complimentary filter tracking loop.
For a full description of the loop filter parameters, see calc_loop_gains().
This filter implements gain scheduling. Before `sched` iterations of the loop filter the behaviour will be identical to the simple loop filter. After `sched` iterations, carrier phase information will be used in the code tracking loop.
Note, this filter requires that the code and carrier frequencies are expressed as a difference from the nominal frequncy (e.g. 1.023MHz nominal GPS C/A code phase rate, 4.092MHz IF for the carrier).
s | The tracking loop state struct to initialise. |
code_freq | The initial code phase rate (i.e. frequency) difference from nominal. |
code_bw | The code tracking loop noise bandwidth. |
code_zeta | The code tracking loop damping ratio. |
code_k | The code tracking loop gain. |
carr_freq | The initial carrier frequency difference from nominal, i.e. Doppler shift. |
carr_bw | The carrier tracking loop noise bandwidth. |
carr_zeta | The carrier tracking loop damping ratio. |
carr_k | The carrier tracking loop gain. |
tau | The complimentary filter cross-over frequency. |
cpc | The number of carrier cycles per complete code, or equivalently the ratio of the carrier frequency to the nominal code frequency. |
sched | The gain scheduling count. |
void comp_tl_update | ( | comp_tl_state_t * | s, |
correlation_t | cs[3] | ||
) |
Update step for a code/carrier phase complimentary filter tracking loop.
The tracking loop output variables, i.e. code and carrier frequencies can be read out directly from the state struct.
s | The tracking loop state struct. |
cs | An array [E, P, L] of correlation_t structs for the Early, Prompt and Late correlations. |
float costas_discriminator | ( | float | I, |
float | Q | ||
) |
Phase discriminator for a Costas loop.
Implements the Costas loop discriminator.
References:
I | The prompt in-phase correlation, . |
Q | The prompt quadrature correlation, . |
float dll_discriminator | ( | correlation_t | cs[3] | ) |
Normalised non-coherent early-minus-late envelope discriminator.
Implements the normalised non-coherent early-minus-late envelope DLL discriminator.
where:
References:
cs | An array [E, P, L] of correlation_t structs for the Early, Prompt and Late correlations. |
float frequency_discriminator | ( | float | I, |
float | Q, | ||
float | prev_I, | ||
float | prev_Q | ||
) |
Frequency discriminator for a FLL, used to aid the PLL.
Implements the frequency discriminator.
Strictly speaking this should have a 1 / dt factor, but then we would later multiply the gain by dt again, and it would cancel out. So why do those unnecessary operations at all?
References:
I | The prompt in-phase correlation, . |
Q | The prompt quadrature correlation, . |
I | The prompt in-phase correlation, . |
Q | The prompt quadrature correlation, . |
void simple_lf_init | ( | simple_lf_state_t * | s, |
float | y0, | ||
float | pgain, | ||
float | igain | ||
) |
Initialise a simple first-order loop filter. The gains can be calculated using calc_loop_gains().
s | The loop filter state struct to initialise. |
y0 | The initial value of the output variable, . |
pgain | The proportional gain, . |
igain | The integral gain, . |
float simple_lf_update | ( | simple_lf_state_t * | s, |
float | error | ||
) |
Update step for the simple first-order loop filter.
Implements the first-order loop filter as shown below:
with transfer function:
s | The loop filter state struct. |
error | The error output from the discriminator, . |
void simple_tl_init | ( | simple_tl_state_t * | s, |
float | loop_freq, | ||
float | code_freq, | ||
float | code_bw, | ||
float | code_zeta, | ||
float | code_k, | ||
float | carr_freq, | ||
float | carr_bw, | ||
float | carr_zeta, | ||
float | carr_k | ||
) |
Initialise a simple tracking loop.
For a full description of the loop filter parameters, see calc_loop_gains().
s | The tracking loop state struct to initialise. |
code_freq | The initial code phase rate (i.e. frequency). |
code_bw | The code tracking loop noise bandwidth. |
code_zeta | The code tracking loop damping ratio. |
code_k | The code tracking loop gain. |
carr_freq | The initial carrier frequency. |
carr_bw | The carrier tracking loop noise bandwidth. |
carr_zeta | The carrier tracking loop damping ratio. |
carr_k | The carrier tracking loop gain. |
void simple_tl_update | ( | simple_tl_state_t * | s, |
correlation_t | cs[3] | ||
) |
Update step for the simple tracking loop.
Implements a basic second-order tracking loop. The code tracking loop is a second-order DLL using dll_discriminator() as its discriminator function. The carrier phase tracking loop is a second-order Costas loop using costas_discriminator().
The tracking loop output variables, i.e. code and carrier frequencies can be read out directly from the state struct.
s | The tracking loop state struct. |
cs | An array [E, P, L] of correlation_t structs for the Early, Prompt and Late correlations. |