2 * This file is part of INAV.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
20 * BMP388 Driver author: Dominic Clifton
21 * INAV port: Michel Pastor
29 #include "build/build_config.h"
30 #include "build/debug.h"
31 #include "common/utils.h"
32 #include "common/log.h" // XXX
34 #include "drivers/time.h"
35 #include "drivers/io.h"
36 #include "drivers/bus.h"
37 #include "drivers/barometer/barometer.h"
38 #include "drivers/barometer/barometer_bmp388.h"
40 #if defined(USE_BARO) && (defined(USE_BARO_BMP388) || defined(USE_BARO_SPI_BMP388) || defined(USE_BARO_BMP390) || defined(USE_BARO_SPI_BMP390))
42 #define BMP388_I2C_ADDR (0x76) // same as BMP280/BMP180
43 #define BMP388_DEFAULT_CHIP_ID (0x50) // from https://github.com/BoschSensortec/BMP3-Sensor-API/blob/master/bmp3_defs.h#L130
44 #define BMP390_DEFAULT_CHIP_ID (0x60) // from https://github.com/BoschSensortec/BMP3-Sensor-API/blob/master/bmp3_defs.h#L133
46 #define BMP388_CMD_REG (0x7E)
47 #define BMP388_RESERVED_UPPER_REG (0x7D)
48 // everything between BMP388_RESERVED_UPPER_REG and BMP388_RESERVED_LOWER_REG is reserved.
49 #define BMP388_RESERVED_LOWER_REG (0x20)
50 #define BMP388_CONFIG_REG (0x1F)
51 #define BMP388_RESERVED_0x1E_REG (0x1E)
52 #define BMP388_ODR_REG (0x1D)
53 #define BMP388_OSR_REG (0x1C)
54 #define BMP388_PWR_CTRL_REG (0x1B)
55 #define BMP388_IF_CONFIG_REG (0x1A)
56 #define BMP388_INT_CTRL_REG (0x19)
57 #define BMP388_FIFO_CONFIG_2_REG (0x18)
58 #define BMP388_FIFO_CONFIG_1_REG (0x17)
59 #define BMP388_FIFO_WTM_1_REG (0x16)
60 #define BMP388_FIFO_WTM_0_REG (0x15)
61 #define BMP388_FIFO_DATA_REG (0x14)
62 #define BMP388_FIFO_LENGTH_1_REG (0x13)
63 #define BMP388_FIFO_LENGTH_0_REG (0x12)
64 #define BMP388_INT_STATUS_REG (0x11)
65 #define BMP388_EVENT_REG (0x10)
66 #define BMP388_SENSORTIME_3_REG (0x0F) // BME780 only
67 #define BMP388_SENSORTIME_2_REG (0x0E)
68 #define BMP388_SENSORTIME_1_REG (0x0D)
69 #define BMP388_SENSORTIME_0_REG (0x0C)
70 #define BMP388_RESERVED_0x0B_REG (0x0B)
71 #define BMP388_RESERVED_0x0A_REG (0x0A)
73 // see friendly register names below
74 #define BMP388_DATA_5_REG (0x09)
75 #define BMP388_DATA_4_REG (0x08)
76 #define BMP388_DATA_3_REG (0x07)
77 #define BMP388_DATA_2_REG (0x06)
78 #define BMP388_DATA_1_REG (0x05)
79 #define BMP388_DATA_0_REG (0x04)
81 #define BMP388_STATUS_REG (0x03)
82 #define BMP388_ERR_REG (0x02)
83 #define BMP388_RESERVED_0x01_REG (0x01)
84 #define BMP388_CHIP_ID_REG (0x00)
86 // friendly register names, from datasheet 4.3.4
87 #define BMP388_PRESS_MSB_23_16_REG BMP388_DATA_2_REG
88 #define BMP388_PRESS_LSB_15_8_REG BMP388_DATA_1_REG
89 #define BMP388_PRESS_XLSB_7_0_REG BMP388_DATA_0_REG
91 // friendly register names, from datasheet 4.3.5
92 #define BMP388_TEMP_MSB_23_16_REG BMP388_DATA_5_REG
93 #define BMP388_TEMP_LSB_15_8_REG BMP388_DATA_4_REG
94 #define BMP388_TEMP_XLSB_7_0_REG BMP388_DATA_3_REG
96 #define BMP388_DATA_FRAME_SIZE ((BMP388_DATA_5_REG - BMP388_DATA_0_REG) + 1) // +1 for inclusive
99 #define BMP388_MODE_SLEEP (0x00)
100 #define BMP388_MODE_FORCED (0x01)
101 #define BMP388_MODE_NORMAL (0x02)
103 #define BMP388_CALIRATION_LOWER_REG (0x30) // See datasheet 4.3.19, "calibration data"
104 #define BMP388_TRIMMING_NVM_PAR_T1_LSB_REG (0x31) // See datasheet 3.11.1 "Memory map trimming coefficients"
105 #define BMP388_TRIMMING_NVM_PAR_P11_REG (0x45) // See datasheet 3.11.1 "Memory map trimming coefficients"
106 #define BMP388_CALIRATION_UPPER_REG (0x57)
108 #define BMP388_TRIMMING_DATA_LENGTH ((BMP388_TRIMMING_NVM_PAR_P11_REG - BMP388_TRIMMING_NVM_PAR_T1_LSB_REG) + 1) // +1 for inclusive
110 #define BMP388_OVERSAMP_1X (0x00)
111 #define BMP388_OVERSAMP_2X (0x01)
112 #define BMP388_OVERSAMP_4X (0x02)
113 #define BMP388_OVERSAMP_8X (0x03)
114 #define BMP388_OVERSAMP_16X (0x04)
115 #define BMP388_OVERSAMP_32X (0x05)
118 #define BMP388_INT_OD_BIT 0
119 #define BMP388_INT_LEVEL_BIT 1
120 #define BMP388_INT_LATCH_BIT 2
121 #define BMP388_INT_FWTM_EN_BIT 3
122 #define BMP388_INT_FFULL_EN_BIT 4
123 #define BMP388_INT_RESERVED_5_BIT 5
124 #define BMP388_INT_DRDY_EN_BIT 6
125 #define BMP388_INT_RESERVED_7_BIT 7
128 #define BMP388_OSR_P_BIT 0 // to 2
129 #define BMP388_OSR4_T_BIT 3 // to 5
130 #define BMP388_OSR_P_MASK (0x03) // -----111
131 #define BMP388_OSR4_T_MASK (0x38) // --111---
133 // configure pressure and temperature oversampling, forced sampling mode
134 #define BMP388_PRESSURE_OSR (BMP388_OVERSAMP_8X)
135 #define BMP388_TEMPERATURE_OSR (BMP388_OVERSAMP_1X)
137 // see Datasheet 3.11.1 Memory Map Trimming Coefficients
138 typedef struct bmp388_calib_param_s
{
153 } __attribute__((packed
)) bmp388_calib_param_t
;
155 STATIC_ASSERT(sizeof(bmp388_calib_param_t
) == BMP388_TRIMMING_DATA_LENGTH
, bmp388_calibration_structure_incorrectly_packed
);
157 static bmp388_calib_param_t bmp388_cal
;
158 // uncompensated pressure and temperature
159 static uint32_t bmp388_up
= 0;
160 static uint32_t bmp388_ut
= 0;
161 static uint8_t sensor_data
[BMP388_DATA_FRAME_SIZE
+1];
163 static int64_t t_lin
= 0;
165 static bool bmp388StartUT(baroDev_t
*baro
);
166 static bool bmp388GetUT(baroDev_t
*baro
);
167 static bool bmp388StartUP(baroDev_t
*baro
);
168 static bool bmp388GetUP(baroDev_t
*baro
);
170 static bool bmp388Calculate(baroDev_t
*baro
, int32_t *pressure
, int32_t *temperature
);
172 static bool bmp388BeginForcedMeasurement(busDevice_t
*busdev
)
174 // enable pressure measurement, temperature measurement, set power mode and start sampling
175 uint8_t mode
= BMP388_MODE_FORCED
<< 4 | 1 << 1 | 1 << 0;
176 return busWrite(busdev
, BMP388_PWR_CTRL_REG
, mode
);
179 static bool bmp388StartUT(baroDev_t
*baro
)
186 static bool bmp388GetUT(baroDev_t
*baro
)
193 static bool bmp388StartUP(baroDev_t
*baro
)
196 return bmp388BeginForcedMeasurement(baro
->busDev
);
199 static bool bmp388GetUP(baroDev_t
*baro
)
201 if (baro
->busDev
->busType
== BUSTYPE_SPI
) {
202 // In SPI mode, first byte read is a dummy byte
203 busReadBuf(baro
->busDev
, BMP388_DATA_0_REG
, &sensor_data
[0], BMP388_DATA_FRAME_SIZE
+ 1);
205 // In I2C mode, no dummy byte is read
206 busReadBuf(baro
->busDev
, BMP388_DATA_0_REG
, &sensor_data
[1], BMP388_DATA_FRAME_SIZE
);
209 bmp388_up
= sensor_data
[1] << 0 | sensor_data
[2] << 8 | sensor_data
[3] << 16;
210 bmp388_ut
= sensor_data
[4] << 0 | sensor_data
[5] << 8 | sensor_data
[6] << 16;
214 // Returns temperature in DegC, resolution is 0.01 DegC. Output value of "5123" equals 51.23 DegC
215 static int64_t bmp388CompensateTemperature(uint32_t uncomp_temperature
)
217 uint64_t partial_data1
;
218 uint64_t partial_data2
;
219 uint64_t partial_data3
;
220 int64_t partial_data4
;
221 int64_t partial_data5
;
222 int64_t partial_data6
;
225 partial_data1
= uncomp_temperature
- (256 * bmp388_cal
.T1
);
226 partial_data2
= bmp388_cal
.T2
* partial_data1
;
227 partial_data3
= partial_data1
* partial_data1
;
228 partial_data4
= (int64_t)partial_data3
* bmp388_cal
.T3
;
229 partial_data5
= ((int64_t)(partial_data2
* 262144) + partial_data4
);
230 partial_data6
= partial_data5
/ 4294967296;
231 /* Update t_lin, needed for pressure calculation */
232 t_lin
= partial_data6
;
233 comp_temp
= (int64_t)((partial_data6
* 25) / 16384);
238 static uint64_t bmp388CompensatePressure(uint32_t uncomp_pressure
)
240 int64_t partial_data1
;
241 int64_t partial_data2
;
242 int64_t partial_data3
;
243 int64_t partial_data4
;
244 int64_t partial_data5
;
245 int64_t partial_data6
;
250 partial_data1
= t_lin
* t_lin
;
251 partial_data2
= partial_data1
/ 64;
252 partial_data3
= (partial_data2
* t_lin
) / 256;
253 partial_data4
= (bmp388_cal
.P8
* partial_data3
) / 32;
254 partial_data5
= (bmp388_cal
.P7
* partial_data1
) * 16;
255 partial_data6
= (bmp388_cal
.P6
* t_lin
) * 4194304;
256 offset
= (bmp388_cal
.P5
* 140737488355328) + partial_data4
+ partial_data5
+ partial_data6
;
258 partial_data2
= (bmp388_cal
.P4
* partial_data3
) / 32;
259 partial_data4
= (bmp388_cal
.P3
* partial_data1
) * 4;
260 partial_data5
= (bmp388_cal
.P2
- 16384) * t_lin
* 2097152;
261 sensitivity
= ((bmp388_cal
.P1
- 16384) * 70368744177664) + partial_data2
+ partial_data4
+ partial_data5
;
263 partial_data1
= (sensitivity
/ 16777216) * uncomp_pressure
;
264 partial_data2
= bmp388_cal
.P10
* t_lin
;
265 partial_data3
= partial_data2
+ (65536 * bmp388_cal
.P9
);
266 partial_data4
= (partial_data3
* uncomp_pressure
) / 8192;
267 partial_data5
= (partial_data4
* uncomp_pressure
) / 512;
268 partial_data6
= (int64_t)((uint64_t)uncomp_pressure
* (uint64_t)uncomp_pressure
);
269 partial_data2
= (bmp388_cal
.P11
* partial_data6
) / 65536;
270 partial_data3
= (partial_data2
* uncomp_pressure
) / 128;
271 partial_data4
= (offset
/ 4) + partial_data1
+ partial_data5
+ partial_data3
;
272 comp_press
= (((uint64_t)partial_data4
* 25) / (uint64_t)1099511627776);
277 STATIC_UNIT_TESTED
bool bmp388Calculate(baroDev_t
*baro
, int32_t *pressure
, int32_t *temperature
)
285 t
= bmp388CompensateTemperature(bmp388_ut
);
286 p
= bmp388CompensatePressure(bmp388_up
);
289 *pressure
= (int32_t)(p
/ 256);
296 #define DETECTION_MAX_RETRY_COUNT 5
297 static bool deviceDetect(busDevice_t
* busDev
)
303 if (busDev
->busType
== BUSTYPE_SPI
) {
304 // In SPI mode, first byte read is a dummy byte
308 // In I2C mode, no dummy byte is read
313 for (int retry
= 0; retry
< DETECTION_MAX_RETRY_COUNT
; retry
++) {
316 bool ack
= busReadBuf(busDev
, BMP388_CHIP_ID_REG
, chipId
, nRead
);
318 if (ack
&& (*pId
== BMP388_DEFAULT_CHIP_ID
|| *pId
== BMP390_DEFAULT_CHIP_ID
)) {
326 bool bmp388Detect(baroDev_t
*baro
)
328 baro
->busDev
= busDeviceInit(BUSTYPE_ANY
, DEVHW_BMP388
, 0, OWNER_BARO
);
329 if (baro
->busDev
== NULL
) {
333 busSetSpeed(baro
->busDev
, BUS_SPEED_STANDARD
);
335 if (!deviceDetect(baro
->busDev
)) {
336 busDeviceDeInit(baro
->busDev
);
341 if (baro
->busDev
->busType
== BUSTYPE_SPI
) {
342 // In SPI mode, first byte read is a dummy byte
343 uint8_t calibration_buf
[sizeof(bmp388_calib_param_t
) + 1];
344 busReadBuf(baro
->busDev
, BMP388_TRIMMING_NVM_PAR_T1_LSB_REG
, calibration_buf
, sizeof(bmp388_calib_param_t
) + 1);
345 memcpy(&bmp388_cal
, calibration_buf
+ 1, sizeof(bmp388_calib_param_t
));
347 // In I2C mode, no dummy byte is read
348 busReadBuf(baro
->busDev
, BMP388_TRIMMING_NVM_PAR_T1_LSB_REG
, (uint8_t*)&bmp388_cal
, sizeof(bmp388_calib_param_t
));
351 // set oversampling + power mode (forced), and start sampling
352 busWrite(baro
->busDev
, BMP388_OSR_REG
,
353 ((BMP388_PRESSURE_OSR
<< BMP388_OSR_P_BIT
) & BMP388_OSR_P_MASK
) |
354 ((BMP388_TEMPERATURE_OSR
<< BMP388_OSR4_T_BIT
) & BMP388_OSR4_T_MASK
)
357 bmp388BeginForcedMeasurement(baro
->busDev
);
360 baro
->get_ut
= bmp388GetUT
;
361 baro
->start_ut
= bmp388StartUT
;
363 baro
->up_delay
= 234 + (392 + ((1 << (BMP388_PRESSURE_OSR
+ 1)) * 2000)) + (313 + ((1 << (BMP388_TEMPERATURE_OSR
+ 1)) * 2000));
364 baro
->start_up
= bmp388StartUP
;
365 baro
->get_up
= bmp388GetUP
;
367 baro
->calculate
= bmp388Calculate
;