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
cdb79426
Commit
cdb79426
authored
Apr 18, 2012
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rt/dev/softpll_ng: non-blocking API
parent
ce16467f
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
186 additions
and
63 deletions
+186
-63
softpll_ng.c
rt/dev/softpll_ng.c
+146
-47
softpll_ng.h
rt/dev/softpll_ng.h
+14
-4
spll_defs.h
rt/dev/spll_defs.h
+9
-3
spll_external.h
rt/dev/spll_external.h
+7
-7
spll_main.h
rt/dev/spll_main.h
+5
-0
spll_ptracker.h
rt/dev/spll_ptracker.h
+5
-2
No files found.
rt/dev/softpll_ng.c
View file @
cdb79426
...
...
@@ -43,6 +43,7 @@ struct softpll_state {
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_ptracker_state
ptrackers
[
MAX_PTRACKERS
];
};
...
...
@@ -53,6 +54,7 @@ void _irq_entry()
{
volatile
uint32_t
trr
;
int
src
=
-
1
,
tag
,
i
;
struct
softpll_state
*
s
=
(
struct
softpll_state
*
)
&
softpll
;
/* check if there are more tags in the FIFO */
if
(
!
(
SPLL
->
CSR
&
SPLL_TRR_CSR_EMPTY
))
...
...
@@ -66,67 +68,67 @@ void _irq_entry()
{
case
SEQ_DISABLED
:
break
;
case
SEQ_START_EXT
:
external_update
((
struct
spll_external_state
*
)
&
s
oftpll
.
ext
,
tag
,
src
);
external_start
((
struct
spll_external_state
*
)
&
softpll
.
ext
);
case
SEQ_START_EXT
:
external_update
((
struct
spll_external_state
*
)
&
s
->
ext
,
tag
,
src
);
external_start
((
struct
spll_external_state
*
)
&
s
->
ext
);
softpll
.
seq_state
=
SEQ_WAIT_EXT
;
break
;
case
SEQ_WAIT_EXT
:
if
(
external_locked
((
struct
spll_external_state
*
)
&
softpll
.
ext
))
if
(
external_locked
((
struct
spll_external_state
*
)
&
s
->
ext
))
softpll
.
seq_state
=
SEQ_START_HELPER
;
break
;
case
SEQ_START_HELPER
:
softpll
.
helper_locked
=
0
;
helper_start
((
struct
spll_helper_state
*
)
&
softpll
.
helper
);
helper_start
((
struct
spll_helper_state
*
)
&
s
->
helper
);
softpll
.
seq_state
=
SEQ_WAIT_HELPER
;
break
;
case
SEQ_WAIT_HELPER
:
if
(
softpll
.
helper
.
ld
.
locked
&&
!
softpll
.
helper_locked
)
{
softpll
.
helper_locked
=
1
;
if
(
softpll
.
mode
==
MODE_SLAVE
)
if
(
softpll
.
mode
==
SPLL_
MODE_SLAVE
)
softpll
.
seq_state
=
SEQ_START_MAIN
;
else
{
//
for(i=0;i<n_chan_ref; i++)
// ptracker_start((struct spll_ptracker_state *) &softpll.ptrackers[i]);
for
(
i
=
0
;
i
<
n_chan_ref
;
i
++
)
ptracker_start
((
struct
spll_ptracker_state
*
)
&
s
->
ptrackers
[
i
]);
softpll
.
seq_state
=
SEQ_READY
;
}
}
break
;
case
SEQ_START_MAIN
:
mpll_start
((
struct
spll_main_state
*
)
&
s
oftpll
.
mpll
);
case
SEQ_START_MAIN
:
mpll_start
((
struct
spll_main_state
*
)
&
s
->
mpll
);
softpll
.
seq_state
=
SEQ_WAIT_MAIN
;
break
;
case
SEQ_WAIT_MAIN
:
case
SEQ_WAIT_MAIN
:
if
(
softpll
.
mpll
.
ld
.
locked
)
{
softpll
.
seq_state
=
SEQ_READY
;
//
for(i=0;i<n_chan_ref; i++)
// ptracker_start((struct spll_ptracker_state *) &softpll.ptrackers[i]);
for
(
i
=
0
;
i
<
n_chan_ref
;
i
++
)
ptracker_start
((
struct
spll_ptracker_state
*
)
&
s
->
ptrackers
[
i
]);
}
break
;
case
SEQ_READY
:
if
(
!
softpll
.
helper
.
ld
.
locked
)
{
{
// SPLL->OCER = 0;
// SPLL->RCER = 0;
//softpll.seq_state = SEQ_START_HELPER;
}
else
if
(
softpll
.
mode
==
MODE_GRAND_MASTER
&&
!
external_locked
((
struct
spll_external_state
*
)
&
softpll
.
ext
))
}
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
;
}
else
if
(
softpll
.
mode
==
MODE_SLAVE
&&
!
softpll
.
mpll
.
ld
.
locked
)
}
else
if
(
softpll
.
mode
==
SPLL_
MODE_SLAVE
&&
!
softpll
.
mpll
.
ld
.
locked
)
{
softpll
.
seq_state
=
SEQ_START_MAIN
;
};
...
...
@@ -137,30 +139,33 @@ void _irq_entry()
switch
(
softpll
.
seq_state
)
{
case
SEQ_WAIT_EXT
:
external_update
((
struct
spll_external_state
*
)
&
s
oftpll
.
ext
,
tag
,
src
);
external_update
((
struct
spll_external_state
*
)
&
s
->
ext
,
tag
,
src
);
break
;
case
SEQ_WAIT_HELPER
:
if
(
softpll
.
mode
==
MODE_GRAND_MASTER
)
external_update
((
struct
spll_external_state
*
)
&
s
oftpll
.
ext
,
tag
,
src
);
helper_update
((
struct
spll_helper_state
*
)
&
softpll
.
helper
,
tag
,
src
);
if
(
softpll
.
mode
==
SPLL_
MODE_GRAND_MASTER
)
external_update
((
struct
spll_external_state
*
)
&
s
->
ext
,
tag
,
src
);
helper_update
((
struct
spll_helper_state
*
)
&
s
->
helper
,
tag
,
src
);
break
;
case
SEQ_WAIT_MAIN
:
case
SEQ_READY
:
helper_update
((
struct
spll_helper_state
*
)
&
softpll
.
helper
,
tag
,
src
);
helper_update
((
struct
spll_helper_state
*
)
&
s
->
helper
,
tag
,
src
);
if
(
softpll
.
mode
==
MODE_GRAND_MASTER
)
external_update
((
struct
spll_external_state
*
)
&
softpll
.
ext
,
tag
,
src
);
if
(
softpll
.
mode
==
MODE_SLAVE
)
mpll_update
((
struct
spll_main_state
*
)
&
softpll
.
mpll
,
tag
,
src
);
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_ref
;
i
++
)
ptracker_update
((
struct
spll_ptracker_state
*
)
&
s
->
ptrackers
[
i
],
tag
,
src
);
break
;
}
}
...
...
@@ -172,18 +177,20 @@ void spll_init(int mode, int slave_ref_channel, int align_pps)
{
char
mode_str
[
20
];
volatile
int
dummy
;
int
i
;
disable_irq
();
n_chan_ref
=
SPLL_CSR_N_REF_R
(
SPLL
->
CSR
);
n_chan_out
=
SPLL_CSR_N_OUT_R
(
SPLL
->
CSR
);
softpll
.
helper_locked
=
0
;
softpll
.
mode
=
mode
;
SPLL
->
DAC_HPLL
=
0
;
SPLL
->
DAC_MAIN
=
0
;
timer_delay
(
100000
);
//timer_delay(100000);
SPLL
->
CSR
=
0
;
SPLL
->
OCER
=
0
;
SPLL
->
RCER
=
0
;
...
...
@@ -196,34 +203,41 @@ void spll_init(int mode, int slave_ref_channel, int align_pps)
switch
(
mode
)
{
case
MODE_DISABLED
:
case
SPLL_
MODE_DISABLED
:
strcpy
(
mode_str
,
"Disabled"
);
softpll
.
seq_state
=
SEQ_DISABLED
;
break
;
case
MODE_GRAND_MASTER
:
case
SPLL_
MODE_GRAND_MASTER
:
strcpy
(
mode_str
,
"Grand Master"
);
softpll
.
seq_state
=
SEQ_START_EXT
;
external_init
(
&
softpll
.
ext
,
n_chan_ref
+
n_chan_out
,
align_pps
);
helper_init
(
&
softpll
.
helper
,
n_chan_ref
);
helper_init
(
&
softpll
.
helper
,
n_chan_ref
);
break
;
case
MODE_FREE_RUNNING_MASTER
:
case
SPLL_
MODE_FREE_RUNNING_MASTER
:
strcpy
(
mode_str
,
"Free-running Master"
);
softpll
.
seq_state
=
SEQ_START_HELPER
;
helper_init
(
&
softpll
.
helper
,
n_chan_ref
);
helper_init
(
&
softpll
.
helper
,
n_chan_ref
);
break
;
case
MODE_SLAVE
:
case
SPLL_
MODE_SLAVE
:
strcpy
(
mode_str
,
"Slave"
);
softpll
.
seq_state
=
SEQ_START_HELPER
;
helper_init
(
&
softpll
.
helper
,
slave_ref_channel
);
helper_init
(
&
softpll
.
helper
,
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
);
break
;
}
}
for
(
i
=
0
;
i
<
n_chan_ref
;
i
++
)
ptracker_init
(
&
softpll
.
ptrackers
[
i
],
i
,
n_chan_ref
,
PTRACKER_AVERAGE_SAMPLES
);
TRACE
(
"SPLL_Init: running as %s, %d ref channels, %d out channels
\n
"
,
mode_str
,
n_chan_ref
,
n_chan_out
);
...
...
@@ -237,10 +251,95 @@ void spll_init(int mode, int slave_ref_channel, int align_pps)
enable_irq
();
for
(;;)
mprintf
(
"irqcount %d Seqstate %d TmrTics %d m %d ast %d
\n
"
,
irq_count
,
softpll
.
seq_state
,
timer_get_tics
(),
softpll
.
mode
,
softpll
.
ext
.
realign_state
);
/* for(;;)
{
mprintf("irqcount %d Seqstate %d TmrTics %d m %d ast %d ", irq_count, softpll.seq_state, timer_get_tics(), softpll.mode, softpll.ext.realign_state);
for(i=0;i<n_chan_ref;i++)
{
int ph, ready;
ready = spll_read_ptracker(i, &ph);
mprintf("rp%d[%d]: %dps ", i, ready, ph);
}
mprintf("\n");
}*/
}
void
spll_shutdown
()
{
SPLL
->
OCER
=
0
;
SPLL
->
RCER
=
0
;
SPLL
->
ECCR
=
0
;
SPLL
->
EIC_IDR
=
1
;
}
void
spll_start_channel
(
int
channel
)
{
if
(
softpll
.
seq_state
!=
SEQ_READY
||
!
channel
)
return
;
mpll_start
(
&
softpll
.
aux
[
channel
-
1
]);
}
void
spll_stop_channel
(
int
channel
)
{
if
(
!
channel
)
return
-
1
;
mpll_stop
(
&
softpll
.
aux
[
channel
-
1
]);
}
int
spll_check_lock
()
int
spll_check_lock
(
int
channel
)
{
return
softpll
.
seq_state
==
SEQ_READY
;
if
(
!
channel
)
return
(
softpll
.
seq_state
==
SEQ_READY
);
else
return
(
softpll
.
seq_state
==
SEQ_READY
)
&&
softpll
.
aux
[
channel
-
1
].
ld
.
locked
;
}
static
int32_t
from_picos
(
int32_t
ps
)
{
return
(
int32_t
)
((
int64_t
)
ps
*
(
int64_t
)(
1
<<
HPLL_N
)
/
(
int64_t
)
CLOCK_PERIOD_PICOSECONDS
);
}
static
int32_t
to_picos
(
int32_t
units
)
{
return
(
int32_t
)
(((
int64_t
)
units
*
(
int64_t
)
CLOCK_PERIOD_PICOSECONDS
)
>>
HPLL_N
);
}
/* Channel 0 = local PLL reference, 1...N = aux oscillators */
void
spll_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
));
}
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
spll_read_ptracker
(
int
channel
,
int32_t
*
phase_ps
)
{
volatile
struct
spll_ptracker_state
*
st
=
&
softpll
.
ptrackers
[
channel
];
*
phase_ps
=
to_picos
(
st
->
phase_val
);
return
st
->
ready
;
}
void
spll_get_num_channels
(
int
*
n_ref
,
int
*
n_out
)
{
if
(
n_ref
)
*
n_ref
=
n_chan_ref
;
if
(
n_out
)
*
n_out
=
n_chan_out
;
}
void
spll_show_stats
()
{
if
(
softpll
.
mode
>
0
)
TRACE
(
"Irq_count %d Sequencer_state %d mode %d Alignment_state %d HL%d EL%d ML%d HY=%d MY=%d
\n
"
,
irq_count
,
softpll
.
seq_state
,
softpll
.
mode
,
softpll
.
ext
.
realign_state
,
softpll
.
helper
.
ld
.
locked
,
softpll
.
ext
.
ld
.
locked
,
softpll
.
mpll
.
ld
.
locked
,
softpll
.
helper
.
pi
.
y
,
softpll
.
mpll
.
pi
.
y
);
}
rt/dev/softpll_ng.h
View file @
cdb79426
...
...
@@ -5,11 +5,21 @@
#include <stdlib.h>
/* Modes */
#define MODE_GRAND_MASTER 0
#define MODE_FREE_RUNNING_MASTER 1
#define MODE_SLAVE 2
#define MODE_DISABLED 3
#define SPLL_MODE_GRAND_MASTER 1
#define SPLL_MODE_FREE_RUNNING_MASTER 2
#define SPLL_MODE_SLAVE 3
#define SPLL_MODE_DISABLED 4
void
spll_init
(
int
mode
,
int
slave_ref_channel
,
int
align_pps
);
void
spll_shutdown
();
void
spll_start_channel
(
int
channel
);
void
spll_stop_channel
(
int
channel
);
int
spll_check_lock
(
int
channel
);
void
spll_set_phase_shift
(
int
channel
,
int32_t
value_picoseconds
);
void
spll_get_phase_shift
(
int
channel
,
int32_t
*
current
,
int32_t
*
target
);
int
spll_read_ptracker
(
int
channel
,
int32_t
*
phase_ps
);
void
spll_get_num_channels
(
int
*
n_ref
,
int
*
n_out
);
#endif
rt/dev/spll_defs.h
View file @
cdb79426
...
...
@@ -12,6 +12,9 @@ WARNING: These parameters must be in sync with the generics of the HDL instantia
/* Reference clock frequency, in [Hz] */
#define CLOCK_FREQ 62500000
/* Reference clock period, in picoseconds */
#define CLOCK_PERIOD_PICOSECONDS 16000
/* 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
...
...
@@ -27,12 +30,15 @@ WARNING: These parameters must be in sync with the generics of the HDL instantia
/* Max. allowed number of reference channels. Can be used to tweak memory usage. */
#define MAX_CHAN_REF 7
/* Max. allowed number of
output
channels */
#define MAX_CHAN_
OUT
1
/* Max. allowed number of
auxillary
channels */
#define MAX_CHAN_
AUX
1
/* Max. allowed number of phase trackers */
#define MAX_PTRACKERS 6
/* Number of bits of the DAC(s) driving the oscillator(s). Must be the same for
all the outputs. */
#define DAC_BITS 16
\ No newline at end of file
#define DAC_BITS 16
/* Number of samples in a single ptracker averaging bin */
#define PTRACKER_AVERAGE_SAMPLES 512
\ No newline at end of file
rt/dev/spll_external.h
View file @
cdb79426
...
...
@@ -56,7 +56,7 @@ struct spll_external_state {
spll_lock_det_t
ld
;
};
static
void
external_init
(
struct
spll_external_state
*
s
,
int
ext_ref
,
int
realign_clocks
)
static
void
external_init
(
struct
spll_external_state
*
s
,
int
ext_ref
,
int
realign_clocks
)
{
s
->
pi
.
y_min
=
5
;
...
...
@@ -85,9 +85,9 @@ static void external_init(struct spll_external_state *s, int ext_ref, int realig
lowpass_init
(
&
s
->
lp_long
,
300
);
}
static
inline
void
realign_fsm
(
struct
spll_external_state
*
s
)
static
inline
void
realign_fsm
(
struct
spll_external_state
*
s
)
{
volatile
uint32_t
eccr
;
uint32_t
eccr
;
switch
(
s
->
realign_state
)
...
...
@@ -143,7 +143,7 @@ static inline void realign_fsm(struct spll_external_state *s)
}
}
static
int
external_update
(
struct
spll_external_state
*
s
,
int
tag
,
int
source
)
static
int
external_update
(
struct
spll_external_state
*
s
,
int
tag
,
int
source
)
{
int
err
,
y
,
y2
,
yd
,
ylt
;
...
...
@@ -195,9 +195,9 @@ static int external_update(struct spll_external_state *s, int tag, int source)
}
static
void
external_start
(
struct
spll_external_state
*
s
)
static
void
external_start
(
struct
spll_external_state
*
s
)
{
mprintf
(
"ExtStartup
\n
"
);
//
mprintf("ExtStartup\n");
SPLL
->
ECCR
=
0
;
...
...
@@ -209,7 +209,7 @@ static void external_start(struct spll_external_state *s)
spll_debug
(
DBG_EVENT
|
DBG_EXT
,
DBG_EVT_START
,
1
);
}
static
inline
int
external_locked
(
struct
spll_external_state
*
s
)
static
inline
int
external_locked
(
struct
spll_external_state
*
s
)
{
return
(
s
->
ld
.
locked
&&
(
s
->
realign_clocks
?
s
->
realign_state
==
REALIGN_DONE
:
1
));
}
\ No newline at end of file
rt/dev/spll_main.h
View file @
cdb79426
...
...
@@ -55,6 +55,11 @@ static void mpll_start(struct spll_main_state *s)
spll_debug
(
DBG_EVENT
|
DBG_MAIN
,
DBG_EVT_START
,
1
);
}
static
void
mpll_stop
(
struct
spll_main_state
*
s
)
{
spll_enable_tagger
(
s
->
id_out
,
0
);
}
static
int
mpll_update
(
struct
spll_main_state
*
s
,
int
tag
,
int
source
)
{
...
...
rt/dev/spll_ptracker.h
View file @
cdb79426
...
...
@@ -46,6 +46,8 @@ static int ptracker_update(struct spll_ptracker_state *s, int tag, int source)
{
int
delta
=
(
s
->
tag_a
-
s
->
tag_b
)
&
((
1
<<
HPLL_N
)
-
1
);
s
->
sample_n
++
;
if
(
s
->
avg_count
==
0
)
{
...
...
@@ -55,8 +57,8 @@ static int ptracker_update(struct spll_ptracker_state *s, int tag, int source)
s
->
preserve_sign
=
1
;
else
s
->
preserve_sign
=
0
;
s
->
avg_count
++
;
s
->
acc
=
delta
;
}
else
{
...
...
@@ -78,6 +80,7 @@ static int ptracker_update(struct spll_ptracker_state *s, int tag, int source)
}
}
s
->
tag_b
=
s
->
tag_a
=
-
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