From 273766a4ea1061920fa8cbf92f32c63d094029cb Mon Sep 17 00:00:00 2001 From: Alexander Lerach Date: Mon, 19 Jan 2026 15:21:18 +0100 Subject: [PATCH] drivers: auav, read sensor eeprom to get cal range (#26294) * drivers: auav, read sensor eeprom to get cal range * added review feedback --- .../differential_pressure/auav/AUAV.cpp | 35 ++++----- .../differential_pressure/auav/AUAV.hpp | 6 +- .../auav/AUAV_Absolute.cpp | 6 ++ .../auav/AUAV_Absolute.hpp | 1 + .../auav/AUAV_Differential.cpp | 76 ++++++++++++++++++- .../auav/AUAV_Differential.hpp | 10 +++ 6 files changed, 114 insertions(+), 20 deletions(-) diff --git a/src/drivers/differential_pressure/auav/AUAV.cpp b/src/drivers/differential_pressure/auav/AUAV.cpp index 66f8a3b46b..fb89148133 100644 --- a/src/drivers/differential_pressure/auav/AUAV.cpp +++ b/src/drivers/differential_pressure/auav/AUAV.cpp @@ -77,6 +77,10 @@ AUAV::~AUAV() void AUAV::RunImpl() { switch (_state) { + case STATE::READ_FACTORY_DATA: + handle_state_read_factory_data(); + break; + case STATE::READ_CALIBDATA: handle_state_read_calibdata(); break; @@ -107,23 +111,6 @@ int AUAV::init() return ret; } - int32_t hw_model = 0; - param_get(param_find("SENS_EN_AUAVX"), &hw_model); - - switch (hw_model) { - case 1: /* AUAV L05D (+- 5 inH20) */ - _cal_range = 10.0f; - break; - - case 2: /* AUAV L10D (+- 10 inH20) */ - _cal_range = 20.0f; - break; - - case 3: /* AUAV L30D (+- 30 inH20) */ - _cal_range = 60.0f; - break; - } - ScheduleClear(); ScheduleNow(); return PX4_OK; @@ -148,6 +135,20 @@ int AUAV::probe() return PX4_ERROR; } +void AUAV::handle_state_read_factory_data() +{ + int status = read_factory_data(); + + if (status == PX4_OK) { + /* Factory data read or sensor does not have any, move to next state */ + _state = STATE::READ_CALIBDATA; + ScheduleNow(); + + } else { + ScheduleDelayed(100_ms); + } +} + void AUAV::handle_state_read_calibdata() { int status = PX4_OK; diff --git a/src/drivers/differential_pressure/auav/AUAV.hpp b/src/drivers/differential_pressure/auav/AUAV.hpp index b6d952d813..7011e8b748 100644 --- a/src/drivers/differential_pressure/auav/AUAV.hpp +++ b/src/drivers/differential_pressure/auav/AUAV.hpp @@ -61,6 +61,7 @@ public: protected: enum class STATE : uint8_t { + READ_FACTORY_DATA, READ_CALIBDATA, REQUEST_MEASUREMENT, GATHER_MEASUREMENT @@ -107,7 +108,9 @@ protected: virtual int64_t get_conversion_interval() const = 0; virtual calib_eeprom_addr_t get_calib_eeprom_addr() const = 0; virtual float process_pressure_dig(const float pressure_dig) const = 0; + virtual int read_factory_data() = 0; + void handle_state_read_factory_data(); void handle_state_read_calibdata(); void handle_state_request_measurement(); void handle_state_gather_measurement(); @@ -117,8 +120,7 @@ protected: float correct_pressure(const uint32_t pressure_raw, const uint32_t temperature_raw) const; float process_temperature_raw(const float temperature_raw) const; - float _cal_range{10.0f}; - STATE _state{STATE::READ_CALIBDATA}; + STATE _state{STATE::READ_FACTORY_DATA}; calib_data_t _calib_data {}; perf_counter_t _sample_perf; diff --git a/src/drivers/differential_pressure/auav/AUAV_Absolute.cpp b/src/drivers/differential_pressure/auav/AUAV_Absolute.cpp index bded1d626d..69e01d50fc 100644 --- a/src/drivers/differential_pressure/auav/AUAV_Absolute.cpp +++ b/src/drivers/differential_pressure/auav/AUAV_Absolute.cpp @@ -77,3 +77,9 @@ float AUAV_Absolute::process_pressure_dig(const float pressure_dig) const const float pressure_mbar = 250.f + 1.25f * ((pressure_dig - (0.1f * (1 << 24))) / (1 << 24)) * 1000.f; return pressure_mbar * MBAR_TO_PA; } + +int AUAV_Absolute::read_factory_data() +{ + /* Absolute sensor doesn't need to read factory data */ + return PX4_OK; +} diff --git a/src/drivers/differential_pressure/auav/AUAV_Absolute.hpp b/src/drivers/differential_pressure/auav/AUAV_Absolute.hpp index 603649a783..5ab105f5a5 100644 --- a/src/drivers/differential_pressure/auav/AUAV_Absolute.hpp +++ b/src/drivers/differential_pressure/auav/AUAV_Absolute.hpp @@ -68,6 +68,7 @@ private: int64_t get_conversion_interval() const override; calib_eeprom_addr_t get_calib_eeprom_addr() const override; float process_pressure_dig(const float pressure_dig) const override; + int read_factory_data() override; uORB::PublicationMulti _sensor_baro_pub{ORB_ID(sensor_baro)}; }; diff --git a/src/drivers/differential_pressure/auav/AUAV_Differential.cpp b/src/drivers/differential_pressure/auav/AUAV_Differential.cpp index 3a4243b366..b2d2b1fa21 100644 --- a/src/drivers/differential_pressure/auav/AUAV_Differential.cpp +++ b/src/drivers/differential_pressure/auav/AUAV_Differential.cpp @@ -33,10 +33,38 @@ #include "AUAV_Differential.hpp" #include +#include AUAV_Differential::AUAV_Differential(const I2CSPIDriverConfig &config) : AUAV(config) { + /* Initialize cal_range from parameter as fallback value */ + int32_t hw_model = 0; + param_get(param_find("SENS_EN_AUAVX"), &hw_model); + + switch (hw_model) { + case 1: /* AUAV L05D (+- 5 inH20) */ + _cal_range = 10; + break; + + case 2: /* AUAV L10D (+- 10 inH20) */ + _cal_range = 20; + break; + + case 3: /* AUAV L30D (+- 30 inH20) */ + _cal_range = 60; + break; + + default: + _cal_range = 10; /* Default fallback */ + break; + } +} + +void AUAV_Differential::print_status() +{ + AUAV::print_status(); + PX4_INFO("cal range: %" PRId32, _cal_range); } void AUAV_Differential::publish_pressure(const float pressure_p, const float temperature_c, @@ -83,6 +111,52 @@ AUAV::calib_eeprom_addr_t AUAV_Differential::get_calib_eeprom_addr() const float AUAV_Differential::process_pressure_dig(const float pressure_dig) const { - const float pressure_in_h = 1.25f * ((pressure_dig - (1 << 23)) / (1 << 24)) * _cal_range; + const float pressure_in_h = 1.25f * ((pressure_dig - (1 << 23)) / (1 << 24)) * static_cast(_cal_range); return pressure_in_h * INH_TO_PA; } + +int AUAV_Differential::read_factory_data() +{ + /* The differential sensor needs the cal_range from the absolute sensor's EEPROM. + * Temporarily switch to the absolute sensor's I2C address to read it, then switch back. */ + + uint8_t original_address = get_device_address(); + set_device_address(I2C_ADDRESS_ABSOLUTE); + + /* Read the calibration range from the absolute sensor's EEPROM */ + uint16_t factory_data = 0; + int status = read_calibration_eeprom(EEPROM_ABS_CAL_RNG, factory_data); + + set_device_address(original_address); + + if (status != PX4_OK) { + return status; + } + + /* If EEPROM data is 0, stop trying (sensor does not have factory data) */ + if (factory_data == 0) { + PX4_INFO("Differential: cal range data is 0, using fallback value"); + return PX4_OK; + } + + /* Decode the two bytes as ASCII characters */ + uint8_t char_high = (factory_data >> 8) & 0xFF; + uint8_t char_low = factory_data & 0xFF; + + /* Validate that both characters are ASCII digits (0-9) */ + if (!isdigit(char_high) || !isdigit(char_low)) { + return PX4_ERROR; + } + + int32_t sensor_type = ((char_high - '0') * 10) + (char_low - '0'); + + /* Check if the detected sensor type is valid */ + if (sensor_type != AUAV_LD_05 && sensor_type != AUAV_LD_10 && sensor_type != AUAV_LD_30) { + return PX4_ERROR; + } + + _cal_range = sensor_type * 2; + PX4_INFO("Differential: read cal range %" PRId32 " from absolute sensor EEPROM", _cal_range); + + return PX4_OK; +} diff --git a/src/drivers/differential_pressure/auav/AUAV_Differential.hpp b/src/drivers/differential_pressure/auav/AUAV_Differential.hpp index 168fb322b6..1b3ce238ce 100644 --- a/src/drivers/differential_pressure/auav/AUAV_Differential.hpp +++ b/src/drivers/differential_pressure/auav/AUAV_Differential.hpp @@ -37,6 +37,7 @@ #include /* AUAV EEPROM addresses for differential channel */ +static constexpr uint8_t EEPROM_ABS_CAL_RNG = 0x25; static constexpr uint8_t EEPROM_DIFF_AHW = 0x2B; static constexpr uint8_t EEPROM_DIFF_ALW = 0x2C; static constexpr uint8_t EEPROM_DIFF_BHW = 0x2D; @@ -57,17 +58,26 @@ static_assert(DIFF_CONVERSION_INTERVAL >= 7000, "Conversion interval is too fast /* Conversions */ static constexpr float INH_TO_PA = 249.08f; +/* Valid AUAV types */ +static constexpr int32_t AUAV_LD_05 = 5; +static constexpr int32_t AUAV_LD_10 = 10; +static constexpr int32_t AUAV_LD_30 = 30; + class AUAV_Differential : public AUAV { public: explicit AUAV_Differential(const I2CSPIDriverConfig &config); ~AUAV_Differential() = default; + void print_status() override; + private: void publish_pressure(const float pressure_p, const float temperature_c, const hrt_abstime timestamp_sample) override; int64_t get_conversion_interval() const override; calib_eeprom_addr_t get_calib_eeprom_addr() const override; float process_pressure_dig(const float pressure_dig) const override; + int read_factory_data() override; uORB::PublicationMulti _differential_pressure_pub{ORB_ID(differential_pressure)}; + int32_t _cal_range{10}; };