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 SENSOR_DATA_BUF_SIZE 6 108 #define RES_ULTRA_LOW_POWER 1 109 #define RES_LOW_POWER 2 110 #define RES_STANDARD 3 112 #define RES_ULTRA_HIGH 6 119 #define OSRST(v) ((v) << 5) 120 #define OSRSP(v) ((v) << 2) 135 } BMP_280_Calibration;
137 static BMP_280_Calibration calib_data;
139 static I2C_Handle i2c_handle;
142 SENSOR_STATUS_DISABLED,
143 SENSOR_STATUS_INITIALISED,
144 SENSOR_STATUS_NOT_READY,
148 static volatile SENSOR_STATUS sensor_status = SENSOR_STATUS_DISABLED;
151 #define SENSOR_STARTUP_DELAY 3 153 static struct ctimer startup_timer;
160 sensor_status = SENSOR_STATUS_READY;
165 i2c_write_read(
void *writeBuf,
size_t writeCount,
void *readBuf,
size_t readCount)
167 I2C_Transaction i2cTransaction = {
168 .writeBuf = writeBuf,
169 .writeCount = writeCount,
171 .readCount = readCount,
172 .slaveAddress = BMP280_I2C_ADDRESS,
175 return I2C_transfer(i2c_handle, &i2cTransaction);
177 #define i2c_write(writeBuf, writeCount) i2c_write_read(writeBuf, writeCount, NULL, 0) 178 #define i2c_read(readBuf, readCount) i2c_write_read(NULL, 0, readBuf, readCount) 194 I2C_Params i2cParams;
195 I2C_Params_init(&i2cParams);
197 i2cParams.transferMode = I2C_MODE_BLOCKING;
198 i2cParams.bitRate = I2C_400kHz;
200 i2c_handle = I2C_open(Board_I2C0, &i2cParams);
201 if(i2c_handle == NULL) {
205 uint8_t reset_data[] = { ADDR_RESET, VAL_RESET_EXECUTE };
207 uint8_t calib_reg = ADDR_CALIB;
209 return i2c_write_read(&calib_reg,
sizeof(calib_reg), &calib_data,
sizeof(calib_data))
211 && i2c_write(reset_data,
sizeof(reset_data));
225 uint8_t val = (enable)
226 ? PM_FORCED | OSRSP(1) | OSRST(1)
229 uint8_t ctrl_meas_data[] = { ADDR_CTRL_MEAS, val };
230 return i2c_write(&ctrl_meas_data,
sizeof(ctrl_meas_data));
246 uint8_t press_msb_reg = ADDR_PRESS_MSB;
247 return i2c_write_read(&press_msb_reg,
sizeof(press_msb_reg), data, count);
260 convert(uint8_t *data, int32_t *temp, uint32_t *press)
262 BMP_280_Calibration *p = &calib_data;
265 const int32_t upress = (int32_t)(
266 (((uint32_t)data[0]) << 12) |
267 (((uint32_t)data[1]) << 4) |
268 (((uint32_t)data[2]) >> 4)
271 const int32_t utemp = (int32_t)(
272 (((uint32_t)data[3]) << 12) |
273 (((uint32_t)data[4]) << 4) |
274 (((uint32_t)data[5]) >> 4)
278 int32_t v_x1_u32r = (((utemp >> 3) - ((int32_t)p->dig_t1 << 1)) * (int32_t)p->dig_t2) >> 11;
279 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;
281 const uint32_t t_fine = v_x1_u32r + v_x2_u32r;
282 const int32_t temperature = (t_fine * 5 + 128) >> 8;
286 v_x1_u32r = ((int32_t)t_fine >> 1) - (int32_t)64000;
287 v_x2_u32r = (((v_x1_u32r >> 2) * (v_x1_u32r >> 2)) >> 11) * (int32_t)p->dig_p6;
288 v_x2_u32r = ((v_x1_u32r * (int32_t)p->dig_p5) << 1) + v_x2_u32r;
289 v_x2_u32r = (v_x2_u32r >> 2) + ((int32_t)p->dig_p4 << 16);
290 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;
291 v_x1_u32r = ((32768 + v_x1_u32r) * (int32_t)p->dig_p1) >> 15;
299 uint32_t pressure = (((uint32_t)((int32_t)1048576 - upress)) - (v_x2_u32r >> 12)) * 3125;
300 if((int32_t)pressure < 0) {
301 pressure = (pressure << 1) / (uint32_t)v_x1_u32r;
303 pressure = (pressure / (uint32_t)v_x1_u32r) * 2;
306 v_x1_u32r = (((int32_t)(((pressure >> 3) * (pressure >> 3)) >> 13)) * (int32_t)p->dig_p9) >> 12;
307 v_x2_u32r = ((int32_t)(pressure >> 2) * (int32_t)p->dig_p8) >> 13;
308 pressure = (uint32_t)(((v_x1_u32r + v_x2_u32r + p->dig_p7) >> 4) + (int32_t)pressure);
327 uint8_t sensor_value[SENSOR_DATA_BUF_SIZE];
329 if(sensor_status != SENSOR_STATUS_READY) {
330 PRINTF(
"Sensor disabled or starting up (%d)\n", sensor_status);
331 return BMP_280_READING_ERROR;
335 case BMP_280_SENSOR_TYPE_TEMP:
336 case BMP_280_SENSOR_TYPE_PRESS:
337 memset(sensor_value, 0, SENSOR_DATA_BUF_SIZE);
338 if(!
read_data(sensor_value, SENSOR_DATA_BUF_SIZE)) {
339 return BMP_280_READING_ERROR;
342 PRINTF(
"val: %02x%02x%02x %02x%02x%02x\n",
343 sensor_value[0], sensor_value[1], sensor_value[2],
344 sensor_value[3], sensor_value[4], sensor_value[5]);
346 convert(sensor_value, &temp, &pres);
348 if(type == BMP_280_SENSOR_TYPE_TEMP) {
350 }
else if(type == BMP_280_SENSOR_TYPE_PRESS) {
357 PRINTF(
"Invalid BMP 208 Sensor Type\n");
358 return BMP_280_READING_ERROR;
374 case SENSORS_HW_INIT:
377 sensor_status = SENSOR_STATUS_INITIALISED;
379 sensor_status = SENSOR_STATUS_DISABLED;
385 if(sensor_status == SENSOR_STATUS_DISABLED) {
391 sensor_status = SENSOR_STATUS_NOT_READY;
395 sensor_status = SENSOR_STATUS_INITIALISED;
402 return sensor_status;
416 return sensor_status;
418 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.