Commit e260b717 authored by Federico Vaga's avatar Federico Vaga

Merge branch 'release/v4.0.2'

parents 6a269212 0ccb1471
......@@ -6,6 +6,13 @@
Changelog
=========
4.0.2 - 2022-03-16
==================
Bugfix
------
- configuration values overwritten by the library
- offset not converted from raw to uV on read
4.0.1 - 2022-02-11
==================
Bugfix
......
......@@ -592,6 +592,8 @@ class PyFmcAdc100m14b4ch(PyAdcAbstract):
ADC_CONF_100M14B4CHA_FSM_STATE_POST = 4
ADC_CONF_100M14B4CHA_FSM_STATE_DECR = 5
ADC_CONF_100M14B4CHA_DAC_VREF_uV = 5000000
def __init__(self, devid):
super(PyFmcAdc100m14b4ch, self).__init__(devid)
self.__dbg_path = "/sys/kernel/debug/fmc-adc-100m.{:d}.auto/".format(self.dev_id)
......
......@@ -72,7 +72,7 @@ flawfinder:
$(FLAWFINDER) -SQDC --error-level=4 .
clean:
rm -f $(LIB) $(LIBS_XYZ) .depend *.o *~
rm -f $(LIB) $(LIBS_XYZ) .depend *.o *~ *.so*
.depend: Makefile $(wildcard *.c *.h ../*.h)
$(CC) $(CFLAGS) -M $(LOBJ:.o=.c) -o $@
......
......@@ -472,7 +472,7 @@ static int adc_100m14b4cha_config_acq(struct adc_dev *adc,
/**
* Convert offset value from microVolt to raw
* @param[in] offset value in micro Volt
* @param[in] value_uv value in micro Volt
*
* @return offset raw value
*/
......@@ -483,6 +483,20 @@ static uint32_t __offset_uv_to_raw(uint32_t value_uv)
return (0x8000LL * (value_uv_s + ADC_100M14B4CHA_DAC_VREF_uV))/ADC_100M14B4CHA_DAC_VREF_uV;
}
/**
* Convert offset value from raw to microVolt
* @param[in] value_raw raw value
*
* @return offset in micro Volt
*/
static uint32_t __offset_raw_to_uv(uint32_t value_raw)
{
int32_t value_raw_s = (int32_t)value_raw;
return (value_raw_s * (ADC_100M14B4CHA_DAC_VREF_uV / 0x8000LL)) - ADC_100M14B4CHA_DAC_VREF_uV;
}
#define ADC_100M14B4CHA_MAX_CHN_SRC FA100M14B4C_NCHAN
/**
* It configures the options related to the channel
......@@ -500,6 +514,7 @@ static int adc_100m14b4cha_config_chn(struct adc_dev *adc,
unsigned int direction)
{
struct __adc_dev_zio *fa = to_dev_zio(adc);
uint32_t value_tmp = *value;
char path[1024];
int err;
......@@ -520,12 +535,12 @@ 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);
value_tmp = __offset_uv_to_raw(value_tmp);
break;
case __ADC_CONF_CHN_OFFSET_ZERO:
snprintf(path, sizeof(path), "cset%u/ch%u-offset-zero",
fa->cset, source);
*value = __offset_uv_to_raw(*value);
value_tmp = __offset_uv_to_raw(value_tmp);
break;
case ADC_CONF_CHN_SATURATION:
snprintf(path, sizeof(path), "cset%u/ch%u-saturation",
......@@ -535,16 +550,33 @@ static int adc_100m14b4cha_config_chn(struct adc_dev *adc,
errno = ADC_ENOCAP;
return -1;
}
err = adc_param[direction](adc, path, NULL, (int *)value);
if (!err && direction == ADC_CONF_SET &&
index == ADC_CONF_CHN_RANGE) {
/*
* Whenever the user changes voltage range we need to adjust
* the zero-offset value (if any)
*/
return adc_100m14b4cha_offset_zero_set(adc);
err = adc_param[direction](adc, path, NULL, (int *)&value_tmp);
if (err)
return err;
if (direction == ADC_CONF_SET) {
switch(index) {
case ADC_CONF_CHN_RANGE:
/*
* Whenever the user changes voltage range we need to adjust
* the zero-offset value (if any)
*/
err = adc_100m14b4cha_offset_zero_set(adc);
break;
default:
break;
}
}
if (direction == ADC_CONF_GET) {
switch(index) {
case ADC_CONF_CHN_OFFSET:
case __ADC_CONF_CHN_OFFSET_ZERO:
*value = __offset_raw_to_uv(value_tmp);
break;
default:
*value = value_tmp;
break;
}
}
return err;
}
......
......@@ -64,7 +64,8 @@ class TestAdcGetterSetterChannel(object):
conf_rb = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_CHN, channel)
conf_rb.mask_set(PyAdcConf.ADC_CONF_CHN_RANGE)
adc100m14b4cha.retrieve_config(conf_rb)
assert conf.value_get(PyAdcConf.ADC_CONF_CHN_RANGE) == conf_rb.value_get(PyAdcConf.ADC_CONF_CHN_RANGE)
assert vref == conf.value_get(PyAdcConf.ADC_CONF_CHN_RANGE)
assert vref == conf_rb.value_get(PyAdcConf.ADC_CONF_CHN_RANGE)
@pytest.mark.parametrize("termination", [True, False])
@pytest.mark.parametrize("channel", range(4))
......@@ -78,9 +79,12 @@ class TestAdcGetterSetterChannel(object):
conf_rb = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_CHN, channel)
conf_rb.mask_set(PyAdcConf.ADC_CONF_CHN_TERMINATION)
adc100m14b4cha.retrieve_config(conf_rb)
assert conf.value_get(PyAdcConf.ADC_CONF_CHN_TERMINATION) == conf_rb.value_get(PyAdcConf.ADC_CONF_CHN_TERMINATION)
assert int(termination) == conf.value_get(PyAdcConf.ADC_CONF_CHN_TERMINATION)
assert int(termination) == conf_rb.value_get(PyAdcConf.ADC_CONF_CHN_TERMINATION)
@pytest.mark.parametrize("offset", range(-5000000, 4999999 + 1, 100000))
@pytest.mark.parametrize("offset", [-5000152] +
list(range(-PyFmcAdc100m14b4ch.ADC_CONF_100M14B4CHA_DAC_VREF_uV,
PyFmcAdc100m14b4ch.ADC_CONF_100M14B4CHA_DAC_VREF_uV - 1, 100000)))
@pytest.mark.parametrize("channel", range(4))
def test_adc_offset(self, adc100m14b4cha, offset, channel):
"""Test that we can read/write offset on all channels"""
......@@ -92,12 +96,23 @@ class TestAdcGetterSetterChannel(object):
conf_rb = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_CHN, channel)
conf_rb.mask_set(PyAdcConf.ADC_CONF_CHN_OFFSET)
adc100m14b4cha.retrieve_config(conf_rb)
assert conf.value_get(PyAdcConf.ADC_CONF_CHN_OFFSET) == conf_rb.value_get(PyAdcConf.ADC_CONF_CHN_OFFSET)
@pytest.mark.parametrize("offset", [-5000001, 5000000])
assert ctypes.c_uint32(offset).value == conf.value_get(PyAdcConf.ADC_CONF_CHN_OFFSET)
step = PyFmcAdc100m14b4ch.ADC_CONF_100M14B4CHA_DAC_VREF_uV / 0x8000
offset_rb = ctypes.c_int32(conf_rb.value_get(PyAdcConf.ADC_CONF_CHN_OFFSET)).value
assert abs(offset - offset_rb) <= step
@pytest.mark.parametrize("offset", [-5000153, ] +
list(range(-PyFmcAdc100m14b4ch.ADC_CONF_100M14B4CHA_DAC_VREF_uV * 2,
-PyFmcAdc100m14b4ch.ADC_CONF_100M14B4CHA_DAC_VREF_uV -153,
1000000))
+ list(range(PyFmcAdc100m14b4ch.ADC_CONF_100M14B4CHA_DAC_VREF_uV,
PyFmcAdc100m14b4ch.ADC_CONF_100M14B4CHA_DAC_VREF_uV * 2,
1000000)))
@pytest.mark.parametrize("channel", range(4))
def test_adc_offset_invalid(self, adc100m14b4cha, offset, channel):
"""Test that we can read/write offset on all channels"""
"""Test that we can read/write offset on all channels.
Due to approximation the range [-5000152 uV, -5000001 uV]
is treaded as -5000000 uV: hance, a valid value"""
conf = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_CHN, channel)
conf.value_set(PyAdcConf.ADC_CONF_CHN_OFFSET, offset)
assert conf.value_get(PyAdcConf.ADC_CONF_CHN_OFFSET) == ctypes.c_uint32(offset).value
......@@ -116,7 +131,8 @@ class TestAdcGetterSetterChannel(object):
conf_rb = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_CHN, channel)
conf_rb.mask_set(PyAdcConf.ADC_CONF_CHN_SATURATION)
adc100m14b4cha.retrieve_config(conf_rb)
assert conf.value_get(PyAdcConf.ADC_CONF_CHN_SATURATION) == conf_rb.value_get(PyAdcConf.ADC_CONF_CHN_SATURATION)
assert saturation == conf.value_get(PyAdcConf.ADC_CONF_CHN_SATURATION)
assert saturation == conf_rb.value_get(PyAdcConf.ADC_CONF_CHN_SATURATION)
@pytest.mark.parametrize("saturation", [random.randrange(0x8000, 0xFFFFFFFF) for i in range(10)])
@pytest.mark.parametrize("channel", range(4))
......@@ -143,7 +159,8 @@ class TestAdcGetterSetterTriggerThreshold(object):
conf_rb = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_TRG_THR, channel)
conf_rb.mask_set(PyAdcConf.ADC_CONF_TRG_THR_ENABLE)
adc100m14b4cha.retrieve_config(conf_rb)
assert conf.value_get(PyAdcConf.ADC_CONF_TRG_THR_ENABLE) == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_THR_ENABLE)
assert int(enable) == conf.value_get(PyAdcConf.ADC_CONF_TRG_THR_ENABLE)
assert int(enable) == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_THR_ENABLE)
@pytest.mark.parametrize("polarity", [0, 1])
@pytest.mark.parametrize("channel", range(4))
......@@ -157,7 +174,8 @@ class TestAdcGetterSetterTriggerThreshold(object):
conf_rb = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_TRG_THR, channel)
conf_rb.mask_set(PyAdcConf.ADC_CONF_TRG_THR_POLARITY)
adc100m14b4cha.retrieve_config(conf_rb)
assert conf.value_get(PyAdcConf.ADC_CONF_TRG_THR_POLARITY) == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_THR_POLARITY)
assert polarity == conf.value_get(PyAdcConf.ADC_CONF_TRG_THR_POLARITY)
assert polarity == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_THR_POLARITY)
@pytest.mark.parametrize("delay", [2**x for x in range(32)])
@pytest.mark.parametrize("channel", range(4))
......@@ -171,7 +189,8 @@ class TestAdcGetterSetterTriggerThreshold(object):
conf_rb = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_TRG_THR, channel)
conf_rb.mask_set(PyAdcConf.ADC_CONF_TRG_THR_DELAY)
adc100m14b4cha.retrieve_config(conf_rb)
assert conf.value_get(PyAdcConf.ADC_CONF_TRG_THR_DELAY) == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_THR_DELAY)
assert delay == conf.value_get(PyAdcConf.ADC_CONF_TRG_THR_DELAY)
assert delay == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_THR_DELAY)
@pytest.mark.parametrize("threshold", [2**x for x in range(15)])
@pytest.mark.parametrize("channel", range(4))
......@@ -185,7 +204,8 @@ class TestAdcGetterSetterTriggerThreshold(object):
conf_rb = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_TRG_THR, channel)
conf_rb.mask_set(PyAdcConf.ADC_CONF_TRG_THR_THRESHOLD)
adc100m14b4cha.retrieve_config(conf_rb)
assert conf.value_get(PyAdcConf.ADC_CONF_TRG_THR_THRESHOLD) == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_THR_THRESHOLD)
assert threshold == conf.value_get(PyAdcConf.ADC_CONF_TRG_THR_THRESHOLD)
assert threshold == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_THR_THRESHOLD)
@pytest.mark.parametrize("threshold", [2**x for x in range(16, 32)])
@pytest.mark.parametrize("channel", range(4))
......@@ -213,7 +233,8 @@ class TestAdcGetterSetterTriggerThreshold(object):
conf_rb = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_TRG_THR, channel)
conf_rb.mask_set(PyAdcConf.ADC_CONF_TRG_THR_HYSTERESIS)
adc100m14b4cha.retrieve_config(conf_rb)
assert conf.value_get(PyAdcConf.ADC_CONF_TRG_THR_HYSTERESIS) == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_THR_HYSTERESIS)
assert hysteresis == conf.value_get(PyAdcConf.ADC_CONF_TRG_THR_HYSTERESIS)
assert hysteresis == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_THR_HYSTERESIS)
@pytest.mark.parametrize("hysteresis", [2**x for x in range(16, 32)])
@pytest.mark.parametrize("channel", range(4))
......@@ -242,7 +263,8 @@ class TestAdcGetterSetterTriggerExternal(object):
conf_rb = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_TRG_EXT, 0)
conf_rb.mask_set(PyAdcConf.ADC_CONF_TRG_EXT_ENABLE)
adc100m14b4cha.retrieve_config(conf_rb)
assert conf.value_get(PyAdcConf.ADC_CONF_TRG_EXT_ENABLE) == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_EXT_ENABLE)
assert int(enable) == conf.value_get(PyAdcConf.ADC_CONF_TRG_EXT_ENABLE)
assert int(enable) == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_EXT_ENABLE)
@pytest.mark.parametrize("polarity", [0, 1])
def test_adc_polarity(self, adc100m14b4cha, polarity):
......@@ -255,7 +277,8 @@ class TestAdcGetterSetterTriggerExternal(object):
conf_rb = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_TRG_EXT, 0)
conf_rb.mask_set(PyAdcConf.ADC_CONF_TRG_EXT_POLARITY)
adc100m14b4cha.retrieve_config(conf_rb)
assert conf.value_get(PyAdcConf.ADC_CONF_TRG_EXT_POLARITY) == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_EXT_POLARITY)
assert polarity == conf.value_get(PyAdcConf.ADC_CONF_TRG_EXT_POLARITY)
assert polarity == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_EXT_POLARITY)
@pytest.mark.parametrize("delay", [2**x for x in range(32)])
def test_adc_delay(self, adc100m14b4cha, delay):
......@@ -268,4 +291,5 @@ class TestAdcGetterSetterTriggerExternal(object):
conf_rb = PyAdcConf(PyAdcConf.ADC_CONF_TYPE_TRG_EXT, 0)
conf_rb.mask_set(PyAdcConf.ADC_CONF_TRG_EXT_DELAY)
adc100m14b4cha.retrieve_config(conf_rb)
assert conf.value_get(PyAdcConf.ADC_CONF_TRG_EXT_DELAY) == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_EXT_DELAY)
assert delay == conf.value_get(PyAdcConf.ADC_CONF_TRG_EXT_DELAY)
assert delay == conf_rb.value_get(PyAdcConf.ADC_CONF_TRG_EXT_DELAY)
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