34 #if defined(PIOS_INCLUDE_BMP280) || defined(PIOS_INCLUDE_BMP280_SPI)
44 #define BMP280_I2C_ADDR 0x76 // 0x77
45 #define BMP280_ID 0xD0
46 #define BMP280_RESET 0xE0
47 #define BMP280_STATUS 0xF3
48 #define BMP280_CTRL_MEAS 0xF4
49 #define BMP280_CONFIG 0xF5
50 #define BMP280_PRESS_MSB 0xF7
51 #define BMP280_PRESS_LSB 0xF8
52 #define BMP280_PRESS_XLSB 0xF9
53 #define BMP280_TEMP_MSB 0xFA
54 #define BMP280_TEMP_LSB 0xFB
55 #define BMP280_TEMP_XLSB 0xFC
57 #define BMP280_CAL_ADDR 0x88
59 #define BMP280_P0 101.3250f
61 #define BMP280_MODE_CONTINUOUS 0x03
63 #define PIOS_BMP_SPI_SPEED 9500000
66 static int32_t PIOS_BMP280_Read(uint8_t address, uint8_t *buffer, uint8_t len);
67 static int32_t PIOS_BMP280_WriteCommand(uint8_t address, uint8_t buffer);
69 static bool PIOS_BMP280_callback(
void *ctx,
void *output,
70 int ms_to_wait,
int *next_call);
76 enum pios_bmp280_dev_magic {
77 PIOS_BMP280_DEV_MAGIC = 0x32504d42,
82 #ifndef PIOS_EXCLUDE_BMP280_I2C
85 #ifdef PIOS_INCLUDE_BMP280_SPI
90 uint32_t compensatedPressure;
91 int32_t compensatedTemperature;
107 enum pios_bmp280_dev_magic
magic;
112 static struct bmp280_dev *dev;
117 static struct bmp280_dev *PIOS_BMP280_alloc(
void)
119 struct bmp280_dev *bmp280_dev;
121 bmp280_dev = (
struct bmp280_dev *)
PIOS_malloc(
sizeof(*bmp280_dev));
127 *bmp280_dev = (
struct bmp280_dev) {
128 .magic = PIOS_BMP280_DEV_MAGIC
133 bmp280_dev->magic = PIOS_BMP280_DEV_MAGIC;
142 static int32_t PIOS_BMP280_Validate(
struct bmp280_dev *dev)
146 if (dev->magic != PIOS_BMP280_DEV_MAGIC)
158 if (PIOS_BMP280_Read(BMP280_CAL_ADDR, data, 24) != 0)
161 dev->digT1 = (data[ 1] << 8) | data[ 0];
162 dev->digT2 = (data[ 3] << 8) | data[ 2];
163 dev->digT3 = (data[ 5] << 8) | data[ 4];
164 dev->digP1 = (data[ 7] << 8) | data[ 6];
165 dev->digP2 = (data[ 9] << 8) | data[ 8];
166 dev->digP3 = (data[11] << 8) | data[10];
167 dev->digP4 = (data[13] << 8) | data[12];
168 dev->digP5 = (data[15] << 8) | data[14];
169 dev->digP6 = (data[17] << 8) | data[16];
170 dev->digP7 = (data[19] << 8) | data[18];
171 dev->digP8 = (data[21] << 8) | data[20];
172 dev->digP9 = (data[23] << 8) | data[22];
174 if ((dev->digT1 == dev->digT2) &&
175 (dev->digT1 == dev->digP1)) {
180 if (PIOS_BMP280_WriteCommand(BMP280_CONFIG, 0x00) != 0)
193 static int32_t PIOS_BMP280_ClaimDevice(
void)
204 static int32_t PIOS_BMP280_ReleaseDevice(
void)
216 static int32_t PIOS_BMP280_StartADC(
void)
218 if (PIOS_BMP280_Validate(dev) != 0)
222 return(PIOS_BMP280_WriteCommand(BMP280_CTRL_MEAS,
223 dev->oversampling | BMP280_MODE_CONTINUOUS));
231 static int32_t PIOS_BMP280_GetDelay() {
232 if (PIOS_BMP280_Validate(dev) != 0)
235 switch(dev->oversampling) {
250 static int32_t PIOS_BMP280_ReadADC()
252 if (PIOS_BMP280_Validate(dev) != 0)
259 if (PIOS_BMP280_Read(BMP280_PRESS_MSB, data, 6) != 0)
262 static int32_t
T = 0;
264 int32_t raw_temperature = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | ((uint32_t)data[5] >> 4));
266 int32_t varT1, varT2;
268 varT1 = ((((raw_temperature >> 3) - ((int32_t)dev->digT1 << 1))) * ((int32_t)dev->digT2)) >> 11;
269 varT2 = (((((raw_temperature >> 4) - ((int32_t)dev->digT1)) * ((raw_temperature >> 4) - ((int32_t)dev->digT1))) >> 12) * ((int32_t)dev->digT3)) >> 14;
273 T = (varT1 + varT2) * 5;
275 T = (varT1 + varT2) + (T * 4) / 5;
278 dev->compensatedTemperature =
T;
280 int32_t raw_pressure = (int32_t)((((uint32_t)(data[0])) << 12) | (((uint32_t)(data[1])) << 4) | ((uint32_t)data[2] >> 4));
282 if (raw_pressure == 0x80000) {
286 int64_t varP1, varP2,
P;
288 varP1 = ((int64_t)T / 5) - 128000;
289 varP2 = varP1 * varP1 * (int64_t)dev->digP6;
290 varP2 = varP2 + ((varP1 * (int64_t)dev->digP5) << 17);
291 varP2 = varP2 + (((int64_t)dev->digP4) << 35);
292 varP1= ((varP1 * varP1 * (int64_t)dev->digP3) >> 8) + ((varP1 * (int64_t)dev->digP2) << 12);
293 varP1 = (((((int64_t)1) << 47) + varP1)) * ((int64_t)dev->digP1) >> 33;
298 P = 1048576 - raw_pressure;
299 P = (((
P << 31) - varP2) * 3125) / varP1;
300 varP1 = (((int64_t)dev->digP9) * (
P >> 13) * (
P >> 13)) >> 25;
301 varP2 = (((int64_t)dev->digP8) *
P) >> 19;
302 dev->compensatedPressure = (uint32_t)((
P + varP1 + varP2) >> 8) + (((int64_t)dev->digP7) << 4);
306 static inline int32_t PIOS_BMP280_CheckData(
const uint8_t *data,
307 const uint8_t *data_b)
312 for (i = 0; i < 6; i++) {
313 if (data[i] != data_b[i]) {
319 for (i = 1; i < 6; i++) {
320 if (data[i] != data[0]) {
328 #ifndef PIOS_EXCLUDE_BMP280_I2C
329 static int32_t PIOS_BMP280_I2C_Read(
pios_i2c_t i2c_id,
330 uint8_t address, uint8_t *buffer, uint8_t len)
335 .addr = BMP280_I2C_ADDR,
342 .addr = BMP280_I2C_ADDR,
352 static int32_t PIOS_BMP280_I2C_Write(
pios_i2c_t i2c_id,
353 uint8_t *buffer, uint8_t len) {
357 .addr = BMP280_I2C_ADDR,
376 if (PIOS_BMP280_I2C_Read(i2c_device, BMP280_CAL_ADDR, data, 6) != 0)
379 if (PIOS_BMP280_I2C_Read(i2c_device, BMP280_CAL_ADDR, data, 6) != 0)
382 if (PIOS_BMP280_I2C_Read(i2c_device, BMP280_CAL_ADDR, data_b, 6) != 0)
385 int ret = PIOS_BMP280_CheckData(data, data_b);
391 dev = (
struct bmp280_dev *) PIOS_BMP280_alloc();
395 dev->i2c_id = i2c_device;
397 return PIOS_BMP280_Common_Init(cfg);
401 #ifdef PIOS_INCLUDE_BMP280_SPI
402 static int32_t PIOS_BMP280_ClaimBus(
pios_spi_t spi_id, uint32_t spi_slave)
416 static void PIOS_BMP280_ReleaseBus(
pios_spi_t spi_id, uint32_t spi_slave)
423 static int32_t PIOS_BMP280_SPI_Read(
pios_spi_t spi_id, uint32_t spi_slave,
424 uint8_t address, uint8_t *buffer, uint8_t len) {
425 if (PIOS_BMP280_ClaimBus(spi_id, spi_slave) != 0)
432 PIOS_BMP280_ReleaseBus(spi_id, spi_slave);
437 static int32_t PIOS_BMP280_SPI_Write(
pios_spi_t spi_id, uint32_t spi_slave,
438 uint8_t *buffer, uint8_t len) {
439 if (PIOS_BMP280_ClaimBus(spi_id, spi_slave) != 0)
444 PIOS_BMP280_ReleaseBus(spi_id, spi_slave);
456 if (PIOS_BMP280_SPI_Read(spi_device, spi_slave,
457 BMP280_CAL_ADDR, data, 6) != 0)
460 if (PIOS_BMP280_SPI_Read(spi_device, spi_slave,
461 BMP280_CAL_ADDR, data, 6) != 0)
464 if (PIOS_BMP280_SPI_Read(spi_device, spi_slave,
465 BMP280_CAL_ADDR, data_b, 6) != 0)
468 int ret = PIOS_BMP280_CheckData(data, data_b);
474 dev = (
struct bmp280_dev *) PIOS_BMP280_alloc();
478 dev->spi_id = spi_device;
479 dev->spi_slave = spi_slave;
481 return PIOS_BMP280_Common_Init(cfg);
494 static int32_t PIOS_BMP280_Read(uint8_t address, uint8_t *buffer, uint8_t len)
499 #ifndef PIOS_EXCLUDE_BMP280_I2C
500 }
else if (dev->i2c_id) {
501 return PIOS_BMP280_I2C_Read(dev->i2c_id, address, buffer, len);
503 #ifdef PIOS_INCLUDE_BMP280_SPI
504 }
else if (dev->spi_id) {
505 return PIOS_BMP280_SPI_Read(dev->spi_id, dev->spi_slave,
506 address, buffer, len);
521 static int32_t PIOS_BMP280_WriteCommand(uint8_t address, uint8_t buffer)
531 #ifndef PIOS_EXCLUDE_BMP280_I2C
532 }
else if (dev->i2c_id) {
533 return PIOS_BMP280_I2C_Write(dev->i2c_id,
536 #ifdef PIOS_INCLUDE_BMP280_SPI
537 }
else if (dev->spi_id) {
539 return PIOS_BMP280_SPI_Write(dev->spi_id, dev->spi_slave,
552 int32_t PIOS_BMP280_Test()
554 if (PIOS_BMP280_Validate(dev) != 0)
558 int32_t currentTemperature = 0;
559 int32_t currentPressure = 0;
561 PIOS_BMP280_ClaimDevice();
563 currentTemperature = dev->compensatedTemperature;
564 currentPressure = dev->compensatedPressure;
566 PIOS_BMP280_StartADC();
568 PIOS_BMP280_ReadADC();
569 PIOS_BMP280_ReleaseDevice();
571 if (currentTemperature == dev->compensatedTemperature)
574 if (currentPressure == dev->compensatedPressure)
580 static bool PIOS_BMP280_callback(
void *ctx,
void *output,
581 int ms_to_wait,
int *next_call)
583 struct bmp280_dev *dev = (
struct bmp280_dev *)ctx;
589 *next_call = PIOS_BMP280_GetDelay() * 3 / 5;
591 int32_t read_adc_result = 0;
593 PIOS_BMP280_StartADC();
595 PIOS_BMP280_ClaimDevice();
596 read_adc_result = PIOS_BMP280_ReadADC();
597 PIOS_BMP280_ReleaseDevice();
599 if (read_adc_result) {
606 data->
pressure = ((float) dev->compensatedPressure) / 256.0f / 1000.0f;
607 float calc_alt = 44330.0f * (1.0f - powf(data->
pressure / BMP280_P0, (1.0f / 5.255f)));
608 data->
temperature = ((float) dev->compensatedTemperature) / 256.0f / 100.0f;
#define PIOS_SEMAPHORE_TIMEOUT_MAX
Main PiOS header to include all the compiled in PiOS options.
int32_t PIOS_SPI_RC_PinSet(pios_spi_t spi_dev, uint32_t slave_id, bool pin_value)
int32_t PIOS_SPI_ClaimBus(pios_spi_t spi_dev)
void * PIOS_malloc(size_t size)
Configuration structure for the BMP280 driver.
#define BMP280_STANDARD_RESOLUTION
static float T[3]
Scales used in NED transform (local tangent plane approx).
uint8_t data[XFER_BYTES_PER_PACKET]
static struct flyingpicmd_cfg_fa cfg
struct pios_semaphore * PIOS_Semaphore_Create(void)
Creates a binary semaphore.
struct pios_i2c_adapter * pios_i2c_t
uint8_t PIOS_SPI_TransferByte(pios_spi_t spi_dev, uint8_t b)
int32_t PIOS_SPI_SetClockSpeed(pios_spi_t spi_dev, uint32_t speed)
int32_t PIOS_SPI_TransferBlock(pios_spi_t spi_dev, const uint8_t *send_buffer, uint8_t *receive_buffer, uint16_t len)
Pios sensor structure for generic baro data.
bool PIOS_Semaphore_Give(struct pios_semaphore *sema)
Gives binary semaphore.
int32_t PIOS_BMP280_SPI_Init(const struct pios_bmp280_cfg *cfg, pios_spi_t spi_device, uint32_t spi_slave)
int32_t PIOS_I2C_Transfer(pios_i2c_t i2c_id, const struct pios_i2c_txn txn_list[], uint32_t num_txns)
int32_t PIOS_SENSORS_RegisterCallback(enum pios_sensor_type type, PIOS_SENSOR_Callback_t callback, void *ctx)
Register a callback-based sensor with the PIOS_SENSORS interface.
int32_t PIOS_BMP280_Init(const struct pios_bmp280_cfg *cfg, pios_i2c_t i2c_device)
bool PIOS_Semaphore_Take(struct pios_semaphore *sema, uint32_t timeout_ms)
Takes binary semaphore.
#define BMP280_ULTRA_HIGH_RESOLUTION
int32_t PIOS_SPI_ReleaseBus(pios_spi_t spi_dev)
#define PIOS_Assert(test)
int32_t PIOS_DELAY_WaitmS(uint32_t mS)
#define BMP280_HIGH_RESOLUTION
int32_t PIOS_DELAY_WaituS(uint32_t uS)