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
c9d36726
Commit
c9d36726
authored
May 03, 2012
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fd-zio: output begins to work, added tools/fd-raw-output
parent
dfceb810
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
262 additions
and
10 deletions
+262
-10
fd-zio.c
fd-zio.c
+137
-9
fine-delay.h
fine-delay.h
+31
-0
.gitignore
tools/.gitignore
+1
-1
Makefile
tools/Makefile
+1
-0
fd-raw-output.c
tools/fd-raw-output.c
+92
-0
No files found.
fd-zio.c
View file @
c9d36726
...
...
@@ -26,6 +26,7 @@
#include "spec.h"
#include "fine-delay.h"
#include "hw/fd_main_regs.h"
#include "hw/fd_channel_regs.h"
/* The sample size. Mandatory, device-wide */
DEFINE_ZATTR_STD
(
ZDEV
,
fd_zattr_dev_std
)
=
{
...
...
@@ -54,6 +55,24 @@ static struct zio_attribute fd_zattr_input[] = {
ZATTR_EXT_REG
(
"offset"
,
S_IRUGO
,
FD_ATTR_TDC_OFFSET
,
0
),
};
/* Extended attributes for the output csets */
#define _RW_ (S_IRUGO | S_IWUGO)
static
struct
zio_attribute
fd_zattr_output
[]
=
{
ZATTR_EXT_REG
(
"mode"
,
_RW_
,
FD_ATTR_OUT_MODE
,
0
),
ZATTR_EXT_REG
(
"rep"
,
_RW_
,
FD_ATTR_OUT_REP
,
0
),
ZATTR_EXT_REG
(
"start-h"
,
_RW_
,
FD_ATTR_OUT_START_H
,
0
),
ZATTR_EXT_REG
(
"start-l"
,
_RW_
,
FD_ATTR_OUT_START_L
,
0
),
ZATTR_EXT_REG
(
"start-coarse"
,
_RW_
,
FD_ATTR_OUT_START_COARSE
,
0
),
ZATTR_EXT_REG
(
"start-fine"
,
_RW_
,
FD_ATTR_OUT_START_FINE
,
0
),
ZATTR_EXT_REG
(
"end-h"
,
_RW_
,
FD_ATTR_OUT_END_H
,
0
),
ZATTR_EXT_REG
(
"end-l"
,
_RW_
,
FD_ATTR_OUT_END_L
,
0
),
ZATTR_EXT_REG
(
"end-coarse"
,
_RW_
,
FD_ATTR_OUT_END_COARSE
,
0
),
ZATTR_EXT_REG
(
"end-fine"
,
_RW_
,
FD_ATTR_OUT_END_FINE
,
0
),
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
),
};
/* This identifies if our "struct device" is device, input, output */
enum
fd_devtype
{
...
...
@@ -285,6 +304,7 @@ static void fd_timer_fn(unsigned long arg)
struct
spec_fd
*
fd
=
(
void
*
)
arg
;
struct
zio_channel
*
chan
=
NULL
;
struct
zio_device
*
zdev
=
fd
->
zdev
;
int
i
;
if
(
zdev
)
{
chan
=
zdev
->
cset
[
0
].
chan
;
...
...
@@ -304,14 +324,106 @@ static void fd_timer_fn(unsigned long arg)
}
out:
/* Check all output channels with a pending block (FIXME: bad) */
for
(
i
=
1
;
i
<
5
;
i
++
)
if
(
test_and_clear_bit
(
FD_FLAG_DO_OUTPUT
+
i
,
&
fd
->
flags
))
{
struct
zio_cset
*
cset
=
fd
->
zdev
->
cset
+
i
;
cset
->
ti
->
t_op
->
data_done
(
cset
);
printk
(
"called data_done
\n
"
);
}
mod_timer
(
&
fd
->
fifo_timer
,
jiffies
+
fd_timer_period_jiffies
);
}
static
int
fd_output
(
struct
zio_cset
*
cset
)
/* Internal output engine */
static
void
__fd_zio_output
(
struct
spec_fd
*
fd
,
int
index1_4
,
uint32_t
*
attrs
)
{
int
ch
=
index1_4
-
1
;
int
mode
=
attrs
[
FD_ATTR_OUT_MODE
];
int
rep
=
attrs
[
FD_ATTR_OUT_REP
];
int
dcr
;
if
(
mode
==
FD_OUT_MODE_DISABLED
)
{
fd_gpio_clr
(
fd
,
FD_GPIO_OUTPUT_EN
(
index1_4
));
return
;
}
if
(
mode
==
FD_OUT_MODE_DELAY
)
{
/* FIXME: subtract zero offset */
}
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
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_START_L
],
FD_REG_U_STARTL
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_START_COARSE
],
FD_REG_C_START
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_START_FINE
],
FD_REG_F_START
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_END_H
],
FD_REG_U_ENDH
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_END_L
],
FD_REG_U_ENDL
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_END_COARSE
],
FD_REG_C_END
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_END_FINE
],
FD_REG_F_END
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_DELTA_L
],
FD_REG_U_DELTA
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_DELTA_COARSE
],
FD_REG_C_DELTA
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_DELTA_FINE
],
FD_REG_F_DELTA
);
if
(
mode
==
FD_OUT_MODE_DELAY
)
{
dcr
=
0
;
fd_ch_writel
(
fd
,
ch
,
FD_RCR_REP_CNT_W
(
rep
-
1
)
|
(
rep
<
0
?
FD_RCR_CONT
:
0
),
FD_REG_RCR
);
}
else
{
dcr
=
FD_DCR_MODE
;
fd_ch_writel
(
fd
,
ch
,
FD_RCR_REP_CNT_W
(
rep
<
0
?
0
:
rep
-
1
)
|
(
rep
<
0
?
FD_RCR_CONT
:
0
),
FD_REG_RCR
);
}
/*
* For narrowly spaced pulses, we don't have enough time to reload
* the tap number into the corresponding SY89295.
* Therefore, the width/spacing resolution is limited to 4 ns.
* We put the threshold at 200ns ==> coarse == 25
*/
/* FIXME: if((delta_ps - width_ps) < 200000 ||
(width_ps < 200000)) dcr = FD_DCR_NO_FINE; */
//dcr |= FD_DCR_NO_FINE;
fd_ch_writel
(
fd
,
ch
,
dcr
|
FD_DCR_UPDATE
,
FD_REG_DCR
);
fd_ch_writel
(
fd
,
ch
,
dcr
|
FD_DCR_ENABLE
,
FD_REG_DCR
);
if
(
mode
==
FD_OUT_MODE_PULSE
)
fd_ch_writel
(
fd
,
ch
,
dcr
|
FD_DCR_ENABLE
|
FD_DCR_PG_ARM
,
FD_REG_DCR
);
fd_gpio_set
(
fd
,
FD_GPIO_OUTPUT_EN
(
index1_4
));
}
/* This is called on user write */
static
int
fd_zio_output
(
struct
zio_cset
*
cset
)
{
/* FIXME: the output channels */
int
i
;
struct
spec_fd
*
fd
;
struct
zio_control
*
ctrl
;
fd
=
cset
->
zdev
->
private_data
;
ctrl
=
zio_get_ctrl
(
cset
->
chan
->
active_block
);
for
(
i
=
0
;
i
<
4
;
i
++
)
printk
(
"triggered %i: %x (%i)
\n
"
,
i
,
fd_ch_readl
(
fd
,
i
,
FD_REG_DCR
),
fd_ch_readl
(
fd
,
i
,
FD_REG_DCR
)
&
FD_DCR_PG_TRIG
?
1
:
0
);
return
0
;
/* Already done, as the trigger is hardware */
pr_info
(
"%s: attrs: "
,
__func__
);
for
(
i
=
FD_ATTR_DEV__LAST
;
i
<
FD_ATTR_OUT__LAST
;
i
++
)
printk
(
"%08x%c"
,
ctrl
->
attr_channel
.
ext_val
[
i
],
i
==
FD_ATTR_OUT__LAST
-
1
?
'\n'
:
' '
);
__fd_zio_output
(
fd
,
cset
->
index
,
ctrl
->
attr_channel
.
ext_val
);
/*
* There's a buglet in this version of zio: we can't
* just return 0 to say "done". We need to do it later.
*/
set_bit
(
FD_FLAG_DO_OUTPUT
+
cset
->
index
,
&
fd
->
flags
);
return
-
EAGAIN
;
}
/*
...
...
@@ -319,7 +431,7 @@ static int fd_output(struct zio_cset *cset)
* asynchronous. The data_done callback is invoked when the block is
* full.
*/
static
int
fd_input
(
struct
zio_cset
*
cset
)
static
int
fd_
zio_
input
(
struct
zio_cset
*
cset
)
{
struct
spec_fd
*
fd
;
fd
=
cset
->
zdev
->
private_data
;
...
...
@@ -370,7 +482,7 @@ static const struct zio_sysfs_operations fd_zio_s_op = {
static
struct
zio_cset
fd_cset
[]
=
{
{
SET_OBJECT_NAME
(
"fd-input"
),
.
raw_io
=
fd_input
,
.
raw_io
=
fd_
zio_
input
,
.
n_chan
=
1
,
.
ssize
=
4
,
/* FIXME: 0? */
.
flags
=
ZIO_DIR_INPUT
|
ZCSET_TYPE_TIME
,
...
...
@@ -381,31 +493,47 @@ static struct zio_cset fd_cset[] = {
},
{
SET_OBJECT_NAME
(
"fd-ch1"
),
.
raw_io
=
fd_output
,
.
raw_io
=
fd_
zio_
output
,
.
n_chan
=
1
,
.
ssize
=
4
,
/* FIXME: 0? */
.
flags
=
ZIO_DIR_OUTPUT
|
ZCSET_TYPE_TIME
,
.
zattr_set
=
{
.
ext_zattr
=
fd_zattr_output
,
.
n_ext_attr
=
ARRAY_SIZE
(
fd_zattr_output
),
},
},
{
SET_OBJECT_NAME
(
"fd-ch2"
),
.
raw_io
=
fd_output
,
.
raw_io
=
fd_
zio_
output
,
.
n_chan
=
1
,
.
ssize
=
4
,
/* FIXME: 0? */
.
flags
=
ZIO_DIR_OUTPUT
|
ZCSET_TYPE_TIME
,
.
zattr_set
=
{
.
ext_zattr
=
fd_zattr_output
,
.
n_ext_attr
=
ARRAY_SIZE
(
fd_zattr_output
),
},
},
{
SET_OBJECT_NAME
(
"fd-ch3"
),
.
raw_io
=
fd_output
,
.
raw_io
=
fd_
zio_
output
,
.
n_chan
=
1
,
.
ssize
=
4
,
/* FIXME: 0? */
.
flags
=
ZIO_DIR_OUTPUT
|
ZCSET_TYPE_TIME
,
.
zattr_set
=
{
.
ext_zattr
=
fd_zattr_output
,
.
n_ext_attr
=
ARRAY_SIZE
(
fd_zattr_output
),
},
},
{
SET_OBJECT_NAME
(
"fd-ch4"
),
.
raw_io
=
fd_output
,
.
raw_io
=
fd_
zio_
output
,
.
n_chan
=
1
,
.
ssize
=
4
,
/* FIXME: 0? */
.
flags
=
ZIO_DIR_OUTPUT
|
ZCSET_TYPE_TIME
,
.
zattr_set
=
{
.
ext_zattr
=
fd_zattr_output
,
.
n_ext_attr
=
ARRAY_SIZE
(
fd_zattr_output
),
},
},
};
...
...
fine-delay.h
View file @
c9d36726
...
...
@@ -47,6 +47,32 @@ enum fd_zattr_in_idx {
#define FD_TDCF_DISABLE_TSTAMP 2
#define FD_TDCF_TERM_50 4
/* Output ZIO attributes */
enum
fd_zattr_out_idx
{
FD_ATTR_OUT_MODE
=
FD_ATTR_DEV__LAST
,
FD_ATTR_OUT_REP
,
/* Start (or delay) is 4 registers */
FD_ATTR_OUT_START_H
,
FD_ATTR_OUT_START_L
,
FD_ATTR_OUT_START_COARSE
,
FD_ATTR_OUT_START_FINE
,
/* End (start + width) is 4 registers */
FD_ATTR_OUT_END_H
,
FD_ATTR_OUT_END_L
,
FD_ATTR_OUT_END_COARSE
,
FD_ATTR_OUT_END_FINE
,
/* Delta is 3 registers */
FD_ATTR_OUT_DELTA_L
,
FD_ATTR_OUT_DELTA_COARSE
,
FD_ATTR_OUT_DELTA_FINE
,
FD_ATTR_OUT__LAST
,
};
enum
fd_output_mode
{
FD_OUT_MODE_DISABLED
=
0
,
FD_OUT_MODE_DELAY
,
FD_OUT_MODE_PULSE
,
};
/*
* Cset attributes are concatenated to device attributes in the control
* structure, but they start from 0 when allocate for the individual cset
...
...
@@ -113,6 +139,11 @@ enum fd_flags {
FD_FLAG_INITED
=
0
,
FD_FLAG_DO_INPUT
,
FD_FLAG_INPUT_READY
,
FD_FLAG_DO_OUTPUT
,
_FD_FLAG_DO_OUTPUT1
,
/* use: FD_FLAG_DO_OUTPUT + cset->index */
_FD_FLAG_DO_OUTPUT2
,
_FD_FLAG_DO_OUTPUT3
,
_FD_FLAG_DO_OUTPUT4
,
};
/* Internal time: the first three fields should be converted to zio time */
...
...
tools/.gitignore
View file @
c9d36726
...
...
@@ -2,4 +2,4 @@ fd-raw-input
parport-burst
fd-raw-gettime
fd-raw-settime
fd-raw-output
tools/Makefile
View file @
c9d36726
...
...
@@ -8,6 +8,7 @@ hostprogs-y := fd-raw-input
hostprogs-y
+=
fd-raw-gettime
hostprogs-y
+=
fd-raw-settime
hostprogs-y
+=
parport-burst
hostprogs-y
+=
fd-raw-output
# we are not in the kernel, so we need to piggy-back on "make modules"
modules
:
$(hostprogs-y)
...
...
tools/fd-raw-output.c
0 → 100644
View file @
c9d36726
/*
* an output tools that accesses the ZIO device
*
* Copyright (C) 2012 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2 as published by the Free Software Foundation or, at your
* option, any later version.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <glob.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/zio.h>
#include <linux/zio-user.h>
#include <fine-delay.h>
int
main
(
int
argc
,
char
**
argv
)
{
glob_t
glob_buf
;
struct
zio_control
ctrl
;
int
fdc
,
fdd
;
char
*
s
;
int
i
,
j
,
val
,
ch
;
uint32_t
*
attrs
;
/* glob to find the device; use the first */
glob
(
"/dev/zio-fd-*-1-0-ctrl"
,
0
,
NULL
,
&
glob_buf
);
glob
(
"/dev/zio/zio-fd-*-1-0-ctrl"
,
GLOB_APPEND
,
NULL
,
&
glob_buf
);
if
(
glob_buf
.
gl_pathc
!=
1
)
{
fprintf
(
stderr
,
"%s: found %i devices, need 1 only
\n
"
,
argv
[
0
],
glob_buf
.
gl_pathc
);
exit
(
1
);
}
s
=
glob_buf
.
gl_pathv
[
0
];
if
(
getenv
(
"CHAN"
))
{
/* Hack: change the channel */
ch
=
atoi
(
getenv
(
"CHAN"
));
if
(
ch
)
s
[
strlen
(
s
)
-
strlen
(
"1-0-ctrl"
)]
=
'0'
+
ch
;
}
fdc
=
open
(
s
,
O_WRONLY
);
if
(
fdc
<
0
)
{
fprintf
(
stderr
,
"%s: %s: %s
\n
"
,
argv
[
0
],
s
,
strerror
(
errno
));
exit
(
1
);
}
/* Open the data file too, lazily */
strcpy
(
s
+
strlen
(
s
)
-
4
,
"data"
);
fdd
=
open
(
s
,
O_WRONLY
);
if
(
fdd
<
0
)
{
fprintf
(
stderr
,
"%s: %s: %s
\n
"
,
argv
[
0
],
s
,
strerror
(
errno
));
exit
(
1
);
}
memset
(
&
ctrl
,
0
,
sizeof
(
ctrl
));
attrs
=
ctrl
.
attr_channel
.
ext_val
;
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
j
=
i
-
1
+
FD_ATTR_DEV__LAST
;
if
(
sscanf
(
argv
[
i
],
"+%i"
,
&
val
)
==
1
)
{
val
+=
time
(
NULL
);
}
else
if
(
sscanf
(
argv
[
i
],
"%i"
,
&
val
)
!=
1
)
{
fprintf
(
stderr
,
"%s: not a number
\"
%s
\"\n
"
,
argv
[
0
],
argv
[
i
]);
exit
(
1
);
}
attrs
[
j
]
=
val
;
}
/* we need to fill the nsample field of the control */
ctrl
.
attr_trigger
.
std_val
[
1
]
=
1
;
ctrl
.
nsamples
=
1
;
ctrl
.
ssize
=
4
;
ctrl
.
nbits
=
32
;
write
(
fdc
,
&
ctrl
,
sizeof
(
ctrl
));
write
(
fdd
,
"1234"
,
4
);
/* we need to write data to push it out */
exit
(
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