28#warning "Debugging of BMP280 enabled. Using constants to verify formula"
36#define PX_BMP280_REG_CALIB00 0x88
37#define PX_BMP280_REG_CALIB25 0xa1
38#define PX_BMP280_REG_ID 0xd0
39#define PX_BMP280_REG_RESET 0xe0
40#define PX_BMP280_REG_STATUS 0xf3
41#define PX_BMP280_REG_CTRL_MEAS 0xf4
42#define PX_BMP280_REG_CONFIG 0xf5
43#define PX_BMP280_REG_PRESS_MSB 0xf7
44#define PX_BMP280_REG_PRESS_LSB 0xf8
45#define PX_BMP280_REG_PRESS_XLSB 0xf9
46#define PX_BMP280_REG_TEMP_MSB 0xfa
47#define PX_BMP280_REG_TEMP_LSB 0xfb
48#define PX_BMP280_REG_TEMP_XLSB 0xfc
52#define PX_BMP280_REG_ID_VAL 0x58
55#define PX_BMP280_REG_RESET_VAL 0xb6
58#define PX_BMP280_REG_STATUS_MEAS_POS 3
59#define PX_BMP280_REG_STATUS_MEAS_MSK (1 << 3)
60#define PX_BMP280_REG_STATUS_IM_UPDATE_POS 0
61#define PX_BMP280_REG_STATUS_IM_UPDATE_MSK (1 << 0)
64#define PX_BMP280_REG_CTRL_MEAS_OSRS_T_POS 5
65#define PX_BMP280_REG_CTRL_MEAS_OSRS_T_MSK (7 << 5)
66#define PX_BMP280_REG_CTRL_MEAS_OSRS_P_POS 2
67#define PX_BMP280_REG_CTRL_MEAS_OSRS_P_MSK (7 << 2)
68#define PX_BMP280_REG_CTRL_MEAS_MODE_POS 0
69#define PX_BMP280_REG_CTRL_MEAS_MODE_MSK (3 << 0)
70#define PX_BMP280_REG_CTRL_MEAS_OVERS_SKIPPED 0
71#define PX_BMP280_REG_CTRL_MEAS_OVERS_1 1
72#define PX_BMP280_REG_CTRL_MEAS_OVERS_2 2
73#define PX_BMP280_REG_CTRL_MEAS_OVERS_4 3
74#define PX_BMP280_REG_CTRL_MEAS_OVERS_8 4
75#define PX_BMP280_REG_CTRL_MEAS_OVERS_16 5
76#define PX_BMP280_REG_CTRL_MEAS_MODE_SLEEP 0
77#define PX_BMP280_REG_CTRL_MEAS_MODE_FORCED 1
78#define PX_BMP280_REG_CTRL_MEAS_MODE_NORMAL 3
81#define PX_BMP280_REG_CONFIG_T_SB_POS 5
82#define PX_BMP280_REG_CONFIG_T_SB_MSK (7 << 5)
83#define PX_BMP280_REG_CONFIG_FILTER_POS 2
84#define PX_BMP280_REG_CONFIG_FILTER_MSK (7 << 2)
85#define PX_BMP280_REG_CONFIG_SPI3W_EN_POS 0
86#define PX_BMP280_REG_CONFIG_SPI3W_EN_MSK (1 << 0)
89#define PX_BMP280_PRESS_XLSB_POS 4
90#define PX_BMP280_PRESS_XLSB_MSK (15 << 4)
93#define PX_BMP280_TEMP_XLSB_POS 4
94#define PX_BMP280_TEMP_XLSB_MSK (15 << 4)
114#define PX_BMP280_NR_OF_CALS 12
126 uint16_t data[PX_BMP280_NR_OF_CALS];
132static bool px_bmp280_reg_wr(uint8_t adr, uint8_t data)
142 PX_LOG_E(
"Unable to write register value");
149static bool px_bmp280_reg_rd(uint8_t adr, uint8_t * data)
159 PX_LOG_E(
"Unable to write register address");
166 PX_LOG_E(
"Unable to read register value");
173static bool px_bmp280_reg_rd_data(uint8_t adr,
void * data, uint8_t nr_of_bytes)
183 PX_LOG_E(
"Unable to write register address");
190 PX_LOG_E(
"Unable to read register data");
197static bool px_bmp280_cal_rd(
void)
205 adr = PX_BMP280_REG_CALIB00;
207 for(i = 0; i < PX_BMP280_NR_OF_CALS; i++)
210 if(!px_bmp280_reg_rd_data(adr, i2c_data, 2))
213 PX_LOG_E(
"Unable to read calibration value");
216 PX_LOG_D(
"Adr %02X: %02X %02X", adr, i2c_data[0], i2c_data[1]);
220 px_bmp280_cal.data[i] = val;
227 px_bmp280_cal.dig.t1 = 27504;
228 px_bmp280_cal.dig.t2 = 26435;
229 px_bmp280_cal.dig.t3 = -1000;
230 px_bmp280_cal.dig.p1 = 36477;
231 px_bmp280_cal.dig.p2 = -10685;
232 px_bmp280_cal.dig.p3 = 3024;
233 px_bmp280_cal.dig.p4 = 2855;
234 px_bmp280_cal.dig.p5 = 140;
235 px_bmp280_cal.dig.p6 = -7;
236 px_bmp280_cal.dig.p7 = 15500;
237 px_bmp280_cal.dig.p8 = -14600;
238 px_bmp280_cal.dig.p9 = 6000;
262static bool px_bmp280_temp_raw_rd(int32_t * data)
266 if(!px_bmp280_reg_rd_data(PX_BMP280_REG_TEMP_MSB, i2c_data, 3))
272 PX_LOG_D(
"Temp data: %02X %02X %02X", i2c_data[0], i2c_data[1], i2c_data[2]);
275 *data = (int32_t)( (((uint32_t)i2c_data[0]) << 12)
276 | (((uint32_t)i2c_data[1]) << 4)
277 | (((uint32_t)i2c_data[2]) >> 4) );
288static bool px_bmp280_press_raw_rd(int32_t * data)
292 if(!px_bmp280_reg_rd_data(PX_BMP280_REG_PRESS_MSB, i2c_data, 3))
298 PX_LOG_D(
"Press data: %02X %02X %02X", i2c_data[0], i2c_data[1], i2c_data[2]);
301 *data = (int32_t)( (((uint32_t)i2c_data[0]) << 12)
302 | (((uint32_t)i2c_data[1]) << 4)
303 | (((uint32_t)i2c_data[2]) >> 4) );
323static int32_t px_bmp280_comp_temp(int32_t ut, int32_t * t_fine)
329 var1 = ( (((ut >> 3) - ((int32_t)px_bmp280_cal.dig.t1 << 1)))
330 * ((int32_t)px_bmp280_cal.dig.t2)) >> 11;
331 var2 = ( (( ((ut >> 4) - ((int32_t)px_bmp280_cal.dig.t1))
332 * ((ut >> 4) - ((int32_t)px_bmp280_cal.dig.t1))) >> 12)
333 * ((int32_t)px_bmp280_cal.dig.t3)) >> 14;
335 *t_fine = var1 + var2;
336 temp = (*t_fine * 5 + 128) >> 8;
338 PX_LOG_D(
"Compensated Temp = %ld", temp);
353static uint32_t px_bmp280_comp_press(int32_t up, int32_t t_fine)
359 var1 = (((int32_t)t_fine) >> 1) - (int32_t)64000;
360 var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * ((int32_t)px_bmp280_cal.dig.p6);
361 var2 = var2 + ((var1 * ((int32_t)px_bmp280_cal.dig.p5)) << 1);
362 var2 = (var2 >> 2) + (((int32_t)px_bmp280_cal.dig.p4) << 16);
363 var1 = ( ((px_bmp280_cal.dig.p3 * (((var1 >> 2) * (var1 >> 2)) >> 13)) >> 3)
364 + ((((int32_t)px_bmp280_cal.dig.p2) * var1) >> 1)) >> 18;
365 var1 = (((32768 + var1)) * ((int32_t)px_bmp280_cal.dig.p1)) >> 15;
366 press = (((uint32_t)(((int32_t)1048576) - up) - (var2 >> 12))) * 3125;
375 if (press < 0x80000000)
377 press = (press << 1) / ((uint32_t)var1);
381 press = (press / (uint32_t)var1) * 2;
384 var1 = ( ((int32_t)px_bmp280_cal.dig.p9)
385 * ((int32_t)(((press >> 3) * (press >> 3)) >> 13)) ) >> 12;
386 var2 = (((int32_t)(press >> 2)) * ((int32_t)px_bmp280_cal.dig.p8)) >> 13;
387 press = (uint32_t)((int32_t)press + ((var1 + var2 + px_bmp280_cal.dig.p7) >> 4));
389 PX_LOG_D(
"Compensated Pressure = %ld", press);
400 px_bmp280_i2c_handle = handle;
402 if(!px_bmp280_reg_rd(PX_BMP280_REG_ID, &data))
408 if(data != PX_BMP280_REG_ID_VAL)
411 PX_LOG_E(
"Chip ID does not match. Received %02X, but expected %02X",
412 data, PX_BMP280_REG_ID_VAL);
418 if(!px_bmp280_reg_rd(PX_BMP280_REG_STATUS, &data))
425 while(data & PX_BMP280_REG_STATUS_IM_UPDATE_MSK);
427 if(!px_bmp280_cal_rd())
437bool px_bmp280_rd(int32_t * temp, int32_t * press)
443 if(!px_bmp280_cal_rd())
449 data = (PX_BMP280_REG_CTRL_MEAS_OVERS_1 << PX_BMP280_REG_CTRL_MEAS_OSRS_T_POS)
450 + (PX_BMP280_REG_CTRL_MEAS_OVERS_8 << PX_BMP280_REG_CTRL_MEAS_OSRS_P_POS)
451 + (PX_BMP280_REG_CTRL_MEAS_MODE_FORCED << PX_BMP280_REG_CTRL_MEAS_MODE_POS);
452 if(!px_bmp280_reg_wr(PX_BMP280_REG_CTRL_MEAS, data))
455 PX_LOG_E(
"Unable to start measurement");
461 if(!px_bmp280_reg_rd(PX_BMP280_REG_STATUS, &data))
468 while(data & PX_BMP280_REG_STATUS_MEAS_MSK);
470 if(!px_bmp280_temp_raw_rd(temp))
475 if(!px_bmp280_press_raw_rd(press))
480 *temp = px_bmp280_comp_temp(*temp, &t_fine);
482 *press = px_bmp280_comp_press(*press, t_fine);
#define PX_U16_CONCAT_U8(hi8, lo8)
Concatenate 2 x 8 bits to form 16-bit value.
#define PX_LOG_D(format,...)
Macro to display a formatted DEBUG message.
#define PX_LOG_TRACE(format,...)
Macro to output a user format string if PX_LOG=1.
#define PX_LOG_NAME(name)
Macro to declare a log name string once for each file to reduce code size.
#define PX_LOG_LEVEL_IS_D()
Debug level enabled?
#define PX_LOG_E(format,...)
Macro to display a formatted ERROR message.
#define PX_I2C_FLAG_START_AND_STOP
Begin and finish an I2C transaction with a START and STOP condition.
bool px_i2c_rd(px_i2c_handle_t *handle, void *data, size_t nr_of_bytes, uint8_t flags)
Perform an I2C read transaction with an I2C slave.
#define PX_I2C_FLAG_REP_START_AND_STOP
Begin and finish an I2C transaction with a REP START and STOP condition.
#define PX_I2C_FLAG_START_AND_END
Begin and finish an I2C transaction with a START and END condition.
bool px_i2c_wr(px_i2c_handle_t *handle, const void *data, size_t nr_of_bytes, uint8_t flags)
Perform an I2C write transaction with an I2C slave.
Define I2C handle for a slave.
BMP280 calibration coefficients.