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
c0ffd31c
Commit
c0ffd31c
authored
Aug 20, 2019
by
Grzegorz Daniluk
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'greg-wrs-low-jitter' into proposed_master
parents
780ed522
de1a914a
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
291 additions
and
101 deletions
+291
-101
ad9516.c
dev/ad9516.c
+101
-72
ad9516_config.h
dev/ad9516_config.h
+82
-1
board-wrs.h
include/board-wrs.h
+1
-0
gpio-wrs.h
include/gpio-wrs.h
+8
-1
wrc.h
include/wrc.h
+2
-1
softpll_ng.c
softpll/softpll_ng.c
+10
-10
softpll_ng.h
softpll/softpll_ng.h
+2
-0
spll_external.c
softpll/spll_external.c
+49
-11
spll_helper.c
softpll/spll_helper.c
+9
-1
spll_main.c
softpll/spll_main.c
+15
-2
spll_ptracker.c
softpll/spll_ptracker.c
+4
-1
wrs_main.c
wrs_main.c
+8
-1
No files found.
dev/ad9516.c
View file @
c0ffd31c
...
...
@@ -69,23 +69,15 @@ struct ad9516_reg {
#define SPI_CTRL_GO_BSY (1<<8)
#define SPI_CTRL_CHAR_LEN(x) ((x) & 0x7f)
#define GPIO_PLL_RESET_N 1
#define GPIO_SYS_CLK_SEL 0
#define GPIO_PERIPH_RESET_N 3
#define CS_PLL 0
/* AD9516 on SPI CS0 */
static
void
*
oc_spi_base
;
static
int
oc_spi_init
(
void
*
base_addr
)
{
oc_spi_base
=
base_addr
;
writel
(
100
,
oc_spi_base
+
SPI_REG_DIVIDER
);
writel
(
100
,
base_addr
+
SPI_REG_DIVIDER
);
return
0
;
}
static
int
oc_spi_txrx
(
int
ss
,
int
nbits
,
uint32_t
in
,
uint32_t
*
out
)
static
int
oc_spi_txrx
(
void
*
base
,
int
ss
,
int
nbits
,
uint32_t
in
,
uint32_t
*
out
)
{
uint32_t
rval
;
...
...
@@ -94,17 +86,17 @@ static int oc_spi_txrx(int ss, int nbits, uint32_t in, uint32_t *out)
writel
(
SPI_CTRL_ASS
|
SPI_CTRL_CHAR_LEN
(
nbits
)
|
SPI_CTRL_TXNEG
,
oc_spi_
base
+
SPI_REG_CTRL
);
base
+
SPI_REG_CTRL
);
writel
(
in
,
oc_spi_
base
+
SPI_REG_TX0
);
writel
((
1
<<
ss
),
oc_spi_
base
+
SPI_REG_SS
);
writel
(
in
,
base
+
SPI_REG_TX0
);
writel
((
1
<<
ss
),
base
+
SPI_REG_SS
);
writel
(
SPI_CTRL_ASS
|
SPI_CTRL_CHAR_LEN
(
nbits
)
|
SPI_CTRL_TXNEG
|
SPI_CTRL_GO_BSY
,
oc_spi_
base
+
SPI_REG_CTRL
);
base
+
SPI_REG_CTRL
);
while
(
readl
(
oc_spi_
base
+
SPI_REG_CTRL
)
&
SPI_CTRL_GO_BSY
)
while
(
readl
(
base
+
SPI_REG_CTRL
)
&
SPI_CTRL_GO_BSY
)
;
*
out
=
readl
(
oc_spi_
base
+
SPI_REG_RX0
);
*
out
=
readl
(
base
+
SPI_REG_RX0
);
return
0
;
}
...
...
@@ -113,39 +105,39 @@ static int oc_spi_txrx(int ss, int nbits, uint32_t in, uint32_t *out)
* "reg" is 12 bits, "val" is 8 bits, but both are better used as int
*/
static
void
ad9516_write_reg
(
int
reg
,
int
val
)
static
void
ad9516_write_reg
(
void
*
base
,
int
reg
,
int
val
)
{
oc_spi_txrx
(
CS_PLL
,
24
,
(
reg
<<
8
)
|
val
,
NULL
);
oc_spi_txrx
(
base
,
CS_PLL
,
24
,
(
reg
<<
8
)
|
val
,
NULL
);
}
static
int
ad9516_read_reg
(
int
reg
)
static
int
ad9516_read_reg
(
void
*
base
,
int
reg
)
{
uint32_t
rval
;
oc_spi_txrx
(
CS_PLL
,
24
,
(
reg
<<
8
)
|
(
1
<<
23
),
&
rval
);
oc_spi_txrx
(
base
,
CS_PLL
,
24
,
(
reg
<<
8
)
|
(
1
<<
23
),
&
rval
);
return
rval
&
0xff
;
}
static
void
ad9516_load_regset
(
const
struct
ad9516_reg
*
regs
,
int
n_regs
,
int
commit
)
static
void
ad9516_load_regset
(
void
*
base
,
const
struct
ad9516_reg
*
regs
,
int
n_regs
,
int
commit
)
{
int
i
;
for
(
i
=
0
;
i
<
n_regs
;
i
++
)
ad9516_write_reg
(
regs
[
i
].
reg
,
regs
[
i
].
val
);
ad9516_write_reg
(
base
,
regs
[
i
].
reg
,
regs
[
i
].
val
);
if
(
commit
)
ad9516_write_reg
(
0x232
,
1
);
ad9516_write_reg
(
base
,
0x232
,
1
);
}
static
void
ad9516_wait_lock
(
void
)
static
void
ad9516_wait_lock
(
void
*
base
)
{
while
((
ad9516_read_reg
(
0x1f
)
&
1
)
==
0
);
while
((
ad9516_read_reg
(
base
,
0x1f
)
&
1
)
==
0
);
}
#define SECONDARY_DIVIDER 0x100
static
int
ad9516_set_output_divider
(
int
output
,
int
ratio
,
int
phase_offset
)
static
int
ad9516_set_output_divider
(
void
*
spi_base
,
int
output
,
int
ratio
,
int
phase_offset
)
{
uint8_t
lcycles
=
(
ratio
/
2
)
-
1
;
uint8_t
hcycles
=
(
ratio
-
(
ratio
/
2
))
-
1
;
...
...
@@ -158,12 +150,12 @@ static int ad9516_set_output_divider(int output, int ratio, int phase_offset)
if
(
ratio
==
1
)
/* bypass the divider */
{
uint8_t
div_ctl
=
ad9516_read_reg
(
base
+
1
);
ad9516_write_reg
(
base
+
1
,
div_ctl
|
(
1
<<
7
)
|
(
phase_offset
&
0xf
));
uint8_t
div_ctl
=
ad9516_read_reg
(
spi_base
,
base
+
1
);
ad9516_write_reg
(
spi_base
,
base
+
1
,
div_ctl
|
(
1
<<
7
)
|
(
phase_offset
&
0xf
));
}
else
{
uint8_t
div_ctl
=
ad9516_read_reg
(
base
+
1
);
ad9516_write_reg
(
base
+
1
,
(
div_ctl
&
(
~
(
1
<<
7
)))
|
(
phase_offset
&
0xf
));
/* disable bypass bit */
ad9516_write_reg
(
base
,
(
lcycles
<<
4
)
|
hcycles
);
uint8_t
div_ctl
=
ad9516_read_reg
(
spi_base
,
base
+
1
);
ad9516_write_reg
(
spi_base
,
base
+
1
,
(
div_ctl
&
(
~
(
1
<<
7
)))
|
(
phase_offset
&
0xf
));
/* disable bypass bit */
ad9516_write_reg
(
spi_base
,
base
,
(
lcycles
<<
4
)
|
hcycles
);
}
}
else
{
/* LVDS/CMOS outputs */
...
...
@@ -174,16 +166,16 @@ static int ad9516_set_output_divider(int output, int ratio, int phase_offset)
if
(
!
secondary
)
{
if
(
ratio
==
1
)
/* bypass the divider 1 */
ad9516_write_reg
(
base
+
3
,
ad9516_read_reg
(
base
+
3
)
|
0x10
);
ad9516_write_reg
(
spi_base
,
base
+
3
,
ad9516_read_reg
(
spi_base
,
base
+
3
)
|
0x10
);
else
{
ad9516_write_reg
(
base
,
(
lcycles
<<
4
)
|
hcycles
);
ad9516_write_reg
(
base
+
1
,
phase_offset
&
0xf
);
ad9516_write_reg
(
spi_base
,
base
,
(
lcycles
<<
4
)
|
hcycles
);
ad9516_write_reg
(
spi_base
,
base
+
1
,
phase_offset
&
0xf
);
}
}
else
{
if
(
ratio
==
1
)
/* bypass the divider 2 */
ad9516_write_reg
(
base
+
3
,
ad9516_read_reg
(
base
+
3
)
|
0x20
);
ad9516_write_reg
(
spi_base
,
base
+
3
,
ad9516_read_reg
(
spi_base
,
base
+
3
)
|
0x20
);
else
{
ad9516_write_reg
(
base
+
2
,
(
lcycles
<<
4
)
|
hcycles
);
ad9516_write_reg
(
spi_base
,
base
+
2
,
(
lcycles
<<
4
)
|
hcycles
);
// ad9516_write_reg(base + 1, phase_offset & 0xf);
}
...
...
@@ -191,40 +183,46 @@ static int ad9516_set_output_divider(int output, int ratio, int phase_offset)
}
/* update */
ad9516_write_reg
(
0x232
,
0x0
);
ad9516_write_reg
(
0x232
,
0x1
);
ad9516_write_reg
(
0x232
,
0x0
);
ad9516_write_reg
(
spi_base
,
0x232
,
0x0
);
ad9516_write_reg
(
spi_base
,
0x232
,
0x1
);
ad9516_write_reg
(
spi_base
,
0x232
,
0x0
);
return
0
;
}
static
int
ad9516_set_vco_divider
(
int
ratio
)
/* Sets the VCO divider (2..6) or 0 to enable static output */
static
int
ad9516_set_vco_divider
(
void
*
spi_base
,
int
ratio
)
/* Sets the VCO divider (2..6) or 0 to enable static output */
{
if
(
ratio
==
0
)
ad9516_write_reg
(
0x1e0
,
0x5
);
/* static mode */
ad9516_write_reg
(
spi_base
,
0x1e0
,
0x5
);
/* static mode */
else
ad9516_write_reg
(
0x1e0
,
(
ratio
-
2
));
ad9516_write_reg
(
0x232
,
0x1
);
ad9516_write_reg
(
spi_base
,
0x1e0
,
(
ratio
-
2
));
ad9516_write_reg
(
spi_base
,
0x232
,
0x1
);
ad9516_write_reg
(
spi_base
,
0x232
,
0x0
);
return
0
;
}
static
void
ad9516_sync_outputs
(
void
)
static
void
ad9516_sync_outputs
(
void
*
spi_base
)
{
/* VCO divider: static mode */
ad9516_write_reg
(
0x1E0
,
0x7
);
ad9516_write_reg
(
0x232
,
0x1
);
ad9516_write_reg
(
spi_base
,
0x1E0
,
0x7
);
ad9516_write_reg
(
spi_base
,
0x232
,
0x1
);
/* Sync the outputs when they're inactive to avoid +-1 cycle uncertainity */
ad9516_write_reg
(
0x230
,
1
);
ad9516_write_reg
(
0x232
,
1
);
ad9516_write_reg
(
0x230
,
0
);
ad9516_write_reg
(
0x232
,
1
);
ad9516_write_reg
(
spi_base
,
0x230
,
1
);
ad9516_write_reg
(
spi_base
,
0x232
,
1
);
ad9516_write_reg
(
spi_base
,
0x230
,
0
);
ad9516_write_reg
(
spi_base
,
0x232
,
1
);
ad9516_write_reg
(
spi_base
,
0x232
,
0x0
);
}
int
ad9516_init
(
int
scb_version
)
int
ad9516_init
(
int
scb_version
,
int
ljd_present
)
{
pp_printf
(
"Initializing AD9516 PLL...
\n
"
);
oc_spi_init
((
void
*
)
BASE_SPI
);
void
*
spi_base
=
(
void
*
)
BASE_SPI
;
gpio_out
(
GPIO_SYS_CLK_SEL
,
0
);
/* switch to the standby reference clock, since the PLL is off after reset */
...
...
@@ -235,30 +233,34 @@ int ad9516_init(int scb_version)
timer_delay
(
10
);
/* Use unidirectional SPI mode */
ad9516_write_reg
(
0x000
,
0x99
);
ad9516_write_reg
(
spi_base
,
0x000
,
0x99
);
/* Check the presence of the chip */
if
(
ad9516_read_reg
(
0x3
)
!=
0xc3
)
{
if
(
ad9516_read_reg
(
spi_base
,
0x3
)
!=
0xc3
)
{
pp_printf
(
"Error: AD9516 PLL not responding.
\n
"
);
return
-
1
;
}
if
(
scb_version
>=
34
)
//New SCB v3.4. 10MHz Output.
ad9516_load_regset
(
ad9516_base_config_34
,
ARRAY_SIZE
(
ad9516_base_config_34
),
0
);
ad9516_load_regset
(
spi_base
,
ad9516_base_config_34
,
ARRAY_SIZE
(
ad9516_base_config_34
),
0
);
else
//Old one
ad9516_load_regset
(
ad9516_base_config_33
,
ARRAY_SIZE
(
ad9516_base_config_33
),
0
);
ad9516_load_regset
(
spi_base
,
ad9516_base_config_33
,
ARRAY_SIZE
(
ad9516_base_config_33
),
0
);
ad9516_load_regset
(
ad9516_ref_tcxo
,
ARRAY_SIZE
(
ad9516_ref_tcxo
),
1
);
ad9516_wait_lock
();
/* Set R divider value depending on Low-Jitter Daughterboard presence */
if
(
ljd_present
)
ad9516_load_regset
(
spi_base
,
ad9516_ref_ljd
,
ARRAY_SIZE
(
ad9516_ref_tcxo
),
1
);
else
ad9516_load_regset
(
spi_base
,
ad9516_ref_tcxo
,
ARRAY_SIZE
(
ad9516_ref_tcxo
),
1
);
ad9516_wait_lock
(
spi_base
);
ad9516_sync_outputs
();
ad9516_sync_outputs
(
spi_base
);
if
(
scb_version
>=
34
)
{
//New SCB v3.4. 10MHz Output.
ad9516_set_output_divider
(
2
,
4
,
0
);
// OUT2. 187.5 MHz. - not anymore
ad9516_set_output_divider
(
3
,
4
,
0
);
// OUT3. 187.5 MHz. - not anymore
ad9516_set_output_divider
(
spi_base
,
2
,
4
,
0
);
// OUT2. 187.5 MHz. - not anymore
ad9516_set_output_divider
(
spi_base
,
3
,
4
,
0
);
// OUT3. 187.5 MHz. - not anymore
ad9516_set_output_divider
(
4
,
1
,
0
);
// OUT4. 500 MHz.
ad9516_set_output_divider
(
spi_base
,
4
,
1
,
0
);
// OUT4. 500 MHz.
/*The following PLL outputs have been configured through the ad9516_base_config_34 register,
* so it doesn't need to replicate the configuration:
...
...
@@ -271,13 +273,13 @@ int ad9516_init(int scb_version)
}
else
{
//Old one
ad9516_set_output_divider
(
9
,
4
,
0
);
/* AUX/SWCore = 187.5 MHz */
//not needed anymore
ad9516_set_output_divider
(
7
,
8
,
0
);
/* REF = 62.5 MHz */
ad9516_set_output_divider
(
4
,
8
,
0
);
/* GTX = 62.5 MHz */
ad9516_set_output_divider
(
spi_base
,
9
,
4
,
0
);
/* AUX/SWCore = 187.5 MHz */
//not needed anymore
ad9516_set_output_divider
(
spi_base
,
7
,
8
,
0
);
/* REF = 62.5 MHz */
ad9516_set_output_divider
(
spi_base
,
4
,
8
,
0
);
/* GTX = 62.5 MHz */
}
ad9516_sync_outputs
();
ad9516_set_vco_divider
(
3
);
ad9516_sync_outputs
(
spi_base
);
ad9516_set_vco_divider
(
spi_base
,
3
);
pp_printf
(
"AD9516 locked.
\n
"
);
...
...
@@ -288,6 +290,33 @@ int ad9516_init(int scb_version)
return
0
;
}
int
ljd_ad9516_init
(
void
)
{
pp_printf
(
"Initializing Low-Jitter Daughterboard AD9516 PLL...
\n
"
);
oc_spi_init
((
void
*
)
BASE_SPI_LJD_BOARD
);
void
*
spi_base
=
(
void
*
)
BASE_SPI_LJD_BOARD
;
/* Use unidirectional SPI mode */
ad9516_write_reg
((
void
*
)
spi_base
,
0x000
,
0x99
);
/* Check the presence of the chip */
if
(
ad9516_read_reg
((
void
*
)
spi_base
,
0x3
)
!=
0xc3
)
{
pp_printf
(
"Error: Low-Jitter Daughterboard AD9516 PLL not responding.
\n
"
);
return
-
1
;
}
ad9516_write_reg
(
spi_base
,
0x018
,
0x0
);
// reset VCO calibration
ad9516_write_reg
(
spi_base
,
0x232
,
0x0
);
ad9516_write_reg
(
spi_base
,
0x232
,
0x1
);
ad9516_write_reg
(
spi_base
,
0x232
,
0x0
);
ad9516_set_vco_divider
(
spi_base
,
3
);
ad9516_load_regset
(
spi_base
,
ad9516_ljd_base_config
,
ARRAY_SIZE
(
ad9516_ljd_base_config
),
1
);
ad9516_set_output_divider
(
spi_base
,
6
,
8
,
0
);
// OUT6. 62.5MHz
ad9516_set_output_divider
(
spi_base
,
8
,
20
,
0
);
// OUT6. 62.5MHz
return
0
;
}
int
rts_debug_command
(
int
command
,
int
value
)
{
...
...
@@ -296,13 +325,13 @@ int rts_debug_command(int command, int value)
case
RTS_DEBUG_ENABLE_SERDES_CLOCKS
:
if
(
value
)
{
ad9516_write_reg
(
0xf4
,
0x08
);
// OUT4 enabled
ad9516_write_reg
(
0x232
,
0x0
);
ad9516_write_reg
(
0x232
,
0x1
);
ad9516_write_reg
(
(
void
*
)
BASE_SPI
,
0xf4
,
0x08
);
// OUT4 enabled
ad9516_write_reg
(
(
void
*
)
BASE_SPI
,
0x232
,
0x0
);
ad9516_write_reg
(
(
void
*
)
BASE_SPI
,
0x232
,
0x1
);
}
else
{
ad9516_write_reg
(
0xf4
,
0x0a
);
// OUT4 power-down, no serdes clock
ad9516_write_reg
(
0x232
,
0x0
);
ad9516_write_reg
(
0x232
,
0x1
);
ad9516_write_reg
(
(
void
*
)
BASE_SPI
,
0xf4
,
0x0a
);
// OUT4 power-down, no serdes clock
ad9516_write_reg
(
(
void
*
)
BASE_SPI
,
0x232
,
0x0
);
ad9516_write_reg
(
(
void
*
)
BASE_SPI
,
0x232
,
0x1
);
}
break
;
}
...
...
dev/ad9516_config.h
View file @
c0ffd31c
...
...
@@ -143,10 +143,85 @@ const struct ad9516_reg ad9516_base_config_34[] = {
{
0x0231
,
0x00
},
};
/* Configuration for the SCB version greater than or equal 3.4: Base + 6, 7, 8, 9 outputs*/
const
struct
ad9516_reg
ad9516_ljd_base_config
[]
=
{
{
0x0000
,
0x99
},
{
0x0001
,
0x00
},
{
0x0002
,
0x10
},
{
0x0003
,
0xC3
},
{
0x0004
,
0x00
},
{
0x0010
,
0x4C
},
{
0x0011
,
0x00
},
{
0x0012
,
0x00
},
{
0x0013
,
0x06
},
{
0x0014
,
0x12
},
{
0x0015
,
0x00
},
{
0x0016
,
0x04
},
{
0x0017
,
0x00
},
{
0x0018
,
0x07
},
{
0x0019
,
0x00
},
{
0x001A
,
0x00
},
{
0x001B
,
0x00
},
{
0x001C
,
0x01
},
{
0x001D
,
0x00
},
{
0x001E
,
0x00
},
{
0x001F
,
0x0E
},
{
0x00A0
,
0x01
},
{
0x00A1
,
0x00
},
{
0x00A2
,
0x00
},
{
0x00A3
,
0x01
},
{
0x00A4
,
0x00
},
{
0x00A5
,
0x00
},
{
0x00A6
,
0x01
},
{
0x00A7
,
0x00
},
{
0x00A8
,
0x00
},
{
0x00A9
,
0x01
},
{
0x00AA
,
0x00
},
{
0x00AB
,
0x00
},
{
0x00F0
,
0x0A
},
{
0x00F1
,
0x0A
},
{
0x00F2
,
0x0A
},
{
0x00F3
,
0x0A
},
{
0x00F4
,
0x08
},
{
0x00F5
,
0x08
},
// The following registers configure the PLL outputs from 6 to 9.
{
0x0140
,
0x42
},
{
0x0141
,
0x42
},
{
0x0142
,
0x08
},
{
0x0143
,
0x4E
},
{
0x0190
,
0x55
},
{
0x0191
,
0x00
},
{
0x0192
,
0x00
},
{
0x0193
,
0x11
},
{
0x0194
,
0x00
},
{
0x0195
,
0x00
},
{
0x0196
,
0x10
},
{
0x0197
,
0x00
},
{
0x0198
,
0x00
},
{
0x0199
,
0x33
},
{
0x019A
,
0x00
},
{
0x019B
,
0x11
},
{
0x019C
,
0x20
},
{
0x019D
,
0x00
},
{
0x019E
,
0x33
},
{
0x019F
,
0x00
},
{
0x01A0
,
0x11
},
{
0x01A1
,
0x20
},
{
0x01A2
,
0x00
},
{
0x01A3
,
0x00
},
//
{
0x01E0
,
0x01
},
{
0x01E1
,
0x02
},
{
0x0230
,
0x00
},
{
0x0231
,
0x00
},
};
/* Config for 25 MHz VCTCXO reference (RDiv = 5, use REF1) */
const
struct
ad9516_reg
ad9516_ref_tcxo
[]
=
{
{
0x0011
,
0x05
},
{
0x0012
,
0x00
},
/* RDiv =
5
*/
{
0x0012
,
0x00
},
/* RDiv =
4
*/
{
0x001C
,
0x06
}
/* Use REF1 */
};
...
...
@@ -157,3 +232,9 @@ const struct ad9516_reg ad9516_ref_ext[] = {
{
0x001C
,
0x46
}
/* Use REF1 */
};
/* Config for Low-Jitter Daughterboard */
const
struct
ad9516_reg
ad9516_ref_ljd
[]
=
{
{
0x0011
,
0x04
},
{
0x0012
,
0x00
},
/* RDiv = 4 */
{
0x001C
,
0x06
}
/* Use REF1 */
};
include/board-wrs.h
View file @
c0ffd31c
...
...
@@ -21,6 +21,7 @@
#define BASE_GPIO 0x10300
#define BASE_TIMER 0x10400
#define BASE_PPS_GEN 0x10500
#define BASE_SPI_LJD_BOARD 0x10700
/* spll parameter that are board-specific */
#define BOARD_DIVIDE_DMTD_CLOCKS 0
...
...
include/gpio-wrs.h
View file @
c0ffd31c
...
...
@@ -10,6 +10,13 @@
#include "board.h"
#define GPIO_SYS_CLK_SEL 0
#define GPIO_PLL_RESET_N 1
#define GPIO_PERIPH_RESET_N 3
#define GPIO_LJD_BOARD_DETECT 4
extern
int
ljd_present
;
struct
GPIO_WB
{
uint32_t
CODR
;
/*Clear output register*/
...
...
@@ -36,7 +43,7 @@ static inline void gpio_dir(int pin, int val)
__gpio
->
DDR
&=
~
(
1
<<
pin
);
}
static
inline
int
gpio_in
(
int
bank
,
int
pin
)
static
inline
int
gpio_in
(
int
pin
)
{
return
__gpio
->
PSR
&
(
1
<<
pin
)
?
1
:
0
;
}
...
...
include/wrc.h
View file @
c0ffd31c
...
...
@@ -70,7 +70,8 @@ extern int abs(int val);
extern
int
wrc_ui_refperiod
;
/* Init functions and defaults for the wrs build */
int
ad9516_init
(
int
scb_ver
);
int
ad9516_init
(
int
scb_ver
,
int
ljd_present
);
int
ljd_ad9516_init
(
void
);
void
rts_init
(
void
);
int
rtipc_init
(
void
);
void
rts_update
(
void
);
...
...
softpll/softpll_ng.c
View file @
c0ffd31c
...
...
@@ -32,7 +32,7 @@ volatile struct SPLL_WB *SPLL;
volatile
struct
PPSG_WB
*
PPSG
;
int
spll_n_chan_ref
,
spll_n_chan_out
;
int
ljd_present
=
0
;
/* Low-jitter Daughterboard presence indicator */
#define MAIN_CHANNEL (spll_n_chan_ref)
...
...
@@ -485,12 +485,12 @@ void spll_show_stats()
if
(
softpll
.
mode
>
0
)
pp_printf
(
"softpll: irqs %d seq %s mode %d "
"alignment_state %d HL%d ML%d HY=%d MY=%d DelCnt=%d
\n
"
,
"alignment_state %d HL%d ML%d HY=%d MY=%d DelCnt=%d
setpoint:%d
\n
"
,
s
->
irq_count
,
statename
,
s
->
mode
,
s
->
ext
.
align_state
,
s
->
helper
.
ld
.
locked
,
s
->
mpll
.
ld
.
locked
,
s
->
helper
.
pi
.
y
,
s
->
mpll
.
pi
.
y
,
s
->
delock_count
);
s
->
delock_count
,
s
->
mpll
.
phase_shift_current
);
}
int
spll_shifter_busy
(
int
channel
)
...
...
@@ -649,7 +649,7 @@ int spll_update()
return
ret
!=
0
;
}
static
int
spll_measure_frequency
(
int
osc
)
int
spll_measure_frequency
(
int
osc
)
{
volatile
uint32_t
*
reg
;
...
...
@@ -667,7 +667,7 @@ static int spll_measure_frequency(int osc)
return
0
;
}
timer_delay_ms
(
2000
);
//
timer_delay_ms(2000);
return
(
*
reg
)
&
(
0xfffffff
);
}
...
...
@@ -699,20 +699,20 @@ static int calc_apr(int meas_min, int meas_max, int f_center )
void
check_vco_frequencies
()
{
disable_irq
();
//
disable_irq();
int
f_min
,
f_max
;
pll_verbose
(
"SoftPLL VCO Frequency/APR test:
\n
"
);
spll_set_dac
(
-
1
,
0
);
//
spll_set_dac(-1, 0);
f_min
=
spll_measure_frequency
(
SPLL_OSC_DMTD
);
spll_set_dac
(
-
1
,
65535
);
//
spll_set_dac(-1, 65535);
f_max
=
spll_measure_frequency
(
SPLL_OSC_DMTD
);
pll_verbose
(
"DMTD VCO: Low=%d Hz Hi=%d Hz, APR = %d ppm.
\n
"
,
f_min
,
f_max
,
calc_apr
(
f_min
,
f_max
,
62500000
));
spll_set_dac
(
0
,
0
);
//
spll_set_dac(0, 0);
f_min
=
spll_measure_frequency
(
SPLL_OSC_REF
);
spll_set_dac
(
0
,
65535
);
//
spll_set_dac(0, 65535);
f_max
=
spll_measure_frequency
(
SPLL_OSC_REF
);
pll_verbose
(
"REF VCO: Low=%d Hz Hi=%d Hz, APR = %d ppm.
\n
"
,
f_min
,
f_max
,
calc_apr
(
f_min
,
f_max
,
REF_CLOCK_FREQ_HZ
));
...
...
softpll/softpll_ng.h
View file @
c0ffd31c
...
...
@@ -107,6 +107,7 @@ void spll_set_dac(int out_channel, int value);
int
spll_get_dac
(
int
out_channel
);
void
check_vco_frequencies
(
void
);
int
spll_measure_frequency
(
int
osc
);
/*
* Aux and main state:
...
...
@@ -148,6 +149,7 @@ struct spll_fifo_log {
};
#define FIFO_LOG_LEN 16
extern
int
ljd_present
;
#endif // __SOFTPLL_NG_H
softpll/spll_external.c
View file @
c0ffd31c
...
...
@@ -14,13 +14,14 @@
#include "softpll_ng.h"
#include "irq.h"
#define ALIGN_SAMPLE_PERIOD 100000
#define ALIGN_TARGET 0
#define EXT_PERIOD_NS 100
#define EXT_FREQ_HZ 10000000
#define EXT_PPS_LATENCY_PS 30000 // fixme: make configurable
// fixme: make configurable
#define EXT_PPS_LATENCY_PS 30000 // for regular ext channel
#define EXT_PPS_LATENCY_LJD_PS 63000 // for low-jitter daughterboard
void
external_init
(
volatile
struct
spll_external_state
*
s
,
int
ext_ref
,
...
...
@@ -28,6 +29,8 @@ void external_init(volatile struct spll_external_state *s, int ext_ref,
{
int
idx
=
spll_n_chan_ref
+
spll_n_chan_out
;
if
(
ljd_present
)
idx
++
;
helper_init
(
s
->
helper
,
idx
);
mpll_init
(
s
->
main
,
idx
,
spll_n_chan_ref
);
...
...
@@ -38,7 +41,7 @@ void external_init(volatile struct spll_external_state *s, int ext_ref,
void
external_start
(
struct
spll_external_state
*
s
)
{
helper_start
(
s
->
helper
);
helper_start
(
s
->
helper
);
SPLL
->
ECCR
=
SPLL_ECCR_EXT_EN
;
...
...
@@ -50,10 +53,10 @@ void external_start(struct spll_external_state *s)
int
external_locked
(
volatile
struct
spll_external_state
*
s
)
{
if
(
!
s
->
helper
->
ld
.
locked
||
!
s
->
main
->
ld
.
locked
||
!
(
SPLL
->
ECCR
&
SPLL_ECCR_EXT_REF_LOCKED
)
||
// ext PLL became unlocked
(
SPLL
->
ECCR
&
SPLL_ECCR_EXT_REF_STOPPED
))
// 10MHz unplugged (only SPEC)
!
(
SPLL
->
ECCR
&
SPLL_ECCR_EXT_REF_LOCKED
)
||
// ext PLL became unlocked
(
SPLL
->
ECCR
&
SPLL_ECCR_EXT_REF_STOPPED
))
// 10MHz unplugged (only SPEC)
return
0
;
switch
(
s
->
align_state
)
{
case
ALIGN_STATE_EXT_OFF
:
case
ALIGN_STATE_WAIT_CLKIN
:
...
...
@@ -83,27 +86,53 @@ static int align_sample(int channel, int *v)
return
0
;
// sample not valid
}
static
inline
int
get_pps_latency
(
int
sel
)
{
if
(
sel
)
return
EXT_PPS_LATENCY_LJD_PS
;
else
return
EXT_PPS_LATENCY_PS
;
}
int
external_align_fsm
(
volatile
struct
spll_external_state
*
s
)
{
int
v
,
done_sth
=
0
;
static
int
timeout
;
switch
(
s
->
align_state
)
{
case
ALIGN_STATE_EXT_OFF
:
break
;
case
ALIGN_STATE_WAIT_CLKIN
:
if
(
!
(
SPLL
->
ECCR
&
SPLL_ECCR_EXT_REF_STOPPED
)
)
{
if
(
!
ljd_present
&&
!
(
SPLL
->
ECCR
&
SPLL_ECCR_EXT_REF_STOPPED
)
)
{
SPLL
->
ECCR
|=
SPLL_ECCR_EXT_REF_PLLRST
;
s
->
align_state
=
ALIGN_STATE_WAIT_PLOCK
;
done_sth
++
;
}
#if defined(CONFIG_WR_SWITCH)
else
if
(
ljd_present
)
{
uint32_t
f_ext
;
int
ljd_ad9516_stat
;
/* reset ljd ad9516 */
SPLL
->
ECCR
|=
SPLL_ECCR_EXT_REF_PLLRST
;
timer_delay
(
10
);
SPLL
->
ECCR
&=
(
~
SPLL_ECCR_EXT_REF_PLLRST
);
timer_delay
(
10
);
ljd_ad9516_stat
=
ljd_ad9516_init
();
f_ext
=
spll_measure_frequency
(
SPLL_OSC_EXT
);
if
(
!
ljd_ad9516_stat
&&
(
f_ext
>
9999000
)
&&
(
f_ext
<
10001000
))
{
s
->
align_state
=
ALIGN_STATE_WAIT_PLOCK
;
pp_printf
(
"External AD9516 locked
\n
"
);
}
}
#endif
break
;
case
ALIGN_STATE_WAIT_PLOCK
:
SPLL
->
ECCR
&=
(
~
SPLL_ECCR_EXT_REF_PLLRST
);
if
(
SPLL
->
ECCR
&
SPLL_ECCR_EXT_REF_STOPPED
)
if
(
SPLL
->
ECCR
&
SPLL_ECCR_EXT_REF_STOPPED
)
s
->
align_state
=
ALIGN_STATE_WAIT_CLKIN
;
else
if
(
SPLL
->
ECCR
&
SPLL_ECCR_EXT_REF_LOCKED
)
else
if
(
SPLL
->
ECCR
&
SPLL_ECCR_EXT_REF_LOCKED
)
s
->
align_state
=
ALIGN_STATE_START
;
done_sth
++
;
break
;
...
...
@@ -115,6 +144,9 @@ int external_align_fsm(volatile struct spll_external_state *s)
enable_irq
();
s
->
align_state
=
ALIGN_STATE_START_MAIN
;
done_sth
++
;
}
else
if
(
time_after
(
timer_get_tics
(),
timeout
+
5
*
TICS_PER_SECOND
))
{
pll_verbose
(
"EXT: timeout, restarting
\n
"
);
s
->
align_state
=
ALIGN_STATE_WAIT_CLKIN
;
}
break
;
...
...
@@ -127,6 +159,9 @@ int external_align_fsm(volatile struct spll_external_state *s)
s
->
align_state
=
ALIGN_STATE_INIT_CSYNC
;
pll_verbose
(
"EXT: DMTD locked.
\n
"
);
done_sth
++
;
}
else
if
(
time_after
(
timer_get_tics
(),
timeout
+
5
*
TICS_PER_SECOND
))
{
pll_verbose
(
"EXT: timeout, restarting
\n
"
);
s
->
align_state
=
ALIGN_STATE_WAIT_CLKIN
;
}
break
;
...
...
@@ -171,8 +206,8 @@ int external_align_fsm(volatile struct spll_external_state *s)
s
->
align_shift
+=
s
->
align_step
;
mpll_set_phase_shift
(
s
->
main
,
s
->
align_shift
);
}
else
if
(
v
==
s
->
align_target
)
{
s
->
align_shift
+=
EXT_PPS_LATENCY_PS
;
mpll_set_phase_shift
(
s
->
main
,
s
->
align_shift
);
s
->
align_shift
+=
get_pps_latency
(
ljd_present
)
;
mpll_set_phase_shift
(
s
->
main
,
s
->
align_shift
);
s
->
align_state
=
ALIGN_STATE_COMPENSATE_DELAY
;
}
done_sth
++
;
...
...
@@ -197,5 +232,8 @@ int external_align_fsm(volatile struct spll_external_state *s)
default:
break
;
}
if
(
done_sth
>
0
)
{
timeout
=
timer_get_tics
();
}
return
done_sth
!=
0
;
}
softpll/spll_helper.c
View file @
c0ffd31c
...
...
@@ -17,8 +17,13 @@ void helper_init(struct spll_helper_state *s, int ref_channel)
/* Phase branch PI controller */
s
->
pi
.
y_min
=
5
;
s
->
pi
.
y_max
=
(
1
<<
DAC_BITS
)
-
5
;
#if defined(CONFIG_WR_NODE)
s
->
pi
.
kp
=
-
150
;
//(int)(0.3 * 32.0 * 16.0); // / 2;
s
->
pi
.
ki
=
-
2
;
//(int)(0.03 * 32.0 * 3.0); // / 2;
#else
s
->
pi
.
kp
=
150
;
s
->
pi
.
ki
=
2
;
#endif
s
->
pi
.
anti_windup
=
1
;
/* Phase branch lock detection */
...
...
@@ -83,8 +88,11 @@ void helper_start(struct spll_helper_state *s)
{
/* Set the bias to the upper end of tuning range. This is to ensure that
the HPLL will always lock on positive frequency offset. */
#if defined(CONFIG_WR_SWITCH)
s
->
pi
.
bias
=
s
->
pi
.
y_max
;
#else
s
->
pi
.
bias
=
s
->
pi
.
y_min
;
#endif
s
->
p_setpoint
=
0
;
s
->
p_adder
=
0
;
s
->
sample_n
=
0
;
...
...
softpll/spll_main.c
View file @
c0ffd31c
...
...
@@ -31,8 +31,13 @@ void mpll_init(struct spll_main_state *s, int id_ref,
s
->
pi
.
anti_windup
=
1
;
s
->
pi
.
bias
=
30000
;
#if defined(CONFIG_WR_SWITCH)
s
->
pi
.
kp
=
-
1100
;
// / 2;
s
->
pi
.
ki
=
-
30
;
// / 2;
if
(
ljd_present
)
{
s
->
pi
.
kp
=
2000
;
s
->
pi
.
ki
=
15
;
}
else
{
s
->
pi
.
kp
=
1100
;
// / 2;
s
->
pi
.
ki
=
30
;
// / 2;
}
#elif defined(CONFIG_WR_NODE)
s
->
pi
.
kp
=
-
1100
;
// / 2;
s
->
pi
.
ki
=
-
30
;
// / 2;
...
...
@@ -157,11 +162,19 @@ int mpll_update(struct spll_main_state *s, int tag, int source)
if
(
s
->
ld
.
locked
)
{
if
(
s
->
phase_shift_current
<
s
->
phase_shift_target
)
{
s
->
phase_shift_current
++
;
#if defined(CONFIG_WR_SWITCH)
s
->
adder_ref
++
;
#else
s
->
adder_ref
--
;
#endif
}
else
if
(
s
->
phase_shift_current
>
s
->
phase_shift_target
)
{
s
->
phase_shift_current
--
;
#if defined(CONFIG_WR_SWITCH)
s
->
adder_ref
--
;
#else
s
->
adder_ref
++
;
#endif
}
}
if
(
ld_update
((
spll_lock_det_t
*
)
&
s
->
ld
,
err
))
...
...
softpll/spll_ptracker.c
View file @
c0ffd31c
...
...
@@ -56,8 +56,11 @@ int ptrackers_update(struct spll_ptracker_state *ptrackers, int tag,
if
(
!
s
->
enabled
)
return
0
;
#if defined(CONFIG_WR_NODE)
register
int
delta
=
(
tag
-
tag_ref
)
&
((
1
<<
HPLL_N
)
-
1
);
#else
register
int
delta
=
(
tag_ref
-
tag
)
&
((
1
<<
HPLL_N
)
-
1
);
#endif
register
int
index
=
delta
>>
(
HPLL_N
-
2
);
...
...
wrs_main.c
View file @
c0ffd31c
...
...
@@ -13,6 +13,7 @@
#include "minipc.h"
#include "revision.h"
#include "system_checks.h"
#include "gpio-wrs.h"
int
scb_ver
=
33
;
/* SCB version */
...
...
@@ -40,6 +41,12 @@ int main(void)
build_revision
,
build_date
,
build_time
);
pp_printf
(
"SCB version: %d. %s
\n
"
,
scb_ver
,(
scb_ver
>=
34
)
?
"10 MHz SMC Output."
:
""
);
pp_printf
(
"Start counter %d
\n
"
,
stats
.
start_cnt
);
/* Low-jitter Daughterboard detection */
ljd_present
=
gpio_in
(
GPIO_LJD_BOARD_DETECT
);
if
(
ljd_present
)
{
pp_printf
(
"
\n
--- WRS Low jitter board detected. ---
\n
"
);
pp_printf
(
"Allow 1 hour of warming up before starting measurements
\n
"
);
}
pp_printf
(
"--
\n
"
);
if
(
stats
.
start_cnt
>
1
)
{
...
...
@@ -47,7 +54,7 @@ int main(void)
/* for sure problem is in calling second time ad9516_init,
* but not only */
}
ad9516_init
(
scb_ver
);
ad9516_init
(
scb_ver
,
ljd_present
);
rts_init
();
rtipc_init
();
spll_very_init
();
...
...
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