41 #include "lib/sensors.h" 49 #include <ti/drivers/I2C.h> 57 #define PRINTF(...) printf(__VA_ARGS__) 67 #if BOARD_SENSORS_ENABLE 69 #ifndef Board_BMP280_ADDR 70 #error "Board file doesn't define I2C address Board_BMP280_ADDR" 73 #define BMP280_I2C_ADDRESS Board_BMP280_ADDR 76 #define ADDR_CALIB 0x88 77 #define ADDR_PROD_ID 0xD0 78 #define ADDR_RESET 0xE0 79 #define ADDR_STATUS 0xF3 80 #define ADDR_CTRL_MEAS 0xF4 81 #define ADDR_CONFIG 0xF5 82 #define ADDR_PRESS_MSB 0xF7 83 #define ADDR_PRESS_LSB 0xF8 84 #define ADDR_PRESS_XLSB 0xF9 85 #define ADDR_TEMP_MSB 0xFA 86 #define ADDR_TEMP_LSB 0xFB 87 #define ADDR_TEMP_XLSB 0xFC 90 #define VAL_PROD_ID 0x58 91 #define VAL_RESET 0x00 92 #define VAL_STATUS 0x00 93 #define VAL_CTRL_MEAS 0x00 94 #define VAL_CONFIG 0x00 95 #define VAL_PRESS_MSB 0x80 96 #define VAL_PRESS_LSB 0x00 97 #define VAL_TEMP_MSB 0x80 98 #define VAL_TEMP_LSB 0x00 101 #define VAL_RESET_EXECUTE 0xB6 102 #define VAL_CTRL_MEAS_TEST 0x55 105 #define MEAS_DATA_SIZE 6 106 #define CALIB_DATA_SIZE 24 109 #define RES_ULTRA_LOW_POWER 1 110 #define RES_LOW_POWER 2 111 #define RES_STANDARD 3 113 #define RES_ULTRA_HIGH 6 120 #define OSRST(v) ((v) << 5) 121 #define OSRSP(v) ((v) << 2) 136 } BMP_280_Calibration;
138 static BMP_280_Calibration calib_data;
140 static I2C_Handle i2c_handle;
143 SENSOR_STATUS_DISABLED,
144 SENSOR_STATUS_INITIALISED,
145 SENSOR_STATUS_NOT_READY,
149 static volatile SENSOR_STATUS sensor_status = SENSOR_STATUS_DISABLED;
152 #define SENSOR_STARTUP_DELAY 3 154 static struct ctimer startup_timer;
161 sensor_status = SENSOR_STATUS_READY;
166 i2c_write_read(
void *writeBuf,
size_t writeCount,
void *readBuf,
size_t readCount)
168 I2C_Transaction i2cTransaction = {
169 .writeBuf = writeBuf,
170 .writeCount = writeCount,
172 .readCount = readCount,
173 .slaveAddress = BMP280_I2C_ADDRESS,
176 return I2C_transfer(i2c_handle, &i2cTransaction);
178 #define i2c_write(writeBuf, writeCount) i2c_write_read(writeBuf, writeCount, NULL, 0) 179 #define i2c_read(readBuf, readCount) i2c_write_read(NULL, 0, readBuf, readCount) 195 I2C_Params i2cParams;
196 I2C_Params_init(&i2cParams);
198 i2cParams.transferMode = I2C_MODE_BLOCKING;
199 i2cParams.bitRate = I2C_400kHz;
201 i2c_handle = I2C_open(Board_I2C0, &i2cParams);
202 if(i2c_handle == NULL) {
206 uint8_t reset_data[] = { ADDR_RESET, VAL_RESET_EXECUTE };
208 uint8_t calib_reg = ADDR_CALIB;
210 return i2c_write_read(&calib_reg,
sizeof(calib_reg), &calib_data,
sizeof(calib_data))
212 && i2c_write(reset_data,
sizeof(reset_data));
226 uint8_t val = (enable)
227 ? PM_FORCED | OSRSP(1) | OSRST(1)
230 uint8_t ctrl_meas_data[] = { ADDR_CTRL_MEAS, val };
231 return i2c_write(&ctrl_meas_data,
sizeof(ctrl_meas_data));
247 uint8_t press_msb_reg = ADDR_PRESS_MSB;
248 return i2c_write_read(&press_msb_reg,
sizeof(press_msb_reg), data, count);
261 convert(uint8_t *data, int32_t *temp, uint32_t *press)
263 BMP_280_Calibration *p = &calib_data;
266 const int32_t upress = (int32_t)(
267 (((uint32_t)data[0]) << 12) |
268 (((uint32_t)data[1]) << 4) |
269 (((uint32_t)data[2]) >> 4)
272 const int32_t utemp = (int32_t)(
273 (((uint32_t)data[3]) << 12) |
274 (((uint32_t)data[4]) << 4) |
275 (((uint32_t)data[5]) >> 4)
279 int32_t v_x1_u32r = (((utemp >> 3) - ((int32_t)p->dig_t1 << 1)) * (int32_t)p->dig_t2) >> 11;
280 int32_t v_x2_u32r = (((((utemp >> 4) - (int32_t)p->dig_t1) * ((utemp >> 4) - (int32_t)p->dig_t1)) >> 12) * (int32_t)p->dig_t3) >> 14;
282 const uint32_t t_fine = v_x1_u32r + v_x2_u32r;
283 const int32_t temperature = (t_fine * 5 + 128) >> 8;
287 v_x1_u32r = ((int32_t)t_fine >> 1) - (int32_t)64000;
288 v_x2_u32r = (((v_x1_u32r >> 2) * (v_x1_u32r >> 2)) >> 11) * (int32_t)p->dig_p6;
289 v_x2_u32r = ((v_x1_u32r * (int32_t)p->dig_p5) << 1) + v_x2_u32r;
290 v_x2_u32r = (v_x2_u32r >> 2) + ((int32_t)p->dig_p4 << 16);
291 v_x1_u32r = ((((((v_x1_u32r >> 2) * (v_x1_u32r >> 2)) >> 13) * p->dig_p3) >> 3) + (((int32_t)p->dig_p2 * v_x1_u32r) >> 1)) >> 18;
292 v_x1_u32r = ((32768 + v_x1_u32r) * (int32_t)p->dig_p1) >> 15;
300 uint32_t pressure = (((uint32_t)((int32_t)1048576 - upress)) - (v_x2_u32r >> 12)) * 3125;
301 if((int32_t)pressure < 0) {
302 pressure = (pressure << 1) / (uint32_t)v_x1_u32r;
304 pressure = (pressure / (uint32_t)v_x1_u32r) * 2;
307 v_x1_u32r = (((int32_t)(((pressure >> 3) * (pressure >> 3)) >> 13)) * (int32_t)p->dig_p9) >> 12;
308 v_x2_u32r = ((int32_t)(pressure >> 2) * (int32_t)p->dig_p8) >> 13;
309 pressure = (uint32_t)(((v_x1_u32r + v_x2_u32r + p->dig_p7) >> 4) + (int32_t)pressure);
327 if(sensor_status != SENSOR_STATUS_READY) {
328 PRINTF(
"Sensor disabled or starting up (%d)\n", sensor_status);
329 return BMP_280_READING_ERROR;
333 uint8_t sensor_value[MEAS_DATA_SIZE];
336 case BMP_280_SENSOR_TYPE_TEMP:
337 case BMP_280_SENSOR_TYPE_PRESS:
338 memset(sensor_value, 0, MEAS_DATA_SIZE);
339 if(!
read_data(sensor_value, MEAS_DATA_SIZE)) {
340 return BMP_280_READING_ERROR;
343 PRINTF(
"val: %02x%02x%02x %02x%02x%02x\n",
344 sensor_value[0], sensor_value[1], sensor_value[2],
345 sensor_value[3], sensor_value[4], sensor_value[5]);
347 convert(sensor_value, &temp, &pres);
349 if(type == BMP_280_SENSOR_TYPE_TEMP) {
351 }
else if(type == BMP_280_SENSOR_TYPE_PRESS) {
358 PRINTF(
"Invalid BMP 208 Sensor Type\n");
359 return BMP_280_READING_ERROR;
375 case SENSORS_HW_INIT:
378 sensor_status = SENSOR_STATUS_INITIALISED;
380 sensor_status = SENSOR_STATUS_DISABLED;
386 if(sensor_status == SENSOR_STATUS_DISABLED) {
392 sensor_status = SENSOR_STATUS_NOT_READY;
396 sensor_status = SENSOR_STATUS_INITIALISED;
403 return sensor_status;
417 return sensor_status;
419 return SENSOR_STATUS_DISABLED;
void ctimer_stop(struct ctimer *c)
Stop a pending callback timer.
static int status(int type)
Returns the status of the sensor.
static void convert(uint8_t *data, int32_t *temp, uint32_t *press)
Convert raw data to values in degrees C (temp) and Pascal (pressure).
static bool enable_sensor(bool enable)
Enable/disable measurements.
static bool init(void)
Initalise the sensor.
Header file for the Sensortag BMP280 Altimeter / Pressure Sensor.
static int value(int type)
Returns a reading from the sensor.
static bool read_data(uint8_t *data, size_t count)
Read temperature and pressure data.
Header file for the callback timer
static int configure(int type, int enable)
Configuration function for the BMP280 sensor.
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
static void notify_ready(void *unused)
Callback when sensor is ready to read data from.
Header file with definitions related to the sensors on the Sensortags.
const struct sensors_sensor bmp_280_sensor
Exports a global symbol to be used by the sensor API.