diff --git a/drivers/sensor/bme280/CMakeLists.txt b/drivers/sensor/bme280/CMakeLists.txt index 1e7a24f6307..b6efb35d2a6 100644 --- a/drivers/sensor/bme280/CMakeLists.txt +++ b/drivers/sensor/bme280/CMakeLists.txt @@ -2,4 +2,4 @@ zephyr_library() -zephyr_library_sources_ifdef(CONFIG_BME280 bme280.c) +zephyr_library_sources_ifdef(CONFIG_BME280 bme280.c bme280_spi.c bme280_i2c.c) diff --git a/drivers/sensor/bme280/bme280.c b/drivers/sensor/bme280/bme280.c index 1267d39e1ca..13573c305d7 100644 --- a/drivers/sensor/bme280/bme280.c +++ b/drivers/sensor/bme280/bme280.c @@ -3,6 +3,7 @@ /* * Copyright (c) 2016, 2017 Intel Corporation * Copyright (c) 2017 IpTronix S.r.l. + * Copyright (c) 2021 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,8 +12,6 @@ #include #include #include -#include -#include #include #include @@ -20,14 +19,6 @@ #include "bme280.h" -#define BME280_SPI_OPERATION (SPI_WORD_SET(8) | SPI_TRANSFER_MSB | \ - SPI_MODE_CPOL | SPI_MODE_CPHA) - -#define DT_DRV_COMPAT bosch_bme280 - -#define BME280_BUS_SPI DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) -#define BME280_BUS_I2C DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) - LOG_MODULE_REGISTER(BME280, CONFIG_SENSOR_LOG_LEVEL); #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0 @@ -70,36 +61,12 @@ struct bme280_data { #endif }; -union bme280_bus_config { -#if BME280_BUS_SPI - struct spi_config spi_cfg; -#endif -#if BME280_BUS_I2C - uint16_t i2c_addr; -#endif -}; - struct bme280_config { const struct device *bus; const struct bme280_bus_io *bus_io; const union bme280_bus_config bus_config; }; -typedef int (*bme280_bus_check_fn)(const struct device *bus, - const union bme280_bus_config *bus_config); -typedef int (*bme280_reg_read_fn)(const struct device *bus, - const union bme280_bus_config *bus_config, - uint8_t start, uint8_t *buf, int size); -typedef int (*bme280_reg_write_fn)(const struct device *bus, - const union bme280_bus_config *bus_config, - uint8_t reg, uint8_t val); - -struct bme280_bus_io { - bme280_bus_check_fn check; - bme280_reg_read_fn read; - bme280_reg_write_fn write; -}; - static inline struct bme280_data *to_data(const struct device *dev) { return dev->data; @@ -121,128 +88,6 @@ to_bus_config(const struct device *dev) return &to_config(dev)->bus_config; } -#if BME280_BUS_SPI -static int bme280_bus_check_spi(const struct device *bus, - const union bme280_bus_config *bus_config) -{ - const struct spi_cs_control *cs; - - if (!device_is_ready(bus)) { - LOG_DBG("SPI bus %s not ready", bus->name); - return -ENODEV; - } - - cs = bus_config->spi_cfg.cs; - if (cs && !device_is_ready(cs->gpio_dev)) { - LOG_DBG("SPI CS GPIO controller %s not ready", - cs->gpio_dev->name); - return -ENODEV; - } - - return 0; -} - -static int bme280_reg_read_spi(const struct device *bus, - const union bme280_bus_config *bus_config, - uint8_t start, uint8_t *buf, int size) -{ - uint8_t addr; - const struct spi_buf tx_buf = { - .buf = &addr, - .len = 1 - }; - const struct spi_buf_set tx = { - .buffers = &tx_buf, - .count = 1 - }; - struct spi_buf rx_buf[2]; - const struct spi_buf_set rx = { - .buffers = rx_buf, - .count = 2 - }; - int i; - - rx_buf[0].buf = NULL; - rx_buf[0].len = 1; - - rx_buf[1].len = 1; - - for (i = 0; i < size; i++) { - int ret; - - addr = (start + i) | 0x80; - rx_buf[1].buf = &buf[i]; - - ret = spi_transceive(bus, &bus_config->spi_cfg, &tx, &rx); - if (ret) { - LOG_DBG("spi_transceive FAIL %d\n", ret); - return ret; - } - } - - return 0; -} - -static int bme280_reg_write_spi(const struct device *bus, - const union bme280_bus_config *bus_config, - uint8_t reg, uint8_t val) -{ - uint8_t cmd[2] = { reg & 0x7F, val }; - const struct spi_buf tx_buf = { - .buf = cmd, - .len = 2 - }; - const struct spi_buf_set tx = { - .buffers = &tx_buf, - .count = 1 - }; - int ret; - - ret = spi_write(bus, &bus_config->spi_cfg, &tx); - if (ret) { - LOG_DBG("spi_write FAIL %d\n", ret); - return ret; - } - return 0; -} - -static const struct bme280_bus_io bme280_bus_io_spi = { - .check = bme280_bus_check_spi, - .read = bme280_reg_read_spi, - .write = bme280_reg_write_spi, -}; -#endif /* BME280_BUS_SPI */ - -#if BME280_BUS_I2C -static int bme280_bus_check_i2c(const struct device *bus, - const union bme280_bus_config *bus_config) -{ - return device_is_ready(bus) ? 0 : -ENODEV; -} - -static int bme280_reg_read_i2c(const struct device *bus, - const union bme280_bus_config *bus_config, - uint8_t start, uint8_t *buf, int size) -{ - return i2c_burst_read(bus, bus_config->i2c_addr, - start, buf, size); -} - -static int bme280_reg_write_i2c(const struct device *bus, - const union bme280_bus_config *bus_config, - uint8_t reg, uint8_t val) -{ - return i2c_reg_write_byte(bus, bus_config->i2c_addr, - reg, val); -} - -static const struct bme280_bus_io bme280_bus_io_i2c = { - .check = bme280_bus_check_i2c, - .read = bme280_reg_read_i2c, - .write = bme280_reg_write_i2c, -}; -#endif /* BME280_BUS_I2C */ - static inline int bme280_bus_check(const struct device *dev) { return to_config(dev)->bus_io->check(to_bus(dev), to_bus_config(dev)); diff --git a/drivers/sensor/bme280/bme280.h b/drivers/sensor/bme280/bme280.h index 3e8a1a7b859..7ef1c934489 100644 --- a/drivers/sensor/bme280/bme280.h +++ b/drivers/sensor/bme280/bme280.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2016, 2017 Intel Corporation * Copyright (c) 2017 IpTronix S.r.l. + * Copyright (c) 2021 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +11,48 @@ #include #include +#include +#include +#include + +#define DT_DRV_COMPAT bosch_bme280 + +#define BME280_BUS_SPI DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) +#define BME280_BUS_I2C DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) + +union bme280_bus_config { +#if BME280_BUS_SPI + struct spi_config spi_cfg; +#endif +#if BME280_BUS_I2C + uint16_t i2c_addr; +#endif +}; + +typedef int (*bme280_bus_check_fn)(const struct device *bus, + const union bme280_bus_config *bus_config); +typedef int (*bme280_reg_read_fn)(const struct device *bus, + const union bme280_bus_config *bus_config, + uint8_t start, uint8_t *buf, int size); +typedef int (*bme280_reg_write_fn)(const struct device *bus, + const union bme280_bus_config *bus_config, + uint8_t reg, uint8_t val); + +struct bme280_bus_io { + bme280_bus_check_fn check; + bme280_reg_read_fn read; + bme280_reg_write_fn write; +}; + +#if BME280_BUS_SPI +#define BME280_SPI_OPERATION (SPI_WORD_SET(8) | SPI_TRANSFER_MSB | \ + SPI_MODE_CPOL | SPI_MODE_CPHA) +extern const struct bme280_bus_io bme280_bus_io_spi; +#endif + +#if BME280_BUS_I2C +extern const struct bme280_bus_io bme280_bus_io_i2c; +#endif #define BME280_REG_PRESS_MSB 0xF7 #define BME280_REG_COMP_START 0x88 diff --git a/drivers/sensor/bme280/bme280_i2c.c b/drivers/sensor/bme280/bme280_i2c.c new file mode 100644 index 00000000000..7733ca43ce8 --- /dev/null +++ b/drivers/sensor/bme280/bme280_i2c.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, 2017 Intel Corporation + * Copyright (c) 2017 IpTronix S.r.l. + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Bus-specific functionality for BME280s accessed via I2C. + */ + +#include "bme280.h" + +#if BME280_BUS_I2C +static int bme280_bus_check_i2c(const struct device *bus, + const union bme280_bus_config *bus_config) +{ + return device_is_ready(bus) ? 0 : -ENODEV; +} + +static int bme280_reg_read_i2c(const struct device *bus, + const union bme280_bus_config *bus_config, + uint8_t start, uint8_t *buf, int size) +{ + return i2c_burst_read(bus, bus_config->i2c_addr, + start, buf, size); +} + +static int bme280_reg_write_i2c(const struct device *bus, + const union bme280_bus_config *bus_config, + uint8_t reg, uint8_t val) +{ + return i2c_reg_write_byte(bus, bus_config->i2c_addr, + reg, val); +} + +const struct bme280_bus_io bme280_bus_io_i2c = { + .check = bme280_bus_check_i2c, + .read = bme280_reg_read_i2c, + .write = bme280_reg_write_i2c, +}; +#endif /* BME280_BUS_I2C */ diff --git a/drivers/sensor/bme280/bme280_spi.c b/drivers/sensor/bme280/bme280_spi.c new file mode 100644 index 00000000000..3a1964a0ff7 --- /dev/null +++ b/drivers/sensor/bme280/bme280_spi.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2016, 2017 Intel Corporation + * Copyright (c) 2017 IpTronix S.r.l. + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Bus-specific functionality for BME280s accessed via SPI. + */ + +#include +#include "bme280.h" + +#if BME280_BUS_SPI + +LOG_MODULE_DECLARE(BME280, CONFIG_SENSOR_LOG_LEVEL); + +static int bme280_bus_check_spi(const struct device *bus, + const union bme280_bus_config *bus_config) +{ + const struct spi_cs_control *cs; + + if (!device_is_ready(bus)) { + LOG_DBG("SPI bus %s not ready", bus->name); + return -ENODEV; + } + + cs = bus_config->spi_cfg.cs; + if (cs && !device_is_ready(cs->gpio_dev)) { + LOG_DBG("SPI CS GPIO controller %s not ready", + cs->gpio_dev->name); + return -ENODEV; + } + + return 0; +} + +static int bme280_reg_read_spi(const struct device *bus, + const union bme280_bus_config *bus_config, + uint8_t start, uint8_t *buf, int size) +{ + uint8_t addr; + const struct spi_buf tx_buf = { + .buf = &addr, + .len = 1 + }; + const struct spi_buf_set tx = { + .buffers = &tx_buf, + .count = 1 + }; + struct spi_buf rx_buf[2]; + const struct spi_buf_set rx = { + .buffers = rx_buf, + .count = 2 + }; + int i; + + rx_buf[0].buf = NULL; + rx_buf[0].len = 1; + + rx_buf[1].len = 1; + + for (i = 0; i < size; i++) { + int ret; + + addr = (start + i) | 0x80; + rx_buf[1].buf = &buf[i]; + + ret = spi_transceive(bus, &bus_config->spi_cfg, &tx, &rx); + if (ret) { + LOG_DBG("spi_transceive FAIL %d\n", ret); + return ret; + } + } + + return 0; +} + +static int bme280_reg_write_spi(const struct device *bus, + const union bme280_bus_config *bus_config, + uint8_t reg, uint8_t val) +{ + uint8_t cmd[2] = { reg & 0x7F, val }; + const struct spi_buf tx_buf = { + .buf = cmd, + .len = 2 + }; + const struct spi_buf_set tx = { + .buffers = &tx_buf, + .count = 1 + }; + int ret; + + ret = spi_write(bus, &bus_config->spi_cfg, &tx); + if (ret) { + LOG_DBG("spi_write FAIL %d\n", ret); + return ret; + } + return 0; +} + +const struct bme280_bus_io bme280_bus_io_spi = { + .check = bme280_bus_check_spi, + .read = bme280_reg_read_spi, + .write = bme280_reg_write_spi, +}; +#endif /* BME280_BUS_SPI */