Commit 3c981f75 authored by Federico Vaga's avatar Federico Vaga

Comply with fmc-adc-100m v6.0.0 release

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent bf0207cc
......@@ -186,7 +186,8 @@ enum adc_configuration_acquisition {
enum adc_configuration_channel {
ADC_CONF_CHN_RANGE = 0, /**< Volt range */
ADC_CONF_CHN_TERMINATION, /**< channel Termination */
ADC_CONF_CHN_OFFSET, /**< signal offset */
ADC_CONF_CHN_OFFSET, /**< signal offset [uV]. Depending on board
this value could be approximated */
ADC_CONF_CHN_SATURATION, /**< saturation value */
ADC_CONF_CHN_GAIN, /**< signal gain */
__ADC_CONF_CHN_ATTRIBUTE_LAST_INDEX, /**< It represents the the last
......
......@@ -33,6 +33,10 @@
#define ADC_CONF_GET 0
#define ADC_CONF_SET 1
/**
* This is for internal use. It uses the offset raw value
*/
#define __ADC_CONF_CHN_OFFSET_ZERO 200
......@@ -80,9 +84,9 @@ static typeof(adc_get_param) *adc_param[] = {
* ADC internal data
*/
struct adc_100m14b4cha {
/**< keep track of all zero-offset values for each range
/**< keep track of all zero-offset values (raw values) for each range
(100mV 1V 10V) */
int32_t offset_zero[FA100M14B4C_NCHAN][ADC_CONF_100M14B4CHA_CHN_RANGE_N];
uint32_t offset_zero[FA100M14B4C_NCHAN][ADC_CONF_100M14B4CHA_CHN_RANGE_N];
};
static int adc_100m14b4cha_offset_zero_set(struct adc_dev *dev);
......@@ -140,6 +144,7 @@ static int adc_100m14b4cha_buffer_resize(struct adc_dev *dev,
}
#define BUF_SIZE 128
#define FMCADC_100MS_4CH_14BIT_MIN_VERSION 6
static bool adc_100m14b4cha_is_driver_compatible(void)
{
int fd;
......@@ -159,6 +164,9 @@ static bool adc_100m14b4cha_is_driver_compatible(void)
if (ret != 2)
goto out;
if (maj < FMCADC_100MS_4CH_14BIT_MIN_VERSION)
goto out;
ret = sscanf(FMCADC_100MS_4CH_14BIT_GIT_VERSION, "v%u.%u",
&ref_maj, &ref_min);
if (ret != 2)
......@@ -177,6 +185,16 @@ out:
}
#undef BUF_SIZE
static void adc_100m14b4cha_init_data(struct adc_100m14b4cha *adcdata)
{
int i, k;
/* zero-offset 0.000V corresponds to 0x8000 */
for (i = 0; i < FA100M14B4C_NCHAN; ++i)
for (k = 0; k < ADC_CONF_100M14B4CHA_CHN_RANGE_N; ++k)
adcdata->offset_zero[i][k] = 0x8000;
}
/**
* @copydoc adc_open
* @param[in] b the board type description
......@@ -220,8 +238,7 @@ static struct adc_dev *adc_100m14b4cha_open(const struct adc_board_type *b,
fa->priv = malloc(sizeof(struct adc_100m14b4cha));
if (!fa->priv)
return NULL;
memset(fa->priv, 0, sizeof(struct adc_100m14b4cha));
adc_100m14b4cha_init_data(fa->priv);
err = adc_100m14b4cha_offset_zero_set(dev);
if (err)
goto err;
......@@ -448,6 +465,23 @@ static int adc_100m14b4cha_config_acq(struct adc_dev *adc,
}
}
/**
* FMC-ADC-100M14B4CH offset volt reference
*/
#define ADC_100M14B4CHA_DAC_VREF_uV 5000000LL
/**
* Convert offset value from microVolt to raw
* @param[in] offset value in micro Volt
*
* @return offset raw value
*/
static uint32_t __offset_uv_to_raw(uint32_t value_uv)
{
int32_t value_uv_s = (int32_t)value_uv;
return (0x8000LL * (value_uv_s + ADC_100M14B4CHA_DAC_VREF_uV))/ADC_100M14B4CHA_DAC_VREF_uV;
}
#define ADC_100M14B4CHA_MAX_CHN_SRC FA100M14B4C_NCHAN
/**
......@@ -486,6 +520,7 @@ static int adc_100m14b4cha_config_chn(struct adc_dev *adc,
case ADC_CONF_CHN_OFFSET:
snprintf(path, sizeof(path), "cset%u/ch%u-offset",
fa->cset, source);
*value = __offset_uv_to_raw(*value);
break;
case __ADC_CONF_CHN_OFFSET_ZERO:
snprintf(path, sizeof(path), "cset%u/ch%u-offset-zero",
......@@ -1113,7 +1148,7 @@ static int __cfg_offac_apply(struct adc_dev *dev,
unsigned long flags)
{
int err, trgsrc = FA100M14B4C_TRG_SRC_SW, i;
uint32_t offset = 0;
uint32_t offset = 0x8000;
/* zero-offset needs to be cleard always */
for (i = 0; i < FA100M14B4C_NCHAN; ++i) {
......@@ -1139,46 +1174,6 @@ static int __cfg_offac_apply(struct adc_dev *dev,
return 0;
}
/**
* It converts an hardware value to uV
* @param[in] val value to be converted (hardware format)
* @param[in] range switch configuration read from the hardware
*
* @return uV value
*/
static int32_t __convert_hw_to_uv(int32_t val, unsigned int range)
{
int32_t result_int, result_frac, range_uV, factor;
switch (range) {
case ADC_CONF_100M14B4CHA_CHN_RANGE_10V_CAL:
case ADC_CONF_100M14B4CHA_CHN_RANGE_10V:
/* 10V */
range_uV = 10000000;
break;
case ADC_CONF_100M14B4CHA_CHN_RANGE_100mV_CAL:
case ADC_CONF_100M14B4CHA_CHN_RANGE_100mV:
/* 100mV */
range_uV = 100000;
break;
case ADC_CONF_100M14B4CHA_CHN_RANGE_1V_CAL:
case ADC_CONF_100M14B4CHA_CHN_RANGE_1V:
case ADC_CONF_100M14B4CHA_CHN_RANGE_OPEN_DRAIN:
/* 1V */
range_uV = 1000000;
break;
default:
fprintf(stderr, "Invalid switch configuration 0x%x\n", range);
return 0;
}
factor = (range_uV / BIT(14));
result_int = ((val >> 2) * factor);
result_frac = ((val & 0x3) * 10) * (factor / 1000);
return result_int + result_frac;
}
static int __offz_rng_idx_get(enum adc_configuration_100m14b4cha_channel_range range)
{
int idx = 0;
......@@ -1298,7 +1293,6 @@ static int adc_100m14b4cha_offac_sw_avg_man(struct adc_dev *dev,
for (i = 0; i < FA100M14B4C_NCHAN; ++i) {
int range = __offz_rng_idx_get(ranges[i]);
offset[i] = __convert_hw_to_uv(offset[i], ranges[i]);
adcdata->offset_zero[i][range] = offset[i];
}
......@@ -1351,10 +1345,8 @@ static int adc_100m14b4cha_offac_sw_avg_auto(struct adc_dev *dev,
* to the DAC. For this reason we do not need to revert
* that value: the offset sign measured it is fine
*/
for (k = 0; k < FA100M14B4C_NCHAN; ++k) {
offset[k] = __convert_hw_to_uv(offset[k], range);
for (k = 0; k < FA100M14B4C_NCHAN; ++k)
adcdata->offset_zero[k][i] = offset[k];
}
}
out:
......
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