Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
wr-switch-sw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
white-rabbit
wr-switch-sw
Commits
b41e8354
Commit
b41e8354
authored
Dec 05, 2014
by
Grzegorz Daniluk
Committed by
Alessandro Rubini
Dec 10, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
userspace/tools: adding simple tools for setting CLK2 output
parent
58775a73
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
407 additions
and
1 deletion
+407
-1
Makefile
kernel/wbgen-regs/Makefile
+3
-1
gen10mhz-regs.h
kernel/wbgen-regs/gen10mhz-regs.h
+100
-0
gen10mhz-regs.wb
kernel/wbgen-regs/gen10mhz-regs.wb
+128
-0
ppsg-regs.h
kernel/wbgen-regs/ppsg-regs.h
+6
-0
ppsg-regs.wb
kernel/wbgen-regs/ppsg-regs.wb
+18
-0
fpga_io.h
userspace/include/fpga_io.h
+3
-0
.gitignore
userspace/tools/.gitignore
+1
-0
Makefile
userspace/tools/Makefile
+1
-0
wrs_auxclk.c
userspace/tools/wrs_auxclk.c
+147
-0
No files found.
kernel/wbgen-regs/Makefile
View file @
b41e8354
...
@@ -16,10 +16,11 @@ WB_PPSG = $(MODULES_WRC)/wr_pps_gen/pps_gen_wb.wb
...
@@ -16,10 +16,11 @@ WB_PPSG = $(MODULES_WRC)/wr_pps_gen/pps_gen_wb.wb
WB_TSTAMP
=
$(MODULES_WRS)
/wrsw_txtsu/wrsw_txtsu.wb
WB_TSTAMP
=
$(MODULES_WRS)
/wrsw_txtsu/wrsw_txtsu.wb
WB_RTU
=
$(MODULES_WRS)
/wrsw_rtu/rtu_wishbone_slave.wb
WB_RTU
=
$(MODULES_WRS)
/wrsw_rtu/rtu_wishbone_slave.wb
WB_NIC
=
$(MODULES_WRS)
/wrsw_nic/wr_nic.wb
WB_NIC
=
$(MODULES_WRS)
/wrsw_nic/wr_nic.wb
WB_GEN10
=
$(MODULES_WRS)
/wrsw_rt_subsystem/wrsw_gen_10mhz.wb
WB_SOFTPLL
=
$(MODULES_WRC)
/wr_softpll_ng/spll_wb_slave.wb
WB_SOFTPLL
=
$(MODULES_WRC)
/wr_softpll_ng/spll_wb_slave.wb
HEADERS
=
endpoint-regs.h endpoint-mdio.h ppsg-regs.h tstamp-regs.h rtu-regs.h
\
HEADERS
=
endpoint-regs.h endpoint-mdio.h ppsg-regs.h tstamp-regs.h rtu-regs.h
\
nic-regs.h softpll-regs.h pstats-regs.h
nic-regs.h softpll-regs.h pstats-regs.h
gen10mhz-regs.h
WBINPUT
=
$
(
HEADERS:.h
=
wb
)
WBINPUT
=
$
(
HEADERS:.h
=
wb
)
# No default, for people who types "make" everywhere (like me)
# No default, for people who types "make" everywhere (like me)
...
@@ -47,4 +48,5 @@ wbinput:
...
@@ -47,4 +48,5 @@ wbinput:
@
cp
$(WB_RTU)
rtu-regs.wb
@
cp
$(WB_RTU)
rtu-regs.wb
@
cp
$(WB_NIC)
nic-regs.wb
@
cp
$(WB_NIC)
nic-regs.wb
@
cp
$(WB_SOFTPLL)
softpll-regs.wb
@
cp
$(WB_SOFTPLL)
softpll-regs.wb
@
cp
$(WB_GEN10)
gen10mhz-regs.wb
@
echo
"Copied input files from subversions to local directory"
@
echo
"Copied input files from subversions to local directory"
kernel/wbgen-regs/gen10mhz-regs.h
0 → 100644
View file @
b41e8354
/*
Register definitions for slave core: WR Switch aux clock generation module
* File : gen10mhz-regs.h
* Author : auto-generated by wbgen2 from gen10mhz-regs.wb
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE gen10mhz-regs.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_GEN10MHZ
#define __WBGEN2_REGDEFS_GEN10MHZ
#ifdef __KERNEL__
#include <linux/types.h>
#else
#include <stdint.h>
#endif
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Period Register */
/* definitions for field: Half period width in reg: Period Register */
#define GEN10_PR_HP_WIDTH_MASK WBGEN2_GEN_MASK(0, 16)
#define GEN10_PR_HP_WIDTH_SHIFT 0
#define GEN10_PR_HP_WIDTH_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define GEN10_PR_HP_WIDTH_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for register: Duty Cycle Register */
/* definitions for field: Low state width in reg: Duty Cycle Register */
#define GEN10_DCR_LOW_WIDTH_MASK WBGEN2_GEN_MASK(0, 16)
#define GEN10_DCR_LOW_WIDTH_SHIFT 0
#define GEN10_DCR_LOW_WIDTH_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define GEN10_DCR_LOW_WIDTH_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for register: Coarse Shift Register */
/* definitions for register: IODelay Register */
/* definitions for field: Required delay value in reg: IODelay Register */
#define GEN10_IOR_TAP_SET_MASK WBGEN2_GEN_MASK(0, 5)
#define GEN10_IOR_TAP_SET_SHIFT 0
#define GEN10_IOR_TAP_SET_W(value) WBGEN2_GEN_WRITE(value, 0, 5)
#define GEN10_IOR_TAP_SET_R(reg) WBGEN2_GEN_READ(reg, 0, 5)
/* definitions for field: Current delay value read from IODelay in reg: IODelay Register */
#define GEN10_IOR_TAP_CUR_MASK WBGEN2_GEN_MASK(8, 5)
#define GEN10_IOR_TAP_CUR_SHIFT 8
#define GEN10_IOR_TAP_CUR_W(value) WBGEN2_GEN_WRITE(value, 8, 5)
#define GEN10_IOR_TAP_CUR_R(reg) WBGEN2_GEN_READ(reg, 8, 5)
/* definitions for field: IOdelay locked in reg: IODelay Register */
#define GEN10_IOR_LCK WBGEN2_GEN_MASK(31, 1)
/* definitions for register: PPS IODelay Register */
/* definitions for field: Required delay value in reg: PPS IODelay Register */
#define GEN10_PPS_IOR_TAP_SET_MASK WBGEN2_GEN_MASK(0, 5)
#define GEN10_PPS_IOR_TAP_SET_SHIFT 0
#define GEN10_PPS_IOR_TAP_SET_W(value) WBGEN2_GEN_WRITE(value, 0, 5)
#define GEN10_PPS_IOR_TAP_SET_R(reg) WBGEN2_GEN_READ(reg, 0, 5)
/* definitions for field: Current delay value read from IODelay in reg: PPS IODelay Register */
#define GEN10_PPS_IOR_TAP_CUR_MASK WBGEN2_GEN_MASK(8, 5)
#define GEN10_PPS_IOR_TAP_CUR_SHIFT 8
#define GEN10_PPS_IOR_TAP_CUR_W(value) WBGEN2_GEN_WRITE(value, 8, 5)
#define GEN10_PPS_IOR_TAP_CUR_R(reg) WBGEN2_GEN_READ(reg, 8, 5)
PACKED
struct
GEN10_WB
{
/* [0x0]: REG Period Register */
uint32_t
PR
;
/* [0x4]: REG Duty Cycle Register */
uint32_t
DCR
;
/* [0x8]: REG Coarse Shift Register */
uint32_t
CSR
;
/* [0xc]: REG IODelay Register */
uint32_t
IOR
;
/* [0x10]: REG PPS IODelay Register */
uint32_t
PPS_IOR
;
};
#endif
kernel/wbgen-regs/gen10mhz-regs.wb
0 → 100644
View file @
b41e8354
-- -*- Mode: LUA; tab-width: 2 -*-
-- White-Rabbit 10 MHz Clock Generation
-- author: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
--
-- Use wbgen2 to generate code, documentation and more.
-- wbgen2 is available at:
-- http://www.ohwr.org/projects/wishbone-gen
--
peripheral {
name = "WR Switch aux clock generation module";
decription = "The module allows gerating WR-aligned clock of a given \
frequency, duty cycle and phase. By default it is configured to generate 10MHz \
signal.";
hdl_entity = "gen10_wishbone_slave";
prefix = "gen10";
reg {
name = "Period Register";
prefix = "PR";
field {
name = "Half period width";
description = "Defined as a number of 2ns cycles.";
prefix = "HP_WIDTH";
size = 16;
type = PASS_THROUGH;
access_dev = READ_ONLY;
access_bus = READ_WRITE;
};
};
reg {
name = "Duty Cycle Register";
prefix = "DCR";
field {
name = "Low state width";
description = "Defined as a number of 2ns cycles. \
Used together with PR register can be used to generate a square wave with a duty \
cycle different than 0,5.";
prefix = "LOW_WIDTH";
size = 16;
type = PASS_THROUGH;
access_dev = READ_ONLY;
access_bus = READ_WRITE;
};
};
reg {
name = "Coarse Shift Register";
prefix = "CSR";
field {
name = "Coarse shift value in 2ns cycles.";
description = "MUST be not larger than the required clock period";
size = 16;
type = PASS_THROUGH;
access_dev = READ_ONLY;
access_bus = READ_WRITE;
};
};
reg {
name = "IODelay Register";
description = "IODelay may be used if generated signal is in phase with 500MHz \
clock from AD9516 fed to the flip-flop. In that situation clock signal on CLK2 \
output will be jittering by 2ns. Phase shifting it with IODelay eliminates \
this problem.";
prefix = "IOR";
field {
name = "Required delay value";
prefix = "TAP_SET";
size = 5;
type = PASS_THROUGH;
access_dev = READ_ONLY;
access_bus = WRITE_ONLY;
};
field {
name = "Current delay value read from IODelay";
prefix = "TAP_CUR";
align = 8;
size = 5;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
field {
name = "IOdelay locked";
prefix = "LCK";
align = 31;
size = 1;
type = BIT;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
};
reg {
name = "PPS IODelay Register";
description = "Used to control IODelay attached to 1-PPS signal generated \
from the switch. It can be used to preciesly align 1-PPS with CLK2 out.";
prefix = "PPS_IOR";
field {
name = "Required delay value";
prefix = "TAP_SET";
size = 5;
type = PASS_THROUGH;
access_dev = READ_ONLY;
access_bus = WRITE_ONLY;
};
field {
name = "Current delay value read from IODelay";
prefix = "TAP_CUR";
align = 8;
size = 5;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
};
}
kernel/wbgen-regs/ppsg-regs.h
View file @
b41e8354
...
@@ -78,6 +78,12 @@
...
@@ -78,6 +78,12 @@
/* definitions for field: Timecode output(UTC+cycles) valid in reg: External sync control register */
/* definitions for field: Timecode output(UTC+cycles) valid in reg: External sync control register */
#define PPSG_ESCR_TM_VALID WBGEN2_GEN_MASK(2, 1)
#define PPSG_ESCR_TM_VALID WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Set seconds counter in reg: External sync control register */
#define PPSG_ESCR_SEC_SET WBGEN2_GEN_MASK(3, 1)
/* definitions for field: Set nanoseconds counter in reg: External sync control register */
#define PPSG_ESCR_NSEC_SET WBGEN2_GEN_MASK(4, 1)
PACKED
struct
PPSG_WB
{
PACKED
struct
PPSG_WB
{
/* [0x0]: REG Control Register */
/* [0x0]: REG Control Register */
uint32_t
CR
;
uint32_t
CR
;
...
...
kernel/wbgen-regs/ppsg-regs.wb
View file @
b41e8354
...
@@ -192,6 +192,24 @@ peripheral {
...
@@ -192,6 +192,24 @@ peripheral {
clock = "refclk_i";
clock = "refclk_i";
};
};
field {
name = "Set seconds counter";
description = "write 1: set seconds counter to the value stored in ADJ_UTCLO and ADJ_UTCHI. Nanoseconds counter stays unchanged.\
write 0: no effect";
prefix = "SEC_SET";
type = MONOSTABLE;
clock = "refclk_i";
};
field {
name = "Set nanoseconds counter";
description = "write 1: set nanoseconds counter to the value stored in ADJ_NSEC. Seconds counter stays unchanged.\
write 0: no effect";
prefix = "NSEC_SET";
type = MONOSTABLE;
clock = "refclk_i";
};
};
};
};
};
userspace/include/fpga_io.h
View file @
b41e8354
...
@@ -8,6 +8,9 @@
...
@@ -8,6 +8,9 @@
/* PPS Generator */
/* PPS Generator */
#define FPGA_BASE_PPS_GEN 0x10500
#define FPGA_BASE_PPS_GEN 0x10500
/* Aux Clk Generator */
#define FPGA_BASE_GEN_10MHZ 0x10600
/* Routing Table */
/* Routing Table */
#define FPGA_BASE_RTU 0x60000
#define FPGA_BASE_RTU 0x60000
...
...
userspace/tools/.gitignore
View file @
b41e8354
...
@@ -18,3 +18,4 @@ wrs_vlans
...
@@ -18,3 +18,4 @@ wrs_vlans
wrs_dump_shmem
wrs_dump_shmem
sdb-read
sdb-read
nbtee
nbtee
wrs_auxclk
userspace/tools/Makefile
View file @
b41e8354
...
@@ -4,6 +4,7 @@ TOOLS += wrs_version wr_date lm32-vuart wrs_pstats
...
@@ -4,6 +4,7 @@ TOOLS += wrs_version wr_date lm32-vuart wrs_pstats
TOOLS
+=
wrs_vlans wrs_dump_shmem
TOOLS
+=
wrs_vlans wrs_dump_shmem
TOOLS
+=
sdb-read
TOOLS
+=
sdb-read
TOOLS
+=
nbtee
TOOLS
+=
nbtee
TOOLS
+=
wrs_auxclk
WR_INSTALL_ROOT
?=
/usr/lib/white-rabbit
WR_INSTALL_ROOT
?=
/usr/lib/white-rabbit
...
...
userspace/tools/wrs_auxclk.c
0 → 100644
View file @
b41e8354
#include <stdio.h>
#include <getopt.h>
#include <unistd.h>
#include <stdlib.h>
#include <stddef.h>
#include <libwr/switch_hw.h>
#include "fpga_io.h"
#include "regs/gen10mhz-regs.h"
#include "regs/ppsg-regs.h"
#define OPT_HELP 'h'
#define OPT_FREQ 2
#define OPT_DUTY 3
#define OPT_CSHIFT 4
#define OPT_SIGDEL 5
#define OPT_PPSHIFT 6
/* default parameters to generate 10MHz signal */
#define DEF_FREQ 10
#define DEF_DUTY 0.5
#define DEF_CSHIFT 30
#define DEF_SIGDEL 0
#define DEF_PPSHIFT 0
#define MAX_FREQ 250
/* min half-period is 2ns */
#define MIN_FREQ 0.004
/* max half-period is 65535*2ns */
#define CNT_RES 2
#define gen10_write(reg, val) \
_fpga_writel(FPGA_BASE_GEN_10MHZ + offsetof(struct GEN10_WB, reg), val)
#define gen10_read(reg) \
_fpga_readl(FPGA_BASE_GEN_10MHZ + offsetof(struct GEN10_WB, reg))
/* runtime options */
struct
option
ropts
[]
=
{
{
"help"
,
0
,
NULL
,
OPT_HELP
},
{
"freq"
,
1
,
NULL
,
OPT_FREQ
},
{
"duty"
,
1
,
NULL
,
OPT_DUTY
},
{
"cshift"
,
1
,
NULL
,
OPT_CSHIFT
},
{
"sigdel"
,
1
,
NULL
,
OPT_SIGDEL
},
{
"ppshift"
,
1
,
NULL
,
OPT_PPSHIFT
},
{
0
,}};
/*******************/
int
print_help
(
char
*
prgname
)
{
fprintf
(
stderr
,
"Use: %s [--freq <MHz>] [--duty <frac>] [--cshift <ns>]"
" [--ppshift <taps>] [--sigdel <taps>]
\n
"
,
prgname
);
return
0
;
}
int
apply_settings
(
float
freq_mhz
,
float
duty
,
int
cshift_ns
,
int
sigdel_taps
,
int
ppshift_taps
)
{
int
period_ns
;
int
h_width
,
l_width
;
/*first check if values are in range*/
if
(
freq_mhz
>
MAX_FREQ
||
freq_mhz
<
MIN_FREQ
)
{
fprintf
(
stderr
,
"Frequency outside range <%f; %d>
\n
"
,
MIN_FREQ
,
MAX_FREQ
);
return
-
1
;
}
if
(
!
(
duty
>
0
&&
duty
<
1
)
)
{
fprintf
(
stderr
,
"Duty %f outside range (0; 1)
\n
"
,
duty
);
return
-
1
;
}
/* calculate high and low width from frequency and duty */
period_ns
=
1000
/
freq_mhz
;
h_width
=
period_ns
/
CNT_RES
*
duty
;
l_width
=
period_ns
/
CNT_RES
-
h_width
;
/* now check the coarse shift */
if
(
cshift_ns
>
period_ns
||
cshift_ns
<
0
)
{
fprintf
(
stderr
,
"Coarse shift outside range <0; %d>
\n
"
,
period_ns
);
return
-
1
;
}
gen10_write
(
PR
,
h_width
);
gen10_write
(
DCR
,
l_width
);
gen10_write
(
CSR
,
cshift_ns
/
CNT_RES
);
gen10_write
(
IOR
,
sigdel_taps
);
gen10_write
(
PPS_IOR
,
ppshift_taps
);
sleep
(
1
);
/* now read the actual delay (in taps) from IODelays */
sigdel_taps
=
gen10_read
(
IOR
);
sigdel_taps
>>=
GEN10_IOR_TAP_CUR_SHIFT
;
ppshift_taps
=
gen10_read
(
PPS_IOR
);
ppshift_taps
>>=
GEN10_PPS_IOR_TAP_CUR_SHIFT
;
printf
(
"Calculated settings:
\n
"
);
printf
(
"period: %d ns (%d MHz)
\n
"
,
period_ns
,
1000
/
period_ns
);
printf
(
"high: %d ns; low: %d ns
\n
"
,
h_width
,
l_width
);
printf
(
"duty: %f
\n
"
,
(
float
)
h_width
*
CNT_RES
/
period_ns
);
printf
(
"coarse shift: %d
\n
"
,
(
cshift_ns
/
CNT_RES
)
*
CNT_RES
);
printf
(
"PPS shift: %d taps
\n
"
,
ppshift_taps
);
printf
(
"Signal delay: %d taps
\n
"
,
sigdel_taps
);
return
0
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
char
*
prgname
=
argv
[
0
];
float
freq_mhz
=
DEF_FREQ
;
float
duty
=
DEF_DUTY
;
int
cshift_ns
=
DEF_CSHIFT
;
int
sigdel_taps
=
DEF_SIGDEL
;
int
ppshift_taps
=
DEF_PPSHIFT
;
int
c
;
if
(
shw_fpga_mmap_init
()
<
0
)
{
fprintf
(
stderr
,
"%s: Can't access device memory
\n
"
,
prgname
);
exit
(
1
);
}
while
(
(
c
=
getopt_long
(
argc
,
argv
,
"h"
,
ropts
,
NULL
))
!=
-
1
)
{
switch
(
c
)
{
case
OPT_FREQ
:
freq_mhz
=
(
float
)
atof
(
optarg
);
break
;
case
OPT_DUTY
:
duty
=
(
float
)
atof
(
optarg
);
break
;
case
OPT_CSHIFT
:
cshift_ns
=
atoi
(
optarg
);
break
;
case
OPT_SIGDEL
:
sigdel_taps
=
atoi
(
optarg
);
break
;
case
OPT_PPSHIFT
:
ppshift_taps
=
atoi
(
optarg
);
break
;
case
OPT_HELP
:
default:
print_help
(
prgname
);
return
0
;
}
}
apply_settings
(
freq_mhz
,
duty
,
cshift_ns
,
sigdel_taps
,
ppshift_taps
);
return
0
;
}
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