Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
P
PTP noposix stack
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
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
PTP noposix stack
Commits
30c366fe
Commit
30c366fe
authored
Jul 25, 2012
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
softpll: merged WRPC changes (mainly aux clock support)
parent
530698d0
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
212 additions
and
66 deletions
+212
-66
softpll_ng.c
softpll/softpll_ng.c
+186
-46
softpll_ng.h
softpll/softpll_ng.h
+10
-0
spll_common.h
softpll/spll_common.h
+1
-1
spll_defs.h
softpll/spll_defs.h
+5
-0
spll_main.h
softpll/spll_main.h
+10
-19
No files found.
softpll/softpll_ng.c
View file @
30c366fe
...
...
@@ -13,8 +13,8 @@
volatile
int
irq_count
=
0
;
static
volatile
struct
SPLL_WB
*
SPLL
=
(
volatile
struct
SPLL_WB
*
)
BASE_SOFTPLL
;
static
volatile
struct
PPSG_WB
*
PPSG
=
(
volatile
struct
PPSG_WB
*
)
BASE_PPS_GEN
;
static
volatile
struct
SPLL_WB
*
SPLL
;
static
volatile
struct
PPSG_WB
*
PPSG
;
/* The includes below contain code (not only declarations) to enable the compiler
to inline functions where necessary and save some CPU cycles */
...
...
@@ -38,6 +38,16 @@ static volatile struct PPSG_WB *PPSG = (volatile struct PPSG_WB *) BASE_PPS_GEN;
#define SEQ_CLEAR_DACS 9
#define SEQ_WAIT_CLEAR_DACS 10
#define AUX_DISABLED 1
#define AUX_LOCK_PLL 2
#define AUX_ALIGN_PHASE 3
#define AUX_READY 4
struct
spll_aux_state
{
int
state
;
int32_t
phase_target
;
};
struct
softpll_state
{
int
mode
;
int
seq_state
;
...
...
@@ -45,10 +55,13 @@ struct softpll_state {
int
dac_timeout
;
int
default_dac_main
;
int
delock_count
;
int32_t
mpll_shift_ps
;
struct
spll_helper_state
helper
;
struct
spll_external_state
ext
;
struct
spll_main_state
mpll
;
struct
spll_main_state
aux
[
MAX_CHAN_AUX
];
struct
spll_aux_state
aux_fsm
[
MAX_CHAN_AUX
];
struct
spll_ptracker_state
ptrackers
[
MAX_PTRACKERS
];
};
...
...
@@ -80,11 +93,11 @@ void _irq_entry()
softpll
.
dac_timeout
=
timer_get_tics
();
if
(
softpll
.
mode
==
SPLL_MODE_SLAVE
)
spll_resync_dmtd_counter
(
softpll
.
mpll
.
id_ref
);
break
;
case
SEQ_WAIT_CLEAR_DACS
:
if
(
timer_get_tics
()
-
softpll
.
dac_timeout
>
1000
0
)
if
(
timer_get_tics
()
-
softpll
.
dac_timeout
>
TICS_PER_SECOND
/
2
0
)
softpll
.
seq_state
=
(
softpll
.
mode
==
SPLL_MODE_GRAND_MASTER
?
SEQ_START_EXT
:
SEQ_START_HELPER
);
break
;
...
...
@@ -143,15 +156,10 @@ void _irq_entry()
case
SEQ_READY
:
if
(
!
softpll
.
helper
.
ld
.
locked
)
{
// SPLL->OCER = 0;
// SPLL->RCER = 0;
softpll
.
seq_state
=
SEQ_CLEAR_DACS
;
softpll
.
delock_count
++
;
}
else
if
(
softpll
.
mode
==
SPLL_MODE_GRAND_MASTER
&&
!
external_locked
((
struct
spll_external_state
*
)
&
s
->
ext
))
{
// SPLL->OCER = 0;
// SPLL->RCER = 0;
// SPLL->ECCR = 0;
softpll
.
seq_state
=
SEQ_START_EXT
;
softpll
.
delock_count
++
;
}
else
if
(
softpll
.
mode
==
SPLL_MODE_SLAVE
&&
!
softpll
.
mpll
.
ld
.
locked
)
...
...
@@ -182,19 +190,17 @@ void _irq_entry()
if
(
softpll
.
mode
==
SPLL_MODE_GRAND_MASTER
)
external_update
((
struct
spll_external_state
*
)
&
s
->
ext
,
tag
,
src
);
if
(
softpll
.
mode
==
SPLL_MODE_SLAVE
)
{
mpll_update
((
struct
spll_main_state
*
)
&
s
->
mpll
,
tag
,
src
);
for
(
i
=
0
;
i
<
n_chan_out
-
1
;
i
++
)
mpll_update
(
&
softpll
.
aux
[
i
],
tag
,
src
);
}
for
(
i
=
0
;
i
<
n_chan_ref
;
i
++
)
if
(
ptracker_mask
&
(
1
<<
i
))
ptracker_update
((
struct
spll_ptracker_state
*
)
&
s
->
ptrackers
[
i
],
tag
,
src
);
break
;
}
}
irq_count
++
;
...
...
@@ -214,6 +220,9 @@ void spll_init(int mode, int slave_ref_channel, int align_pps)
volatile
int
dummy
;
int
i
;
SPLL
=
(
volatile
struct
SPLL_WB
*
)
BASE_SOFTPLL
;
PPSG
=
(
volatile
struct
PPSG_WB
*
)
BASE_PPS_GEN
;
disable_irq
();
n_chan_ref
=
SPLL_CSR_N_REF_R
(
SPLL
->
CSR
);
...
...
@@ -226,15 +235,14 @@ void spll_init(int mode, int slave_ref_channel, int align_pps)
SPLL
->
DAC_HPLL
=
0
;
SPLL
->
DAC_MAIN
=
0
;
//timer_delay(100000);
SPLL
->
CSR
=
0
;
SPLL
->
OCER
=
0
;
SPLL
->
RCER
=
0
;
SPLL
->
ECCR
=
0
;
SPLL
->
RCGER
=
0
;
SPLL
->
DCCR
=
0
;
SPLL
->
DEGLITCH_THR
=
300
;
SPLL
->
OCCR
=
0
;
SPLL
->
DEGLITCH_THR
=
1000
;
PPSG
->
ESCR
=
0
;
PPSG
->
CR
=
PPSG_CR_CNT_EN
|
PPSG_CR_CNT_RST
|
PPSG_CR_PWIDTH_W
(
100
);
...
...
@@ -257,7 +265,10 @@ void spll_init(int mode, int slave_ref_channel, int align_pps)
mpll_init
(
&
softpll
.
mpll
,
slave_ref_channel
,
n_chan_ref
);
for
(
i
=
0
;
i
<
n_chan_out
-
1
;
i
++
)
{
mpll_init
(
&
softpll
.
aux
[
i
],
slave_ref_channel
,
n_chan_ref
+
i
+
1
);
softpll
.
aux_fsm
[
i
].
state
=
AUX_DISABLED
;
}
break
;
case
SPLL_MODE_FREE_RUNNING_MASTER
:
...
...
@@ -265,12 +276,15 @@ void spll_init(int mode, int slave_ref_channel, int align_pps)
softpll
.
seq_state
=
SEQ_CLEAR_DACS
;
softpll
.
default_dac_main
=
32000
;
helper_init
(
&
softpll
.
helper
,
n_chan_ref
);
helper_init
(
&
softpll
.
helper
,
n_chan_ref
+
slave_ref_channel
);
mpll_init
(
&
softpll
.
mpll
,
slave_ref_channel
,
n_chan_ref
);
for
(
i
=
0
;
i
<
n_chan_out
-
1
;
i
++
)
{
mpll_init
(
&
softpll
.
aux
[
i
],
slave_ref_channel
,
n_chan_ref
+
i
+
1
);
softpll
.
aux_fsm
[
i
].
state
=
AUX_DISABLED
;
}
PPSG
->
ESCR
=
PPSG_ESCR_PPS_VALID
|
PPSG_ESCR_TM_VALID
;
break
;
...
...
@@ -286,7 +300,11 @@ void spll_init(int mode, int slave_ref_channel, int align_pps)
mpll_init
(
&
softpll
.
mpll
,
slave_ref_channel
,
n_chan_ref
);
for
(
i
=
0
;
i
<
n_chan_out
-
1
;
i
++
)
{
mpll_init
(
&
softpll
.
aux
[
i
],
slave_ref_channel
,
n_chan_ref
+
i
+
1
);
softpll
.
aux_fsm
[
i
].
state
=
AUX_DISABLED
;
}
// PPSG->ESCR = PPSG_ESCR_PPS_VALID | PPSG_ESCR_TM_VALID;
...
...
@@ -304,9 +322,7 @@ void spll_init(int mode, int slave_ref_channel, int align_pps)
dummy
=
SPLL
->
PER_HPLL
;
SPLL
->
EIC_IER
=
1
;
SPLL
->
OCER
=
1
;
// _irq_entry();
SPLL
->
OCER
|=
1
;
enable_irq
();
...
...
@@ -335,8 +351,10 @@ void spll_shutdown()
void
spll_start_channel
(
int
channel
)
{
if
(
softpll
.
seq_state
!=
SEQ_READY
||
!
channel
)
{
TRACE
(
"Can't start channel %d, the PLL is not ready
\n
"
,
channel
);
return
;
}
mpll_start
(
&
softpll
.
aux
[
channel
-
1
]);
}
...
...
@@ -367,17 +385,33 @@ static int32_t to_picos(int32_t units)
}
/* Channel 0 = local PLL reference, 1...N = aux oscillators */
void
spll_
set_phase_shift
(
int
channel
,
int32_t
value_picoseconds
)
static
void
set_phase_shift
(
int
channel
,
int32_t
value_picoseconds
)
{
volatile
struct
spll_main_state
*
st
=
(
!
channel
?
&
softpll
.
mpll
:
&
softpll
.
aux
[
channel
-
1
]);
mpll_set_phase_shift
(
st
,
from_picos
(
value_picoseconds
));
int
div
=
(
DIVIDE_DMTD_CLOCKS_BY_2
?
2
:
1
);
mpll_set_phase_shift
(
st
,
from_picos
(
value_picoseconds
)
/
div
);
softpll
.
mpll_shift_ps
=
value_picoseconds
;
}
void
spll_set_phase_shift
(
int
channel
,
int32_t
value_picoseconds
)
{
int
i
;
if
(
channel
==
SPLL_ALL_CHANNELS
)
{
spll_set_phase_shift
(
0
,
value_picoseconds
);
for
(
i
=
0
;
i
<
n_chan_out
-
1
;
i
++
)
if
(
softpll
.
aux_fsm
[
i
].
state
==
AUX_READY
)
set_phase_shift
(
i
+
1
,
value_picoseconds
);
}
else
set_phase_shift
(
channel
,
value_picoseconds
);
}
void
spll_get_phase_shift
(
int
channel
,
int32_t
*
current
,
int32_t
*
target
)
{
volatile
struct
spll_main_state
*
st
=
(
!
channel
?
&
softpll
.
mpll
:
&
softpll
.
aux
[
channel
-
1
]);
if
(
current
)
*
current
=
to_picos
(
st
->
phase_shift_current
);
if
(
target
)
*
target
=
to_picos
(
st
->
phase_shift_target
);
int
div
=
(
DIVIDE_DMTD_CLOCKS_BY_2
?
2
:
1
);
if
(
current
)
*
current
=
to_picos
(
st
->
phase_shift_current
*
div
);
if
(
target
)
*
target
=
to_picos
(
st
->
phase_shift_target
*
div
);
}
int
spll_read_ptracker
(
int
channel
,
int32_t
*
phase_ps
,
int
*
enabled
)
...
...
@@ -387,6 +421,12 @@ int spll_read_ptracker(int channel, int32_t *phase_ps, int *enabled)
if
(
phase
<
0
)
phase
+=
(
1
<<
HPLL_N
);
else
if
(
phase
>=
(
1
<<
HPLL_N
))
phase
-=
(
1
<<
HPLL_N
);
if
(
DIVIDE_DMTD_CLOCKS_BY_2
)
{
phase
<<=
1
;
phase
&=
(
1
<<
HPLL_N
)
-
1
;
}
*
phase_ps
=
to_picos
(
phase
);
if
(
enabled
)
*
enabled
=
ptracker_mask
&
(
1
<<
st
->
id_b
)
?
1
:
0
;
...
...
@@ -433,8 +473,108 @@ void spll_enable_ptracker(int ref_channel, int enable)
}
}
int
spll_get_delock_count
()
{
return
softpll
.
delock_count
;
}
int
spll_update_aux_clocks
()
{
uint32_t
occr_aux_en
=
SPLL_OCCR_OUT_EN_R
(
SPLL
->
OCCR
);
int
i
;
for
(
i
=
0
;
i
<
n_chan_out
-
1
;
i
++
)
{
struct
spll_aux_state
*
s
=
&
softpll
.
aux_fsm
[
i
];
if
((
!
(
occr_aux_en
&
(
1
<<
(
i
+
1
)))
&&
s
->
state
!=
AUX_DISABLED
))
{
TRACE
(
"[aux] disabled channel %d
\n
"
,
i
);
spll_stop_channel
(
i
+
1
);
SPLL
->
OCCR
&=
~
(
SPLL_OCCR_OUT_LOCK_W
((
1
<<
(
i
+
1
))));
s
->
state
=
AUX_DISABLED
;
}
else
switch
(
s
->
state
)
{
case
AUX_DISABLED
:
if
(
occr_aux_en
&
(
1
<<
(
i
+
1
))
&&
softpll
.
mpll
.
ld
.
locked
)
{
TRACE
(
"[aux] enabled channel %d
\n
"
,
i
);
s
->
state
=
AUX_LOCK_PLL
;
spll_start_channel
(
i
+
1
);
}
break
;
case
AUX_LOCK_PLL
:
if
(
softpll
.
aux
[
i
].
ld
.
locked
)
{
TRACE
(
"[aux] channel %d locked [aligning @ %d ps]
\n
"
,
i
,
softpll
.
mpll_shift_ps
);
set_phase_shift
(
i
+
1
,
softpll
.
mpll_shift_ps
);
s
->
state
=
AUX_ALIGN_PHASE
;
}
break
;
case
AUX_ALIGN_PHASE
:
if
(
!
mpll_shifter_busy
(
&
softpll
.
aux
[
i
]))
{
TRACE
(
"[aux] channel %d phase aligned
\n
"
,
i
);
SPLL
->
OCCR
|=
SPLL_OCCR_OUT_LOCK_W
((
1
<<
(
i
+
1
)));
s
->
state
=
AUX_READY
;
}
break
;
case
AUX_READY
:
if
(
!
softpll
.
mpll
.
ld
.
locked
||
!
softpll
.
aux
[
i
].
ld
.
locked
)
{
TRACE
(
"[aux] aux channel or mpll lost lock
\n
"
);
SPLL
->
OCCR
&=
~
(
SPLL_OCCR_OUT_LOCK_W
((
1
<<
(
i
+
1
))));
s
->
state
=
AUX_DISABLED
;
}
break
;
}
}
}
int
spll_get_aux_status
(
int
channel
)
{
int
rval
=
0
;
if
(
softpll
.
aux_fsm
[
channel
].
state
!=
AUX_DISABLED
)
rval
|=
SPLL_AUX_ENABLED
;
if
(
softpll
.
aux_fsm
[
channel
].
state
==
AUX_READY
)
rval
|=
SPLL_AUX_LOCKED
;
return
rval
;
}
int
spll_get_dac
(
int
index
)
{
if
(
index
<
0
)
return
softpll
.
helper
.
pi
.
y
;
else
if
(
index
==
0
)
return
softpll
.
mpll
.
pi
.
y
;
else
if
(
index
>
0
)
return
softpll
.
aux
[
index
-
1
].
pi
.
y
;
return
0
;
}
void
spll_set_dac
(
int
index
,
int
value
)
{
if
(
index
<
0
)
{
softpll
.
helper
.
pi
.
y
=
value
;
SPLL
->
DAC_HPLL
=
value
;
}
else
{
SPLL
->
DAC_MAIN
=
SPLL_DAC_MAIN_DAC_SEL_W
(
index
)
|
(
value
&
0xffff
);
if
(
index
==
0
)
softpll
.
mpll
.
pi
.
y
=
value
;
else
if
(
index
>
0
)
softpll
.
aux
[
index
-
1
].
pi
.
y
=
value
;
}
}
softpll/softpll_ng.h
View file @
30c366fe
...
...
@@ -10,6 +10,10 @@
#define SPLL_MODE_SLAVE 3
#define SPLL_MODE_DISABLED 4
#define SPLL_ALL_CHANNELS 0xffff
#define SPLL_AUX_ENABLED (1<<0)
#define SPLL_AUX_LOCKED (1<<1)
void
spll_init
(
int
mode
,
int
slave_ref_channel
,
int
align_pps
);
void
spll_shutdown
();
...
...
@@ -22,6 +26,12 @@ int spll_read_ptracker(int channel, int32_t *phase_ps, int *enabled);
void
spll_get_num_channels
(
int
*
n_ref
,
int
*
n_out
);
int
spll_shifter_busy
(
int
channel
);
int
spll_get_delock_count
();
int
spll_update_aux_clocks
();
int
spll_get_aux_status
(
int
channel
);
void
spll_set_dac
(
int
index
,
int
value
);
int
spll_get_dac
(
int
index
);
#endif
softpll/spll_common.h
View file @
30c366fe
...
...
@@ -166,7 +166,7 @@ static void spll_enable_tagger(int channel, int enable)
SPLL
->
RCER
&=
~
(
1
<<
channel
);
}
TRACE
(
"%s: ch %d, OCER 0x%x, RCER 0x%x
\n
"
,
__FUNCTION__
,
channel
,
SPLL
->
OCER
,
SPLL
->
RCER
);
//
TRACE("%s: ch %d, OCER 0x%x, RCER 0x%x\n", __FUNCTION__, channel, SPLL->OCER, SPLL->RCER);
}
static
void
spll_resync_dmtd_counter
(
int
channel
)
...
...
softpll/spll_defs.h
View file @
30c366fe
...
...
@@ -15,6 +15,11 @@ WARNING: These parameters must be in sync with the generics of the HDL instantia
/* Reference clock period, in picoseconds */
#define CLOCK_PERIOD_PICOSECONDS 16000
/* optional DMTD clock division to improve FPGA timing closure by avoiding
clock nets directly driving FD inputs. Must be consistent with the
g_divide_inputs_by_2 generic. */
#define DIVIDE_DMTD_CLOCKS_BY_2 0
/* Number of bits in phase tags generated by the DMTDs. Used to sign-extend the tags.
Corresponding VHDL generic: g_tag_bits. */
#define TAG_BITS 22
...
...
softpll/spll_main.h
View file @
30c366fe
...
...
@@ -6,7 +6,6 @@
#define MATCH_WAIT_OUT 2
#undef WITH_SEQUENCING
//#define WITH_SEQUENCING
/* State of the Main PLL */
struct
spll_main_state
{
...
...
@@ -16,7 +15,6 @@ struct spll_main_state {
spll_lock_det_t
ld
;
int
adder_ref
,
adder_out
,
tag_ref
,
tag_out
,
tag_ref_d
,
tag_out_d
;
int
err_d0
,
err_d1
;
// tag sequencing stuff
uint32_t
seq_ref
,
seq_out
;
...
...
@@ -28,6 +26,7 @@ struct spll_main_state {
int
id_ref
,
id_out
;
/* IDs of the reference and the output channel */
int
sample_n
;
int
delock_count
;
int
dac_index
;
};
...
...
@@ -48,6 +47,7 @@ static void mpll_init(struct spll_main_state *s, int id_ref, int id_out)
s
->
ld
.
delock_samples
=
100
;
s
->
id_ref
=
id_ref
;
s
->
id_out
=
id_out
;
s
->
dac_index
=
id_out
-
n_chan_ref
;
pi_init
(
&
s
->
pi
);
ld_init
(
&
s
->
ld
);
...
...
@@ -63,7 +63,7 @@ static void mpll_start(struct spll_main_state *s)
s
->
seq_ref
=
0
;
s
->
seq_out
=
0
;
s
->
match_state
=
MATCH_NEXT_TAG
;
s
->
err_d0
=
s
->
err_d1
=
0
;
s
->
phase_shift_target
=
0
;
s
->
phase_shift_current
=
0
;
s
->
sample_n
=
0
;
...
...
@@ -155,15 +155,6 @@ static int mpll_update(struct spll_main_state *s, int tag, int source)
#ifndef WITH_SEQUENCING
/* if(s->err_d0 - s->err_d1 > -(1<<HPLL_N)/2 && err - s->err_d0 < -(1<<HPLL_N)/2 )
err += (1<<HPLL_N);
if(s->err_d0 - s->err_d1 < (1<<HPLL_N)/2 && err - s->err_d0 > (1<<HPLL_N)/2 )
err -= (1<<HPLL_N);
s->err_d1 = s->err_d0;
s->err_d0 = err;*/
/* Hack: the PLL is locked, so the tags are close to each other. But when we start phase shifting, after reaching
full clock period, one of the reference tags will flip before the other, causing a suddent 2**HPLL_N jump in the error.
So, once the PLL is locked, we just mask out everything above 2**HPLL_N.
...
...
@@ -180,13 +171,13 @@ static int mpll_update(struct spll_main_state *s, int tag, int source)
#endif
y
=
pi_update
(
&
s
->
pi
,
err
);
SPLL
->
DAC_MAIN
=
SPLL_DAC_MAIN_VALUE_W
(
y
)
|
SPLL_DAC_MAIN_DAC_SEL_W
(
s
->
id_out
);
SPLL
->
DAC_MAIN
=
SPLL_DAC_MAIN_VALUE_W
(
y
)
|
SPLL_DAC_MAIN_DAC_SEL_W
(
s
->
dac_index
);
spll_debug
(
DBG_MAIN
|
DBG_REF
,
s
->
tag_ref
+
s
->
adder_ref
,
0
);
spll_debug
(
DBG_MAIN
|
DBG_TAG
,
s
->
tag_out
+
s
->
adder_out
,
0
);
spll_debug
(
DBG_MAIN
|
DBG_ERR
,
err
,
0
);
spll_debug
(
DBG_MAIN
|
DBG_SAMPLE_ID
,
s
->
sample_n
++
,
1
);
//
spll_debug(DBG_MAIN | DBG_Y, y, 1);
spll_debug
(
DBG_MAIN
|
DBG_SAMPLE_ID
,
s
->
sample_n
++
,
0
);
spll_debug
(
DBG_MAIN
|
DBG_Y
,
y
,
1
);
s
->
tag_out
=
-
1
;
s
->
tag_ref
=
-
1
;
...
...
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