Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AP_Baro:add driver for the SPA06 #27905

Merged
merged 3 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 83 additions & 10 deletions libraries/AP_Baro/AP_Baro_SPL06.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
extern const AP_HAL::HAL &hal;

#define SPL06_CHIP_ID 0x10
#define SPA06_CHIP_ID 0x11

#define SPL06_REG_PRESSURE_B2 0x00 // Pressure MSB Register
#define SPL06_REG_PRESSURE_B1 0x01 // Pressure middle byte Register
Expand All @@ -44,15 +45,19 @@ extern const AP_HAL::HAL &hal;
#define SPL06_REG_CHIP_ID 0x0D // Chip ID Register
#define SPL06_REG_CALIB_COEFFS_START 0x10
#define SPL06_REG_CALIB_COEFFS_END 0x21
#define SPA06_REG_CALIB_COEFFS_END 0x24

#define SPL06_CALIB_COEFFS_LEN (SPL06_REG_CALIB_COEFFS_END - SPL06_REG_CALIB_COEFFS_START + 1)
// PRESSURE_CFG_REG
#define SPL06_PRES_RATE_32HZ (0x05 << 4)

// TEMPERATURE_CFG_REG
#define SPL06_TEMP_USE_EXT_SENSOR (1<<7)
#define SPL06_TEMP_RATE_32HZ (0x05 << 4)

// MODE_AND_STATUS_REG
#define SPL06_MEAS_PRESSURE (1<<0) // measure pressure
#define SPL06_MEAS_TEMPERATURE (1<<1) // measure temperature
#define SPL06_MEAS_CON_PRE_TEM 0x07

#define SPL06_MEAS_CFG_CONTINUOUS (1<<2)
#define SPL06_MEAS_CFG_PRESSURE_RDY (1<<4)
Expand All @@ -70,6 +75,13 @@ extern const AP_HAL::HAL &hal;

#define SPL06_OVERSAMPLING_TO_REG_VALUE(n) (ffs(n)-1)

#define SPL06_BACKGROUND_SAMPLE_RATE 32

// enable Background Mode for continuous measurement
#ifndef AP_BARO_SPL06_BACKGROUND_ENABLE
#define AP_BARO_SPL06_BACKGROUND_ENABLE 0
#endif

AP_Baro_SPL06::AP_Baro_SPL06(AP_Baro &baro, AP_HAL::OwnPtr<AP_HAL::Device> dev)
: AP_Baro_Backend(baro)
, _dev(std::move(dev))
Expand Down Expand Up @@ -108,21 +120,43 @@ bool AP_Baro_SPL06::_init()

// Sometimes SPL06 has init problems, that's due to failure of reading using SPI for the first time. The SPL06 is a dual
// protocol sensor(I2C and SPI), sometimes it takes one SPI operation to convert it to SPI mode after it starts up.
bool is_SPL06 = false;

