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
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 114 additions and 20 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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_s> _sensor_baro_pub{ORB_ID(sensor_baro)};
};

View File

@ -33,10 +33,38 @@
#include "AUAV_Differential.hpp"
#include <parameters/param.h>
#include <cctype>
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<float>(_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;
}

View File

@ -37,6 +37,7 @@
#include <uORB/topics/differential_pressure.h>
/* 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_s> _differential_pressure_pub{ORB_ID(differential_pressure)};
int32_t _cal_range{10};
};