Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC DEL 1ns 4cha - Software
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
FMC DEL 1ns 4cha - Software
Commits
2e93c74f
Commit
2e93c74f
authored
May 04, 2012
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tdc and output: added user-offset attributes
parent
661065d7
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
199 additions
and
42 deletions
+199
-42
fine-delay.in
doc/fine-delay.in
+51
-12
fd-zio.c
fd-zio.c
+134
-30
fine-delay.h
fine-delay.h
+14
-0
No files found.
doc/fine-delay.in
View file @
2e93c74f
...
...
@@ -601,16 +601,21 @@ describing the cset:
@smallexample
spusa# ls -Ff /sys/bus/zio/devices/zio-fd-0200/fd-input/
./ enable utc-l chan
trigg
er/
../ current_trigger coarse flags
chan0
/
uevent current_buffer frac offset
name utc-h seq
power/
./ enable utc-l chan
pow
er/
../ current_trigger coarse flags
trigger
/
uevent current_buffer frac offset
chan0/
name utc-h seq
user-offset
@end smallexample
The timestamp-related values in this file reflect the last stamp that
has been enqueued to user space (this may be the next event to be
read by the actual reading process). The @i{offset} attribute
is the stamping offset, in picoseconds, for the TDC channe.
is the stamping offset, in picoseconds, for the TDC channel.
The @i{user-offset} attribute, which currently defaults to 0, is a
signed value that users can write to represent a number of picoseconds
to be added (or subtracted) to the hardware-reported stamps. This is
used to account for delays induced by cabling (range: -0.2s to 0.2s).
The @i{flags} attribute can be used to change three configuration
bits, defined by the respective macros. Please note that the default
...
...
@@ -756,6 +761,9 @@ The following attributes are defined:
FD_ATTR_OUT_DELTA_L,
FD_ATTR_OUT_DELTA_COARSE,
FD_ATTR_OUT_DELTA_FINE,
/* The two offsets */
FD_ATTR_OUT_DELAY_OFF,
FD_ATTR_OUT_USER_OFF,
FD_ATTR_OUT__LAST,
};
enum fd_output_mode {
...
...
@@ -768,10 +776,43 @@ The following attributes are defined:
So, to disable the output, just write 0 to the mode attribute.
To configure pulse or delay all attributes must be written.
@b{Note:} writing to @i{sysfs} is not working with this version of ZIO.
While recent developments introduced more complete consistency between
the various places where attributes live, with this version you can
only write attributes to the control block.
@b{Note:} writing the output configuration (mode, rep, start, end,
delta) to @i{sysfs} is not working with this version of ZIO. And I'
ve
been
too
lazy
to
add
code
to
do
that
.
While
recent
developments
introduced
more
complete
consistency
between
the
various
places
where
attributes
live
,
with
this
version
you
can
only
write
attributes
to
the
control
block
.
The
@
i
{
delay
-
offset
}
attribute
represents
an
offset
that
is
subtracted
from
the
user
-
requested
delay
(@
i
{
start
}
fields
)
when
generating
output
pulses
.
It
represents
internal
card
delays
.
The
value
can
be
modified
from
@
i
{
sysfs
}.
@
b
{
Note
:}
the
@
i
{
delay
-
offset
}
is
not
used
for
pulse
-
generation
mode
.
The
@
i
{
user
-
offset
}
attribute
,
which
currently
defaults
to
0
,
is
a
signed
value
that
users
can
write
to
represent
a
number
of
picoseconds
to
be
added
(
or
subtracted
)
to
the
every
user
-
command
(
for
both
delay
and
pulse
generation
).
This
is
used
to
account
for
delays
induced
by
cabling
(
range
:
-
0.2
s
to
0.2
s
).
The
value
can
be
modified
from
@
i
{
sysfs
}.
This
is
the
unsorted
content
of
the
@
i
{
sysfs
}
directory
for
each
of
the
output
csets
:
@
smallexample
spusa
#
COLUMNS
=
60
ls
-
fF
/
sys
/
bus
/
zio
/
devices
/
zio
-
fd
-
0200
/
fd
-
ch1
./
mode
end
-
l
user
-
offset
../
rep
end
-
coarse
power
/
uevent
start
-
h
end
-
fine
trigger
/
name
start
-
l
delta
-
l
chan0
/
enable
start
-
coarse
delta
-
coarse
current_trigger
start
-
fine
delta
-
fine
current_buffer
end
-
h
delay
-
offset
@
end
smallexample
As
said
,
only
@
i
{
delay
-
offset
}
and
@
i
{
user
-
offset
}
are
designed
to
be
written
by
the
user
.
@
menu
*
Using
fd
-
raw
-
output
::
...
...
@@ -1133,15 +1174,13 @@ allows:
@
itemize
@
bullet
@item There is no support for White Rabbit at this time.
@
item
Generation
of
delayed
pulses
is
missing
(
it
is
not
working
)
@
item
The
API
for
pulse
generation
is
not
yet
available
.
@
item
We
need
interrupt
support
.
The
input
is
performed
with
a
kernel
timer
.
@item There is no EEPROM support. The driver uses default calibration
@
item
There
is
no
EEPROM
support
.
The
driver
uses
default
calibration
.
settings
.
@
item
We
need
a
module
parameter
to
avoid
probing
non
-
fine
-
delay
SPEC
...
...
fd-zio.c
View file @
2e93c74f
...
...
@@ -38,7 +38,7 @@ DEFINE_ZATTR_STD(ZDEV, fd_zattr_dev_std) = {
/* Extended attributes for the device */
static
struct
zio_attribute
fd_zattr_dev
[]
=
{
ZATTR_EXT_REG
(
"version"
,
S_IRUGO
,
FD_ATTR_DEV_VERSION
,
ZATTR_EXT_REG
(
"version"
,
S_IRUGO
,
FD_ATTR_DEV_VERSION
,
FDELAY_VERSION
),
ZATTR_EXT_REG
(
"utc-h"
,
_RW_
,
FD_ATTR_DEV_UTC_H
,
0
),
ZATTR_EXT_REG
(
"utc-l"
,
_RW_
,
FD_ATTR_DEV_UTC_L
,
0
),
...
...
@@ -56,6 +56,7 @@ static struct zio_attribute fd_zattr_input[] = {
ZATTR_EXT_REG
(
"chan"
,
S_IRUGO
,
FD_ATTR_TDC_CHAN
,
0
),
ZATTR_EXT_REG
(
"flags"
,
_RW_
,
FD_ATTR_TDC_FLAGS
,
0
),
ZATTR_EXT_REG
(
"offset"
,
_RW_
,
FD_ATTR_TDC_OFFSET
,
0
),
ZATTR_EXT_REG
(
"user-offset"
,
_RW_
,
FD_ATTR_TDC_USER_OFF
,
0
),
};
/* Extended attributes for the output csets */
...
...
@@ -73,6 +74,8 @@ static struct zio_attribute fd_zattr_output[] = {
ZATTR_EXT_REG
(
"delta-l"
,
_RW_
,
FD_ATTR_OUT_DELTA_L
,
0
),
ZATTR_EXT_REG
(
"delta-coarse"
,
_RW_
,
FD_ATTR_OUT_DELTA_COARSE
,
0
),
ZATTR_EXT_REG
(
"delta-fine"
,
_RW_
,
FD_ATTR_OUT_DELTA_FINE
,
0
),
ZATTR_EXT_REG
(
"delay-offset"
,
_RW_
,
FD_ATTR_OUT_DELAY_OFF
,
0
),
ZATTR_EXT_REG
(
"user-offset"
,
_RW_
,
FD_ATTR_OUT_USER_OFF
,
0
),
};
...
...
@@ -96,7 +99,7 @@ static enum fd_devtype __fd_get_type(struct device *dev)
return
FD_TYPE_OUTPUT
;
}
/* TDC input attributes: only the offset is special */
/* TDC input attributes: only the
user
offset is special */
static
int
fd_zio_info_tdc
(
struct
device
*
dev
,
struct
zio_attribute
*
zattr
,
uint32_t
*
usr_val
)
{
...
...
@@ -106,6 +109,11 @@ static int fd_zio_info_tdc(struct device *dev, struct zio_attribute *zattr,
cset
=
to_zio_cset
(
dev
);
fd
=
cset
->
zdev
->
private_data
;
if
(
zattr
->
priv
.
addr
==
FD_ATTR_TDC_USER_OFF
)
{
*
usr_val
=
fd
->
calib
.
tdc_user_offset
;
return
0
;
}
/*
* For efficiency reasons at read_fifo() time, we store an
* array of integers instead of filling attributes, so here
...
...
@@ -116,6 +124,29 @@ static int fd_zio_info_tdc(struct device *dev, struct zio_attribute *zattr,
return
0
;
}
/* output channel: only the two offsets */
static
int
fd_zio_info_output
(
struct
device
*
dev
,
struct
zio_attribute
*
zattr
,
uint32_t
*
usr_val
)
{
struct
zio_cset
*
cset
;
struct
spec_fd
*
fd
;
int
ch
;
cset
=
to_zio_cset
(
dev
);
ch
=
cset
->
index
-
1
;
fd
=
cset
->
zdev
->
private_data
;
if
(
zattr
->
priv
.
addr
==
FD_ATTR_OUT_DELAY_OFF
)
{
*
usr_val
=
fd
->
calib
.
zero_offset
[
ch
];
return
0
;
}
if
(
zattr
->
priv
.
addr
==
FD_ATTR_OUT_USER_OFF
)
{
*
usr_val
=
fd
->
calib
.
ch_user_offset
[
ch
];
return
0
;
}
return
0
;
}
static
int
fd_wr_mode
(
struct
spec_fd
*
fd
,
int
on
)
{
if
(
on
)
{
...
...
@@ -151,8 +182,10 @@ static int fd_zio_info_get(struct device *dev, struct zio_attribute *zattr,
if
(
__fd_get_type
(
dev
)
==
FD_TYPE_INPUT
)
return
fd_zio_info_tdc
(
dev
,
zattr
,
usr_val
);
if
(
__fd_get_type
(
dev
)
!=
FD_TYPE_WHOLEDEV
)
return
0
;
if
(
__fd_get_type
(
dev
)
==
FD_TYPE_OUTPUT
)
return
fd_zio_info_output
(
dev
,
zattr
,
usr_val
);
/* following is whole-dev */
if
(
zattr
->
priv
.
addr
!=
FD_ATTR_DEV_UTC_H
)
return
0
;
/* reading utc-h calls an atomic get-time */
...
...
@@ -182,8 +215,10 @@ static int fd_zio_conf_tdc(struct device *dev, struct zio_attribute *zattr,
switch
(
zattr
->
priv
.
addr
)
{
case
FD_ATTR_TDC_OFFSET
:
fd
->
calib
.
tdc_zero_offset
=
usr_val
;
pr_info
(
"%s: set new offset: %i
\n
"
,
__func__
,
fd
->
calib
.
tdc_zero_offset
);
goto
out
;
case
FD_ATTR_TDC_USER_OFF
:
fd
->
calib
.
tdc_user_offset
=
usr_val
;
goto
out
;
case
FD_ATTR_TDC_FLAGS
:
...
...
@@ -227,6 +262,29 @@ out:
return
0
;
}
/* only the two offsets */
static
int
fd_zio_conf_output
(
struct
device
*
dev
,
struct
zio_attribute
*
zattr
,
uint32_t
usr_val
)
{
struct
zio_cset
*
cset
;
struct
spec_fd
*
fd
;
int
ch
;
cset
=
to_zio_cset
(
dev
);
fd
=
cset
->
zdev
->
private_data
;
ch
=
cset
->
index
-
1
;
if
(
zattr
->
priv
.
addr
==
FD_ATTR_OUT_DELAY_OFF
)
{
fd
->
calib
.
zero_offset
[
ch
]
=
usr_val
;
return
0
;
}
if
(
zattr
->
priv
.
addr
==
FD_ATTR_OUT_USER_OFF
)
{
fd
->
calib
.
ch_user_offset
[
ch
]
=
usr_val
;
return
0
;
}
return
0
;
}
/* conf_set dispatcher and and device-wide attributes */
static
int
fd_zio_conf_set
(
struct
device
*
dev
,
struct
zio_attribute
*
zattr
,
uint32_t
usr_val
)
...
...
@@ -236,9 +294,12 @@ static int fd_zio_conf_set(struct device *dev, struct zio_attribute *zattr,
struct
spec_fd
*
fd
;
struct
zio_attribute
*
attr
;
if
(
__fd_get_type
(
dev
)
!=
FD_TYPE_WHOLEDEV
)
if
(
__fd_get_type
(
dev
)
==
FD_TYPE_INPUT
)
return
fd_zio_conf_tdc
(
dev
,
zattr
,
usr_val
);
if
(
__fd_get_type
(
dev
)
==
FD_TYPE_OUTPUT
)
return
fd_zio_conf_output
(
dev
,
zattr
,
usr_val
);
/* Remains: wholedev */
zdev
=
to_zio_dev
(
dev
);
attr
=
zdev
->
zattr_set
.
ext_zattr
;
fd
=
zdev
->
private_data
;
...
...
@@ -295,6 +356,64 @@ static void fd_ts_sub(struct fd_time *t, uint64_t pico)
}
}
/* We need to change the time in attribute tuples, so here it is */
enum
attrs
{
__UTC_H
,
__UTC_L
,
__COARSE
,
__FRAC
};
/* the order of our attrs */
static
void
fd_attr_sub
(
uint32_t
*
a
,
uint32_t
pico
)
{
uint32_t
coarse
,
frac
;
fd_split_pico
(
pico
,
&
coarse
,
&
frac
);
if
(
a
[
__FRAC
]
>=
frac
)
{
a
[
__FRAC
]
-=
frac
;
}
else
{
a
[
__FRAC
]
+=
4096
;
a
[
__FRAC
]
-=
frac
;
coarse
++
;
}
if
(
a
[
__COARSE
]
>=
coarse
)
{
a
[
__COARSE
]
-=
coarse
;
}
else
{
a
[
__COARSE
]
+=
125
*
1000
*
1000
;
a
[
__COARSE
]
-=
coarse
;
if
(
likely
(
a
[
__UTC_L
]
!=
0
))
{
a
[
__UTC_L
]
--
;
}
else
{
a
[
__UTC_L
]
=
~
0
;
a
[
__UTC_H
]
--
;
}
}
}
static
void
fd_attr_add
(
uint32_t
*
a
,
uint32_t
pico
)
{
uint32_t
coarse
,
frac
;
fd_split_pico
(
pico
,
&
coarse
,
&
frac
);
a
[
__FRAC
]
+=
frac
;
if
(
a
[
__FRAC
]
>=
4096
)
{
a
[
__FRAC
]
-=
4096
;
coarse
++
;
}
a
[
__COARSE
]
+=
coarse
;
if
(
a
[
__COARSE
]
>
125
*
1000
*
1000
)
{
a
[
__COARSE
]
-=
125
*
1000
*
1000
;
a
[
__UTC_L
]
++
;
if
(
unlikely
(
a
[
__UTC_L
]
==
0
))
a
[
__UTC_H
]
++
;
}
}
static
inline
void
__fd_apply_offset
(
uint32_t
*
a
,
int32_t
off_pico
)
{
if
(
off_pico
)
{
if
(
off_pico
>
0
)
fd_attr_add
(
a
,
off_pico
);
else
fd_attr_sub
(
a
,
-
off_pico
);
}
}
static
int
fd_read_fifo
(
struct
spec_fd
*
fd
,
struct
zio_channel
*
chan
)
{
struct
zio_control
*
ctrl
;
...
...
@@ -329,6 +448,8 @@ static int fd_read_fifo(struct spec_fd *fd, struct zio_channel *chan)
v
[
FD_ATTR_TDC_CHAN
]
=
t
.
channel
;
v
[
FD_ATTR_TDC_OFFSET
]
=
fd
->
calib
.
tdc_zero_offset
;
__fd_apply_offset
(
v
+
FD_ATTR_TDC_UTC_H
,
fd
->
calib
.
tdc_user_offset
);
/* We also need a copy within the device, so sysfs can read it */
memcpy
(
fd
->
tdc_attrs
,
v
+
FD_ATTR_DEV__LAST
,
sizeof
(
fd
->
tdc_attrs
));
...
...
@@ -394,30 +515,13 @@ static void __fd_zio_output(struct spec_fd *fd, int index1_4, uint32_t *attrs)
}
if
(
mode
==
FD_OUT_MODE_DELAY
)
{
uint32_t
coarse
,
frac
;
/* To use fd_ts_sub(), but I'd need to convert twice */
fd_split_pico
(
fd
->
calib
.
zero_offset
[
ch
],
&
coarse
,
&
frac
);
if
(
attrs
[
FD_ATTR_OUT_START_FINE
]
>=
frac
)
{
attrs
[
FD_ATTR_OUT_START_FINE
]
-=
frac
;
}
else
{
attrs
[
FD_ATTR_OUT_START_FINE
]
+=
4096
;
attrs
[
FD_ATTR_OUT_START_FINE
]
-=
frac
;
coarse
++
;
}
if
(
attrs
[
FD_ATTR_OUT_START_COARSE
]
>=
coarse
)
{
attrs
[
FD_ATTR_OUT_START_COARSE
]
-=
coarse
;
}
else
{
attrs
[
FD_ATTR_OUT_START_COARSE
]
+=
125
*
1000
*
1000
;
attrs
[
FD_ATTR_OUT_START_COARSE
]
-=
coarse
;
if
(
likely
(
attrs
[
FD_ATTR_OUT_START_L
]
!=
0
))
{
attrs
[
FD_ATTR_OUT_START_L
]
--
;
}
else
{
attrs
[
FD_ATTR_OUT_START_L
]
=
~
0
;
attrs
[
FD_ATTR_OUT_START_H
]
--
;
}
}
fd_attr_sub
(
attrs
+
FD_ATTR_OUT_START_H
,
fd
->
calib
.
zero_offset
[
ch
]);
}
__fd_apply_offset
(
attrs
+
FD_ATTR_OUT_START_H
,
fd
->
calib
.
ch_user_offset
[
ch
]);
fd_ch_writel
(
fd
,
ch
,
fd
->
ch
[
ch
].
frr_cur
,
FD_REG_FRR
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_START_H
],
FD_REG_U_STARTH
);
...
...
fine-delay.h
View file @
2e93c74f
...
...
@@ -11,6 +11,11 @@
* it when the layout of attributes changes in incompatible ways)
*/
/*
* NOTE: all tuples of 4 register must be enumerated in the proper order:
* utc-h, utc-l, coarse, frac __IN_THIS_ORDER__ because I make arith on them
*/
/* Device-wide ZIO attributes */
enum
fd_zattr_dev_idx
{
FD_ATTR_DEV_VERSION
=
0
,
...
...
@@ -35,6 +40,7 @@ enum fd_command {
/* Input ZIO attributes (i.e. TDC attributes) */
enum
fd_zattr_in_idx
{
/* PLEASE check "NOTE:" above if you edit this*/
FD_ATTR_TDC_UTC_H
=
FD_ATTR_DEV__LAST
,
FD_ATTR_TDC_UTC_L
,
FD_ATTR_TDC_COARSE
,
...
...
@@ -43,6 +49,7 @@ enum fd_zattr_in_idx {
FD_ATTR_TDC_CHAN
,
FD_ATTR_TDC_FLAGS
,
/* enable, termination, see below */
FD_ATTR_TDC_OFFSET
,
FD_ATTR_TDC_USER_OFF
,
FD_ATTR_TDC__LAST
,
};
/* Names have been chosen so that 0 is the default at load time */
...
...
@@ -54,6 +61,7 @@ enum fd_zattr_in_idx {
enum
fd_zattr_out_idx
{
FD_ATTR_OUT_MODE
=
FD_ATTR_DEV__LAST
,
FD_ATTR_OUT_REP
,
/* PLEASE check "NOTE:" above if you edit this*/
/* Start (or delay) is 4 registers */
FD_ATTR_OUT_START_H
,
FD_ATTR_OUT_START_L
,
...
...
@@ -68,6 +76,9 @@ enum fd_zattr_out_idx {
FD_ATTR_OUT_DELTA_L
,
FD_ATTR_OUT_DELTA_COARSE
,
FD_ATTR_OUT_DELTA_FINE
,
/* The two offsets */
FD_ATTR_OUT_DELAY_OFF
,
FD_ATTR_OUT_USER_OFF
,
FD_ATTR_OUT__LAST
,
};
enum
fd_output_mode
{
...
...
@@ -97,6 +108,9 @@ struct fd_calib {
uint32_t
acam_start_offset
;
/* ACAM Start offset value */
uint32_t
atmcr_val
;
/* ATMCR register value */
uint32_t
tdc_zero_offset
;
/* Zero offset of the TDC, in ps */
/* The user can add a signed offset, in picoseconds */
int32_t
tdc_user_offset
;
int32_t
ch_user_offset
[
4
];
};
/* Channels are called 1..4 in all docs. Internally it's 0..3 */
...
...
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