for (uint8_t i=0; i<5; i++) {
if (_dev->read_registers(SPL06_REG_CHIP_ID, &whoami, 1) &&
whoami == SPL06_CHIP_ID) {
is_SPL06=true;
break;
if (_dev->read_registers(SPL06_REG_CHIP_ID, &whoami, 1)) {
switch(whoami) {
case SPL06_CHIP_ID:
type = Type::SPL06;
break;
case SPA06_CHIP_ID:
type = Type::SPA06;
break;
default:
type = Type::UNKNOWN;
break;
}
}

if (type != Type::UNKNOWN)
break;
}

if(!is_SPL06) {
if (type == Type::UNKNOWN) {
return false;
}

// read the calibration data
uint8_t SPL06_CALIB_COEFFS_LEN = 18;
switch(type) {
case Type::SPL06:
SPL06_CALIB_COEFFS_LEN = SPL06_REG_CALIB_COEFFS_END - SPL06_REG_CALIB_COEFFS_START + 1;
break;
case Type::SPA06:
SPL06_CALIB_COEFFS_LEN = SPA06_REG_CALIB_COEFFS_END - SPL06_REG_CALIB_COEFFS_START + 1;
break;
default:
break;
}

uint8_t buf[SPL06_CALIB_COEFFS_LEN];
_dev->read_registers(SPL06_REG_CALIB_COEFFS_START, buf, sizeof(buf));

Expand All @@ -135,12 +169,25 @@ bool AP_Baro_SPL06::_init()
_c20 = ((uint16_t)buf[12] << 8) | (uint16_t)buf[13];
_c21 = ((uint16_t)buf[14] << 8) | (uint16_t)buf[15];
_c30 = ((uint16_t)buf[16] << 8) | (uint16_t)buf[17];
if(type == Type::SPA06) {
_c31 = (buf[18] & 0x80 ? 0xF000 : 0) | ((uint16_t)buf[18] << 4) | (((uint16_t)buf[19] & 0xF0) >> 4);
_c40 = ((buf[19] & 0x8 ? 0xF000 : 0) | ((uint16_t)buf[19] & 0x0F) << 8) | (uint16_t)buf[20];
}

// setup temperature and pressure measurements
_dev->setup_checked_registers(3, 20);

#if AP_BARO_SPL06_BACKGROUND_ENABLE
//set rate and oversampling
_dev->write_register(SPL06_REG_TEMPERATURE_CFG, SPL06_TEMP_RATE_32HZ | SPL06_OVERSAMPLING_TO_REG_VALUE(SPL06_TEMPERATURE_OVERSAMPLING), true);
_dev->write_register(SPL06_REG_PRESSURE_CFG, SPL06_PRES_RATE_32HZ | SPL06_OVERSAMPLING_TO_REG_VALUE(SPL06_PRESSURE_OVERSAMPLING), true);

//enable background mode
_dev->write_register(SPL06_REG_MODE_AND_STATUS, SPL06_MEAS_CON_PRE_TEM, true);
#else
_dev->write_register(SPL06_REG_TEMPERATURE_CFG, SPL06_TEMP_USE_EXT_SENSOR | SPL06_OVERSAMPLING_TO_REG_VALUE(SPL06_TEMPERATURE_OVERSAMPLING), true);
_dev->write_register(SPL06_REG_PRESSURE_CFG, SPL06_OVERSAMPLING_TO_REG_VALUE(SPL06_PRESSURE_OVERSAMPLING), true);
#endif //AP_BARO_SPL06_BACKGROUND_ENABLE

uint8_t int_and_fifo_reg_value = 0;
if (SPL06_TEMPERATURE_OVERSAMPLING > 8) {
Expand All @@ -158,7 +205,11 @@ bool AP_Baro_SPL06::_init()

// request 50Hz update
_timer_counter = -1;
#if AP_BARO_SPL06_BACKGROUND_ENABLE
_dev->register_periodic_callback(1000000/SPL06_BACKGROUND_SAMPLE_RATE, FUNCTOR_BIND_MEMBER(&AP_Baro_SPL06::_timer, void));
#else
_dev->register_periodic_callback(20 * AP_USEC_PER_MSEC, FUNCTOR_BIND_MEMBER(&AP_Baro_SPL06::_timer, void));
#endif //AP_BARO_SPL06_BACKGROUND_ENABLE

return true;
}
Expand All @@ -185,7 +236,15 @@ void AP_Baro_SPL06::_timer(void)
{
uint8_t buf[3];

if ((_timer_counter == -1) || (_timer_counter == 49)) {
#if AP_BARO_SPL06_BACKGROUND_ENABLE
_dev->read_registers(SPL06_REG_TEMPERATURE_START, buf, sizeof(buf));
_update_temperature((int32_t)((buf[0] & 0x80 ? 0xFF000000 : 0) | ((uint32_t)buf[0] << 16) | ((uint32_t)buf[1] << 8) | buf[2]));

_dev->read_registers(SPL06_REG_PRESSURE_START, buf, sizeof(buf));
_update_pressure((int32_t)((buf[0] & 0x80 ? 0xFF000000 : 0) | ((uint32_t)buf[0] << 16) | ((uint32_t)buf[1] << 8) | buf[2]));
#else
//command mode
if ((_timer_counter == -1) || (_timer_counter == 49)) {
// First call and every second start a temperature measurement (50Hz call)
_dev->write_register(SPL06_REG_MODE_AND_STATUS, SPL06_MEAS_TEMPERATURE, false);
_timer_counter = 0; // Next cycle we are reading the temperature
Expand All @@ -202,6 +261,7 @@ void AP_Baro_SPL06::_timer(void)
_dev->write_register(SPL06_REG_MODE_AND_STATUS, SPL06_MEAS_PRESSURE, false);
_timer_counter += 1;
}
#endif //AP_BARO_SPL06_BACKGROUND_ENABLE

_dev->check_next_register();
}
Expand Down Expand Up @@ -236,8 +296,21 @@ void AP_Baro_SPL06::_update_temperature(int32_t temp_raw)
void AP_Baro_SPL06::_update_pressure(int32_t press_raw)
{
const float press_raw_sc = (float)press_raw / raw_value_scale_factor(SPL06_PRESSURE_OVERSAMPLING);
const float pressure_cal = (float)_c00 + press_raw_sc * ((float)_c10 + press_raw_sc * ((float)_c20 + press_raw_sc * _c30));
const float press_temp_comp = _temp_raw * ((float)_c01 + press_raw_sc * ((float)_c11 + press_raw_sc * _c21));
float pressure_cal = 0;
float press_temp_comp = 0;

switch(type) {
case Type::SPL06:
pressure_cal = (float)_c00 + press_raw_sc * ((float)_c10 + press_raw_sc * ((float)_c20 + press_raw_sc * _c30));
press_temp_comp = _temp_raw * ((float)_c01 + press_raw_sc * ((float)_c11 + press_raw_sc * _c21));
break;
case Type::SPA06:
pressure_cal = (float)_c00 + press_raw_sc * ((float)_c10 + press_raw_sc * ((float)_c20 + press_raw_sc * ((float)_c30 + press_raw_sc * _c40)));
press_temp_comp = _temp_raw * ((float)_c01 + press_raw_sc * ((float)_c11 + press_raw_sc * ((float)_c21) + press_raw_sc * _c31));
break;
default:
break;
}

const float press_comp = pressure_cal + press_temp_comp;

Expand Down
9 changes: 8 additions & 1 deletion libraries/AP_Baro/AP_Baro_SPL06.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
class AP_Baro_SPL06 : public AP_Baro_Backend
{
public:
enum class Type {
UNKNOWN,
SPL06,
SPA06,
};
AP_Baro_SPL06(AP_Baro &baro, AP_HAL::OwnPtr<AP_HAL::Device> dev);

/* AP_Baro public interface: */
Expand Down Expand Up @@ -45,7 +50,9 @@ class AP_Baro_SPL06 : public AP_Baro_Backend

// Internal calibration registers
int32_t _c00, _c10;
int16_t _c0, _c1, _c01, _c11, _c20, _c21, _c30;
int16_t _c0, _c1, _c01, _c11, _c20, _c21, _c30, _c31, _c40;

Type type;
};

#endif // AP_BARO_SPL06_ENABLED
1 change: 0 additions & 1 deletion libraries/AP_HAL_ChibiOS/hwdef/RadiolinkPIX6/hwdef.dat
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ COMPASS IST8310 I2C:ALL_INTERNAL:0x0E false ROTATION_YAW_180

# one baro
BARO SPL06 I2C:0:0x76
BARO SPA06 I2C:0:0x76

# microSD support
PC8 SDMMC_D0 SDMMC1
Expand Down
Loading