From 4690689b8fb893401c838b0dc33b098a97613fca Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Mon, 18 Nov 2024 11:23:25 +1300 Subject: [PATCH 1/3] drivers: Copy SPL06 to SPA06 --- src/drivers/barometer/Kconfig | 1 + src/drivers/barometer/goertek/CMakeLists.txt | 3 +- .../barometer/goertek/spa06/CMakeLists.txt | 45 ++++ src/drivers/barometer/goertek/spa06/Kconfig | 5 + src/drivers/barometer/goertek/spa06/SPA06.cpp | 248 ++++++++++++++++++ src/drivers/barometer/goertek/spa06/SPA06.hpp | 120 +++++++++ .../barometer/goertek/spa06/SPA06_I2C.cpp | 102 +++++++ .../barometer/goertek/spa06/SPA06_SPI.cpp | 104 ++++++++ .../barometer/goertek/spa06/parameters.c | 41 +++ src/drivers/barometer/goertek/spa06/spa06.h | 108 ++++++++ .../barometer/goertek/spa06/spa06_main.cpp | 141 ++++++++++ src/drivers/drv_sensor.h | 1 + 12 files changed, 918 insertions(+), 1 deletion(-) create mode 100644 src/drivers/barometer/goertek/spa06/CMakeLists.txt create mode 100644 src/drivers/barometer/goertek/spa06/Kconfig create mode 100644 src/drivers/barometer/goertek/spa06/SPA06.cpp create mode 100644 src/drivers/barometer/goertek/spa06/SPA06.hpp create mode 100644 src/drivers/barometer/goertek/spa06/SPA06_I2C.cpp create mode 100644 src/drivers/barometer/goertek/spa06/SPA06_SPI.cpp create mode 100644 src/drivers/barometer/goertek/spa06/parameters.c create mode 100644 src/drivers/barometer/goertek/spa06/spa06.h create mode 100644 src/drivers/barometer/goertek/spa06/spa06_main.cpp diff --git a/src/drivers/barometer/Kconfig b/src/drivers/barometer/Kconfig index da9c2dd7143a..868b55262131 100644 --- a/src/drivers/barometer/Kconfig +++ b/src/drivers/barometer/Kconfig @@ -11,6 +11,7 @@ menu "barometer" select DRIVERS_BAROMETER_MS5611 select DRIVERS_BAROMETER_MAIERTEK_MPC2520 select DRIVERS_BAROMETER_GOERTEK_SPL06 + select DRIVERS_BAROMETER_GOERTEK_SPA06 select DRIVERS_BAROMETER_INVENSENSE_ICP101XX select DRIVERS_BAROMETER_INVENSENSE_ICP201XX ---help--- diff --git a/src/drivers/barometer/goertek/CMakeLists.txt b/src/drivers/barometer/goertek/CMakeLists.txt index 867eb64fcaa0..b626766ddd9a 100644 --- a/src/drivers/barometer/goertek/CMakeLists.txt +++ b/src/drivers/barometer/goertek/CMakeLists.txt @@ -1,6 +1,6 @@ ############################################################################ # -# Copyright (c) 2022 PX4 Development Team. All rights reserved. +# Copyright (c) 2022-2024 PX4 Development Team. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -32,3 +32,4 @@ ############################################################################ add_subdirectory(spl06) +add_subdirectory(spa06) diff --git a/src/drivers/barometer/goertek/spa06/CMakeLists.txt b/src/drivers/barometer/goertek/spa06/CMakeLists.txt new file mode 100644 index 000000000000..572b5dab2a1b --- /dev/null +++ b/src/drivers/barometer/goertek/spa06/CMakeLists.txt @@ -0,0 +1,45 @@ +############################################################################ +# +# Copyright (c) 2024 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_module( + MODULE drivers__barometer__spa06 + MAIN spa06 + SRCS + SPA06.cpp + SPA06.hpp + SPA06_I2C.cpp + SPA06_SPI.cpp + spa06_main.cpp + DEPENDS + px4_work_queue + ) diff --git a/src/drivers/barometer/goertek/spa06/Kconfig b/src/drivers/barometer/goertek/spa06/Kconfig new file mode 100644 index 000000000000..7190a27defaa --- /dev/null +++ b/src/drivers/barometer/goertek/spa06/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_BAROMETER_GOERTEK_SPA06 + bool "spa06" + default n + ---help--- + Enable support for spa06 diff --git a/src/drivers/barometer/goertek/spa06/SPA06.cpp b/src/drivers/barometer/goertek/spa06/SPA06.cpp new file mode 100644 index 000000000000..fb81db54825e --- /dev/null +++ b/src/drivers/barometer/goertek/spa06/SPA06.cpp @@ -0,0 +1,248 @@ +/**************************************************************************** + * + * Copyright (c) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "SPA06.hpp" + +SPA06::SPA06(const I2CSPIDriverConfig &config, spa06::ISPA06 *interface) : + I2CSPIDriver(config), + _interface(interface), + _sample_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": sample")), + _measure_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": measure")), + _comms_errors(perf_alloc(PC_COUNT, MODULE_NAME": comms errors")) +{ +} + +SPA06::~SPA06() +{ + // free perf counters + perf_free(_sample_perf); + perf_free(_measure_perf); + perf_free(_comms_errors); + + delete _interface; +} + +/* +float +SPA06::scale_factor(int oversampling_rate) +{ + float k; + + switch (oversampling_rate) { + case 1: + k = 524288.0f; + break; + + case 2: + k = 1572864.0f; + break; + + case 4: + k = 3670016.0f; + break; + + case 8: + k = 7864320.0f; + break; + + case 16: + k = 253952.0f; + break; + + case 32: + k = 516096.0f; + break; + + case 64: + k = 1040384.0f; + break; + + case 128: + k = 2088960.0f; + break; + + default: + k = 0; + break; + } + + return k; +} +*/ + +int +SPA06::calibrate() +{ + uint8_t buf[18]; + + _interface->read(SPA06_ADDR_CAL, buf, sizeof(buf)); + + _cal.c0 = (uint16_t)buf[0] << 4 | (uint16_t)buf[1] >> 4; + _cal.c0 = (_cal.c0 & 1 << 11) ? (0xf000 | _cal.c0) : _cal.c0; + + _cal.c1 = (uint16_t)(buf[1] & 0x0f) << 8 | (uint16_t)buf[2]; + _cal.c1 = (_cal.c1 & 1 << 11) ? (0xf000 | _cal.c1) : _cal.c1; + + _cal.c00 = (uint32_t)buf[3] << 12 | (uint32_t)buf[4] << 4 | (uint16_t)buf[5] >> 4; + _cal.c00 = (_cal.c00 & 1 << 19) ? (0xfff00000 | _cal.c00) : _cal.c00; + + _cal.c10 = (uint32_t)(buf[5] & 0x0f) << 16 | (uint32_t)buf[6] << 8 | (uint32_t)buf[7]; + _cal.c10 = (_cal.c10 & 1 << 19) ? (0xfff00000 | _cal.c10) : _cal.c10; + + _cal.c01 = (uint16_t)buf[8] << 8 | buf[9]; + _cal.c11 = (uint16_t)buf[10] << 8 | buf[11]; + _cal.c20 = (uint16_t)buf[12] << 8 | buf[13]; + _cal.c21 = (uint16_t)buf[14] << 8 | buf[15]; + _cal.c30 = (uint16_t)buf[16] << 8 | buf[17]; + + // PX4_INFO("c0:%d \nc1:%d \nc00:%d \nc10:%d \nc01:%d \nc11:%d \nc20:%d \nc21:%d \nc30:%d\n", + // _cal.c0,_cal.c1, + // _cal.c00,_cal.c10, + // _cal.c01,_cal.c11,_cal.c20,_cal.c21,_cal.c30 + // ); + //PX4_DEBUG("c0:%f",_cal.c0); + return OK; +} +int +SPA06::init() +{ + int8_t tries = 5; + // reset sensor + _interface->set_reg(SPA06_VALUE_RESET, SPA06_ADDR_RESET); + usleep(10000); + + // check id + if (_interface->get_reg(SPA06_ADDR_ID) != SPA06_VALUE_ID) { + PX4_DEBUG("id of your baro is not: 0x%02x", SPA06_VALUE_ID); + return -EIO; + } + + while (tries--) { + uint8_t meas_cfg = _interface->get_reg(SPA06_ADDR_MEAS_CFG); + + if (meas_cfg & (1 << 7) && meas_cfg & (1 << 6)) { + break; + } + + usleep(10000); + } + + if (tries < 0) { + PX4_DEBUG("spa06 cal failed"); + return -EIO; + } + + // get calibration and pre process them + calibrate(); + + // set config, recommended settings + _interface->set_reg(_curr_prs_cfg, SPA06_ADDR_PRS_CFG); + kp = 253952.0f; // refer to scale_factor() + _interface->set_reg(_curr_tmp_cfg, SPA06_ADDR_TMP_CFG); + kt = 524288.0f; + + + _interface->set_reg(1 << 2, SPA06_ADDR_CFG_REG); + _interface->set_reg(7, SPA06_ADDR_MEAS_CFG); + + Start(); + + return OK; +} + +void +SPA06::Start() +{ + // schedule a cycle to start things + ScheduleNow(); +} + +void +SPA06::RunImpl() +{ + collect(); + + ScheduleDelayed(_measure_interval); +} +int +SPA06::collect() +{ + perf_begin(_sample_perf); + + // this should be fairly close to the end of the conversion, so the best approximation of the time + const hrt_abstime timestamp_sample = hrt_absolute_time(); + + if (_interface->read(SPA06_ADDR_DATA, (uint8_t *)&_data, sizeof(_data)) != OK) { + perf_count(_comms_errors); + perf_cancel(_sample_perf); + return -EIO; + } + + int32_t temp_raw = (uint32_t)_data.t_msb << 16 | (uint32_t)_data.t_lsb << 8 | (uint32_t)_data.t_xlsb; + temp_raw = (temp_raw & 1 << 23) ? (0xff000000 | temp_raw) : temp_raw; + + int32_t press_raw = (uint32_t)_data.p_msb << 16 | (uint32_t) _data.p_lsb << 8 | (uint32_t) _data.p_xlsb; + press_raw = (press_raw & 1 << 23) ? (0xff000000 | press_raw) : press_raw; + + // calculate + float ftsc = (float)temp_raw / kt; + float fpsc = (float)press_raw / kp; + float qua2 = (float)_cal.c10 + fpsc * ((float)_cal.c20 + fpsc * (float)_cal.c30); + float qua3 = ftsc * fpsc * ((float)_cal.c11 + fpsc * (float)_cal.c21); + + float fp = (float)_cal.c00 + fpsc * qua2 + ftsc * (float)_cal.c01 + qua3; + float temperature = (float)_cal.c0 * 0.5f + (float)_cal.c1 * ftsc; + + + sensor_baro_s sensor_baro{}; + sensor_baro.timestamp_sample = timestamp_sample; + sensor_baro.device_id = _interface->get_device_id(); + sensor_baro.pressure = fp; + sensor_baro.temperature = temperature; + sensor_baro.error_count = perf_event_count(_comms_errors); + sensor_baro.timestamp = hrt_absolute_time(); + _sensor_baro_pub.publish(sensor_baro); + + perf_end(_sample_perf); + + return OK; +} + +void +SPA06::print_status() +{ + I2CSPIDriverBase::print_status(); + perf_print_counter(_sample_perf); + perf_print_counter(_measure_perf); + perf_print_counter(_comms_errors); +} diff --git a/src/drivers/barometer/goertek/spa06/SPA06.hpp b/src/drivers/barometer/goertek/spa06/SPA06.hpp new file mode 100644 index 000000000000..565e572a3e79 --- /dev/null +++ b/src/drivers/barometer/goertek/spa06/SPA06.hpp @@ -0,0 +1,120 @@ +/**************************************************************************** + * + * Copyright (c) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include "spa06.h" + +#include +#include +#include +#include +#include +#include +#include + +class SPA06 : public I2CSPIDriver +{ +public: + SPA06(const I2CSPIDriverConfig &config, spa06::ISPA06 *interface); + virtual ~SPA06(); + + static I2CSPIDriverBase *instantiate(const I2CSPIDriverConfig &config, int runtime_instance); + static void print_usage(); + + int init(); + void print_status(); + + void RunImpl(); +private: + void Start(); + // float scale_factor(int oversampling_rate); + + int collect(); //get results and publish + int calibrate(); + + uORB::PublicationMulti _sensor_baro_pub{ORB_ID(sensor_baro)}; + + spa06::ISPA06 *_interface; + spa06::data_s _data; + spa06::calibration_s _cal{}; + + // set config, recommended settings + // + // oversampling rate : single | 2 | 4 | 8 | 16 | 32 | 64 | 128 + // scale factor(KP/KT): 524288 | 1572864 | 3670016 | 7864320 | 253952 | 516096 | 1040384 | 2088960 + + // configuration of pressure measurement rate (PM_RATE) and resolution (PM_PRC) + // + // bit[7]: reserved + // + // PM_RATE[6:4] : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 + // measurement rate: 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 + // note: applicable for measurements in background mode only + // + // PM_PRC[3:0] : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 + // oversampling (times): single | 2 | 4 | 8 | 16 | 32 | 64 | 128 + // measurement time(ms): 3.6 | 5.2 | 8.4 | 14.8 | 27.6 | 53.2 | 104.4 | 206.8 + // precision(PaRMS) : 5.0 | | 2.5 | | 1.2 | 0.9 | 0.5 | + // note: use in combination with a bit shift when the oversampling rate is > 8 times. see CFG_REG(0x19) register + static constexpr uint8_t _curr_prs_cfg{4 << 4 | 4}; + + // configuration of temperature measurment rate (TMP_RATE) and resolution (TMP_PRC) + // + // temperature measurement: internal sensor (in ASIC) | external sensor (in pressure sensor MEMS element) + // TMP_EXT[7] : 0 | 1 + // note: it is highly recommended to use the same temperature sensor as the source of the calibration coefficients wihch can be read from reg 0x28 + // + // TMP_RATE[6:4] : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 + // measurement rate: 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 + // note: applicable for measurements in background mode only + // + // bit[3]: reserved + // + // TMP_PRC[2:0] : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 + // oversampling (times): single | 2 | 4 | 8 | 16 | 32 | 64 | 128 + // note: single(default) measurement time 3.6ms, other settings are optional, and may not be relevant + // note: use in combination with a bit shift when the oversampling rate is > 8 times. see CFG_REG(0x19) register + static constexpr uint8_t _curr_tmp_cfg{1 << 7 | 4 << 4 | 0}; + + bool _collect_phase{false}; + float kp; + float kt; + + perf_counter_t _sample_perf; + perf_counter_t _measure_perf; + perf_counter_t _comms_errors; + + static constexpr uint32_t _sample_rate{16}; + static constexpr uint32_t _measure_interval{1000000 / _sample_rate / 2}; +}; diff --git a/src/drivers/barometer/goertek/spa06/SPA06_I2C.cpp b/src/drivers/barometer/goertek/spa06/SPA06_I2C.cpp new file mode 100644 index 000000000000..e3e6044037c9 --- /dev/null +++ b/src/drivers/barometer/goertek/spa06/SPA06_I2C.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** + * + * Copyright (c) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file SPA06_I2C.cpp + * + * SPI interface for Goertek SPA06 + */ + +#include "spa06.h" + +#include +#include + +#if defined(CONFIG_I2C) + +class SPA06_I2C: public device::I2C, public spa06::ISPA06 +{ +public: + SPA06_I2C(uint8_t bus, uint32_t device, int bus_frequency); + virtual ~SPA06_I2C() override = default; + + int init() override { return I2C::init(); } + + uint8_t get_reg(uint8_t addr) override; + int set_reg(uint8_t value, uint8_t addr) override; + + int read(uint8_t addr, uint8_t *buf, uint8_t len) override; + //spa06::data_s *get_data(uint8_t addr) override; + //spa06::calibration_s *get_calibration(uint8_t addr) override; + + uint32_t get_device_id() const override { return device::I2C::get_device_id(); } + + uint8_t get_device_address() const override { return device::I2C::get_device_address(); } +private: + spa06::calibration_s _cal{}; + spa06::data_s _data{}; +}; + +spa06::ISPA06 *spa06_i2c_interface(uint8_t busnum, uint32_t device, int bus_frequency) +{ + return new SPA06_I2C(busnum, device, bus_frequency); +} + +SPA06_I2C::SPA06_I2C(uint8_t bus, uint32_t device, int bus_frequency) : + I2C(DRV_BARO_DEVTYPE_SPA06, MODULE_NAME, bus, device, bus_frequency) +{ +} + +uint8_t +SPA06_I2C::get_reg(uint8_t addr) +{ + uint8_t cmd[2] = { (uint8_t)(addr), 0}; + transfer(&cmd[0], 1, &cmd[1], 1); + + return cmd[1]; +} + +int +SPA06_I2C::set_reg(uint8_t value, uint8_t addr) +{ + uint8_t cmd[2] = { (uint8_t)(addr), value}; + return transfer(cmd, sizeof(cmd), nullptr, 0); +} + +int +SPA06_I2C::read(uint8_t addr, uint8_t *buf, uint8_t len) +{ + return transfer(&addr, 1, buf, len); +} + +#endif // CONFIG_I2C diff --git a/src/drivers/barometer/goertek/spa06/SPA06_SPI.cpp b/src/drivers/barometer/goertek/spa06/SPA06_SPI.cpp new file mode 100644 index 000000000000..80c6112090fb --- /dev/null +++ b/src/drivers/barometer/goertek/spa06/SPA06_SPI.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** + * + * Copyright (c) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file SPA06_SPI.cpp + * + * SPI interface for Goertek SPA06 + */ + +#include "spa06.h" + +#include +#include + +#if defined(CONFIG_SPI) + +/* SPI protocol address bits */ +#define DIR_READ (1<<7) //for set +#define DIR_WRITE ~(1<<7) //for clear + +class SPA06_SPI: public device::SPI, public spa06::ISPA06 +{ +public: + SPA06_SPI(uint8_t bus, uint32_t device, int bus_frequency, spi_mode_e spi_mode); + virtual ~SPA06_SPI() override = default; + + int init() override { return SPI::init(); } + + uint8_t get_reg(uint8_t addr) override; + int set_reg(uint8_t value, uint8_t addr) override; + + int read(uint8_t addr, uint8_t *buf, uint8_t len) override; + + uint32_t get_device_id() const override { return device::SPI::get_device_id(); } + + uint8_t get_device_address() const override { return device::SPI::get_device_address(); } +}; + +spa06::ISPA06 * +spa06_spi_interface(uint8_t busnum, uint32_t device, int bus_frequency, spi_mode_e spi_mode) +{ + return new SPA06_SPI(busnum, device, bus_frequency, spi_mode); +} + +SPA06_SPI::SPA06_SPI(uint8_t bus, uint32_t device, int bus_frequency, spi_mode_e spi_mode) : + SPI(DRV_BARO_DEVTYPE_SPA06, MODULE_NAME, bus, device, spi_mode, bus_frequency) +{ +} + +uint8_t +SPA06_SPI::get_reg(uint8_t addr) +{ + uint8_t cmd[2] = { (uint8_t)(addr | DIR_READ), 0}; // set MSB bit + transfer(&cmd[0], &cmd[0], 2); + + return cmd[1]; +} + +int +SPA06_SPI::set_reg(uint8_t value, uint8_t addr) +{ + uint8_t cmd[2] = { (uint8_t)(addr & DIR_WRITE), value}; // clear MSB bit + return transfer(&cmd[0], nullptr, 2); +} + +int +SPA06_SPI::read(uint8_t addr, uint8_t *buf, uint8_t len) +{ + uint8_t tx_buf[len + 1] = {(uint8_t)(addr | DIR_READ)}; // GCC support VLA, let's use it + + return transfer(tx_buf, buf, len); +} + +#endif // CONFIG_SPI diff --git a/src/drivers/barometer/goertek/spa06/parameters.c b/src/drivers/barometer/goertek/spa06/parameters.c new file mode 100644 index 000000000000..a7853291310f --- /dev/null +++ b/src/drivers/barometer/goertek/spa06/parameters.c @@ -0,0 +1,41 @@ +/**************************************************************************** + * + * Copyright (c) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * Goertek SPA06 Barometer (external I2C) + * + * @reboot_required true + * @group Sensors + * @boolean + */ +PARAM_DEFINE_INT32(SENS_EN_SPA06, 0); diff --git a/src/drivers/barometer/goertek/spa06/spa06.h b/src/drivers/barometer/goertek/spa06/spa06.h new file mode 100644 index 000000000000..b31276af8761 --- /dev/null +++ b/src/drivers/barometer/goertek/spa06/spa06.h @@ -0,0 +1,108 @@ +/**************************************************************************** + * + * Copyright (c) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file spa06.h + * + * Shared defines for the spa06 driver. + */ +#pragma once + +#include + +#define SPA06_ADDR_ID 0x0d +#define SPA06_ADDR_RESET 0x0c // set to reset +#define SPA06_ADDR_CAL 0x10 +#define SPA06_ADDR_PRS_CFG 0x06 +#define SPA06_ADDR_TMP_CFG 0x07 +#define SPA06_ADDR_MEAS_CFG 0x08 +#define SPA06_ADDR_CFG_REG 0x09 +#define SPA06_ADDR_DATA 0x00 + + +#define SPA06_VALUE_RESET 9 +#define SPA06_VALUE_ID 0x10 + +namespace spa06 +{ + +#pragma pack(push,1) +struct calibration_s { + int16_t c0, c1; + int32_t c00, c10; + int16_t c01, c11, c20, c21, c30; +}; //calibration data + +struct data_s { + uint8_t p_msb; + uint8_t p_lsb; + uint8_t p_xlsb; + + uint8_t t_msb; + uint8_t t_lsb; + uint8_t t_xlsb; +}; // data +#pragma pack(pop) + +class ISPA06 +{ +public: + virtual ~ISPA06() = default; + + virtual int init() = 0; + + // read reg value + virtual uint8_t get_reg(uint8_t addr) = 0; + + // write reg value + virtual int set_reg(uint8_t value, uint8_t addr) = 0; + + // bulk read of data into buffer, return same pointer + virtual int read(uint8_t addr, uint8_t *buf, uint8_t len) = 0; + // bulk read of calibration data into buffer, return same pointer + + virtual uint32_t get_device_id() const = 0; + + virtual uint8_t get_device_address() const = 0; +}; + +} /* namespace */ + + +/* interface factories */ +#if defined(CONFIG_SPI) +extern spa06::ISPA06 *spa06_spi_interface(uint8_t busnum, uint32_t device, int bus_frequency, spi_mode_e spi_mode); +#endif // CONFIG_SPI +#if defined(CONFIG_I2C) +extern spa06::ISPA06 *spa06_i2c_interface(uint8_t busnum, uint32_t device, int bus_frequency); +#endif // CONFIG_I2C diff --git a/src/drivers/barometer/goertek/spa06/spa06_main.cpp b/src/drivers/barometer/goertek/spa06/spa06_main.cpp new file mode 100644 index 000000000000..848b1f19a712 --- /dev/null +++ b/src/drivers/barometer/goertek/spa06/spa06_main.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** + * + * Copyright (c) 2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +#include "SPA06.hpp" + +#include + +extern "C" { __EXPORT int spa06_main(int argc, char *argv[]); } + +void +SPA06::print_usage() +{ + PRINT_MODULE_USAGE_NAME("spa06", "driver"); + PRINT_MODULE_USAGE_SUBCATEGORY("baro"); + PRINT_MODULE_USAGE_COMMAND("start"); +#if defined(CONFIG_I2C) + PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, true); + PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x76); +#else + PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(false, true); +#endif + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); +} + +I2CSPIDriverBase *SPA06::instantiate(const I2CSPIDriverConfig &config, int runtime_instance) +{ + spa06::ISPA06 *interface = nullptr; + +#if defined(CONFIG_I2C) + + if (config.bus_type == BOARD_I2C_BUS) { + interface = spa06_i2c_interface(config.bus, config.i2c_address, config.bus_frequency); + + } + +#endif // CONFIG_I2C +#if defined(CONFIG_SPI) + + if (config.bus_type == BOARD_SPI_BUS) { + interface = spa06_spi_interface(config.bus, config.spi_devid, config.bus_frequency, config.spi_mode); + } + +#endif // CONFIG_SPI + + if (interface == nullptr) { + PX4_ERR("failed creating interface for bus %i", config.bus); + return nullptr; + } + + if (interface->init() != OK) { + delete interface; + PX4_DEBUG("no device on bus %i", config.bus); + return nullptr; + } + + SPA06 *dev = new SPA06(config, interface); + + if (dev == nullptr) { + delete interface; + return nullptr; + } + + if (OK != dev->init()) { + delete dev; + return nullptr; + } + + return dev; +} + +int +spa06_main(int argc, char *argv[]) +{ + using ThisDriver = SPA06; + BusCLIArguments cli{true, true}; +#if defined(CONFIG_I2C) + cli.i2c_address = 0x76; + cli.default_i2c_frequency = 100 * 1000; +#endif // CONFIG_I2C +#if defined(CONFIG_SPI) + cli.default_spi_frequency = 10 * 1000 * 1000; +#endif // CONFIG_SPI + + const char *verb = cli.parseDefaultArguments(argc, argv); + + if (!verb) { + ThisDriver::print_usage(); + return -1; + } + + BusInstanceIterator iterator(MODULE_NAME, cli, DRV_BARO_DEVTYPE_SPA06); + + if (!strcmp(verb, "start")) { + return ThisDriver::module_start(cli, iterator); + } + + if (!strcmp(verb, "stop")) { + return ThisDriver::module_stop(iterator); + } + + if (!strcmp(verb, "status")) { + return ThisDriver::module_status(iterator); + } + + ThisDriver::print_usage(); + return -1; +} diff --git a/src/drivers/drv_sensor.h b/src/drivers/drv_sensor.h index 904d63aeba7b..8b33acb0f1ad 100644 --- a/src/drivers/drv_sensor.h +++ b/src/drivers/drv_sensor.h @@ -247,6 +247,7 @@ #define DRV_DIFF_PRESS_DEVTYPE_AUAV 0xE6 #define DRV_BARO_DEVTYPE_AUAV 0xE7 +#define DRV_BARO_DEVTYPE_SPA06 0xE8 #define DRV_DEVTYPE_UNUSED 0xff From 53d443a1b157bffb9f1aafe75e346b36ecd22a87 Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Mon, 18 Nov 2024 15:02:32 +1300 Subject: [PATCH 2/3] drivers: add SPA06 --- ROMFS/px4fmu_common/init.d/rc.sensors | 7 +++ src/drivers/barometer/goertek/spa06/SPA06.cpp | 53 +++++++++++-------- src/drivers/barometer/goertek/spa06/SPA06.hpp | 27 +++++----- src/drivers/barometer/goertek/spa06/spa06.h | 13 +++-- 4 files changed, 57 insertions(+), 43 deletions(-) diff --git a/ROMFS/px4fmu_common/init.d/rc.sensors b/ROMFS/px4fmu_common/init.d/rc.sensors index b85f36e09de3..7f479a3b1f02 100644 --- a/ROMFS/px4fmu_common/init.d/rc.sensors +++ b/ROMFS/px4fmu_common/init.d/rc.sensors @@ -211,6 +211,13 @@ then spl06 -X -a 0x77 start fi +# SPA06 sensor external I2C +if param compare -s SENS_EN_SPA06 1 +then + spa06 -X start + spa06 -X -a 0x77 start +fi + # PCF8583 counter (RPM sensor) if param compare -s SENS_EN_PCF8583 1 then diff --git a/src/drivers/barometer/goertek/spa06/SPA06.cpp b/src/drivers/barometer/goertek/spa06/SPA06.cpp index fb81db54825e..a1b1b4118fc5 100644 --- a/src/drivers/barometer/goertek/spa06/SPA06.cpp +++ b/src/drivers/barometer/goertek/spa06/SPA06.cpp @@ -103,34 +103,44 @@ SPA06::scale_factor(int oversampling_rate) int SPA06::calibrate() { - uint8_t buf[18]; + uint8_t buf[21]; _interface->read(SPA06_ADDR_CAL, buf, sizeof(buf)); - _cal.c0 = (uint16_t)buf[0] << 4 | (uint16_t)buf[1] >> 4; + _cal.c0 = (uint16_t)(buf[0]) << 4 | (uint16_t)(buf[1]) >> 4; + // If value is negative, we need to fill the missing bits. _cal.c0 = (_cal.c0 & 1 << 11) ? (0xf000 | _cal.c0) : _cal.c0; - _cal.c1 = (uint16_t)(buf[1] & 0x0f) << 8 | (uint16_t)buf[2]; + _cal.c1 = (uint16_t)(buf[1] & 0x0F) << 8 | buf[2]; _cal.c1 = (_cal.c1 & 1 << 11) ? (0xf000 | _cal.c1) : _cal.c1; - _cal.c00 = (uint32_t)buf[3] << 12 | (uint32_t)buf[4] << 4 | (uint16_t)buf[5] >> 4; + _cal.c00 = (uint32_t)(buf[3]) << 12 | (uint32_t)(buf[4]) << 4 | (buf[5]) >> 4; _cal.c00 = (_cal.c00 & 1 << 19) ? (0xfff00000 | _cal.c00) : _cal.c00; - _cal.c10 = (uint32_t)(buf[5] & 0x0f) << 16 | (uint32_t)buf[6] << 8 | (uint32_t)buf[7]; + _cal.c10 = (uint32_t)(buf[5] & 0x0F) << 16 | (uint32_t)(buf[6]) << 8 | buf[7]; _cal.c10 = (_cal.c10 & 1 << 19) ? (0xfff00000 | _cal.c10) : _cal.c10; - _cal.c01 = (uint16_t)buf[8] << 8 | buf[9]; - _cal.c11 = (uint16_t)buf[10] << 8 | buf[11]; - _cal.c20 = (uint16_t)buf[12] << 8 | buf[13]; - _cal.c21 = (uint16_t)buf[14] << 8 | buf[15]; - _cal.c30 = (uint16_t)buf[16] << 8 | buf[17]; - - // PX4_INFO("c0:%d \nc1:%d \nc00:%d \nc10:%d \nc01:%d \nc11:%d \nc20:%d \nc21:%d \nc30:%d\n", - // _cal.c0,_cal.c1, - // _cal.c00,_cal.c10, - // _cal.c01,_cal.c11,_cal.c20,_cal.c21,_cal.c30 - // ); - //PX4_DEBUG("c0:%f",_cal.c0); + _cal.c01 = (uint16_t)(buf[8]) << 8 | buf[9]; + + _cal.c11 = (uint16_t)(buf[10]) << 8 | buf[11]; + + _cal.c20 = (uint16_t)(buf[12]) << 8 | buf[13]; + + _cal.c21 = (uint16_t)(buf[14]) << 8 | buf[15]; + + _cal.c30 = (uint16_t)(buf[16]) << 8 | buf[17]; + + _cal.c31 = (uint16_t)(buf[18]) << 4 | (uint16_t)(buf[19] & 0xF0) >> 4; + _cal.c31 = (_cal.c31 & 1 << 11) ? (0xf000 | _cal.c31) : _cal.c31; + + _cal.c40 = (uint16_t)(buf[19] & 0x0F) << 8 | buf[20]; + _cal.c40 = (_cal.c40 & 1 << 11) ? (0xf000 | _cal.c40) : _cal.c40; + + PX4_DEBUG("c0:%d\nc1:%d\nc00:%ld\nc10:%ld\nc01:%d\nc11:%d\nc20:%d\nc21:%d\nc30:%d\nc31:%d\nc40:%d\n", + _cal.c0, _cal.c1, + _cal.c00, _cal.c10, + _cal.c01, _cal.c11, _cal.c20, _cal.c21, _cal.c30, _cal.c31, _cal.c40); + return OK; } int @@ -158,7 +168,7 @@ SPA06::init() } if (tries < 0) { - PX4_DEBUG("spa06 cal failed"); + PX4_DEBUG("spa06 sensor or coef not ready"); return -EIO; } @@ -171,8 +181,9 @@ SPA06::init() _interface->set_reg(_curr_tmp_cfg, SPA06_ADDR_TMP_CFG); kt = 524288.0f; - + // Enable FIFO _interface->set_reg(1 << 2, SPA06_ADDR_CFG_REG); + // Continuous pressure and temperature mesasurement. _interface->set_reg(7, SPA06_ADDR_MEAS_CFG); Start(); @@ -217,8 +228,8 @@ SPA06::collect() // calculate float ftsc = (float)temp_raw / kt; float fpsc = (float)press_raw / kp; - float qua2 = (float)_cal.c10 + fpsc * ((float)_cal.c20 + fpsc * (float)_cal.c30); - float qua3 = ftsc * fpsc * ((float)_cal.c11 + fpsc * (float)_cal.c21); + float qua2 = (float)_cal.c10 + fpsc * ((float)_cal.c20 + fpsc * ((float)_cal.c30) + fpsc * (float)_cal.c40); + float qua3 = ftsc * fpsc * ((float)_cal.c11 + fpsc * ((float)_cal.c21) + fpsc * (float)_cal.c31); float fp = (float)_cal.c00 + fpsc * qua2 + ftsc * (float)_cal.c01 + qua3; float temperature = (float)_cal.c0 * 0.5f + (float)_cal.c1 * ftsc; diff --git a/src/drivers/barometer/goertek/spa06/SPA06.hpp b/src/drivers/barometer/goertek/spa06/SPA06.hpp index 565e572a3e79..255da708195c 100644 --- a/src/drivers/barometer/goertek/spa06/SPA06.hpp +++ b/src/drivers/barometer/goertek/spa06/SPA06.hpp @@ -76,10 +76,8 @@ class SPA06 : public I2CSPIDriver // configuration of pressure measurement rate (PM_RATE) and resolution (PM_PRC) // - // bit[7]: reserved - // - // PM_RATE[6:4] : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 - // measurement rate: 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 + // PM_RATE[7:4] : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 + // measurement rate: 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 25/16 | 25/8 | 25/4 | 25/2 | 25 | 50 | 100 | 200 // note: applicable for measurements in background mode only // // PM_PRC[3:0] : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 @@ -87,25 +85,24 @@ class SPA06 : public I2CSPIDriver // measurement time(ms): 3.6 | 5.2 | 8.4 | 14.8 | 27.6 | 53.2 | 104.4 | 206.8 // precision(PaRMS) : 5.0 | | 2.5 | | 1.2 | 0.9 | 0.5 | // note: use in combination with a bit shift when the oversampling rate is > 8 times. see CFG_REG(0x19) register - static constexpr uint8_t _curr_prs_cfg{4 << 4 | 4}; + // + // -> 32 measurements per second, 16 oversampling + static constexpr uint8_t _curr_prs_cfg{5 << 4 | 4}; // configuration of temperature measurment rate (TMP_RATE) and resolution (TMP_PRC) // // temperature measurement: internal sensor (in ASIC) | external sensor (in pressure sensor MEMS element) - // TMP_EXT[7] : 0 | 1 - // note: it is highly recommended to use the same temperature sensor as the source of the calibration coefficients wihch can be read from reg 0x28 - // - // TMP_RATE[6:4] : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 - // measurement rate: 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 + // PM_RATE[7:4] : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 + // measurement rate: 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 25/16 | 25/8 | 25/4 | 25/2 | 25 | 50 | 100 | 200 // note: applicable for measurements in background mode only // - // bit[3]: reserved - // // TMP_PRC[2:0] : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 // oversampling (times): single | 2 | 4 | 8 | 16 | 32 | 64 | 128 // note: single(default) measurement time 3.6ms, other settings are optional, and may not be relevant // note: use in combination with a bit shift when the oversampling rate is > 8 times. see CFG_REG(0x19) register - static constexpr uint8_t _curr_tmp_cfg{1 << 7 | 4 << 4 | 0}; + + // -> 32 measurements per second, single oversampling + static constexpr uint8_t _curr_tmp_cfg{5 << 4 | 0}; bool _collect_phase{false}; float kp; @@ -115,6 +112,6 @@ class SPA06 : public I2CSPIDriver perf_counter_t _measure_perf; perf_counter_t _comms_errors; - static constexpr uint32_t _sample_rate{16}; - static constexpr uint32_t _measure_interval{1000000 / _sample_rate / 2}; + static constexpr uint32_t _sample_rate{32}; + static constexpr uint32_t _measure_interval{1000000 / _sample_rate}; }; diff --git a/src/drivers/barometer/goertek/spa06/spa06.h b/src/drivers/barometer/goertek/spa06/spa06.h index b31276af8761..4412974f351f 100644 --- a/src/drivers/barometer/goertek/spa06/spa06.h +++ b/src/drivers/barometer/goertek/spa06/spa06.h @@ -34,7 +34,7 @@ /** * @file spa06.h * - * Shared defines for the spa06 driver. + * Shared defines for the SPA06 driver. */ #pragma once @@ -51,7 +51,7 @@ #define SPA06_VALUE_RESET 9 -#define SPA06_VALUE_ID 0x10 +#define SPA06_VALUE_ID 0x11 namespace spa06 { @@ -60,8 +60,8 @@ namespace spa06 struct calibration_s { int16_t c0, c1; int32_t c00, c10; - int16_t c01, c11, c20, c21, c30; -}; //calibration data + int16_t c01, c11, c20, c21, c30, c31, c40; +}; struct data_s { uint8_t p_msb; @@ -71,7 +71,7 @@ struct data_s { uint8_t t_msb; uint8_t t_lsb; uint8_t t_xlsb; -}; // data +}; #pragma pack(pop) class ISPA06 @@ -96,10 +96,9 @@ class ISPA06 virtual uint8_t get_device_address() const = 0; }; -} /* namespace */ +} // namespace spa06 -/* interface factories */ #if defined(CONFIG_SPI) extern spa06::ISPA06 *spa06_spi_interface(uint8_t busnum, uint32_t device, int bus_frequency, spi_mode_e spi_mode); #endif // CONFIG_SPI From 4b33f57c11fba5d6ccc764933f4c9ae069bc297d Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Tue, 19 Nov 2024 14:57:07 +1300 Subject: [PATCH 3/3] boards: add SPA06 to KakuteH7/H7mini/H7v2 boards --- boards/holybro/kakuteh7/init/rc.board_sensors | 5 ++++- boards/holybro/kakuteh7mini/init/rc.board_sensors | 5 ++++- boards/holybro/kakuteh7v2/init/rc.board_sensors | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/boards/holybro/kakuteh7/init/rc.board_sensors b/boards/holybro/kakuteh7/init/rc.board_sensors index eb0413343b01..2d26d786e0c4 100644 --- a/boards/holybro/kakuteh7/init/rc.board_sensors +++ b/boards/holybro/kakuteh7/init/rc.board_sensors @@ -11,4 +11,7 @@ then icm42688p -R 6 -s start fi -bmp280 -X start +if ! bmp280 -X start +then + spa06 -X start +fi diff --git a/boards/holybro/kakuteh7mini/init/rc.board_sensors b/boards/holybro/kakuteh7mini/init/rc.board_sensors index 4577115c1d7f..58e58905af12 100644 --- a/boards/holybro/kakuteh7mini/init/rc.board_sensors +++ b/boards/holybro/kakuteh7mini/init/rc.board_sensors @@ -12,4 +12,7 @@ then fi fi -bmp280 -X start +if ! bmp280 -X start +then + spa06 -X start +fi diff --git a/boards/holybro/kakuteh7v2/init/rc.board_sensors b/boards/holybro/kakuteh7v2/init/rc.board_sensors index ad7025102a30..25387e78478b 100644 --- a/boards/holybro/kakuteh7v2/init/rc.board_sensors +++ b/boards/holybro/kakuteh7v2/init/rc.board_sensors @@ -9,4 +9,7 @@ then icm42688p -R 0 -s start fi -bmp280 -X start +if ! bmp280 -X start +then + spa06 -X start +fi