drivers: auav, read sensor eeprom to get cal range (#26294)

* drivers: auav, read sensor eeprom to get cal range

* added review feedback
This commit is contained in:
Alexander Lerach
2026-01-19 15:21:18 +01:00
committed by GitHub
parent f98fdbc452
commit 273766a4ea
6 changed files with 114 additions and 20 deletions
+18 -17
View File
@@ -77,6 +77,10 @@ AUAV::~AUAV()
void AUAV::RunImpl() void AUAV::RunImpl()
{ {
switch (_state) { switch (_state) {
case STATE::READ_FACTORY_DATA:
handle_state_read_factory_data();
break;
case STATE::READ_CALIBDATA: case STATE::READ_CALIBDATA:
handle_state_read_calibdata(); handle_state_read_calibdata();
break; break;
@@ -107,23 +111,6 @@ int AUAV::init()
return ret; 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(); ScheduleClear();
ScheduleNow(); ScheduleNow();
return PX4_OK; return PX4_OK;
@@ -148,6 +135,20 @@ int AUAV::probe()
return PX4_ERROR; 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() void AUAV::handle_state_read_calibdata()
{ {
int status = PX4_OK; int status = PX4_OK;
@@ -61,6 +61,7 @@ public:
protected: protected:
enum class STATE : uint8_t { enum class STATE : uint8_t {
READ_FACTORY_DATA,
READ_CALIBDATA, READ_CALIBDATA,
REQUEST_MEASUREMENT, REQUEST_MEASUREMENT,
GATHER_MEASUREMENT GATHER_MEASUREMENT
@@ -107,7 +108,9 @@ protected:
virtual int64_t get_conversion_interval() const = 0; virtual int64_t get_conversion_interval() const = 0;
virtual calib_eeprom_addr_t get_calib_eeprom_addr() 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 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_read_calibdata();
void handle_state_request_measurement(); void handle_state_request_measurement();
void handle_state_gather_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 correct_pressure(const uint32_t pressure_raw, const uint32_t temperature_raw) const;
float process_temperature_raw(const float temperature_raw) const; float process_temperature_raw(const float temperature_raw) const;
float _cal_range{10.0f}; STATE _state{STATE::READ_FACTORY_DATA};
STATE _state{STATE::READ_CALIBDATA};
calib_data_t _calib_data {}; calib_data_t _calib_data {};
perf_counter_t _sample_perf; perf_counter_t _sample_perf;
@@ -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; const float pressure_mbar = 250.f + 1.25f * ((pressure_dig - (0.1f * (1 << 24))) / (1 << 24)) * 1000.f;
return pressure_mbar * MBAR_TO_PA; return pressure_mbar * MBAR_TO_PA;
} }
int AUAV_Absolute::read_factory_data()
{
/* Absolute sensor doesn't need to read factory data */
return PX4_OK;
}
@@ -68,6 +68,7 @@ private:
int64_t get_conversion_interval() const override; int64_t get_conversion_interval() const override;
calib_eeprom_addr_t get_calib_eeprom_addr() const override; calib_eeprom_addr_t get_calib_eeprom_addr() const override;
float process_pressure_dig(const float pressure_dig) const override; float process_pressure_dig(const float pressure_dig) const override;
int read_factory_data() override;
uORB::PublicationMulti<sensor_baro_s> _sensor_baro_pub{ORB_ID(sensor_baro)}; uORB::PublicationMulti<sensor_baro_s> _sensor_baro_pub{ORB_ID(sensor_baro)};
}; };
@@ -33,10 +33,38 @@
#include "AUAV_Differential.hpp" #include "AUAV_Differential.hpp"
#include <parameters/param.h> #include <parameters/param.h>
#include <cctype>
AUAV_Differential::AUAV_Differential(const I2CSPIDriverConfig &config) : AUAV_Differential::AUAV_Differential(const I2CSPIDriverConfig &config) :
AUAV(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, 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 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<float>(_cal_range);
return pressure_in_h * INH_TO_PA; 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;
}
@@ -37,6 +37,7 @@
#include <uORB/topics/differential_pressure.h> #include <uORB/topics/differential_pressure.h>
/* AUAV EEPROM addresses for differential channel */ /* 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_AHW = 0x2B;
static constexpr uint8_t EEPROM_DIFF_ALW = 0x2C; static constexpr uint8_t EEPROM_DIFF_ALW = 0x2C;
static constexpr uint8_t EEPROM_DIFF_BHW = 0x2D; static constexpr uint8_t EEPROM_DIFF_BHW = 0x2D;
@@ -57,17 +58,26 @@ static_assert(DIFF_CONVERSION_INTERVAL >= 7000, "Conversion interval is too fast
/* Conversions */ /* Conversions */
static constexpr float INH_TO_PA = 249.08f; 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 class AUAV_Differential : public AUAV
{ {
public: public:
explicit AUAV_Differential(const I2CSPIDriverConfig &config); explicit AUAV_Differential(const I2CSPIDriverConfig &config);
~AUAV_Differential() = default; ~AUAV_Differential() = default;
void print_status() override;
private: private:
void publish_pressure(const float pressure_p, const float temperature_c, const hrt_abstime timestamp_sample) override; void publish_pressure(const float pressure_p, const float temperature_c, const hrt_abstime timestamp_sample) override;
int64_t get_conversion_interval() const override; int64_t get_conversion_interval() const override;
calib_eeprom_addr_t get_calib_eeprom_addr() const override; calib_eeprom_addr_t get_calib_eeprom_addr() const override;
float process_pressure_dig(const float pressure_dig) const override; float process_pressure_dig(const float pressure_dig) const override;
int read_factory_data() override;
uORB::PublicationMulti<differential_pressure_s> _differential_pressure_pub{ORB_ID(differential_pressure)}; uORB::PublicationMulti<differential_pressure_s> _differential_pressure_pub{ORB_ID(differential_pressure)};
int32_t _cal_range{10};
}; };