From f41179dbe600951d4e4d9f16c26a3cad2fde8c80 Mon Sep 17 00:00:00 2001 From: Adrian Stanea Date: Wed, 27 Sep 2023 10:02:40 +0300 Subject: [PATCH] M2kAnalogIn: sync calibration state with device attrs and use new calibration attr - Sync class parameters: m_adc_calib_offset, m_adc_calib_gain with device attributes. These are used to calibrate the raw data to volts. - In firmware version 0.32, the device attribute won't be used by the hardware, samples will be recieved uncalibrated. The calibration will be done in software. - I new libm2k, use the calibration attr is used to disable setting the computed calibration values in HW. - Note: - set calibration = 'true' (string vale): stops the HW calibration - set calibration = 'false' (string value): enables the HW calibration Signed-off-by: Adrian Stanea --- src/analog/m2kanalogin_impl.cpp | 22 ++++++++++++++++++++++ src/analog/m2kanalogin_impl.hpp | 16 ++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/analog/m2kanalogin_impl.cpp b/src/analog/m2kanalogin_impl.cpp index 2305ef66..e9bcc48c 100644 --- a/src/analog/m2kanalogin_impl.cpp +++ b/src/analog/m2kanalogin_impl.cpp @@ -43,10 +43,16 @@ M2kAnalogInImpl::M2kAnalogInImpl(iio_context * ctx, std::string adc_dev, bool sy m_trigger(trigger) { LIBM2K_LOG(INFO, "[BEGIN] Initialize M2kAnalogIn"); + firmware_version = Utils::getFirmwareVersion(ctx); + m_m2k_adc = make_shared(ctx, adc_dev); m_m2k_fabric = make_shared(ctx, "m2k-fabric"); m_ad5625_dev = make_shared(ctx, "ad5625"); + if (firmware_version >= "v0.32") { + setCalibrateHDL("true"); + } + /* Filters applied while decimating affect the / amplitude of the received data */ m_filter_compensation_table[1E8] = 1.00; @@ -135,6 +141,9 @@ void M2kAnalogInImpl::syncDevice() } else { m_adc_calib_offset.at(i) = 2048; } + if (firmware_version >= "v0.32") { + m_adc_calib_gain.at(i) = getCalibscale(i); + } m_adc_hw_offset_raw.at(i) = m_ad5625_dev->getLongValue(2 + i, "raw", true); m_adc_hw_vert_offset.at(i) = convertRawToVoltsVerticalOffset(static_cast(i), m_adc_hw_offset_raw.at(i) - m_adc_calib_offset.at(i)); @@ -241,6 +250,10 @@ double M2kAnalogInImpl::setCalibscale(unsigned int index, double calibscale) if (index >= getNbChannels()) { THROW_M2K_EXCEPTION("M2kAnalogIn: no such channel", libm2k::EXC_OUT_OF_RANGE); } + // update class attribute as well as the attribute in the device + if (firmware_version >= "v0.32") { + m_adc_calib_gain.at(index) = calibscale; + } return m_m2k_adc->setDoubleValue(index, calibscale, "calibscale"); } @@ -941,3 +954,12 @@ int M2kAnalogInImpl::getAdcCalibOffset(ANALOG_IN_CHANNEL channel) return (adc_hw_offset - convertVoltsToRawVerticalOffset(channel, m_adc_hw_vert_offset.at(channel))); } } + +void M2kAnalogInImpl::setCalibrateHDL(std::string calibrate_val) +{ + m_m2k_adc->setStringValue("calibrate", calibrate_val); +} +std::string M2kAnalogInImpl::getCalibrateHDL() +{ + return m_m2k_adc->getStringValue("calibrate"); +} \ No newline at end of file diff --git a/src/analog/m2kanalogin_impl.hpp b/src/analog/m2kanalogin_impl.hpp index c760b852..2e409c7d 100644 --- a/src/analog/m2kanalogin_impl.hpp +++ b/src/analog/m2kanalogin_impl.hpp @@ -141,6 +141,7 @@ class M2kAnalogInImpl : public M2kAnalogIn bool hasCalibbias(); void loadNbKernelBuffers(); private: + std::string firmware_version; std::shared_ptr m_ad5625_dev; std::shared_ptr m_m2k_fabric; std::shared_ptr m_m2k_adc; @@ -180,6 +181,21 @@ class M2kAnalogInImpl : public M2kAnalogIn int convertVoltsToRawVerticalOffset(ANALOG_IN_CHANNEL channel, double vertOffset); double convertRawToVoltsVerticalOffset(ANALOG_IN_CHANNEL channel, int rawVertOffset); + + /** + * This function can stop the calibration process for the ADC at the HW level. + * The possible values can be checked in IIO in the "calibrate_available" device attribute of m2k-adc. + * + * When calibrate is set to true, the calibration won't affect the ADC samples. When set to false + * the calibration is applied. It should be set before doing calibration to avoid sending samples. + * + * Introduced in fw v0.32 to solve a bug where after HW calibration, some samples were missing due to rounding errors. + * + * @param calibrate_val The calibration value to set. Can take values "true" or "false" as std::strings. + * + */ + void setCalibrateHDL(std::string calibrate_val); + std::string getCalibrateHDL(); }; } }