ESPHome 2026.4.0-dev
Loading...
Searching...
No Matches
spa06_base.h
Go to the documentation of this file.
1// SPA06 interface code for ESPHome
2// All datasheet page references refer to Goermicro SPA06-003 datasheet version 2.0
3
4#pragma once
5
7#include "esphome/core/hal.h"
10
11namespace esphome::spa06_base {
12
13// Read sizes. All other registers are size 1
14constexpr size_t SPA06_MEAS_LEN = 3;
15constexpr size_t SPA06_COEF_LEN = 21;
16
17// Soft reset command (0b1001, 0x9)
18constexpr uint8_t SPA06_SOFT_RESET = 0x9;
19
20// SPA06 Register Addresses
21enum Register : uint8_t {
22 SPA06_PSR = 0x00, // Pressure Reading MSB (or all 3)
23 SPA06_PSR_B1 = 0x01, // Pressure Reading LSB
24 SPA06_PSR_B0 = 0x02, // Pressure Reading XLSB (LSB: Pressure flag in FIFO)
25 SPA06_TMP = 0x03, // Temperature Reading MSB (or all 3)
26 SPA06_TMP_B1 = 0x04, // Temperature Reading LSB
27 SPA06_TMP_B0 = 0x05, // Temperature Reading XLSB
28 SPA06_PSR_CFG = 0x06, // Pressure Configuration
29 SPA06_TMP_CFG = 0x07, // Temperature Configuration
30 SPA06_MEAS_CFG = 0x08, // Measurement Configuration (includes readiness)
31 SPA06_CFG_REG = 0x09, // Configuration Register
32 SPA06_INT_STS = 0x0A, // Interrupt Status
33 SPA06_FIFO_STS = 0x0B, // FIFO Status
34 SPA06_RESET = 0x0C, // Reset + FIFO Flush
35 SPA06_ID = 0x0D, // Product ID and revision
36 SPA06_COEF = 0x10, // Coefficients (0x10-0x24)
37 SPA06_INVALID_CMD = 0x25, // End of enum command
38};
39
40// Oversampling config.
52
53// Measuring rate config
72
73// Measuring control config, set in MEAS_CFG register.
74// See datasheet pages 28-29
83
84// Oversampling scale factors. See datasheet page 15.
85constexpr uint32_t OVERSAMPLING_K_LUT[8] = {524288, 1572864, 3670016, 7864320, 253952, 516096, 1040384, 2088960};
86PROGMEM_STRING_TABLE(MeasRateStrings, "1Hz", "2Hz", "4Hz", "8Hz", "16Hz", "32Hz", "64Hz", "128Hz", "1.5625Hz",
87 "3.125Hz", "6.25Hz", "12.5Hz", "25Hz", "50Hz", "100Hz", "200Hz");
88PROGMEM_STRING_TABLE(OversamplingStrings, "X1", "X2", "X4", "X8", "X16", "X32", "X64", "X128");
89
90inline static const LogString *oversampling_to_str(const Oversampling oversampling) {
91 return OversamplingStrings::get_log_str(static_cast<uint8_t>(oversampling), OversamplingStrings::LAST_INDEX);
92}
93inline static const LogString *meas_rate_to_str(SampleRate rate) {
94 return MeasRateStrings::get_log_str(static_cast<uint8_t>(rate), MeasRateStrings::LAST_INDEX);
95}
97 return OVERSAMPLING_K_LUT[static_cast<uint8_t>(oversampling)];
98};
99
101 public:
103 void setup() override;
104 void update() override;
105 void dump_config() override;
106
108 void set_conversion_time(uint16_t conversion_time) { this->conversion_time_ = conversion_time; }
109 void set_temperature_sensor(sensor::Sensor *temperature_sensor) { this->temperature_sensor_ = temperature_sensor; }
110 void set_pressure_sensor(sensor::Sensor *pressure_sensor) { this->pressure_sensor_ = pressure_sensor; }
111 void set_temperature_oversampling_config(Oversampling temperature_oversampling) {
112 this->temperature_oversampling_ = temperature_oversampling;
113 this->kt_ = oversampling_to_scale_factor(temperature_oversampling);
114 }
115 void set_pressure_oversampling_config(Oversampling pressure_oversampling) {
116 this->pressure_oversampling_ = pressure_oversampling;
117 this->kp_ = oversampling_to_scale_factor(pressure_oversampling);
118 }
121
122 protected:
123 // Virtual read functions. Implemented in SPI/I2C components
124 virtual bool spa_read_byte(uint8_t reg, uint8_t *data) = 0;
125 virtual bool spa_write_byte(uint8_t reg, uint8_t data) = 0;
126 virtual bool spa_read_bytes(uint8_t reg, uint8_t *data, size_t len) = 0;
127 virtual bool spa_write_bytes(uint8_t reg, uint8_t *data, size_t len) = 0;
128
130 // Soft reset
131 bool soft_reset_();
132 // Protocol-specific reset (used for SPI only, implemented as noop for I2C)
133 virtual void protocol_reset() {}
134 // Read temperature and calculate Celsius and scaled raw temperatures
135 bool read_temperature_(float &temperature, float &t_raw_sc);
136 // No pressure only read! Pressure calculation depends on scaled temperature value
137 // Read temperature and calculate Celsius temperature, Pascal pressure, and scaled raw temperature
138 bool read_temperature_and_pressure_(float &temperature, float &pressure, float &t_raw_sc);
139 // Read coefficients. Stores in class variables.
140 bool read_coefficients_();
141
143 // Write temperature settings to TMP_CFG register
145 // Write pressure settings to PRS_CFG register
147 // Write measurement settings to MEAS_CRTL register
149
150 // Write communication settings to CFG_REG register
151 // Set pressure_shift to true if pressure oversampling >X8
152 // Set temperature_shift to true if temperature oversampling >X8
153 bool write_communication_settings_(bool pressure_shift, bool temperature_shift, bool interrupt_hl = false,
154 bool interrupt_fifo = false, bool interrupt_tmp = false,
155 bool interrupt_prs = false, bool enable_fifo = false, bool spi_3wire = false);
156
158 // Write function for both temperature and pressure (deduplicates code)
159 bool write_sensor_settings_(Oversampling oversampling, SampleRate rate, uint8_t reg);
160 // Convert raw temperature reading into Celsius
161 float convert_temperature_(const float &t_raw_sc);
162 // Convert raw pressure and scaled raw temperature into Pascals
163 float convert_pressure_(const float &p_raw_sc, const float &t_raw_sc);
164
166 // Oversampling scale factors. Defaults are for X16 (pressure) and X1 (temp)
167 uint32_t kp_{253952}, kt_{524288};
168 // Coefficients for calculating pressure and temperature from raw values
169 // Obtained from IC during setup
170 int32_t c00_{0}, c10_{0};
171 int16_t c0_{0}, c1_{0}, c01_{0}, c11_{0}, c20_{0}, c21_{0}, c30_{0}, c31_{0}, c40_{0};
172
180 // Default conversion time: 27.6ms (16x pres) + 3.6ms (1x temp) ~ 32ms
181 uint16_t conversion_time_{32};
182
183 union {
184 struct {
188 uint8_t reg;
189 } pt_meas_cfg_ = {.reg = 0}; // PRS_CFG and TMP_CFG
190
191 union {
192 struct {
193 uint8_t meas_crtl : 3;
194 bool tmp_ext : 1;
195 bool prs_ready : 1;
196 bool tmp_ready : 1;
197 bool sensor_ready : 1;
198 bool coef_ready : 1;
200 uint8_t reg;
201 } meas_ = {.reg = 0}; // MEAS_REG
202
203 union {
204 struct {
205 uint8_t _reserved : 5;
206 bool int_prs : 1;
207 bool int_tmp : 1;
210 uint8_t reg;
211 } int_status_ = {.reg = 0}; // INT_STS
212
213 union {
214 struct {
215 bool spi_3wire : 1;
216 bool fifo_en : 1;
217 bool p_shift : 1;
218 bool t_shift : 1;
219 bool int_prs : 1;
220 bool int_tmp : 1;
221 bool int_fifo : 1;
222 bool int_hl : 1;
224 uint8_t reg;
225 } cfg_ = {.reg = 0}; // CFG_REG
226
227 union {
228 struct {
229 bool fifo_empty : 1;
230 bool fifo_full : 1;
231 uint8_t _reserved : 6;
233 uint8_t reg;
234 } fifo_sts_ = {.reg = 0}; // FIFO_STS
235
236 union {
237 struct {
238 // Set to true to flush FIFO
239 bool fifo_flush : 1;
240 // Reserved bits
241 uint8_t _reserved : 3;
242 // Soft reset. Set to 1001 (0x9) to perform reset.
243 uint8_t soft_rst : 4;
245 uint8_t reg = 0;
246 } reset_ = {.reg = 0}; // RESET
247
248 union {
249 struct {
250 uint8_t prod_id : 4;
251 uint8_t rev_id : 4;
253 uint8_t reg = 0;
254 } prod_id_ = {.reg = 0}; // ID
255
256}; // class SPA06Component
257} // namespace esphome::spa06_base
This class simplifies creating components that periodically check a state.
Definition component.h:589
Base-class for all sensors.
Definition sensor.h:47
void set_pressure_sample_rate_config(SampleRate rate)
Definition spa06_base.h:119
void set_temperature_oversampling_config(Oversampling temperature_oversampling)
Definition spa06_base.h:111
void set_temperature_sample_rate_config(SampleRate rate)
Definition spa06_base.h:120
union esphome::spa06_base::SPA06Component::@159 reset_
struct esphome::spa06_base::SPA06Component::@154::@161 bit
union esphome::spa06_base::SPA06Component::@155 meas_
virtual bool spa_write_bytes(uint8_t reg, uint8_t *data, size_t len)=0
union esphome::spa06_base::SPA06Component::@160 prod_id_
union esphome::spa06_base::SPA06Component::@156 int_status_
union esphome::spa06_base::SPA06Component::@157 cfg_
virtual bool spa_read_bytes(uint8_t reg, uint8_t *data, size_t len)=0
union esphome::spa06_base::SPA06Component::@154 pt_meas_cfg_
void set_temperature_sensor(sensor::Sensor *temperature_sensor)
Definition spa06_base.h:109
bool write_measurement_settings_(MeasCrtl crtl)
float convert_temperature_(const float &t_raw_sc)
bool read_temperature_(float &temperature, float &t_raw_sc)
virtual bool spa_write_byte(uint8_t reg, uint8_t data)=0
bool read_temperature_and_pressure_(float &temperature, float &pressure, float &t_raw_sc)
bool write_temperature_settings_(Oversampling oversampling, SampleRate rate)
union esphome::spa06_base::SPA06Component::@158 fifo_sts_
bool write_pressure_settings_(Oversampling oversampling, SampleRate rate)
virtual bool spa_read_byte(uint8_t reg, uint8_t *data)=0
bool write_communication_settings_(bool pressure_shift, bool temperature_shift, bool interrupt_hl=false, bool interrupt_fifo=false, bool interrupt_tmp=false, bool interrupt_prs=false, bool enable_fifo=false, bool spi_3wire=false)
bool write_sensor_settings_(Oversampling oversampling, SampleRate rate, uint8_t reg)
float convert_pressure_(const float &p_raw_sc, const float &t_raw_sc)
void set_pressure_oversampling_config(Oversampling pressure_oversampling)
Definition spa06_base.h:115
void set_conversion_time(uint16_t conversion_time)
Definition spa06_base.h:108
void set_pressure_sensor(sensor::Sensor *pressure_sensor)
Definition spa06_base.h:110
constexpr size_t SPA06_COEF_LEN
Definition spa06_base.h:15
uint32_t oversampling_to_scale_factor(const Oversampling oversampling)
Definition spa06_base.h:96
constexpr uint8_t SPA06_SOFT_RESET
Definition spa06_base.h:18
constexpr size_t SPA06_MEAS_LEN
Definition spa06_base.h:14
constexpr uint32_t OVERSAMPLING_K_LUT[8]
Definition spa06_base.h:85
PROGMEM_STRING_TABLE(MeasRateStrings, "1Hz", "2Hz", "4Hz", "8Hz", "16Hz", "32Hz", "64Hz", "128Hz", "1.5625Hz", "3.125Hz", "6.25Hz", "12.5Hz", "25Hz", "50Hz", "100Hz", "200Hz")
std::string size_t len
Definition helpers.h:1045
static void uint32_t
uint16_t temperature
Definition sun_gtil2.cpp:12
uint8_t pressure
Definition tt21100.cpp:7