Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
A
adc-lib
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
misc
adc-lib
Commits
c107af64
Commit
c107af64
authored
Oct 23, 2018
by
Federico Vaga
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'release/v2.2'
parents
f0f1224b
655c0b9f
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1611 additions
and
432 deletions
+1611
-432
conf.py
doc/conf.py
+7
-2
library-api.rst
doc/library-api.rst
+1
-89
library-user.rst
doc/library-user.rst
+165
-152
Makefile
lib/Makefile
+1
-0
adc-genericfake.c
lib/adc-genericfake.c
+15
-0
adc-lib-100m14b4cha.h
lib/adc-lib-100m14b4cha.h
+14
-0
adc-lib-int.h
lib/adc-lib-int.h
+8
-0
adc-lib.h
lib/adc-lib.h
+61
-1
adc-ziofake.c
lib/adc-ziofake.c
+15
-0
fmc-adc-100m14b4cha.c
lib/fmc-adc-100m14b4cha.c
+552
-30
lib-math.c
lib/lib-math.c
+62
-0
lib.c
lib/lib.c
+100
-0
route.c
lib/route.c
+183
-5
adc-acq.c
tools/adc-acq.c
+427
-153
No files found.
doc/conf.py
View file @
c107af64
...
...
@@ -59,9 +59,9 @@ author = 'Federico Vaga <federico.vaga@cern.ch>'
# built documents.
#
# The short X.Y version.
version
=
'2.
1
'
version
=
'2.
2
'
# The full version, including alpha/beta/rc tags.
release
=
'2.
1
.0'
release
=
'2.
2
.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
...
...
@@ -201,4 +201,9 @@ breathe_projects = {
"adc-lib"
:
"doxygen-lib-output/xml/"
,
}
breathe_projects_source
=
{
"adc-lib"
:
(
"../lib/"
,
[
"adc-lib.h"
,
"route.c"
])
}
breathe_default_project
=
"adc-lib"
doc/library-api.rst
View file @
c107af64
The Library API
================
Enumerations And Constants
-----------------------------
.. doxygenenum:: adc_supported_boards
.. doxygenenum:: adc_configuration_type
.. doxygenenum:: adc_configuration_trigger_ext
.. doxygenenum:: adc_configuration_trigger_thr
.. doxygenenum:: adc_configuration_acquisition
.. doxygenenum:: adc_configuration_channel
.. doxygenenum:: adc_configuration_board
Board Specific
''''''''''''''
FMC ADC 100M 14 bit 4 Channel
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. doxygenenum:: adc_configuration_100m14b4cha
Data Structures
---------------
.. doxygenstruct:: adc_conf
:members:
.. doxygenstruct:: adc_buffer
:members:
.. doxygenstruct:: adc_timestamp
:members:
Functions
----------
.. doxygenfunction:: adc_init
.. doxygenfunction:: adc_exit
.. doxygenfunction:: adc_strerror
.. doxygenfunction:: adc_open
.. doxygenfunction:: adc_open_by_lun
.. doxygenfunction:: adc_close
.. doxygenfunction:: adc_apply_config
.. doxygenfunction:: adc_retrieve_config
.. doxygenfunction:: adc_set_conf_mask
.. doxygenfunction:: adc_set_conf_mask_all
.. doxygenfunction:: adc_set_conf
.. doxygenfunction:: adc_get_conf
.. doxygenfunction:: adc_reset_conf
.. doxygenfunction:: adc_get_capabilities
.. doxygenfunction:: adc_set_param
.. doxygenfunction:: adc_get_param
.. doxygenfunction:: adc_acq_start
.. doxygenfunction:: adc_acq_poll
.. doxygenfunction:: adc_acq_stop
.. doxygenfunction:: adc_request_buffer
.. doxygenfunction:: adc_release_buffer
.. doxygenfunction:: adc_fill_buffer
.. doxygenfunction:: adc_tstamp_buffer
.. doxygenfunction:: adc_trigger_fire
.. autodoxygenfile:: adc-lib.h
doc/library-user.rst
View file @
c107af64
This diff is collapsed.
Click to expand it.
lib/Makefile
View file @
c107af64
...
...
@@ -23,6 +23,7 @@ LOBJ += init.o
LOBJ
+=
config-zio.o
LOBJ
+=
buffer-zio.o
LOBJ
+=
lib.o
LOBJ
+=
lib-math.o
LOBJ
+=
adc-ziofake.o
LOBJ
+=
adc-genericfake.o
LOBJ
+=
adc-zio.o
...
...
lib/adc-genericfake.c
View file @
c107af64
...
...
@@ -330,6 +330,20 @@ static int adc_genfake_fill_buffer(struct adc_dev *dev,
return
0
;
}
static
int
adc_genfake_buffer_get_sample
(
struct
adc_buffer
*
buf
,
unsigned
int
chan
,
unsigned
int
acq_sample
,
int32_t
*
value
)
{
if
(
chan
>=
1
)
{
errno
=
EINVAL
;
return
-
1
;
}
*
value
=
((
int8_t
*
)
buf
->
data
)[
acq_sample
];
return
0
;
}
static
struct
adc_operations
fa_generic_fake_op
=
{
.
open
=
adc_genfake_open
,
...
...
@@ -349,6 +363,7 @@ static struct adc_operations fa_generic_fake_op = {
.
fill_buffer
=
adc_genfake_fill_buffer
,
.
tstamp_buffer
=
adc_genfake_tstamp_buffer
,
.
release_buffer
=
adc_genfake_release_buffer
,
.
buffer_get_sample
=
adc_genfake_buffer_get_sample
,
};
#define ADC_GENERICFAKE_BRD_MASK (1LL << ADC_CONF_BRD_N_CHAN)
...
...
lib/adc-lib-100m14b4cha.h
View file @
c107af64
...
...
@@ -23,6 +23,20 @@ extern "C" {
#include "adc-lib.h"
#define ADC_CONF_100M14B4CHA_CHN_RANGE_N 3
/**
* List of known voltage ranges to be used with the configuration option
* ADC_CONF_CHN_RANGE
*/
enum
adc_configuration_100m14b4cha_channel_range
{
ADC_CONF_100M14B4CHA_CHN_RANGE_OPEN_DRAIN
=
0
,
ADC_CONF_100M14B4CHA_CHN_RANGE_100mV
=
0x23
,
ADC_CONF_100M14B4CHA_CHN_RANGE_1V
=
0x11
,
ADC_CONF_100M14B4CHA_CHN_RANGE_10V
=
0x45
,
ADC_CONF_100M14B4CHA_CHN_RANGE_100mV_CAL
=
0x42
,
ADC_CONF_100M14B4CHA_CHN_RANGE_1V_CAL
=
0x40
,
ADC_CONF_100M14B4CHA_CHN_RANGE_10V_CAL
=
0x44
,
};
/**
* List of possible buffer types (options for ADC_CONF_100M14B4CHA_BUF_TYPE)
...
...
lib/adc-lib-int.h
View file @
c107af64
...
...
@@ -45,6 +45,9 @@ struct adc_operations {
typeof
(
adc_release_buffer
)
*
release_buffer
;
/**< @related adc_release_buffer */
typeof
(
adc_trigger_fire
)
*
trigger_fire
;
/**< @related adc_trigger_fire */
typeof
(
adc_buffer_get_sample
)
*
buffer_get_sample
;
/**< @related adc_buffer_get_sample */
typeof
(
adc_buffer_fixup
)
*
buffer_fixup
;
/**< @related adc_buffer_fixup*/
typeof
(
adc_offset_auto_clear
)
*
offset_auto_clear
;
/**< @related adc_offset_auto_clear */
};
...
...
@@ -88,6 +91,7 @@ struct __adc_dev_zio {
char
*
sysbase
;
/**< base path to device sysfs */
unsigned
long
samplesize
;
/**< size of 1 sample */
unsigned
long
pagesize
;
/**< size of 1 page */
void
*
priv
;
/**< specific ZIO board data */
/* Mandatory field */
struct
adc_gid
gid
;
/**< general ADC descriptor */
};
...
...
@@ -181,6 +185,10 @@ int adc_zio_get_param(struct adc_dev *dev, char *name,
int
adc_zio_sysfs_set
(
struct
__adc_dev_zio
*
fa
,
char
*
name
,
uint32_t
*
value
);
int
adc_offset_auto_clear_sw_avg
(
struct
adc_dev
*
dev
,
unsigned
long
flags
,
int32_t
*
offset
);
/*adc-genericfake*/
...
...
lib/adc-lib.h
View file @
c107af64
...
...
@@ -26,6 +26,12 @@ extern "C" {
#define ADC_ENOMASK 1030
#define ADC_EDISABLED 1031
#define ADC_EROUTE 1032
#define ADC_ENOP_SWTRG 1033
#define ADC_ENOP_OFFCLR 1034
#define ADC_ENOP_OFFCLRHW 1035
#define ADC_ENOP_OFFCLRSW 1036
#define ADC_OFF_AC_RESTORE_S 1037
#define ADC_OFF_AC_RESTORE_R 1038
/**
* Opaque type. any instance of this should be used as token
...
...
@@ -64,6 +70,7 @@ struct adc_buffer {
void
*
mapaddr
;
/**< mmap address */
unsigned
long
maplen
;
/**< mmap length */
unsigned
long
flags
;
/**< internal to the library */
void
*
priv
;
/**< library private date */
};
...
...
@@ -242,6 +249,13 @@ enum adc_configuration_type {
#define __ADC_CONF_LEN 64
/* number of allocated items in each structure */
/**
* It enumerates all possible flags for adc_conf.flags
*/
enum
adc_conf_flags
{
ADC_CONF_F_ERROR
=
(
1ULL
<<
0
),
/**< configuration failed */
};
/**
* ADC configuration descriptor.
*/
...
...
@@ -250,7 +264,7 @@ struct adc_conf {
uint32_t
dev_type
;
/**< device type */
uint32_t
route_to
;
/**< internal route to a particular sub-device
(e.g. a channel) */
uint32_t
flags
;
/**<
FIXME how to identify invalid?
*/
uint32_t
flags
;
/**<
flags from adc_conf_flags
*/
uint64_t
mask
;
/**< capabilities mask, 1 when the correspondent
value in ``value[]`` is valid */
uint32_t
value
[
__ADC_CONF_LEN
];
/**< array of configuration value.
...
...
@@ -265,6 +279,30 @@ struct adc_conf {
(used by adc_open) */
#define ADC_F_VERBOSE 0x00020000
/**< Flag used to verbose on stdout/stderr
(usable by any function)*/
#define ADC_F_FIXUP 0x00400000
/**< Flag used to fixup a buffer when
filling it (usable by adc_fill_buffer) */
/**
* Enumeration of all possible flags to driver the auto-clear offset
*/
enum
adc_offset_auto_clear_flags
{
ADC_OFFSET_AC_F_MANUAL
=
0x00000001
,
/**< the signal will be acquired with
the last configuration set */
ADC_OFFSET_AC_F_RESTORE
=
0x00000002
,
/**< restore previous
configuration when done. It
does not have any effect when
MANUAL is active*/
ADC_OFFSET_AC_F_SOFTWARE
=
0x00000004
,
/**< use software mechanism,
it implies manual
configuration */
ADC_OFFSET_AC_F_ZERO
=
0x00000008
,
/**< it sets the zero-offset to zero;
which means that it removes any
previously set zero-offset. */
__ADC_OFFSET_AC_F_MASK
=
(
ADC_OFFSET_AC_F_MANUAL
|
ADC_OFFSET_AC_F_RESTORE
|
ADC_OFFSET_AC_F_SOFTWARE
|
ADC_OFFSET_AC_F_ZERO
),
/**< used internally */
};
/**
* @defgroup dev Basic
...
...
@@ -287,6 +325,8 @@ extern struct adc_dev *adc_open_by_lun(char *name, int lun,
extern
int
adc_close
(
struct
adc_dev
*
dev
);
extern
int
adc_trigger_fire
(
struct
adc_dev
*
dev
);
extern
int
adc_has_trigger_fire
(
struct
adc_dev
*
dev
);
extern
int
adc_offset_auto_clear
(
struct
adc_dev
*
dev
,
unsigned
long
flags
);
/**@}*/
...
...
@@ -357,8 +397,13 @@ extern int adc_reset_conf(struct adc_dev *dev, unsigned int flags,
struct
adc_conf
*
conf
);
extern
int
adc_apply_config
(
struct
adc_dev
*
dev
,
unsigned
int
flags
,
struct
adc_conf
*
conf
);
extern
int
adc_apply_config_n
(
struct
adc_dev
*
dev
,
unsigned
int
flags
,
struct
adc_conf
*
conf
,
unsigned
int
n
);
extern
int
adc_retrieve_config
(
struct
adc_dev
*
dev
,
struct
adc_conf
*
conf
);
extern
int
adc_retrieve_config_n
(
struct
adc_dev
*
dev
,
struct
adc_conf
*
conf
,
unsigned
int
n
);
extern
uint64_t
adc_get_capabilities
(
struct
adc_dev
*
dev
,
enum
adc_configuration_type
type
);
extern
int
adc_get_param
(
struct
adc_dev
*
dev
,
char
*
name
,
...
...
@@ -396,6 +441,21 @@ extern struct adc_timestamp *adc_tstamp_buffer(struct adc_buffer *buf,
extern
int
adc_release_buffer
(
struct
adc_dev
*
dev
,
struct
adc_buffer
*
buf
,
void
(
*
free_fn
)(
void
*
));
extern
int
adc_buffer_get_sample
(
struct
adc_buffer
*
buf
,
unsigned
int
chan
,
unsigned
int
acq_sample
,
int32_t
*
value
);
extern
int
adc_buffer_fixup
(
struct
adc_buffer
*
buf
);
/**@}*/
/**
* @defgroup buf_math Buffer Math
* Mathematical operations on buffers
* @{
*/
extern
int
adc_buffer_math_avg
(
struct
adc_buffer
*
buf
,
unsigned
int
chan
,
int32_t
*
avg
);
/**@}*/
/* libfmcadc version string */
...
...
lib/adc-ziofake.c
View file @
c107af64
...
...
@@ -34,6 +34,20 @@ static struct adc_dev *adc_ziofake_open(const struct adc_board_type *b,
return
dev
;
}
static
int
adc_ziofake_buffer_get_sample
(
struct
adc_buffer
*
buf
,
unsigned
int
chan
,
unsigned
int
acq_sample
,
int32_t
*
value
)
{
if
(
chan
>=
1
)
{
errno
=
EINVAL
;
return
-
1
;
}
*
value
=
((
int8_t
*
)
buf
->
data
)[
acq_sample
];
return
0
;
}
#define ADC_ZIO_ACQ_MASK (1LL << ADC_CONF_ACQ_N_SHOTS) | \
(1LL << ADC_CONF_ACQ_POST_SAMP) | \
...
...
@@ -62,6 +76,7 @@ static struct adc_operations fa_zio_fake_op = {
.
fill_buffer
=
adc_zio_fill_buffer
,
.
tstamp_buffer
=
adc_zio_tstamp_buffer
,
.
release_buffer
=
adc_zio_release_buffer
,
.
buffer_get_sample
=
adc_ziofake_buffer_get_sample
,
};
struct
adc_board_type
adc_ziofake
=
{
...
...
lib/fmc-adc-100m14b4cha.c
View file @
c107af64
This diff is collapsed.
Click to expand it.
lib/lib-math.c
0 → 100644
View file @
c107af64
/*
* Routing public functions to device-specific code
*
* Copyright (C) 2018 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* 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 <errno.h>
#include <string.h>
#include "adc-lib.h"
#include "adc-lib-int.h"
/**
* It computes the avarege voltage within the given buffer
* @param[in] buf data set to use
* @param[in] chan channel number [0, NCHAN]
* @param[out] avg the computer avarage. The scale depends on the
* configuration,
* @return 0 on success, -1 on error and errno is set appropriately
* EINVAL: if the buffer is invalid, or channel is invalid
*/
int
adc_buffer_math_avg
(
struct
adc_buffer
*
buf
,
unsigned
int
chan
,
int32_t
*
avg
)
{
struct
adc_conf
cfg_brd
;
uint32_t
nchan
=
0
;
int
i
,
err
;
int64_t
total
=
0
;
memset
(
&
cfg_brd
,
0
,
sizeof
(
struct
adc_conf
));
cfg_brd
.
type
=
ADC_CONF_TYPE_BRD
;
adc_set_conf_mask_all
(
&
cfg_brd
,
buf
->
dev
);
err
=
adc_retrieve_config
(
buf
->
dev
,
&
cfg_brd
);
if
(
err
)
return
err
;
adc_get_conf
(
&
cfg_brd
,
ADC_CONF_BRD_N_CHAN
,
&
nchan
);
if
(
chan
>=
nchan
)
{
errno
=
EINVAL
;
return
-
1
;
}
for
(
i
=
0
;
i
<
buf
->
nsamples
;
++
i
)
{
int32_t
val
;
err
=
adc_buffer_get_sample
(
buf
,
chan
,
i
,
&
val
);
if
(
err
)
return
err
;
total
+=
val
;
}
*
avg
=
total
/
buf
->
nsamples
;
return
0
;
}
lib/lib.c
View file @
c107af64
...
...
@@ -9,6 +9,7 @@
* version 2 as published by the Free Software Foundation or, at your
* option, any later version.
*/
#include <errno.h>
#include <string.h>
#include "adc-lib.h"
#include "adc-lib-int.h"
...
...
@@ -31,6 +32,12 @@ static struct adc_errors {
{
ADC_ENOMASK
,
"Missing configuration mask"
},
{
ADC_EDISABLED
,
"Trigger is disabled: I/O aborted"
},
{
ADC_EROUTE
,
"Cannot route correctly the configuration"
},
{
ADC_ENOP_SWTRG
,
"Operation not supported: software trigger"
},
{
ADC_ENOP_OFFCLR
,
"Operation not supported: offset auto-clear"
},
{
ADC_ENOP_OFFCLRHW
,
"Operation not supported: offset auto-clear hardware"
},
{
ADC_ENOP_OFFCLRSW
,
"Operation not supported: offset auto-clear software"
},
{
ADC_OFF_AC_RESTORE_S
,
"Offset auto-clear: cannot store configuration"
},
{
ADC_OFF_AC_RESTORE_R
,
"Offset auto-clear: cannot restore configuration"
},
{
0
,
}
};
...
...
@@ -86,3 +93,96 @@ uint64_t adc_get_capabilities(struct adc_dev *dev,
return
b
->
board
->
capabilities
[
type
];
}
/**
* It computes what are the necessary offsets to apply on channels
* in order to clear a constant offset.
* @param[in] dev ADC device token
* @param[in] flags options @see adc_offset_auto_clear_flags
* @param[out] offset vector of compensation offsets (one for each channel)
* @return 0 on success, -1 on error and errno is set appropriately
* EINVAL: invalid flags value
* ADC_ENOP_SWTRG: when software trigger is missing
*
* The configuration is board dependent, so here we just run and apply
* the compensation offset. The configuration is left to the user.
*
* Since this function uses software trigger, the user should disable
* all trigger sources except the software one.
*
* NOTE: offset is a vector, so when you call this function be careful
* about the size of that parameter, it must big enough to host a value
* for each board channel.
*/
int
adc_offset_auto_clear_sw_avg
(
struct
adc_dev
*
dev
,
unsigned
long
flags
,
int32_t
*
offset
)
{
struct
adc_conf
cfg
;
struct
adc_buffer
*
buf
;
struct
timeval
tv
=
{
0
,
0
};
uint32_t
nchan
,
pre
,
post
;
int
err
,
err_stop
,
i
;
unsigned
int
nsamples
;
if
(
!
(
flags
&
ADC_OFFSET_AC_F_SOFTWARE
))
{
errno
=
EINVAL
;
return
-
1
;
}
if
(
!
adc_has_trigger_fire
(
dev
))
{
errno
=
ADC_ENOP_SWTRG
;
return
-
1
;
}
memset
(
&
cfg
,
0
,
sizeof
(
struct
adc_conf
));
cfg
.
type
=
ADC_CONF_TYPE_ACQ
;
adc_set_conf_mask
(
&
cfg
,
ADC_CONF_ACQ_PRE_SAMP
);
adc_set_conf_mask
(
&
cfg
,
ADC_CONF_ACQ_POST_SAMP
);
err
=
adc_retrieve_config
(
dev
,
&
cfg
);
if
(
err
)
return
err
;
adc_get_conf
(
&
cfg
,
ADC_CONF_ACQ_PRE_SAMP
,
&
pre
);
adc_get_conf
(
&
cfg
,
ADC_CONF_ACQ_POST_SAMP
,
&
post
);
nsamples
=
pre
+
post
;
memset
(
&
cfg
,
0
,
sizeof
(
struct
adc_conf
));
cfg
.
type
=
ADC_CONF_TYPE_BRD
;
adc_set_conf_mask
(
&
cfg
,
ADC_CONF_BRD_N_CHAN
);
err
=
adc_retrieve_config
(
dev
,
&
cfg
);
if
(
err
)
return
err
;
adc_get_conf
(
&
cfg
,
ADC_CONF_BRD_N_CHAN
,
&
nchan
);
buf
=
adc_request_buffer
(
dev
,
nsamples
,
NULL
,
0
);
if
(
!
buf
)
return
-
1
;
err
=
adc_acq_start
(
dev
,
ADC_F_FLUSH
,
&
tv
);
if
(
err
)
goto
out
;
err
=
adc_trigger_fire
(
dev
);
if
(
err
)
goto
out
;
tv
.
tv_sec
=
10
;
err
=
adc_fill_buffer
(
dev
,
buf
,
0
,
&
tv
);
if
(
err
)
goto
out
;
for
(
i
=
0
;
i
<
nchan
;
++
i
)
{
err
=
adc_buffer_math_avg
(
buf
,
i
,
&
offset
[
i
]);
if
(
err
)
goto
out
;
}
out:
adc_release_buffer
(
dev
,
buf
,
NULL
);
err_stop
=
adc_acq_stop
(
dev
,
0
);
if
(
err_stop
)
return
err_stop
;
return
err
;
}
lib/route.c
View file @
c107af64
...
...
@@ -75,6 +75,8 @@ static const struct adc_board_type *find_board(char *name)
* It should be passed around but not be looked into.
*
* @todo Open should choose the buffer type
*
* It initialize the board, this can be different board to board.
*/
struct
adc_dev
*
adc_open
(
char
*
name
,
unsigned
int
dev_id
,
unsigned
long
totalsamples
,
...
...
@@ -254,13 +256,19 @@ int adc_acq_stop(struct adc_dev *dev, unsigned int flags)
* @param[in] flags
* @param[in] conf configuration to apply
* @return 0 on success, -1 on error and errno is set appropriately
*
* If the configuration cannot be applied entirely, then this function
* will set ADC_CONF_F_ERROR in conf->flags
*/
int
adc_apply_config
(
struct
adc_dev
*
dev
,
unsigned
int
flags
,
struct
adc_conf
*
conf
)
struct
adc_conf
*
conf
)
{
struct
adc_gid
*
g
=
(
struct
adc_gid
*
)
dev
;
const
struct
adc_board_type
*
b
=
g
->
board
;
uint64_t
cap_mask
;
int
err
;
conf
->
flags
&=
~
ADC_CONF_F_ERROR
;
if
(
!
b
->
adc_op
->
apply_config
)
{
errno
=
ADC_ENOP
;
...
...
@@ -282,9 +290,40 @@ int adc_apply_config(struct adc_dev *dev, unsigned int flags,
errno
=
ADC_ENOCAP
;
return
-
1
;
}
return
b
->
adc_op
->
apply_config
(
dev
,
flags
,
conf
);
err
=
b
->
adc_op
->
apply_config
(
dev
,
flags
,
conf
);
if
(
err
)
conf
->
flags
|=
ADC_CONF_F_ERROR
;
return
err
;
}
/**
* It applies the given configuration to the device
* @param[in] dev ADC device token
* @param[in] flags
* @param[in] conf list of configurations to apply
* @param[in] n number of valid configurations in conf
* @return 0 on success, -1 on error and errno is set appropriately
*
* If a configuration cannot be applied entirely, then this function
* will set ADC_CONF_F_ERROR in conf[i].flags
*/
int
adc_apply_config_n
(
struct
adc_dev
*
dev
,
unsigned
int
flags
,
struct
adc_conf
*
conf
,
unsigned
int
n
)
{
unsigned
int
i
;
int
err_last
=
0
;
for
(
i
=
0
;
i
<
n
;
++
i
)
{
int
err
=
adc_apply_config
(
dev
,
flags
,
&
conf
[
i
]);
if
(
err
)
{
err_last
=
err
;
continue
;
}
}
return
err_last
;
}
/**
* It retrieve the current device configuration
...
...
@@ -292,12 +331,18 @@ int adc_apply_config(struct adc_dev *dev, unsigned int flags,
* @param[in,out] conf configuration descriptor to fill with configuration
* values.
* @return 0 on success, -1 on error and errno is set appropriately
*
* If the configuration cannot be retrieved entirely, then this function
* will set ADC_CONF_F_ERROR in conf->flags
*/
int
adc_retrieve_config
(
struct
adc_dev
*
dev
,
struct
adc_conf
*
conf
)
{
struct
adc_gid
*
g
=
(
struct
adc_gid
*
)
dev
;
const
struct
adc_board_type
*
b
=
g
->
board
;
uint64_t
cap_mask
;
int
err
;
conf
->
flags
&=
~
ADC_CONF_F_ERROR
;
if
(
!
b
->
adc_op
->
retrieve_config
)
{
errno
=
ADC_ENOP
;
...
...
@@ -319,9 +364,39 @@ int adc_retrieve_config(struct adc_dev *dev, struct adc_conf *conf)
errno
=
ADC_ENOCAP
;
return
-
1
;
}
return
b
->
adc_op
->
retrieve_config
(
dev
,
conf
);
err
=
b
->
adc_op
->
retrieve_config
(
dev
,
conf
);
if
(
err
)
conf
->
flags
|=
ADC_CONF_F_ERROR
;
return
err
;
}
/**
* It retrieve the current device configuration
* @param[in] dev ADC device token
* @param[in,out] conf configuration descriptor to fill with configuration
* values.
* @param[in] n number of valid configurations in conf
* @return 0 on success, -1 on error and errno is set appropriately
*
* If a configuration cannot be retrieved entirely, then this function
* will set ADC_CONF_F_ERROR in conf[i].flags
*/
int
adc_retrieve_config_n
(
struct
adc_dev
*
dev
,
struct
adc_conf
*
conf
,
unsigned
int
n
)
{
unsigned
int
i
;
int
err_last
=
0
;
for
(
i
=
0
;
i
<
n
;
++
i
)
{
int
err
=
adc_retrieve_config
(
dev
,
&
conf
[
i
]);
if
(
err
)
{
err_last
=
err
;
continue
;
}
}
return
err_last
;
}
/**
* It get a single parameter from the device
...
...
@@ -402,6 +477,7 @@ struct adc_buffer *adc_request_buffer(struct adc_dev *dev,
* @param[in] dev ADC device token
* @param[in] buf the buffer to fill
* @param[in] flags used to control how to fill the buffer
* (ADC_F_FIXUP)
* @param[in] timeout maximum time to fill the buffer. The behavior
* is similar to *select(1)*. If NULL, there is no timeout and
* the function will wait until the data is ready.
...
...
@@ -419,13 +495,21 @@ int adc_fill_buffer(struct adc_dev *dev,
{
struct
adc_gid
*
g
=
(
struct
adc_gid
*
)
dev
;
const
struct
adc_board_type
*
b
=
g
->
board
;
int
err
;
if
(
!
b
->
adc_op
->
fill_buffer
)
{
errno
=
ADC_ENOP
;
return
-
1
;
}
return
b
->
adc_op
->
fill_buffer
(
dev
,
buf
,
flags
,
timeout
);
err
=
b
->
adc_op
->
fill_buffer
(
dev
,
buf
,
flags
,
timeout
);
if
(
err
)
return
err
;
if
(
flags
&
ADC_F_FIXUP
)
return
adc_buffer_fixup
(
buf
);
return
0
;
}
...
...
@@ -499,6 +583,7 @@ int adc_has_trigger_fire(struct adc_dev *dev)
* It forces the board to trigger the acquisition
* @param[in] dev ADC device token
* @return 0 on success, -1 on error and errno is set appropriately
* ADC_ENOP_SWTRG: when software trigger is not supported
*/
int
adc_trigger_fire
(
struct
adc_dev
*
dev
)
{
...
...
@@ -506,8 +591,101 @@ int adc_trigger_fire(struct adc_dev *dev)
const
struct
adc_board_type
*
b
=
g
->
board
;
if
(
!
b
->
adc_op
->
trigger_fire
)
{
errno
=
ADC_ENOP
;
errno
=
ADC_ENOP
_SWTRG
;
return
-
1
;
}
return
b
->
adc_op
->
trigger_fire
(
dev
);
}
/**
* It gets a sample from the buffer
* @param[in] buf buffer to use
* @param[in] chan which channel
* @param[in] acq_sample acquisition sample
* @param[out] value
* @return 0 on success, -1 on error and errno is set appropriately
* ADC_ENOP if the operation is not supported by the board that
* acquired the buffer
*/
int
adc_buffer_get_sample
(
struct
adc_buffer
*
buf
,
unsigned
int
chan
,
unsigned
int
acq_sample
,
int32_t
*
value
)
{
struct
adc_gid
*
g
=
(
struct
adc_gid
*
)
buf
->
dev
;
const
struct
adc_board_type
*
b
=
g
->
board
;
if
(
!
b
->
adc_op
->
buffer_get_sample
)
{
errno
=
ADC_ENOP
;
return
-
1
;
}
if
(
acq_sample
>=
buf
->
nsamples
)
{
errno
=
EINVAL
;
return
-
1
;
}
return
b
->
adc_op
->
buffer_get_sample
(
buf
,
chan
,
acq_sample
,
value
);
}
/**
* It fixes the given buffer if there is any need
* @param[in, out] buf acquistion buffer (filled)
* @return 0 on success, -1 on error and errno is set appropriately
*
* This is used by board specifc code to compensate some known error
*/
int
adc_buffer_fixup
(
struct
adc_buffer
*
buf
)
{
struct
adc_gid
*
g
=
(
struct
adc_gid
*
)
buf
->
dev
;
const
struct
adc_board_type
*
b
=
g
->
board
;
if
(
b
->
adc_op
->
buffer_fixup
)
return
b
->
adc_op
->
buffer_fixup
(
buf
);
return
0
;
}
/**
* It checks if the board support offset auto-clear
* @param[in] dev ADC device token
* @return 1 when it does support offset auto clear; 0 when it does not
*/
int
adc_has_offset_auto_clear
(
struct
adc_dev
*
dev
)
{
struct
adc_gid
*
g
=
(
struct
adc_gid
*
)
dev
;
const
struct
adc_board_type
*
b
=
g
->
board
;
return
!!
b
->
adc_op
->
offset_auto_clear
;
}
/**
* It clears eventual offsets on all channel
* @param[in] dev ADC device token
* @param[in] flags options @see adc_offset_auto_clear_flags
* @return 0 on success, -1 on error and errno is set appropriately
* EINVAL: invalid flags value
* ADC_ENOP_OFFCLR: when offset auto-clear is not supported
*
* NOTE: The function may overwrite your current configuration (unless
* you use a flag) and it may remove any trace of previous acquisitions.
*
* Offset configuration is always overwritten (no matter what flag you use)
*/
int
adc_offset_auto_clear
(
struct
adc_dev
*
dev
,
unsigned
long
flags
)
{
struct
adc_gid
*
g
=
(
struct
adc_gid
*
)
dev
;
const
struct
adc_board_type
*
b
=
g
->
board
;
if
(
!
adc_has_offset_auto_clear
(
dev
))
{
errno
=
ADC_ENOP_OFFCLR
;
return
-
1
;
}
if
(
flags
&
~
__ADC_OFFSET_AC_F_MASK
)
{
errno
=
EINVAL
;
return
-
1
;
}
return
b
->
adc_op
->
offset_auto_clear
(
dev
,
flags
);
}
tools/adc-acq.c
View file @
c107af64
This diff is collapsed.
Click to expand it.
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