Commit 2a2c7344 authored by Federico Vaga's avatar Federico Vaga

lib: add prototype and documentation about offset clear

I am going to introduce the offset auto-clear feature.
The purpre is to compensate any external (constant) offset
on a given channel. It may happen because of temperature or other
external factors.

Within this commit I present the API and the documentation of it.
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent cf84af6e
......@@ -207,7 +207,34 @@ and get values with :cpp:func:`adc_get_param()`
err = adc_set_param(adc, "identifier", NULL, &v_int);
err = adc_get_param(adc, "identifier", NULL, &v_int);
Offset Auto Clear
'''''''''''''''''
It may happen that due to temperature or other external factors there are
constant offsets on channels. This library, through function
:cpp:func:`adc_offset_auto_clear()` offers a mechanism to be able
to compensate these offsets.::
err = adc_offset_auto_clear(adc, 2, 0x0);
During this procedure, by default, the library will disconnect any input
signal and connect the channel to the local ground level. By using the flag
:cpp:any:`ADC_OFFSET_AC_F_MANUAL` it is possible to use the current input signal
and compensate it.
During this process, the library may change the ADC configuration.
It is possible to ask the library to restore any previous configuration by
using the flag :cpp:any:`ADC_OFFSET_AC_F_RESTORE`.
If this feature is not supported in hardware or in the driver, it is possible
to ask for a software implementation by using the flag
:cpp:any:`ADC_OFFSET_AC_F_SOFTWARE`. In this case the idea is to run some
acquisitions, compute the average and apply this value as offset compensation.
If on a particular board the offset auto-clear needs extra parameters, you
have to set them using :ref:`board specific configurations<lib:usr:cfg:cus>`.
.. _`lib:usr:cfg:cus`:
Board Specific Configuration
''''''''''''''''''''''''''''
......
......@@ -47,6 +47,7 @@ struct adc_operations {
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 */
};
......
......@@ -27,6 +27,9 @@ extern "C" {
#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
/**
* Opaque type. any instance of this should be used as token
......@@ -270,6 +273,24 @@ struct adc_conf {
#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_MASK=(ADC_OFFSET_AC_F_MANUAL |
ADC_OFFSET_AC_F_RESTORE |
ADC_OFFSET_AC_F_SOFTWARE), /**< used internally */
};
/**
* @defgroup dev Basic
* Basic library functions
......@@ -291,6 +312,9 @@ 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 int chan,
unsigned long flags);
/**@}*/
......
......@@ -734,6 +734,14 @@ static int adc_100m14b4cha_buffer_get_sample(struct adc_buffer *buf,
return 0;
}
static int adc_100m14b4cha_offset_auto_clear(struct adc_dev *dev,
unsigned int chan,
unsigned long flags)
{
errno = EPERM;
return -1;
}
#define ADC_100M_4CH_14BIT_ACQ_MASK (1LL << ADC_CONF_ACQ_N_SHOTS) | \
(1LL << ADC_CONF_ACQ_POST_SAMP) | \
(1LL << ADC_CONF_ACQ_PRE_SAMP) | \
......@@ -785,6 +793,7 @@ static struct adc_operations fa_100ms_4ch_14bit_op = {
.buffer_get_sample = adc_100m14b4cha_buffer_get_sample,
.buffer_fixup = NULL,
.offset_auto_clear = adc_100m14b4cha_offset_auto_clear,
};
struct adc_board_type fmcadc_100ms_4ch_14bit = {
......
......@@ -32,6 +32,9 @@ static struct adc_errors {
{ 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"},
{ 0, }
};
......
......@@ -569,3 +569,50 @@ int adc_buffer_fixup(struct adc_buffer *buf)
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 aventual offsets on a given channel
* @param[in] dev ADC device token
* @param[in] chan channel number
* @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 int chan,
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, chan, flags);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment