Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Software for White Rabbit PTP Core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
32
Issues
32
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Software for White Rabbit PTP Core
Commits
20f3af5b
Commit
20f3af5b
authored
Nov 03, 2011
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
softpll.c: added some codes, commenting still to be finished
parent
bba1b564
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
47 additions
and
50 deletions
+47
-50
softpll.c
dev/softpll.c
+47
-50
No files found.
dev/softpll.c
View file @
20f3af5b
/*
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
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment