union {uint32_t val; uint8_t raw[3]; } ut; //uncompensated T
union {uint32_t val; uint8_t raw[3]; } up; //uncompensated P
uint8_t state;
uint32_t deadline;
} bmp280_ctx;
/* transform a series of bytes from big endian to little
endian and vice versa. */
void swap_endianness(void *buf, size_t size) {
/* we swap in-place, so we only have to
* place _one_ element on a temporary tray
*/
uint8_t tray;
uint8_t *from;
uint8_t *to;
/* keep swapping until the pointers have assed each other */
for (from = (uint8_t*)buf, to = &from[size-1]; from < to; from++, to--) {
tray = *from;
*from = *to;
*to = tray;
}
}
void i2c_BMP280_readCalibration(){
delay(10);
//read calibration data in one go
size_t s_bytes = (uint8_t*)&bmp280_ctx.dig_P9 - (uint8_t*)&bmp280_ctx.dig_T1 + sizeof(bmp280_ctx.dig_T1);
i2c_read_reg_to_buf(BMP280_ADDRESS, 0x88, (uint8_t*)&bmp280_ctx.dig_T1, s_bytes);
// now fix endianness
//int16_t *p;
//for (p = (int16_t*)&bmp280_ctx.dig_T1; p <= &bmp280_ctx.dig_P9; p++) {
// swap_endianness(p, sizeof(*p));
//}
}
// read uncompensated pressure value: read result bytes
// the datasheet suggests a delay of 25.5 ms (oversampling settings 3) after the send command
void i2c_BMP280_UP_Read () {
i2c_read_reg_to_buf(BMP280_ADDRESS, 0xF7, (uint8_t*)&bmp280_ctx.up.val, 3);
swap_endianness(&bmp280_ctx.up.val, 3);
bmp280_ctx.up.val >>= 4;
}
// read uncompensated temperature value: read result bytes
// the datasheet suggests a delay of 4.5 ms after the send command
void i2c_BMP280_UT_Read() {
i2c_read_reg_to_buf(BMP280_ADDRESS, 0xFA, (uint8_t*)&bmp280_ctx.ut.val, 3);
swap_endianness(&bmp280_ctx.ut.val, 3);
bmp280_ctx.ut.val >>= 4;
}
//return 0: no data available, no computation ; 1: new value available ; 2: no new value, but computation time
uint8_t Baro_update() { // first UT conversion is started in init procedure
if (currentTime < bmp280_ctx.deadline) return 0;
bmp280_ctx.deadline = currentTime+6000; // 1.5ms margin according to the spec (4.5ms T convetion time)
if (bmp280_ctx.state == 0) {
i2c_BMP280_UT_Read();
bmp280_ctx.state = 1;
Baro_Common();
bmp280_ctx.deadline += 21000; // 6000+21000=27000 1.5ms margin according to the spec (25.5ms P convetion time with OSS=3)
return 1;
} else {
i2c_BMP280_UP_Read();
i2c_BMP280_Calculate();
bmp280_ctx.state = 0;
return 2;
}
}
#endif