diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 5fad444c993c254e0132e537e4c5006fd956c6ae..546f47851d453b05701df6f1feae42208e17b5b4 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -46,9 +46,10 @@ ifneq (,$(filter bmp180,$(USEMODULE))) USEMODULE += xtimer endif -ifneq (,$(filter bme280,$(USEMODULE))) +ifneq (,$(filter bm%280,$(USEMODULE))) FEATURES_REQUIRED += periph_i2c USEMODULE += xtimer + USEMODULE += bmx280 endif ifneq (,$(filter cc110x,$(USEMODULE))) diff --git a/drivers/Makefile.include b/drivers/Makefile.include index cdfaa2acf36809d7d6ce76aab174b2af6a980225..1f24aad678a9e1f062107dd0b6bd7be39fff45f7 100644 --- a/drivers/Makefile.include +++ b/drivers/Makefile.include @@ -73,8 +73,8 @@ endif ifneq (,$(filter jc42,$(USEMODULE))) USEMODULE_INCLUDES += $(RIOTBASE)/drivers/jc42/include endif -ifneq (,$(filter bme280,$(USEMODULE))) - USEMODULE_INCLUDES += $(RIOTBASE)/drivers/bme280/include +ifneq (,$(filter bm%280,$(USEMODULE))) + USEMODULE_INCLUDES += $(RIOTBASE)/drivers/bmx280/include endif ifneq (,$(filter tsl2561,$(USEMODULE))) USEMODULE_INCLUDES += $(RIOTBASE)/drivers/tsl2561/include diff --git a/drivers/bme280/include/bme280_internals.h b/drivers/bme280/include/bme280_internals.h deleted file mode 100644 index 2c28b676e584ae90b612647716e877862a83a116..0000000000000000000000000000000000000000 --- a/drivers/bme280/include/bme280_internals.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2016 Kees Bakker, SODAQ - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @ingroup drivers_bme280 - * @brief Internal addresses, registers, constants for the BME280 sensor. - * @{ - * @file - * @brief Internal addresses, registers, constants for the BME280 sensor. - * - * @author Kees Bakker <kees@sodaq.com> - */ - -#ifndef BME280_INTERNALS_H -#define BME280_INTERNALS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @name BME280 registers - * @{ - */ -#define BME280_DIG_T1_LSB_REG 0x88 -#define BME280_DIG_T1_MSB_REG 0x89 -#define BME280_DIG_T2_LSB_REG 0x8A -#define BME280_DIG_T2_MSB_REG 0x8B -#define BME280_DIG_T3_LSB_REG 0x8C -#define BME280_DIG_T3_MSB_REG 0x8D -#define BME280_DIG_P1_LSB_REG 0x8E -#define BME280_DIG_P1_MSB_REG 0x8F -#define BME280_DIG_P2_LSB_REG 0x90 -#define BME280_DIG_P2_MSB_REG 0x91 -#define BME280_DIG_P3_LSB_REG 0x92 -#define BME280_DIG_P3_MSB_REG 0x93 -#define BME280_DIG_P4_LSB_REG 0x94 -#define BME280_DIG_P4_MSB_REG 0x95 -#define BME280_DIG_P5_LSB_REG 0x96 -#define BME280_DIG_P5_MSB_REG 0x97 -#define BME280_DIG_P6_LSB_REG 0x98 -#define BME280_DIG_P6_MSB_REG 0x99 -#define BME280_DIG_P7_LSB_REG 0x9A -#define BME280_DIG_P7_MSB_REG 0x9B -#define BME280_DIG_P8_LSB_REG 0x9C -#define BME280_DIG_P8_MSB_REG 0x9D -#define BME280_DIG_P9_LSB_REG 0x9E -#define BME280_DIG_P9_MSB_REG 0x9F - -#define BME280_DIG_H1_REG 0xA1 - -#define BME280_CHIP_ID 0x60 /* The identifier of the BME280 */ -#define BME280_CHIP_ID_REG 0xD0 -#define BME280_RST_REG 0xE0 /* Softreset Reg */ - -#define BME280_DIG_H2_LSB_REG 0xE1 -#define BME280_DIG_H2_MSB_REG 0xE2 -#define BME280_DIG_H3_REG 0xE3 -#define BME280_DIG_H4_MSB_REG 0xE4 /* H4[11:4] */ -#define BME280_DIG_H4_H5_REG 0xE5 /* H5[3:0] H4[3:0] */ -#define BME280_DIG_H5_MSB_REG 0xE6 /* H5[11:4] */ -#define BME280_DIG_H6_REG 0xE7 - -#define BME280_CTRL_HUMIDITY_REG 0xF2 /* Ctrl Humidity Reg */ -#define BME280_STAT_REG 0xF3 /* Status Reg */ -#define BME280_CTRL_MEAS_REG 0xF4 /* Ctrl Measure Reg */ -#define BME280_CONFIG_REG 0xF5 /* Configuration Reg */ -#define BME280_PRESSURE_MSB_REG 0xF7 /* Pressure MSB */ -#define BME280_PRESSURE_LSB_REG 0xF8 /* Pressure LSB */ -#define BME280_PRESSURE_XLSB_REG 0xF9 /* Pressure XLSB */ -#define BME280_TEMPERATURE_MSB_REG 0xFA /* Temperature MSB */ -#define BME280_TEMPERATURE_LSB_REG 0xFB /* Temperature LSB */ -#define BME280_TEMPERATURE_XLSB_REG 0xFC /* Temperature XLSB */ -#define BME280_HUMIDITY_MSB_REG 0xFD /* Humidity MSB */ -#define BME280_HUMIDITY_LSB_REG 0xFE /* Humidity LSB */ -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* BME280_INTERNALS_H */ -/** @} */ diff --git a/drivers/bme280/include/bme280_params.h b/drivers/bme280/include/bme280_params.h deleted file mode 100644 index 8f1f7c6180c95f1a9d7ee49e735ed765aff6adff..0000000000000000000000000000000000000000 --- a/drivers/bme280/include/bme280_params.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2016 Kees Bakker, SODAQ - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @ingroup drivers_bme280 - * - * @{ - * @file - * @brief Default configuration for BME280 - * - * @author Kees Bakker <kees@sodaq.com> - */ - -#ifndef BME280_PARAMS_H -#define BME280_PARAMS_H - -#include "bme280.h" -#include "saul_reg.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Set default configuration parameters for the BME280 - * @{ - */ -#ifndef BME280_PARAM_I2C_DEV -#define BME280_PARAM_I2C_DEV I2C_DEV(0) -#endif -#ifndef BME280_PARAM_I2C_ADDR -#define BME280_PARAM_I2C_ADDR (0x77) -#endif - -/* Defaults for Weather Monitoring */ -#define BME280_PARAMS_DEFAULT \ - { \ - .i2c_dev = BME280_PARAM_I2C_DEV, \ - .i2c_addr = BME280_PARAM_I2C_ADDR, \ - .t_sb = BME280_SB_0_5, \ - .filter = BME280_FILTER_OFF, \ - .run_mode = BME280_MODE_FORCED, \ - .temp_oversample = BME280_OSRS_X1, \ - .press_oversample = BME280_OSRS_X1, \ - .humid_oversample = BME280_OSRS_X1, \ - } -/**@}*/ - -/** - * @brief Configure BME280 - */ -static const bme280_params_t bme280_params[] = -{ -#ifdef BME280_PARAMS_BOARD - BME280_PARAMS_BOARD, -#else - BME280_PARAMS_DEFAULT, -#endif -}; - -/** - * @brief The number of configured sensors - */ -#define BME280_NUMOF (sizeof(bme280_params) / sizeof(bme280_params[0])) - -/** - * @brief Configuration details of SAUL registry entries - * - * This two dimensional array contains static details of the sensors - * for each device. Please be awar that the indexes are used in - * auto_init_bme280, so make sure the indexes match. - */ -static const saul_reg_info_t bme280_saul_reg_info[BME280_NUMOF][3] = -{ - { - { .name = "bme280-temp" }, - { .name = "bme280-humidity" }, - { .name = "bme280-press" }, - }, -}; - -#ifdef __cplusplus -} -#endif - -#endif /* BME280_PARAMS_H */ -/** @} */ diff --git a/drivers/bme280/Makefile b/drivers/bmx280/Makefile similarity index 66% rename from drivers/bme280/Makefile rename to drivers/bmx280/Makefile index 693aef674e6208f60f577ec96b1ad0f117b04a4c..48422e909a47d7cd428d10fa73825060ccc8d8c2 100644 --- a/drivers/bme280/Makefile +++ b/drivers/bmx280/Makefile @@ -1,3 +1 @@ -MODULE = bme280 - include $(RIOTBASE)/Makefile.base diff --git a/drivers/bme280/bme280.c b/drivers/bmx280/bmx280.c similarity index 75% rename from drivers/bme280/bme280.c rename to drivers/bmx280/bmx280.c index c9f5706d8dfc4a6a111778840b83ff2ed014dd15..24837730692fab98308b806ac7f59e40b792e98e 100644 --- a/drivers/bme280/bme280.c +++ b/drivers/bmx280/bmx280.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2016 Kees Bakker, SODAQ + * 2017 Inria * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -7,12 +8,11 @@ */ /** - * @ingroup drivers_bme280 + * @ingroup drivers_bmx280 * @{ * * @file - * @brief Device driver implementation for the BME280 temperature, - * pressure and humidity sensor. + * @brief Device driver implementation for sensors BMX280 (BME280 and BMP280). * * @author Kees Bakker <kees@sodaq.com> * @@ -23,21 +23,21 @@ #include <math.h> #include "log.h" -#include "bme280.h" -#include "bme280_internals.h" -#include "bme280_params.h" +#include "bmx280.h" +#include "bmx280_internals.h" +#include "bmx280_params.h" #include "periph/i2c.h" #include "xtimer.h" #define ENABLE_DEBUG (0) #include "debug.h" -static int read_calibration_data(bme280_t* dev); -static int do_measurement(bme280_t* dev); -static uint8_t get_ctrl_meas(bme280_t* dev); -static uint8_t get_status(bme280_t* dev); -static uint8_t read_u8_reg(bme280_t* dev, uint8_t reg); -static void write_u8_reg(bme280_t* dev, uint8_t reg, uint8_t b); +static int read_calibration_data(bmx280_t* dev); +static int do_measurement(bmx280_t* dev); +static uint8_t get_ctrl_meas(bmx280_t* dev); +static uint8_t get_status(bmx280_t* dev); +static uint8_t read_u8_reg(bmx280_t* dev, uint8_t reg); +static void write_u8_reg(bmx280_t* dev, uint8_t reg, uint8_t b); static uint16_t get_uint16_le(const uint8_t *buffer, size_t offset); static int16_t get_int16_le(const uint8_t *buffer, size_t offset); @@ -62,10 +62,10 @@ static int32_t t_fine; static uint8_t measurement_regs[8]; /*---------------------------------------------------------------------------* - * BME280 Core API * + * BMX280 Core API * *---------------------------------------------------------------------------*/ -int bme280_init(bme280_t* dev, const bme280_params_t* params) +int bmx280_init(bmx280_t* dev, const bmx280_params_t* params) { uint8_t chip_id; @@ -74,37 +74,37 @@ int bme280_init(bme280_t* dev, const bme280_params_t* params) /* Initialize I2C interface */ if (i2c_init_master(dev->params.i2c_dev, I2C_SPEED_NORMAL)) { DEBUG("[Error] I2C device not enabled\n"); - return BME280_ERR_I2C; + return BMX280_ERR_I2C; } /* Read chip ID */ - chip_id = read_u8_reg(dev, BME280_CHIP_ID_REG); - if (chip_id != BME280_CHIP_ID) { - DEBUG("[Error] Did not detect a BME280 at address %02x (%02X != %02X)\n", - dev->params.i2c_addr, chip_id, BME280_CHIP_ID); - return BME280_ERR_NODEV; + chip_id = read_u8_reg(dev, BMX280_CHIP_ID_REG); + if ((chip_id != BME280_CHIP_ID) && (chip_id != BMP280_CHIP_ID)) { + DEBUG("[Error] Did not detect a BMX280 at address %02x (%02x != %02x or %02x)\n", + dev->params.i2c_addr, chip_id, BME280_CHIP_ID, BMP280_CHIP_ID); + return BMX280_ERR_NODEV; } /* Read compensation data, 0x88..0x9F, 0xA1, 0xE1..0xE7 */ if (read_calibration_data(dev)) { DEBUG("[Error] Could not read calibration data\n"); - return BME280_ERR_NOCAL; + return BMX280_ERR_NOCAL; } - return BME280_OK; + return BMX280_OK; } /* * Returns temperature in DegC, resolution is 0.01 DegC. * t_fine carries fine temperature as global value */ -int16_t bme280_read_temperature(bme280_t* dev) +int16_t bmx280_read_temperature(bmx280_t* dev) { if (do_measurement(dev) < 0) { return INT16_MIN; } - bme280_calibration_t *cal = &dev->calibration; /* helper variable */ + bmx280_calibration_t *cal = &dev->calibration; /* helper variable */ /* Read the uncompensated temperature */ int32_t adc_T = (((uint32_t)measurement_regs[3 + 0]) << 12) | @@ -133,9 +133,9 @@ int16_t bme280_read_temperature(bme280_t* dev) /* * Returns pressure in Pa */ -uint32_t bme280_read_pressure(bme280_t *dev) +uint32_t bmx280_read_pressure(bmx280_t *dev) { - bme280_calibration_t *cal = &dev->calibration; /* helper variable */ + bmx280_calibration_t *cal = &dev->calibration; /* helper variable */ /* Read the uncompensated pressure */ int32_t adc_P = (((uint32_t)measurement_regs[0 + 0]) << 12) | @@ -172,9 +172,10 @@ uint32_t bme280_read_pressure(bme280_t *dev) return p_acc >> 8; } -uint16_t bme280_read_humidity(bme280_t *dev) +#if defined(MODULE_BME280) +uint16_t bme280_read_humidity(bmx280_t *dev) { - bme280_calibration_t *cal = &dev->calibration; /* helper variable */ + bmx280_calibration_t *cal = &dev->calibration; /* helper variable */ /* Read the uncompensated pressure */ int32_t adc_H = (((uint32_t)measurement_regs[6 + 0]) << 8) | @@ -204,6 +205,7 @@ uint16_t bme280_read_humidity(bme280_t *dev) /* First multiply to avoid losing the accuracy after the shift by ten */ return (100 * ((uint32_t)var1 >> 12)) >> 10; } +#endif /** * Read compensation data, 0x88..0x9F, 0xA1, 0xE1..0xE7 @@ -211,11 +213,15 @@ uint16_t bme280_read_humidity(bme280_t *dev) * This function reads all calibration bytes at once. These are * the registers DIG_T1_LSB (0x88) upto and including DIG_H6 (0xE7). */ -static int read_calibration_data(bme280_t* dev) +static int read_calibration_data(bmx280_t* dev) { uint8_t buffer[128]; /* 128 should be enough to read all calibration bytes */ int nr_bytes; - int nr_bytes_to_read = (BME280_DIG_H6_REG - BME280_DIG_T1_LSB_REG) + 1; +#ifdef MODULE_BME280 + int nr_bytes_to_read = (BME280_DIG_H6_REG - BMX280_DIG_T1_LSB_REG) + 1; +#else + int nr_bytes_to_read = (BMX280_DIG_P9_MSB_REG - BMX280_DIG_T1_LSB_REG) + 1; +#endif uint8_t offset = 0x88; memset(buffer, 0, sizeof(buffer)); @@ -228,20 +234,21 @@ static int read_calibration_data(bme280_t* dev) DUMP_BUFFER("Raw Calibration Data", buffer, nr_bytes); /* All little endian */ - dev->calibration.dig_T1 = get_uint16_le(buffer, BME280_DIG_T1_LSB_REG - offset); - dev->calibration.dig_T2 = get_int16_le(buffer, BME280_DIG_T2_LSB_REG - offset); - dev->calibration.dig_T3 = get_int16_le(buffer, BME280_DIG_T3_LSB_REG - offset); - - dev->calibration.dig_P1 = get_uint16_le(buffer, BME280_DIG_P1_LSB_REG - offset); - dev->calibration.dig_P2 = get_int16_le(buffer, BME280_DIG_P2_LSB_REG - offset); - dev->calibration.dig_P3 = get_int16_le(buffer, BME280_DIG_P3_LSB_REG - offset); - dev->calibration.dig_P4 = get_int16_le(buffer, BME280_DIG_P4_LSB_REG - offset); - dev->calibration.dig_P5 = get_int16_le(buffer, BME280_DIG_P5_LSB_REG - offset); - dev->calibration.dig_P6 = get_int16_le(buffer, BME280_DIG_P6_LSB_REG - offset); - dev->calibration.dig_P7 = get_int16_le(buffer, BME280_DIG_P7_LSB_REG - offset); - dev->calibration.dig_P8 = get_int16_le(buffer, BME280_DIG_P8_LSB_REG - offset); - dev->calibration.dig_P9 = get_int16_le(buffer, BME280_DIG_P9_LSB_REG - offset); - + dev->calibration.dig_T1 = get_uint16_le(buffer, BMX280_DIG_T1_LSB_REG - offset); + dev->calibration.dig_T2 = get_int16_le(buffer, BMX280_DIG_T2_LSB_REG - offset); + dev->calibration.dig_T3 = get_int16_le(buffer, BMX280_DIG_T3_LSB_REG - offset); + + dev->calibration.dig_P1 = get_uint16_le(buffer, BMX280_DIG_P1_LSB_REG - offset); + dev->calibration.dig_P2 = get_int16_le(buffer, BMX280_DIG_P2_LSB_REG - offset); + dev->calibration.dig_P3 = get_int16_le(buffer, BMX280_DIG_P3_LSB_REG - offset); + dev->calibration.dig_P4 = get_int16_le(buffer, BMX280_DIG_P4_LSB_REG - offset); + dev->calibration.dig_P5 = get_int16_le(buffer, BMX280_DIG_P5_LSB_REG - offset); + dev->calibration.dig_P6 = get_int16_le(buffer, BMX280_DIG_P6_LSB_REG - offset); + dev->calibration.dig_P7 = get_int16_le(buffer, BMX280_DIG_P7_LSB_REG - offset); + dev->calibration.dig_P8 = get_int16_le(buffer, BMX280_DIG_P8_LSB_REG - offset); + dev->calibration.dig_P9 = get_int16_le(buffer, BMX280_DIG_P9_LSB_REG - offset); + +#if defined(MODULE_BME280) dev->calibration.dig_H1 = buffer[BME280_DIG_H1_REG - offset]; dev->calibration.dig_H2 = get_int16_le(buffer, BME280_DIG_H2_LSB_REG - offset); dev->calibration.dig_H3 = buffer[BME280_DIG_H3_REG - offset]; @@ -250,20 +257,22 @@ static int read_calibration_data(bme280_t* dev) dev->calibration.dig_H5 = (((int16_t)buffer[BME280_DIG_H5_MSB_REG - offset]) << 4) + ((buffer[BME280_DIG_H4_H5_REG - offset] & 0xF0) >> 4); dev->calibration.dig_H6 = buffer[BME280_DIG_H6_REG - offset]; +#endif - DEBUG("[INFO] Chip ID = 0x%02X\n", buffer[BME280_CHIP_ID_REG - offset]); + DEBUG("[INFO] Chip ID = 0x%02X\n", buffer[BMX280_CHIP_ID_REG - offset]); /* Config is only be writable in sleep mode */ (void)i2c_write_reg(dev->params.i2c_dev, dev->params.i2c_addr, - BME280_CTRL_MEAS_REG, 0); + BMX280_CTRL_MEAS_REG, 0); uint8_t b; /* Config Register */ /* spi3w_en unused */ b = ((dev->params.t_sb & 7) << 5) | ((dev->params.filter & 7) << 2); - write_u8_reg(dev, BME280_CONFIG_REG, b); + write_u8_reg(dev, BMX280_CONFIG_REG, b); +#if defined(MODULE_BME280) /* * Note from the datasheet about ctrl_hum: "Changes to this register only become effective * after a write operation to "ctrl_meas". @@ -271,11 +280,12 @@ static int read_calibration_data(bme280_t* dev) */ b = dev->params.humid_oversample & 7; write_u8_reg(dev, BME280_CTRL_HUMIDITY_REG, b); +#endif b = ((dev->params.temp_oversample & 7) << 5) | ((dev->params.press_oversample & 7) << 2) | (dev->params.run_mode & 3); - write_u8_reg(dev, BME280_CTRL_MEAS_REG, b); + write_u8_reg(dev, BMX280_CTRL_MEAS_REG, b); return 0; } @@ -283,7 +293,7 @@ static int read_calibration_data(bme280_t* dev) /** * @brief Start a measurement and read the registers */ -static int do_measurement(bme280_t* dev) +static int do_measurement(bmx280_t* dev) { /* * If settings has FORCED mode, then the device go to sleep after @@ -296,7 +306,7 @@ static int do_measurement(bme280_t* dev) /* Set the run_mode back to what we want. */ ctrl_meas &= ~3; ctrl_meas |= dev->params.run_mode; - write_u8_reg(dev, BME280_CTRL_MEAS_REG, ctrl_meas); + write_u8_reg(dev, BMX280_CTRL_MEAS_REG, ctrl_meas); /* Wait for measurement ready? */ size_t count = 0; @@ -307,7 +317,7 @@ static int do_measurement(bme280_t* dev) } int nr_bytes; int nr_bytes_to_read = sizeof(measurement_regs); - uint8_t offset = BME280_PRESSURE_MSB_REG; + uint8_t offset = BMX280_PRESSURE_MSB_REG; nr_bytes = i2c_read_regs(dev->params.i2c_dev, dev->params.i2c_addr, offset, measurement_regs, nr_bytes_to_read); @@ -320,17 +330,17 @@ static int do_measurement(bme280_t* dev) return 0; } -static uint8_t get_ctrl_meas(bme280_t* dev) +static uint8_t get_ctrl_meas(bmx280_t* dev) { - return read_u8_reg(dev, BME280_CTRL_MEAS_REG); + return read_u8_reg(dev, BMX280_CTRL_MEAS_REG); } -static uint8_t get_status(bme280_t* dev) +static uint8_t get_status(bmx280_t* dev) { - return read_u8_reg(dev, BME280_STAT_REG); + return read_u8_reg(dev, BMX280_STAT_REG); } -static uint8_t read_u8_reg(bme280_t* dev, uint8_t reg) +static uint8_t read_u8_reg(bmx280_t* dev, uint8_t reg) { uint8_t b; /* Assuming device is correct, it should return 1 (nr bytes) */ @@ -338,7 +348,7 @@ static uint8_t read_u8_reg(bme280_t* dev, uint8_t reg) return b; } -static void write_u8_reg(bme280_t* dev, uint8_t reg, uint8_t b) +static void write_u8_reg(bmx280_t* dev, uint8_t reg, uint8_t b) { /* Assuming device is correct, it should return 1 (nr bytes) */ (void)i2c_write_reg(dev->params.i2c_dev, dev->params.i2c_addr, reg, b); diff --git a/drivers/bme280/bme280_saul.c b/drivers/bmx280/bmx280_saul.c similarity index 65% rename from drivers/bme280/bme280_saul.c rename to drivers/bmx280/bmx280_saul.c index e37c9ed82f389d719710cbf38a10c8abcd1cee55..e767d8402e5ad684364eface9c80f4efe6ac2d3b 100644 --- a/drivers/bme280/bme280_saul.c +++ b/drivers/bmx280/bmx280_saul.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2016 Kees Bakker, SODAQ + * 2017 Inria * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -7,68 +8,73 @@ */ /** - * @ingroup driver_bme280 + * @ingroup driver_bmx280 * @{ * * @file - * @brief SAUL adoption for BME280 sensor. + * @brief SAUL adoption for BMX280 sensors (BME280 and BMP280). * * @author Kees Bakker <kees@sodaq.com> + * @author Alexandre Abadie <alexandre.abadie@inria.fr> * * @} */ #include "saul.h" -#include "bme280.h" +#include "bmx280.h" static int read_temperature(void *dev, phydat_t *res) { - bme280_t *d = (bme280_t *)dev; + bmx280_t *d = (bmx280_t *)dev; - res->val[0] = bme280_read_temperature(d); + res->val[0] = bmx280_read_temperature(d); res->unit = UNIT_TEMP_C; res->scale = -2; return 1; } -static int read_relative_humidity(void *dev, phydat_t *res) +static int read_pressure(void *dev, phydat_t *res) { - bme280_t *d = (bme280_t *)dev; + bmx280_t *d = (bmx280_t *)dev; - res->val[0] = bme280_read_humidity(d); - res->unit = UNIT_PERCENT; - res->scale = -2; + res->val[0] = bmx280_read_pressure(d) / 100; + res->unit = UNIT_PA; + res->scale = 2; return 1; } -static int read_pressure(void *dev, phydat_t *res) +#ifdef MODULE_BME280 +static int read_relative_humidity(void *dev, phydat_t *res) { - bme280_t *d = (bme280_t *)dev; + bmx280_t *d = (bmx280_t *)dev; - res->val[0] = bme280_read_pressure(d) / 100; - res->unit = UNIT_PA; - res->scale = 2; + res->val[0] = bme280_read_humidity(d); + res->unit = UNIT_PERCENT; + res->scale = -2; return 1; } +#endif -const saul_driver_t bme280_temperature_saul_driver = { +const saul_driver_t bmx280_temperature_saul_driver = { .read = read_temperature, .write = saul_notsup, .type = SAUL_SENSE_TEMP, }; -const saul_driver_t bme280_relative_humidity_saul_driver = { - .read = read_relative_humidity, +const saul_driver_t bmx280_pressure_saul_driver = { + .read = read_pressure, .write = saul_notsup, - .type = SAUL_SENSE_HUM, + .type = SAUL_SENSE_PRESS, }; -const saul_driver_t bme280_pressure_saul_driver = { - .read = read_pressure, +#ifdef MODULE_BME280 +const saul_driver_t bme280_relative_humidity_saul_driver = { + .read = read_relative_humidity, .write = saul_notsup, - .type = SAUL_SENSE_PRESS, + .type = SAUL_SENSE_HUM, }; +#endif diff --git a/drivers/bmx280/include/bmx280_internals.h b/drivers/bmx280/include/bmx280_internals.h new file mode 100644 index 0000000000000000000000000000000000000000..87f35fa640caaccaadc76ed8059444ca27741861 --- /dev/null +++ b/drivers/bmx280/include/bmx280_internals.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2016 Kees Bakker, SODAQ + * 2017 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup drivers_bmx280 + * @brief Internal addresses, registers, constants for the BMX280 family sensors. + * @{ + * @file + * @brief Internal addresses, registers, constants for the BMX280 family sensors. + * + * @author Kees Bakker <kees@sodaq.com> + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + */ + +#ifndef BMX280_INTERNALS_H +#define BMX280_INTERNALS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name BME280 registers + * @{ + */ +#define BME280_CHIP_ID 0x60 /* The identifier of the BME280 */ +#define BMP280_CHIP_ID 0x58 /* The identifier of the BMP280 */ +#define BMX280_CHIP_ID_REG 0xD0 +#define BMEX80_RST_REG 0xE0 /* Softreset Reg */ + +#define BMX280_DIG_T1_LSB_REG 0x88 +#define BMX280_DIG_T1_MSB_REG 0x89 +#define BMX280_DIG_T2_LSB_REG 0x8A +#define BMX280_DIG_T2_MSB_REG 0x8B +#define BMX280_DIG_T3_LSB_REG 0x8C +#define BMX280_DIG_T3_MSB_REG 0x8D +#define BMX280_DIG_P1_LSB_REG 0x8E +#define BMX280_DIG_P1_MSB_REG 0x8F +#define BMX280_DIG_P2_LSB_REG 0x90 +#define BMX280_DIG_P2_MSB_REG 0x91 +#define BMX280_DIG_P3_LSB_REG 0x92 +#define BMX280_DIG_P3_MSB_REG 0x93 +#define BMX280_DIG_P4_LSB_REG 0x94 +#define BMX280_DIG_P4_MSB_REG 0x95 +#define BMX280_DIG_P5_LSB_REG 0x96 +#define BMX280_DIG_P5_MSB_REG 0x97 +#define BMX280_DIG_P6_LSB_REG 0x98 +#define BMX280_DIG_P6_MSB_REG 0x99 +#define BMX280_DIG_P7_LSB_REG 0x9A +#define BMX280_DIG_P7_MSB_REG 0x9B +#define BMX280_DIG_P8_LSB_REG 0x9C +#define BMX280_DIG_P8_MSB_REG 0x9D +#define BMX280_DIG_P9_LSB_REG 0x9E +#define BMX280_DIG_P9_MSB_REG 0x9F + +#define BME280_DIG_H1_REG 0xA1 +#define BME280_DIG_H2_LSB_REG 0xE1 +#define BME280_DIG_H2_MSB_REG 0xE2 +#define BME280_DIG_H3_REG 0xE3 +#define BME280_DIG_H4_MSB_REG 0xE4 /* H4[11:4] */ +#define BME280_DIG_H4_H5_REG 0xE5 /* H5[3:0] H4[3:0] */ +#define BME280_DIG_H5_MSB_REG 0xE6 /* H5[11:4] */ +#define BME280_DIG_H6_REG 0xE7 + +#define BMX280_STAT_REG 0xF3 /* Status Reg */ +#define BMX280_CTRL_MEAS_REG 0xF4 /* Ctrl Measure Reg */ +#define BMX280_CONFIG_REG 0xF5 /* Configuration Reg */ +#define BMX280_PRESSURE_MSB_REG 0xF7 /* Pressure MSB */ +#define BMX280_PRESSURE_LSB_REG 0xF8 /* Pressure LSB */ +#define BMX280_PRESSURE_XLSB_REG 0xF9 /* Pressure XLSB */ +#define BMX280_TEMPERATURE_MSB_REG 0xFA /* Temperature MSB */ +#define BMX280_TEMPERATURE_LSB_REG 0xFB /* Temperature LSB */ +#define BMX280_TEMPERATURE_XLSB_REG 0xFC /* Temperature XLSB */ +#define BME280_CTRL_HUMIDITY_REG 0xF2 /* Ctrl Humidity Reg */ +#define BME280_HUMIDITY_MSB_REG 0xFD /* Humidity MSB */ +#define BME280_HUMIDITY_LSB_REG 0xFE /* Humidity LSB */ +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* BMX280_INTERNALS_H */ +/** @} */ diff --git a/drivers/bmx280/include/bmx280_params.h b/drivers/bmx280/include/bmx280_params.h new file mode 100644 index 0000000000000000000000000000000000000000..56d469513176c081aed47a4eeb3951709b0ef1bb --- /dev/null +++ b/drivers/bmx280/include/bmx280_params.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2016 Kees Bakker, SODAQ + * 2017 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup drivers_bmx280 + * + * @{ + * @file + * @brief Default configuration for BMX280 + * + * @author Kees Bakker <kees@sodaq.com> + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + */ + +#ifndef BMX280_PARAMS_H +#define BMX280_PARAMS_H + +#include "bmx280.h" +#include "saul_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set default configuration parameters for the BMX280 + * @{ + */ +#ifndef BMX280_PARAM_I2C_DEV +#define BMX280_PARAM_I2C_DEV I2C_DEV(0) +#endif +#ifndef BMX280_PARAM_I2C_ADDR +#define BMX280_PARAM_I2C_ADDR (0x77) +#endif + +/* Defaults for Weather Monitoring */ +#define BMX280_PARAMS_DEFAULT \ + { \ + .i2c_dev = BMX280_PARAM_I2C_DEV, \ + .i2c_addr = BMX280_PARAM_I2C_ADDR, \ + .t_sb = BMX280_SB_0_5, \ + .filter = BMX280_FILTER_OFF, \ + .run_mode = BMX280_MODE_FORCED, \ + .temp_oversample = BMX280_OSRS_X1, \ + .press_oversample = BMX280_OSRS_X1, \ + .humid_oversample = BMX280_OSRS_X1, \ + } +/**@}*/ + +/** + * @brief Configure BMX280 + */ +static const bmx280_params_t bmx280_params[] = +{ +#ifdef BMX280_PARAMS_BOARD + BMX280_PARAMS_BOARD, +#else + BMX280_PARAMS_DEFAULT +#endif +}; + +/** + * @brief The number of configured sensors + */ +#define BMX280_NUMOF (sizeof(bmx280_params) / sizeof(bmx280_params[0])) + +/** + * @brief Configuration details of SAUL registry entries + * + * This two dimensional array contains static details of the sensors + * for each device. Please be awar that the indexes are used in + * auto_init_bmx280, so make sure the indexes match. + */ +#if defined(MODULE_BME280) +static const saul_reg_info_t bmx280_saul_reg_info[BMX280_NUMOF][3] = +#else +static const saul_reg_info_t bmx280_saul_reg_info[BMX280_NUMOF][2] = +#endif +{ + { + { .name = "bmx280-temp" }, + { .name = "bmx280-press" }, +#if defined(MODULE_BME280) + { .name = "bme280-humidity" }, +#endif + }, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* BMX280_PARAMS_H */ +/** @} */ diff --git a/drivers/include/bme280.h b/drivers/include/bmx280.h similarity index 50% rename from drivers/include/bme280.h rename to drivers/include/bmx280.h index 3a336414bf28c7c101cad39ee8b222477f8da861..5ce302e8610bd767c6b5f07b3289f37f13a941e4 100644 --- a/drivers/include/bme280.h +++ b/drivers/include/bmx280.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2016 Kees Bakker, SODAQ + * 2017 Inria * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -7,13 +8,13 @@ */ /** - * @defgroup drivers_bme280 BME280 + * @defgroup drivers_bmx280 BMX280 * @ingroup drivers_sensors - * @brief Device driver interface for the BME280 sensor + * @brief Device driver interface for the BMX280 sensors (BMP280 and BME280). * * @{ * @file - * @brief Device driver interface for the BME280 sensor. + * @brief Device driver interface for the BMX280 sensors (BMP280 and BME280). * * @details There are three sensor values that can be read: temperature, * pressure and humidity. The BME280 device usually measures them @@ -25,11 +26,13 @@ * you can call the other two. * * @author Kees Bakker <kees@sodaq.com> + * @author Alexandre Abadie <alexandre.abadie@inria.fr> */ -#ifndef BME280_H -#define BME280_H +#ifndef BMX280_H +#define BMX280_H +#include <inttypes.h> #include "saul.h" #include "periph/i2c.h" @@ -38,7 +41,7 @@ extern "C" { #endif /** - * @brief Calibration struct for the BME280 sensor + * @brief Calibration struct for the BMX280 sensor * * This must be read from the device at startup. */ @@ -63,62 +66,62 @@ typedef struct { int16_t dig_H4; /**< H4 coefficient */ int16_t dig_H5; /**< H5 coefficient */ int8_t dig_H6; /**< H6 coefficient */ -} bme280_calibration_t; +} bmx280_calibration_t; /** - * @brief Values for t_sb field of the BME280 config register + * @brief Values for t_sb field of the BMX280 config register */ typedef enum { - BME280_SB_0_5 = 0, - BME280_SB_62_5 = 1, - BME280_SB_125 = 2, - BME280_SB_250 = 3, - BME280_SB_500 = 4, - BME280_SB_1000 = 5, - BME280_SB_10 = 6, - BME280_SB_20 = 7 -} bme280_t_sb_t; + BMX280_SB_0_5 = 0, + BMX280_SB_62_5 = 1, + BMX280_SB_125 = 2, + BMX280_SB_250 = 3, + BMX280_SB_500 = 4, + BMX280_SB_1000 = 5, + BMX280_SB_10 = 6, + BMX280_SB_20 = 7 +} bmx280_t_sb_t; /** - * @brief Values for filter field of the BME280 config register + * @brief Values for filter field of the BMX280 config register */ typedef enum { - BME280_FILTER_OFF = 0, - BME280_FILTER_2 = 1, - BME280_FILTER_4 = 2, - BME280_FILTER_8 = 3, - BME280_FILTER_16 = 4, -} bme280_filter_t; + BMX280_FILTER_OFF = 0, + BMX280_FILTER_2 = 1, + BMX280_FILTER_4 = 2, + BMX280_FILTER_8 = 3, + BMX280_FILTER_16 = 4, +} bmx280_filter_t; /** - * @brief Values for mode field of the BME280 ctrl_meas register + * @brief Values for mode field of the BMX280 ctrl_meas register */ typedef enum { - BME280_MODE_SLEEP = 0, - BME280_MODE_FORCED = 1, - BME280_MODE_FORCED2 = 2, /* Same as FORCED */ - BME280_MODE_NORMAL = 3 -} bme280_mode_t; + BMX280_MODE_SLEEP = 0, + BMX280_MODE_FORCED = 1, + BMX280_MODE_FORCED2 = 2, /* Same as FORCED */ + BMX280_MODE_NORMAL = 3 +} bmx280_mode_t; /** * @brief Values for oversampling settings * * These values are used for: * - osrs_h field of the BME280 ctrl_hum register - * - osrs_t field of the BME280 ctrl_meas register - * - osrs_p field of the BME280 ctrl_meas register + * - osrs_t field of the BMX280 ctrl_meas register + * - osrs_p field of the BMX280 ctrl_meas register */ typedef enum { - BME280_OSRS_SKIPPED = 0, - BME280_OSRS_X1 = 1, - BME280_OSRS_X2 = 2, - BME280_OSRS_X4 = 3, - BME280_OSRS_X8 = 4, - BME280_OSRS_X16 = 5, -} bme280_osrs_t; + BMX280_OSRS_SKIPPED = 0, + BMX280_OSRS_X1 = 1, + BMX280_OSRS_X2 = 2, + BMX280_OSRS_X4 = 3, + BMX280_OSRS_X8 = 4, + BMX280_OSRS_X16 = 5, +} bmx280_osrs_t; /** - * @brief Parameters for the BME280 sensor + * @brief Parameters for the BMX280 sensor * * These parameters are needed to configure the device at startup. */ @@ -128,96 +131,89 @@ typedef struct { uint8_t i2c_addr; /**< I2C address */ /* Config Register */ - bme280_t_sb_t t_sb; /**< standby */ - bme280_filter_t filter; /**< filter coefficient */ + bmx280_t_sb_t t_sb; /**< standby */ + bmx280_filter_t filter; /**< filter coefficient */ uint8_t spi3w_en; /**< Enables 3-wire SPI interface */ /* ctrl_meas */ - bme280_mode_t run_mode; /**< ctrl_meas mode */ - bme280_osrs_t temp_oversample; /**< ctrl_meas osrs_t */ - bme280_osrs_t press_oversample; /**< ctrl_meas osrs_p */ + bmx280_mode_t run_mode; /**< ctrl_meas mode */ + bmx280_osrs_t temp_oversample; /**< ctrl_meas osrs_t */ + bmx280_osrs_t press_oversample; /**< ctrl_meas osrs_p */ /* ctrl_hum */ - bme280_osrs_t humid_oversample; /**< ctrl_hum osrs_h */ -} bme280_params_t; + bmx280_osrs_t humid_oversample; /**< ctrl_hum osrs_h */ +} bmx280_params_t; /** - * @brief Device descriptor for the BME280 sensor + * @brief Device descriptor for the BMX280 sensor */ typedef struct { - bme280_params_t params; /**< Device Parameters */ - bme280_calibration_t calibration; /**< Calibration Data */ -} bme280_t; + bmx280_params_t params; /**< Device Parameters */ + bmx280_calibration_t calibration; /**< Calibration Data */ +} bmx280_t; /** * @brief Status and error return codes */ enum { - BME280_OK = 0, /**< everything was fine */ - BME280_ERR_I2C = -1, /**< error initializing the I2C bus */ - BME280_ERR_NODEV = -2, /**< did not detect BME280 */ - BME280_ERR_NOCAL = -3, /**< could not read calibration data */ + BMX280_OK = 0, /**< everything was fine */ + BMX280_ERR_I2C = -1, /**< error initializing the I2C bus */ + BMX280_ERR_NODEV = -2, /**< did not detect BME280 or BMP280 */ + BMX280_ERR_NOCAL = -3, /**< could not read calibration data */ }; /** - * @brief export SAUL endpoints - * @{ - */ -extern const saul_driver_t bme280_temperature_saul_driver; -extern const saul_driver_t bme280_relative_humidity_saul_driver; -extern const saul_driver_t bme280_pressure_saul_driver; -/** @} */ - -/** - * @brief Initialize the given BME280 device + * @brief Initialize the given BMX280 device * - * @param[out] dev Initialized device descriptor of BME280 device - * @param[in] params The parameters for the BME280 device (sampling rate, etc) + * @param[out] dev Initialized device descriptor of BMX280 device + * @param[in] params The parameters for the BMX280 device (sampling rate, etc) * - * @return BME280_OK on success - * @return BME280_ERR_I2C - * @return BME280_ERR_NODEV - * @return BME280_ERR_NOCAL + * @return BMX280_OK on success + * @return BMX280_ERR_I2C + * @return BMX280_ERR_NODEV + * @return BMX280_ERR_NOCAL */ -int bme280_init(bme280_t* dev, const bme280_params_t* params); +int bmx280_init(bmx280_t* dev, const bmx280_params_t* params); /** - * @brief Read temperature value from the given BME280 device, returned in centi °C + * @brief Read temperature value from the given BMX280 device, returned in centi °C * - * @param[in] dev Device descriptor of BME280 device to read from + * @param[in] dev Device descriptor of BMX280 device to read from * * @returns The temperature in centi Celsius. In case of an error * it returns INT16_MIN. */ -int16_t bme280_read_temperature(bme280_t* dev); +int16_t bmx280_read_temperature(bmx280_t* dev); /** - * @brief Read humidity value from the given BME280 device, returned in centi %RH + * @brief Read air pressure value from the given BMX280 device, returned in PA * - * @details This function should only be called after doing bme280_read_temperature + * @details This function should only be called after doing bmx280_read_temperature * first. * - * @param[in] dev Device descriptor of BME280 device to read from + * @param[in] dev Device descriptor of BMX280 device to read from * - * @returns Humidity in centi %RH (i.e. the percentage times 100) + * @returns The air pressure in Pa */ -uint16_t bme280_read_humidity(bme280_t *dev); +uint32_t bmx280_read_pressure(bmx280_t *dev); +#if defined(MODULE_BME280) /** - * @brief Read air pressure value from the given BME280 device, returned in PA + * @brief Read humidity value from the given BME280 device, returned in centi %RH * - * @details This function should only be called after doing bme280_read_temperature - * first. + * @details This function should only be called after doing bmx280_read_temperature + * first. It's only available with BME280 sensor. * * @param[in] dev Device descriptor of BME280 device to read from * - * @returns The air pressure in Pa + * @returns Humidity in centi %RH (i.e. the percentage times 100) */ -uint32_t bme280_read_pressure(bme280_t *dev); +uint16_t bme280_read_humidity(bmx280_t *dev); +#endif #ifdef __cplusplus } #endif -#endif /* BME280_H */ +#endif /* BMX280_H */ /** @} */ diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index 9be9dbf5836c292d076a8c96ad2c0d0544cace87..29cad6e3898875d95923341a902a1eccaddffe78 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -60,5 +60,9 @@ PSEUDOMODULES += sock_udp PSEUDOMODULES += at86rf23% PSEUDOMODULES += at86rf21% +# include variants of the BMX280 drivers as pseudo modules +PSEUDOMODULES += bmp280 +PSEUDOMODULES += bme280 + # add all pseudo random number generator variants as pseudomodules PSEUDOMODULES += prng_%