Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit Switch - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
86
Issues
86
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
White Rabbit Switch - Software
Commits
a467691c
Commit
a467691c
authored
Apr 14, 2016
by
Adam Wujek
💬
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'greg-auxclk'
parents
2994b5e3
8c32932e
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
128 additions
and
79 deletions
+128
-79
wrs_auxclk.c
userspace/tools/wrs_auxclk.c
+128
-79
No files found.
userspace/tools/wrs_auxclk.c
View file @
a467691c
...
...
@@ -16,11 +16,11 @@
#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 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 */
...
...
@@ -40,7 +40,23 @@ struct option ropts[] = {
{
"cshift"
,
1
,
NULL
,
OPT_CSHIFT
},
{
"sigdel"
,
1
,
NULL
,
OPT_SIGDEL
},
{
"ppshift"
,
1
,
NULL
,
OPT_PPSHIFT
},
{
0
,}};
{
0
,}
};
/*******************/
/* data structures */
struct
params
{
float
freq_mhz
;
int
period_ns
;
float
duty
;
int
h_width
,
l_width
;
int
cshift_ns
;
int
sigdel_taps
;
int
ppshift_taps
;
};
/*******************/
int
print_help
(
char
*
prgname
)
...
...
@@ -51,54 +67,64 @@ int print_help(char *prgname)
return
0
;
}
int
apply_settings
(
float
freq_mhz
,
float
duty
,
int
cshift_ns
,
int
sigdel_taps
,
int
ppshift_taps
)
int
calc_settings
(
struct
params
*
req
,
struct
params
*
calc
)
{
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
;
}
calc
->
freq_mhz
=
req
->
freq_mhz
;
if
(
req
->
freq_mhz
>
MAX_FREQ
)
calc
->
freq_mhz
=
MAX_FREQ
;
if
(
req
->
freq_mhz
<
MIN_FREQ
)
calc
->
freq_mhz
=
MIN_FREQ
;
if
(
!
(
req
->
duty
>
0
&&
req
->
duty
<
1
))
req
->
duty
=
0
.
5
;
req
->
period_ns
=
1000
/
calc
->
freq_mhz
;
calc
->
h_width
=
req
->
period_ns
/
CNT_RES
*
req
->
duty
;
calc
->
l_width
=
req
->
period_ns
/
CNT_RES
-
calc
->
h_width
;
/* last step, calculate the actual frequency and period based on the
* actual h_width and l_width */
calc
->
period_ns
=
(
calc
->
h_width
+
calc
->
l_width
)
*
CNT_RES
;
calc
->
freq_mhz
=
1000
/
calc
->
period_ns
;
calc
->
duty
=
(
float
)
calc
->
h_width
*
CNT_RES
/
calc
->
period_ns
;
/* just copy the values that don't change */
calc
->
cshift_ns
=
req
->
cshift_ns
;
calc
->
sigdel_taps
=
req
->
sigdel_taps
;
calc
->
ppshift_taps
=
req
->
ppshift_taps
;
/* check if what's about to be generated matches the request */
if
(
req
->
period_ns
==
calc
->
period_ns
&&
req
->
duty
==
calc
->
duty
)
return
0
;
else
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
);
int
apply_settings
(
struct
params
*
p
)
{
gen10_write
(
PR
,
p
->
h_width
);
gen10_write
(
DCR
,
p
->
l_width
);
gen10_write
(
CSR
,
p
->
cshift_ns
/
CNT_RES
);
gen10_write
(
IOR
,
p
->
sigdel_taps
);
gen10_write
(
PPS_IOR
,
p
->
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
);
p
->
sigdel_taps
=
gen10_read
(
IOR
);
p
->
sigdel_taps
>>=
GEN10_IOR_TAP_CUR_SHIFT
;
p
->
ppshift_taps
=
gen10_read
(
PPS_IOR
);
p
->
ppshift_taps
>>=
GEN10_PPS_IOR_TAP_CUR_SHIFT
;
return
0
;
}
int
print_settings
(
FILE
*
f
,
struct
params
*
p
)
{
fprintf
(
f
,
"frequency: %.3f MHz (%d ns)
\n
"
,
p
->
freq_mhz
,
p
->
period_ns
);
fprintf
(
f
,
"high: %d ns; low: %d ns
\n
"
,
p
->
h_width
,
p
->
l_width
);
fprintf
(
f
,
"duty: %f
\n
"
,
p
->
duty
);
fprintf
(
f
,
"coarse shift: %d
\n
"
,
(
p
->
cshift_ns
/
CNT_RES
)
*
CNT_RES
);
fprintf
(
f
,
"PPS shift: %d taps
\n
"
,
p
->
ppshift_taps
);
fprintf
(
f
,
"Signal delay: %d taps
\n
"
,
p
->
sigdel_taps
);
return
0
;
}
...
...
@@ -106,42 +132,65 @@ int apply_settings(float freq_mhz, float duty, int cshift_ns, int sigdel_taps,
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
;
struct
params
req
=
{
DEF_FREQ
,
0
,
DEF_DUTY
,
0
,
0
,
DEF_CSHIFT
,
DEF_SIGDEL
,
DEF_PPSHIFT
};
struct
params
calc
;
int
c
,
ret
;
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
1
;
while
(
(
c
=
getopt_long
(
argc
,
argv
,
"h"
,
ropts
,
NULL
))
!=
-
1
)
{
switch
(
c
)
{
case
OPT_FREQ
:
req
.
freq_mhz
=
(
float
)
atof
(
optarg
);
break
;
case
OPT_DUTY
:
req
.
duty
=
(
float
)
atof
(
optarg
);
break
;
case
OPT_CSHIFT
:
req
.
cshift_ns
=
atoi
(
optarg
);
break
;
case
OPT_SIGDEL
:
req
.
sigdel_taps
=
atoi
(
optarg
);
break
;
case
OPT_PPSHIFT
:
req
.
ppshift_taps
=
atoi
(
optarg
);
break
;
case
OPT_HELP
:
default:
print_help
(
prgname
);
return
1
;
}
}
return
apply_settings
(
freq_mhz
,
duty
,
cshift_ns
,
sigdel_taps
,
ppshift_taps
);
ret
=
calc_settings
(
&
req
,
&
calc
);
if
(
!
(
calc
.
duty
>
0
&&
calc
.
duty
<
1
))
{
fprintf
(
stderr
,
"Requested duty %.2f (calculated %.2f)"
" outside range (0; 1)
\n
"
,
req
.
duty
,
calc
.
duty
);
return
1
;
}
/* now check the coarse shift */
if
(
calc
.
cshift_ns
>
calc
.
period_ns
||
calc
.
cshift_ns
<
0
)
{
fprintf
(
stderr
,
"Coarse shift outside range <0; %d>
\n
"
,
req
.
period_ns
);
return
1
;
}
if
(
ret
!=
0
)
{
fprintf
(
stderr
,
"Could not generate required signal, here is "
"the alternative you could use:
\n
"
);
print_settings
(
stderr
,
&
calc
);
return
1
;
}
apply_settings
(
&
calc
);
printf
(
"Applied settings:
\n
"
);
print_settings
(
stdout
,
&
calc
);
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