Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit Switch - Gateware
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
12
Issues
12
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Projects
White Rabbit Switch - Gateware
Commits
8fefa391
Commit
8fefa391
authored
Apr 13, 2012
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rt: external 10MHz reference support for softpll, updated SPLL register layout
parent
e466e7f5
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
224 additions
and
59 deletions
+224
-59
softpll_ng.c
rt/dev/softpll_ng.c
+72
-41
spll_common.h
rt/dev/spll_common.h
+23
-0
spll_debug.h
rt/dev/spll_debug.h
+1
-0
spll_defs.h
rt/dev/spll_defs.h
+1
-1
spll_external.h
rt/dev/spll_external.h
+96
-0
softpll_regs.h
rt/include/hw/softpll_regs.h
+31
-17
No files found.
rt/dev/softpll_ng.c
View file @
8fefa391
...
...
@@ -22,14 +22,29 @@ static volatile struct SPLL_WB *SPLL = (volatile struct SPLL_WB *) BASE_SOFTPLL;
#include "spll_helper.h"
#include "spll_main.h"
#include "spll_ptracker.h"
#include "spll_external.h"
#define CHAN_TCXO 4
#define CHAN_EXT 5
static
volatile
struct
spll_helper_state
helper
;
static
volatile
struct
spll_external_state
extpll
;
static
volatile
struct
spll_main_state
mpll
;
static
volatile
struct
spll_ptracker_state
ptrackers
[
MAX_PTRACKERS
];
#define MODE_GRAND_MASTER 0
#define MODE_FREERUNNING_MASTER 1
#define MODE_SLAVE 2
static
volatile
int
mode
=
MODE_GRAND_MASTER
;
static
volatile
int
helper_locked
=
0
;
void
_irq_entry
()
{
volatile
uint32_t
trr
;
int
src
=
-
1
,
tag
;
int
i
;
if
(
!
(
SPLL
->
CSR
&
SPLL_TRR_CSR_EMPTY
))
{
...
...
@@ -37,27 +52,64 @@ void _irq_entry()
src
=
SPLL_TRR_R0_CHAN_ID_R
(
trr
);
tag
=
SPLL_TRR_R0_VALUE_R
(
trr
);
helper_update
(
&
helper
,
tag
,
src
);
mpll_update
(
&
mpll
,
tag
,
src
);
switch
(
mode
)
{
case
MODE_GRAND_MASTER
:
external_update
(
&
extpll
,
tag
,
src
);
break
;
};
// helper_update(&helper, tag, src);
/* if(helper.ld.locked && !helper_locked)
{
for(i=0;i<n_chan_ref; i++)
ptracker_init(&ptrackers[i], CHAN_TCXO, i, 512);
}
if(helper.ld.locked)
{
for(i=0;i<n_chan_ref; i++)
ptracker_update(&ptrackers[i], tag, src);
} else {
for(i=0;i<n_chan_ref; i++)
ptrackers[i].ready = 0;
}
*/
/*
if(helper.ld.locked && !helper_locked)
{
if(!master_mode) mpll_start(&mpll);
helper_locked= 1;
}
if(helper.ld.locked && !master_mode)
{
mpll_update(&mpll, tag, src);
}*/
}
irq_count
++
;
clear_irq
();
irq_count
++
;
clear_irq
();
}
void
spll_init
()
void
spll_init
(
int
_master_mode
,
int
ref_channel
)
{
volatile
int
dummy
;
disable_irq
();
n_chan_ref
=
SPLL_CSR_N_REF_R
(
SPLL
->
CSR
);
n_chan_out
=
SPLL_CSR_N_OUT_R
(
SPLL
->
CSR
);
TRACE
(
"SPLL_Init: %d ref channels, %d out channels
\n
"
,
n_chan_ref
,
n_chan_out
);
helper_locked
=
0
;
// master_mode = _master_mode;
TRACE
(
"SPLL_Init: %s mode, %d ref channels, %d out channels
\n
"
,
_master_mode
?
"Master"
:
"Slave"
,
n_chan_ref
,
n_chan_out
);
SPLL
->
DAC_HPLL
=
0
;
timer_delay
(
100000
);
timer_delay
(
100000
);
SPLL
->
CSR
=
0
;
SPLL
->
OCER
=
0
;
SPLL
->
RCER
=
0
;
...
...
@@ -67,44 +119,23 @@ void spll_init()
while
(
!
(
SPLL
->
TRR_CSR
&
SPLL_TRR_CSR_EMPTY
))
dummy
=
SPLL
->
TRR_R0
;
dummy
=
SPLL
->
PER_HPLL
;
SPLL
->
EIC_IER
=
1
;
}
int
spll_check_lock
()
{
return
helper
.
ld
.
locked
?
1
:
0
;
}
#define CHAN_TCXO 8
void
spll_test
()
{
int
i
=
0
;
volatile
int
dummy
;
// helper_init(&helper, master_mode ? CHAN_TCXO : ref_channel);
// if(!master_mode)
// mpll_init(&mpll, ref_channel, CHAN_TCXO);
// helper_start(&helper);
external_init
(
&
extpll
,
CHAN_EXT
);
external_start
(
&
extpll
,
1
);
spll_init
();
helper_init
(
&
helper
,
0
);
helper_start
(
&
helper
);
mpll_init
(
&
mpll
,
0
,
CHAN_TCXO
);
enable_irq
();
// mpll_init(&mpll, 0, CHAN_TCXO);
while
(
!
helper
.
ld
.
locked
)
;
//TRACE("%d\n", helper.phase.ld.locked);
TRACE
(
"Helper locked, starting main
\n
"
);
mpll_start
(
&
mpll
);
for
(;;)
mprintf
(
"irqcount %d t %d lock %d
\n
"
,
irq_count
,
eee
,
extpll
.
ld
.
locked
);
}
/*
#define CHAN_AUX 7
#define CHAN_EXT 6
int spll_gm_measure_ext_phase()
int
spll_check_lock
()
{
SPLL->CSR = 0;
SPLL->DCCR = SPLL_DCCR_GATE_DIV_W(25);
SPLL->RCGER = (1<<CHAN_AUX);
SPLL->RCGER = (1<<CHAN_EXT);
return
0
;
// return helper.ld.locked & (mpll.ld.locked || master_mode) ? 1 : 0;
}
*/
\ No newline at end of file
rt/dev/spll_common.h
View file @
8fefa391
...
...
@@ -34,6 +34,11 @@ typedef struct {
int
locked
;
/* Non-zero: we are locked */
}
spll_lock_det_t
;
/* simple, 1st-order lowpass filter */
typedef
struct
{
int
alpha
;
int
y_d
;
}
spll_lowpass_t
;
/* Processes a single sample (x) with PI control algorithm (pi). Returns the value (y) to
drive the actuator. */
...
...
@@ -113,6 +118,24 @@ static void ld_init(spll_lock_det_t *ld)
ld
->
lock_cnt
=
0
;
}
static
void
lowpass_init
(
spll_lowpass_t
*
lp
,
int
alpha
)
{
lp
->
y_d
=
0x80000000
;
lp
->
alpha
=
alpha
;
}
static
int
lowpass_update
(
spll_lowpass_t
*
lp
,
int
x
)
{
if
(
lp
->
y_d
==
0x80000000
)
{
lp
->
y_d
=
x
;
return
x
;
}
else
{
lp
->
y_d
=
lp
->
y_d
+
((
lp
->
alpha
*
(
x
-
lp
->
y_d
))
>>
16
);
return
lp
->
y_d
;
}
}
/* Enables/disables DDMTD tag generation on a given (channel).
...
...
rt/dev/spll_debug.h
View file @
8fefa391
...
...
@@ -22,6 +22,7 @@ integral/proportional gains on the response of the system.
#define DBG_SAMPLE_ID 6
#define DBG_HELPER 0x20
/* Sample source: Helper PLL */
#define DBG_EXT 0x40
/* Sample source: External Reference PLL */
#define DBG_MAIN 0x0
/* ... : Main PLL */
#define DBG_EVT_START 1
/* PLL has just started */
...
...
rt/dev/spll_defs.h
View file @
8fefa391
...
...
@@ -31,7 +31,7 @@ WARNING: These parameters must be in sync with the generics of the HDL instantia
#define MAX_CHAN_OUT 1
/* Max. allowed number of phase trackers */
#define MAX_TRACKERS 6
#define MAX_
P
TRACKERS 6
/* Number of bits of the DAC(s) driving the oscillator(s). Must be the same for
all the outputs. */
...
...
rt/dev/spll_external.h
0 → 100644
View file @
8fefa391
#define BB_ERROR_BITS 16
struct
spll_external_state
{
int
ref_src
;
int
sample_n
;
int
ph_err_offset
,
ph_err_cur
,
ph_err_d0
,
ph_raw_d0
;
spll_pi_t
pi
;
spll_lowpass_t
lp_short
,
lp_long
;
spll_lock_det_t
ld
;
};
static
void
external_init
(
struct
spll_external_state
*
s
,
int
ext_ref
)
{
s
->
pi
.
y_min
=
5
;
s
->
pi
.
y_max
=
(
1
<<
DAC_BITS
)
-
5
;
s
->
pi
.
kp
=
(
int
)(
300
);
s
->
pi
.
ki
=
(
int
)(
1
);
s
->
pi
.
anti_windup
=
1
;
s
->
pi
.
bias
=
32768
;
/* Phase branch lock detection */
s
->
ld
.
threshold
=
250
;
s
->
ld
.
lock_samples
=
10000
;
s
->
ld
.
delock_samples
=
9990
;
s
->
ref_src
=
ext_ref
;
s
->
ph_err_cur
=
0
;
s
->
ph_err_d0
=
0
;
s
->
ph_raw_d0
=
0
;
pi_init
(
&
s
->
pi
);
ld_init
(
&
s
->
ld
);
lowpass_init
(
&
s
->
lp_short
,
4000
);
lowpass_init
(
&
s
->
lp_long
,
1000
);
}
static
int
external_update
(
struct
spll_external_state
*
s
,
int
tag
,
int
source
)
{
int
err
,
y
,
y2
,
yd
,
ylt
;
if
(
source
==
s
->
ref_src
)
{
int
wrap
=
tag
&
(
1
<<
BB_ERROR_BITS
)
?
1
:
0
;
tag
&=
((
1
<<
BB_ERROR_BITS
)
-
1
);
// mprintf("err %d\n", tag);
if
(
wrap
)
{
if
(
tag
>
s
->
ph_raw_d0
)
s
->
ph_err_offset
-=
(
1
<<
BB_ERROR_BITS
);
else
if
(
tag
<=
s
->
ph_raw_d0
)
s
->
ph_err_offset
+=
(
1
<<
BB_ERROR_BITS
);
}
s
->
ph_raw_d0
=
tag
;
err
=
(
tag
+
s
->
ph_err_offset
)
-
s
->
ph_err_d0
;
s
->
ph_err_d0
=
(
tag
+
s
->
ph_err_offset
);
y
=
pi_update
(
&
s
->
pi
,
err
);
y2
=
lowpass_update
(
&
s
->
lp_short
,
y
);
ylt
=
lowpass_update
(
&
s
->
lp_long
,
y
);
SPLL
->
DAC_MAIN
=
y2
&
0xffff
;
spll_debug
(
DBG_ERR
|
DBG_EXT
,
ylt
,
0
);
spll_debug
(
DBG_SAMPLE_ID
|
DBG_EXT
,
s
->
sample_n
++
,
0
);
spll_debug
(
DBG_Y
|
DBG_EXT
,
y2
,
1
);
if
(
ld_update
(
&
s
->
ld
,
y2
-
ylt
))
return
SPLL_LOCKED
;
}
return
SPLL_LOCKING
;
}
static
void
external_start
(
struct
spll_external_state
*
s
,
int
align_pps
)
{
s
->
sample_n
=
0
;
SPLL
->
ECCR
=
SPLL_ECCR_EXT_EN
;
mprintf
(
"ExtStartup
\n
"
);
spll_debug
(
DBG_EVENT
|
DBG_EXT
,
DBG_EVT_START
,
1
);
if
(
align_pps
)
{
SPLL
->
ECCR
|=
SPLL_ECCR_ALIGN_EN
;
while
(
!
(
SPLL
->
ECCR
&
SPLL_ECCR_ALIGN_DONE
));
}
}
rt/include/hw/softpll_regs.h
View file @
8fefa391
...
...
@@ -3,7 +3,7 @@
* File : softpll_regs.h
* Author : auto-generated by wbgen2 from spll_wb_slave.wb
* Created :
Wed Mar 7 11:09:46
2012
* Created :
Thu Apr 12 14:15:28
2012
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE spll_wb_slave.wb
...
...
@@ -14,8 +14,6 @@
#ifndef __WBGEN2_REGDEFS_SPLL_WB_SLAVE_WB
#define __WBGEN2_REGDEFS_SPLL_WB_SLAVE_WB
#include <stdint.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
...
...
@@ -54,17 +52,31 @@
/* definitions for field: Enable Period Measurement in reg: SPLL Control/Status Register */
#define SPLL_CSR_PER_EN WBGEN2_GEN_MASK(19, 1)
/* definitions for register: External Clock Control Register */
/* definitions for field: Enable External Clock BB Detector in reg: External Clock Control Register */
#define SPLL_ECCR_EXT_EN WBGEN2_GEN_MASK(0, 1)
/* definitions for field: External Clock Input Available in reg: External Clock Control Register */
#define SPLL_ECCR_EXT_SUPPORTED WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Enable PPS/phase alignment in reg: External Clock Control Register */
#define SPLL_ECCR_ALIGN_EN WBGEN2_GEN_MASK(2, 1)
/* definitions for field: PPS/phase alignment done in reg: External Clock Control Register */
#define SPLL_ECCR_ALIGN_DONE WBGEN2_GEN_MASK(3, 1)
/* definitions for register: DMTD Clock Control Register */
/* definitions for field: DMTD Clock
Gate
Divider in reg: DMTD Clock Control Register */
/* definitions for field: DMTD Clock
Undersampling
Divider in reg: DMTD Clock Control Register */
#define SPLL_DCCR_GATE_DIV_MASK WBGEN2_GEN_MASK(0, 6)
#define SPLL_DCCR_GATE_DIV_SHIFT 0
#define SPLL_DCCR_GATE_DIV_W(value) WBGEN2_GEN_WRITE(value, 0, 6)
#define SPLL_DCCR_GATE_DIV_R(reg) WBGEN2_GEN_READ(reg, 0, 6)
/* definitions for register: Reference Channel
Gat
ing Enable Register */
/* definitions for register: Reference Channel
Undersampl
ing Enable Register */
/* definitions for field: Reference Channel
Gating Enable in reg: Reference Channel Gat
ing Enable Register */
/* definitions for field: Reference Channel
Undersampling Enable in reg: Reference Channel Undersampl
ing Enable Register */
#define SPLL_RCGER_GATE_SEL_MASK WBGEN2_GEN_MASK(0, 32)
#define SPLL_RCGER_GATE_SEL_SHIFT 0
#define SPLL_RCGER_GATE_SEL_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
...
...
@@ -206,28 +218,30 @@
PACKED
struct
SPLL_WB
{
/* [0x0]: REG SPLL Control/Status Register */
uint32_t
CSR
;
/* [0x4]: REG DMTD Clock Control Register */
/* [0x4]: REG External Clock Control Register */
uint32_t
ECCR
;
/* [0x8]: REG DMTD Clock Control Register */
uint32_t
DCCR
;
/* [0x
8]: REG Reference Channel Gat
ing Enable Register */
/* [0x
c]: REG Reference Channel Undersampl
ing Enable Register */
uint32_t
RCGER
;
/* [0x
c
]: REG Output Channel Control Register */
/* [0x
10
]: REG Output Channel Control Register */
uint32_t
OCCR
;
/* [0x1
0
]: REG Reference Channel Enable Register */
/* [0x1
4
]: REG Reference Channel Enable Register */
uint32_t
RCER
;
/* [0x1
4
]: REG Output Channel Enable Register */
/* [0x1
8
]: REG Output Channel Enable Register */
uint32_t
OCER
;
/* [0x1
8
]: REG HPLL Period Error */
/* [0x1
c
]: REG HPLL Period Error */
uint32_t
PER_HPLL
;
/* [0x
1c
]: REG Helper DAC Output */
/* [0x
20
]: REG Helper DAC Output */
uint32_t
DAC_HPLL
;
/* [0x2
0
]: REG Main DAC Output */
/* [0x2
4
]: REG Main DAC Output */
uint32_t
DAC_MAIN
;
/* [0x2
4
]: REG Deglitcher threshold */
/* [0x2
8
]: REG Deglitcher threshold */
uint32_t
DEGLITCH_THR
;
/* [0x2
8
]: REG Debug FIFO Register - SPLL side */
/* [0x2
c
]: REG Debug FIFO Register - SPLL side */
uint32_t
DFR_SPLL
;
/* padding to: 16 words */
uint32_t
__padding_0
[
5
];
uint32_t
__padding_0
[
4
];
/* [0x40]: REG Interrupt disable register */
uint32_t
EIC_IDR
;
/* [0x44]: REG Interrupt enable register */
...
...
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