|
|
|
@ -23,6 +23,7 @@ |
|
|
|
|
*/ |
|
|
|
|
#include <stddef.h> |
|
|
|
|
#include "bmp280.h" |
|
|
|
|
#include "driver/i2c.h" |
|
|
|
|
|
|
|
|
|
#ifdef BMP280_DEBUG |
|
|
|
|
#include <stdio.h> |
|
|
|
@ -65,36 +66,58 @@ void bmp280_init_default_params(bmp280_params_t *params) |
|
|
|
|
params->standby = BMP280_STANDBY_250; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool read_register16(i2c_dev_t *dev, uint8_t addr, uint16_t *value) |
|
|
|
|
static inline esp_err_t read_data(bmp280_i2c_dev_t *dev, uint8_t addr, uint8_t *value, uint8_t len) |
|
|
|
|
{ |
|
|
|
|
uint8_t d[] = {0, 0}; |
|
|
|
|
if (!i2c_slave_read(dev->bus, dev->addr, &addr, d, sizeof(d))) { |
|
|
|
|
*value = d[0] | (d[1] << 8); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
int ret; |
|
|
|
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create(); |
|
|
|
|
i2c_master_start(cmd); |
|
|
|
|
i2c_master_write_byte(cmd, dev->addr << 1 | I2C_MASTER_WRITE, true); |
|
|
|
|
i2c_master_write_byte(cmd, addr, true); |
|
|
|
|
i2c_master_start(cmd); |
|
|
|
|
i2c_master_write_byte(cmd, dev->addr << 1 | I2C_MASTER_READ, true); |
|
|
|
|
i2c_master_read(cmd, value, len, I2C_MASTER_LAST_NACK); |
|
|
|
|
i2c_master_stop(cmd); |
|
|
|
|
ret = i2c_master_cmd_begin(dev->i2c_num, cmd, pdMS_TO_TICKS(BMP280_I2C_TIMEOUT_MS)); |
|
|
|
|
i2c_cmd_link_delete(cmd); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static esp_err_t read_register16(bmp280_i2c_dev_t *dev, uint8_t addr, uint16_t *value) |
|
|
|
|
{ |
|
|
|
|
uint8_t bytes[2]; |
|
|
|
|
esp_err_t ret = read_data(dev, addr, bytes, 2); |
|
|
|
|
*value = bytes[1] << 8 | bytes[0]; |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline int read_data(i2c_dev_t *dev, uint8_t addr, uint8_t *value, uint8_t len) |
|
|
|
|
static esp_err_t write_register8(bmp280_i2c_dev_t *dev, uint8_t addr, uint8_t value) |
|
|
|
|
{ |
|
|
|
|
return i2c_slave_read(dev->bus, dev->addr, &addr, value, len); |
|
|
|
|
int ret; |
|
|
|
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create(); |
|
|
|
|
i2c_master_start(cmd); |
|
|
|
|
i2c_master_write_byte(cmd, dev->addr << 1 | I2C_MASTER_WRITE, 1); |
|
|
|
|
i2c_master_write_byte(cmd, addr, true); |
|
|
|
|
i2c_master_write_byte(cmd, value, true); |
|
|
|
|
i2c_master_stop(cmd); |
|
|
|
|
ret = i2c_master_cmd_begin(dev->i2c_num, cmd, pdMS_TO_TICKS(BMP280_I2C_TIMEOUT_MS)); |
|
|
|
|
i2c_cmd_link_delete(cmd); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool read_calibration_data(bmp280_t *dev) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
if (read_register16(&dev->i2c_dev, 0x88, &dev->dig_T1) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0x8a, (uint16_t *)&dev->dig_T2) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0x8c, (uint16_t *)&dev->dig_T3) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0x8e, &dev->dig_P1) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0x90, (uint16_t *)&dev->dig_P2) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0x92, (uint16_t *)&dev->dig_P3) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0x94, (uint16_t *)&dev->dig_P4) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0x96, (uint16_t *)&dev->dig_P5) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0x98, (uint16_t *)&dev->dig_P6) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0x9a, (uint16_t *)&dev->dig_P7) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0x9c, (uint16_t *)&dev->dig_P8) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0x9e, (uint16_t *)&dev->dig_P9)) { |
|
|
|
|
if (ESP_OK == read_register16(&dev->i2c_dev, 0x88, &dev->dig_T1) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0x8a, (uint16_t *)&dev->dig_T2) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0x8c, (uint16_t *)&dev->dig_T3) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0x8e, &dev->dig_P1) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0x90, (uint16_t *)&dev->dig_P2) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0x92, (uint16_t *)&dev->dig_P3) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0x94, (uint16_t *)&dev->dig_P4) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0x96, (uint16_t *)&dev->dig_P5) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0x98, (uint16_t *)&dev->dig_P6) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0x9a, (uint16_t *)&dev->dig_P7) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0x9c, (uint16_t *)&dev->dig_P8) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0x9e, (uint16_t *)&dev->dig_P9)) { |
|
|
|
|
|
|
|
|
|
debug("Calibration data received:"); |
|
|
|
|
debug("dig_T1=%d", dev->dig_T1); |
|
|
|
@ -120,12 +143,13 @@ static bool read_hum_calibration_data(bmp280_t *dev) |
|
|
|
|
{ |
|
|
|
|
uint16_t h4, h5; |
|
|
|
|
|
|
|
|
|
if (!read_data(&dev->i2c_dev, 0xa1, &dev->dig_H1, 1) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0xe1, (uint16_t *)&dev->dig_H2) && |
|
|
|
|
!read_data(&dev->i2c_dev, 0xe3, &dev->dig_H3, 1) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0xe4, &h4) && |
|
|
|
|
read_register16(&dev->i2c_dev, 0xe5, &h5) && |
|
|
|
|
!read_data(&dev->i2c_dev, 0xe7, (uint8_t *)&dev->dig_H6, 1)) { |
|
|
|
|
if (ESP_OK == read_data(&dev->i2c_dev, 0xa1, &dev->dig_H1, 1) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0xe1, (uint16_t *)&dev->dig_H2) && |
|
|
|
|
ESP_OK == read_data(&dev->i2c_dev, 0xe3, &dev->dig_H3, 1) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0xe4, &h4) && |
|
|
|
|
ESP_OK == read_register16(&dev->i2c_dev, 0xe5, &h5) && |
|
|
|
|
ESP_OK == read_data(&dev->i2c_dev, 0xe7, (uint8_t *)&dev->dig_H6, 1)) |
|
|
|
|
{ |
|
|
|
|
dev->dig_H4 = (h4 & 0x00ff) << 4 | (h4 & 0x0f00) >> 8; |
|
|
|
|
dev->dig_H5 = h5 >> 4; |
|
|
|
|
debug("Calibration data received:"); |
|
|
|
@ -141,11 +165,6 @@ static bool read_hum_calibration_data(bmp280_t *dev) |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int write_register8(i2c_dev_t *dev, uint8_t addr, uint8_t value) |
|
|
|
|
{ |
|
|
|
|
return i2c_slave_write(dev->bus, dev->addr, &addr, &value, 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool bmp280_init(bmp280_t *dev, bmp280_params_t *params) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
@ -154,7 +173,7 @@ bool bmp280_init(bmp280_t *dev, bmp280_params_t *params) |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (read_data(&dev->i2c_dev, BMP280_REG_ID, &dev->id, 1)) { |
|
|
|
|
if (ESP_OK != read_data(&dev->i2c_dev, BMP280_REG_ID, &dev->id, 1)) { |
|
|
|
|
debug("Sensor not found"); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
@ -165,15 +184,15 @@ bool bmp280_init(bmp280_t *dev, bmp280_params_t *params) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Soft reset.
|
|
|
|
|
if (write_register8(&dev->i2c_dev, BMP280_REG_RESET, BMP280_RESET_VALUE)) { |
|
|
|
|
if (ESP_OK != write_register8(&dev->i2c_dev, BMP280_REG_RESET, BMP280_RESET_VALUE)) { |
|
|
|
|
debug("Failed resetting sensor"); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Wait until finished copying over the NVP data.
|
|
|
|
|
while (1) { |
|
|
|
|
uint8_t status; |
|
|
|
|
if (!read_data(&dev->i2c_dev, BMP280_REG_STATUS, &status, 1) && (status & 1) == 0) |
|
|
|
|
uint8_t status = 1; |
|
|
|
|
if (ESP_OK != read_data(&dev->i2c_dev, BMP280_REG_STATUS, &status, 1) || (status & 1) == 0) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -189,7 +208,7 @@ bool bmp280_init(bmp280_t *dev, bmp280_params_t *params) |
|
|
|
|
|
|
|
|
|
uint8_t config = (params->standby << 5) | (params->filter << 2); |
|
|
|
|
debug("Writing config reg=%x", config); |
|
|
|
|
if (write_register8(&dev->i2c_dev, BMP280_REG_CONFIG, config)) { |
|
|
|
|
if (ESP_OK != write_register8(&dev->i2c_dev, BMP280_REG_CONFIG, config)) { |
|
|
|
|
debug("Failed configuring sensor"); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
@ -206,14 +225,14 @@ bool bmp280_init(bmp280_t *dev, bmp280_params_t *params) |
|
|
|
|
// Write crtl hum reg first, only active after write to BMP280_REG_CTRL.
|
|
|
|
|
uint8_t ctrl_hum = params->oversampling_humidity; |
|
|
|
|
debug("Writing ctrl hum reg=%x", ctrl_hum); |
|
|
|
|
if (write_register8(&dev->i2c_dev, BMP280_REG_CTRL_HUM, ctrl_hum)) { |
|
|
|
|
if (ESP_OK != write_register8(&dev->i2c_dev, BMP280_REG_CTRL_HUM, ctrl_hum)) { |
|
|
|
|
debug("Failed controlling sensor"); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
debug("Writing ctrl reg=%x", ctrl); |
|
|
|
|
if (write_register8(&dev->i2c_dev, BMP280_REG_CTRL, ctrl)) { |
|
|
|
|
if (ESP_OK != write_register8(&dev->i2c_dev, BMP280_REG_CTRL, ctrl)) { |
|
|
|
|
debug("Failed controlling sensor"); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
@ -224,12 +243,12 @@ bool bmp280_init(bmp280_t *dev, bmp280_params_t *params) |
|
|
|
|
bool bmp280_force_measurement(bmp280_t *dev) |
|
|
|
|
{ |
|
|
|
|
uint8_t ctrl; |
|
|
|
|
if (read_data(&dev->i2c_dev, BMP280_REG_CTRL, &ctrl, 1)) |
|
|
|
|
if (ESP_OK != read_data(&dev->i2c_dev, BMP280_REG_CTRL, &ctrl, 1)) |
|
|
|
|
return false; |
|
|
|
|
ctrl &= ~0b11; // clear two lower bits
|
|
|
|
|
ctrl |= BMP280_MODE_FORCED; |
|
|
|
|
debug("Writing ctrl reg=%x", ctrl); |
|
|
|
|
if (write_register8(&dev->i2c_dev, BMP280_REG_CTRL, ctrl)) { |
|
|
|
|
if (ESP_OK != write_register8(&dev->i2c_dev, BMP280_REG_CTRL, ctrl)) { |
|
|
|
|
debug("Failed starting forced mode"); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
@ -239,7 +258,7 @@ bool bmp280_force_measurement(bmp280_t *dev) |
|
|
|
|
bool bmp280_is_measuring(bmp280_t *dev) |
|
|
|
|
{ |
|
|
|
|
uint8_t status; |
|
|
|
|
if (read_data(&dev->i2c_dev, BMP280_REG_STATUS, &status, 1)) |
|
|
|
|
if (ESP_OK != read_data(&dev->i2c_dev, BMP280_REG_STATUS, &status, 1)) |
|
|
|
|
return false; |
|
|
|
|
if (status & (1 << 3)) { |
|
|
|
|
debug("Status: measuring"); |
|
|
|
@ -341,7 +360,7 @@ bool bmp280_read_fixed(bmp280_t *dev, int32_t *temperature, |
|
|
|
|
|
|
|
|
|
// Need to read in one sequence to ensure they match.
|
|
|
|
|
size_t size = humidity ? 8 : 6; |
|
|
|
|
if (read_data(&dev->i2c_dev, 0xf7, data, size)) { |
|
|
|
|
if (ESP_OK != read_data(&dev->i2c_dev, 0xf7, data, size)) { |
|
|
|
|
debug("Failed reading"); |
|
|
|
|
return false; |
|
|
|
|
} |