Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC ADC 100M 14b 4cha - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
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 ADC 100M 14b 4cha - Software
Commits
4d718e33
Commit
4d718e33
authored
Feb 27, 2019
by
Federico Vaga
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into feature/platform
parents
ba43309b
1401c213
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
77 additions
and
29 deletions
+77
-29
driver-user.rst
doc/driver-user.rst
+18
-3
fa-calibration.c
kernel/fa-calibration.c
+26
-7
fa-zio-drv.c
kernel/fa-zio-drv.c
+2
-2
fau-calibration.c
tools/fau-calibration.c
+31
-17
No files found.
doc/driver-user.rst
View file @
4d718e33
...
...
@@ -181,10 +181,18 @@ The ADC registers can be accessed in the proper sysfs directory. For a
card in slot 0 of bus 2 (like shown above), the directory is
*/sys/bus/zio/devices/adc-100m14b-0200*.
The overall device (*adc-100m14b*) does not offer configuration items
besides its own temperature (read-only) because configuration is
specific of the cset and the trigger, or the individual channel.
The overall device (*adc-100m14b*) provides the following attributes:
calibration_data
It is a binary attribute which allows the user to change the runt-time
calibration data (the EEPROM will not be touched). The ``fau-calibration``
tool can be used to read write calibration data.
To be consistent, this binary interface expects **only** little endian
values because this is the endianess used to store calibration data for
this device.
temperature
It shows the current temperature
The Channel Set
'''''''''''''''
...
...
@@ -511,6 +519,13 @@ integer.
- Values
- Comments
* - device
- calibration_data
- rw
- --
-
- Run-time calibration data
* - device
- temperature
- ro
...
...
kernel/fa-calibration.c
View file @
4d718e33
...
...
@@ -73,24 +73,40 @@ static void fa_verify_calib(struct device *msgdev,
}
}
static
void
fa_endian_calib
(
struct
fa_calib
*
calib
)
/**
* @calib: calibration data
*
* We know for sure that our structure is only made of 16bit fields
*/
static
void
fa_calib_le16_to_cpus
(
struct
fa_calib
*
calib
)
{
int
i
;
uint16_t
*
p
=
(
void
*
)
calib
;
/* We know for sure that our structure is only made of 16bit fields */
for
(
i
=
0
;
i
<
sizeof
(
*
calib
)
/
sizeof
(
uint16_t
);
i
++
)
le16_to_cpus
(
p
+
i
);
/* s == in situ */
}
/**
* @calib: calibration data
*
* We know for sure that our structure is only made of 16bit fields
*/
static
void
fa_calib_cpu_to_le16s
(
struct
fa_calib
*
calib
)
{
int
i
;
uint16_t
*
p
=
(
void
*
)
calib
;
for
(
i
=
0
;
i
<
sizeof
(
*
calib
)
/
sizeof
(
uint16_t
);
i
++
)
cpu_to_le16s
(
p
+
i
);
/* s == in situ */
}
void
fa_identity_calib_set
(
struct
fa_dev
*
fa
)
{
/* Retrieve calibration data from the eeprom, then verify it */
memcpy
(
&
fa
->
calib
,
&
fa_identity_calib
,
sizeof
(
fa
->
calib
));
fa_
endian_calib
(
&
fa
->
calib
);
fa_
calib_le16_to_cpus
(
&
fa
->
calib
);
fa_verify_calib
(
&
fa
->
pdev
->
dev
,
&
fa
->
calib
,
&
fa_identity_calib
);
dev_info
(
fa
->
msgdev
,
"%s succeeds.
\n
"
,
__func__
);
}
/**
...
...
@@ -119,7 +135,7 @@ static ssize_t fa_write_eeprom(struct file *file, struct kobject *kobj,
if
(
off
!=
0
||
count
!=
sizeof
(
*
calib
))
return
-
EINVAL
;
fa_
endian_calib
(
calib
);
fa_
calib_le16_to_cpus
(
calib
);
fa_verify_calib
(
dev
,
calib
,
&
fa_identity_calib
);
/*
...
...
@@ -139,11 +155,14 @@ static ssize_t fa_read_eeprom(struct file *file, struct kobject *kobj,
{
struct
device
*
dev
=
container_of
(
kobj
,
struct
device
,
kobj
);
struct
fa_dev
*
fa
=
get_zfadc
(
dev
);
struct
fa_calib
*
calib
=
(
struct
fa_calib
*
)
buf
;
if
(
off
!=
0
||
count
<
sizeof
(
fa
->
calib
))
return
-
EINVAL
;
memcpy
(
buf
,
&
fa
->
calib
,
sizeof
(
fa
->
calib
));
memcpy
(
calib
,
&
fa
->
calib
,
sizeof
(
fa
->
calib
));
fa_calib_cpu_to_le16s
(
calib
);
return
count
;
}
...
...
@@ -151,7 +170,7 @@ static ssize_t fa_read_eeprom(struct file *file, struct kobject *kobj,
struct
bin_attribute
dev_attr_calibration
=
{
.
attr
=
{
.
name
=
"calibration_data"
,
.
mode
=
0
7
44
,
.
mode
=
0
6
44
,
},
.
size
=
sizeof
(
struct
fa_calib
),
.
write
=
fa_write_eeprom
,
...
...
kernel/fa-zio-drv.c
View file @
4d718e33
...
...
@@ -544,7 +544,7 @@ static int zfad_zio_probe(struct zio_device *zdev)
if
(
err
)
return
err
;
err
=
device_create_bin_file
(
&
zdev
->
cset
->
head
.
dev
,
&
dev_attr_calibration
);
err
=
device_create_bin_file
(
&
zdev
->
head
.
dev
,
&
dev_attr_calibration
);
if
(
err
)
return
err
;
...
...
@@ -560,7 +560,7 @@ static int zfad_zio_probe(struct zio_device *zdev)
*/
static
int
zfad_zio_remove
(
struct
zio_device
*
zdev
)
{
device_remove_bin_file
(
&
zdev
->
cset
->
head
.
dev
,
&
dev_attr_calibration
);
device_remove_bin_file
(
&
zdev
->
head
.
dev
,
&
dev_attr_calibration
);
return
0
;
}
...
...
tools/fau-calibration.c
View file @
4d718e33
// SPDX-License-Identifier: GPL-3.0-or-later
/*
* It lists all VME devices
* Copyright (C) 2018 CERN (www.cern.ch)
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*/
...
...
@@ -15,6 +14,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <endian.h>
#include <fmc-adc-100m14b4cha.h>
...
...
@@ -29,6 +29,7 @@ static const char help_msg[] =
"This could be used to change the ADC calibration data at runtime
\n
"
"by redirectiong the binary output of this program to the proper
\n
"
"sysfs binary attribute
\n
"
"Rembember that we expect all values to be little endian
\n
"
"
\n
"
"General options:
\n
"
"-h Print this message
\n
"
...
...
@@ -44,33 +45,38 @@ static const char help_msg[] =
/**
* Read calibration data from file
* @path: file path
* @data: data location
* @size: data size
* @calib: calibration data
* @offset: offset in file
*
* Return: number of bytes read
*/
static
int
fau_calibration_read
(
char
*
path
,
void
*
data
,
size_t
size
,
off_t
offset
)
static
int
fau_calibration_read
(
char
*
path
,
struct
fa_calib
*
calib
,
off_t
offset
)
{
int
fd
;
int
ret
=
0
;
uint16_t
*
data16
=
(
uint16_t
*
)
calib
;
int
i
;
fd
=
open
(
path
,
O_RDONLY
);
if
(
fd
<
0
)
return
-
1
;
ret
=
lseek
(
fd
,
offset
,
SEEK_SET
);
if
(
ret
>=
0
)
ret
=
read
(
fd
,
data
,
size
);
ret
=
read
(
fd
,
calib
,
sizeof
(
*
calib
)
);
close
(
fd
);
/* Fix endianess */
for
(
i
=
0
;
i
<
sizeof
(
*
calib
)
/
sizeof
(
uint16_t
);
++
i
)
data16
[
i
]
=
le16toh
(
data16
[
i
]);
return
ret
;
}
static
void
fau_calibration_dump_stanza
(
struct
fa_calib_stanza
*
stanza
)
{
fprintf
(
stdout
,
" temperature:
0x%x
\n
"
,
stanza
->
temperature
);
fprintf
(
stdout
,
" temperature:
%f C
\n
"
,
stanza
->
temperature
*
0
.
01
);
fprintf
(
stdout
,
" gain: [0x%04"
PRIx16
", 0x%04"
PRIx16
", 0x%04"
PRIx16
", 0x%04"
PRIx16
"]
\n
"
,
stanza
->
gain
[
0
],
stanza
->
gain
[
1
],
...
...
@@ -118,25 +124,33 @@ static void fau_calibration_dump_machine(struct fa_calib *calib)
/**
* Write calibration data to device
* @devid: Device ID
* @data: data location
* @size: data size
* @calib: calibration data
*
* Return: number of bytes wrote
*/
static
int
fau_calibration_write
(
unsigned
int
devid
,
void
*
data
,
size_t
size
)
static
int
fau_calibration_write
(
unsigned
int
devid
,
struct
fa_calib
*
calib
)
{
struct
fa_calib
calib_cp
;
char
path
[
128
];
uint16_t
*
data16
;
int
i
;
int
fd
;
int
ret
;
sprintf
(
path
,
"/sys/bus/zio/devices/adc-100m14b-%04x/c
set0/c
alibration_data"
,
"/sys/bus/zio/devices/adc-100m14b-%04x/calibration_data"
,
devid
);
/* Fix endianess */
memcpy
(
&
calib_cp
,
calib
,
sizeof
(
calib_cp
));
data16
=
(
uint16_t
*
)
&
calib_cp
;
for
(
i
=
0
;
i
<
sizeof
(
calib_cp
)
/
sizeof
(
uint16_t
);
++
i
)
data16
[
i
]
=
htole16
(
data16
[
i
]);
fd
=
open
(
path
,
O_WRONLY
);
if
(
fd
<
0
)
return
-
1
;
ret
=
write
(
fd
,
data
,
size
);
ret
=
write
(
fd
,
&
calib_cp
,
sizeof
(
calib_cp
)
);
close
(
fd
);
return
ret
;
...
...
@@ -195,7 +209,7 @@ int main(int argc, char *argv[])
}
/* Read EEPROM file */
ret
=
fau_calibration_read
(
path
,
&
calib
,
sizeof
(
calib
),
offset
);
ret
=
fau_calibration_read
(
path
,
&
calib
,
offset
);
if
(
ret
<
0
)
{
fprintf
(
stderr
,
"Can't read calibration data from '%s'. %s
\n
"
,
path
,
strerror
(
errno
));
...
...
@@ -216,7 +230,7 @@ int main(int argc, char *argv[])
/* Write calibration data */
if
(
write
)
{
ret
=
fau_calibration_write
(
devid
,
&
calib
,
sizeof
(
calib
)
);
ret
=
fau_calibration_write
(
devid
,
&
calib
);
if
(
ret
<
0
)
{
fprintf
(
stderr
,
"Can't write calibration data to '0x%x'. %s
\n
"
,
...
...
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