drivers: sensor: bme280: convert to new DT API
Make this multi-instance and use the new API. Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
parent
8b56e7a63c
commit
8aadf89579
2 changed files with 353 additions and 135 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* bmp280.c - Driver for Bosch BMP280 temperature and pressure sensor */
|
/* bme280.c - Driver for Bosch BME280 temperature and pressure sensor */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2017 Intel Corporation
|
* Copyright (c) 2016, 2017 Intel Corporation
|
||||||
|
@ -7,34 +7,140 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DT_DRV_COMPAT bosch_bme280
|
|
||||||
|
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <drivers/sensor.h>
|
#include <drivers/sensor.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <drivers/gpio.h>
|
#include <drivers/gpio.h>
|
||||||
|
#include <drivers/i2c.h>
|
||||||
|
#include <drivers/spi.h>
|
||||||
#include <sys/byteorder.h>
|
#include <sys/byteorder.h>
|
||||||
#include <sys/__assert.h>
|
#include <sys/__assert.h>
|
||||||
|
|
||||||
#if DT_ANY_INST_ON_BUS(i2c)
|
|
||||||
#include <drivers/i2c.h>
|
|
||||||
#elif DT_ANY_INST_ON_BUS(spi)
|
|
||||||
#include <drivers/spi.h>
|
|
||||||
#endif
|
|
||||||
#include <logging/log.h>
|
#include <logging/log.h>
|
||||||
|
|
||||||
#include "bme280.h"
|
#include "bme280.h"
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT bosch_bme280
|
||||||
|
|
||||||
|
#define BME280_BUS_SPI DT_ANY_INST_ON_BUS(spi)
|
||||||
|
#define BME280_BUS_I2C DT_ANY_INST_ON_BUS(i2c)
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(BME280, CONFIG_SENSOR_LOG_LEVEL);
|
LOG_MODULE_REGISTER(BME280, CONFIG_SENSOR_LOG_LEVEL);
|
||||||
|
|
||||||
static int bm280_reg_read(struct bme280_data *data,
|
#if DT_NUM_INST(DT_DRV_COMPAT) == 0
|
||||||
|
#warning "BME280 driver enabled without any devices"
|
||||||
|
#endif
|
||||||
|
|
||||||
u8_t start, u8_t *buf, int size)
|
/*
|
||||||
|
* This driver is an example of why devices should be resolvable at
|
||||||
|
* link time instead of only at runtime via device_get_binding().
|
||||||
|
*
|
||||||
|
* We only need to store 'bus' and 'spi_cs' in RAM because we can't
|
||||||
|
* resolve devices at link time. They should be moved to ROM if that
|
||||||
|
* becomes possible. That would in turn enable several further
|
||||||
|
* cleanups.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct bme280_data {
|
||||||
|
struct device *bus;
|
||||||
|
#if BME280_BUS_SPI
|
||||||
|
struct spi_cs_control spi_cs;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Compensation parameters. */
|
||||||
|
u16_t dig_t1;
|
||||||
|
s16_t dig_t2;
|
||||||
|
s16_t dig_t3;
|
||||||
|
u16_t dig_p1;
|
||||||
|
s16_t dig_p2;
|
||||||
|
s16_t dig_p3;
|
||||||
|
s16_t dig_p4;
|
||||||
|
s16_t dig_p5;
|
||||||
|
s16_t dig_p6;
|
||||||
|
s16_t dig_p7;
|
||||||
|
s16_t dig_p8;
|
||||||
|
s16_t dig_p9;
|
||||||
|
u8_t dig_h1;
|
||||||
|
s16_t dig_h2;
|
||||||
|
u8_t dig_h3;
|
||||||
|
s16_t dig_h4;
|
||||||
|
s16_t dig_h5;
|
||||||
|
s8_t dig_h6;
|
||||||
|
|
||||||
|
/* Compensated values. */
|
||||||
|
s32_t comp_temp;
|
||||||
|
u32_t comp_press;
|
||||||
|
u32_t comp_humidity;
|
||||||
|
|
||||||
|
/* Carryover between temperature and pressure/humidity compensation. */
|
||||||
|
s32_t t_fine;
|
||||||
|
|
||||||
|
u8_t chip_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bme280_spi_cfg {
|
||||||
|
struct spi_config spi_cfg;
|
||||||
|
const char *cs_gpios_label;
|
||||||
|
};
|
||||||
|
|
||||||
|
union bme280_bus_config {
|
||||||
|
#if BME280_BUS_SPI
|
||||||
|
const struct bme280_spi_cfg *spi_cfg;
|
||||||
|
#endif
|
||||||
|
#if BME280_BUS_I2C
|
||||||
|
u16_t i2c_addr;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bme280_config {
|
||||||
|
const char *bus_label;
|
||||||
|
const struct bme280_reg_io *reg_io;
|
||||||
|
const union bme280_bus_config bus_config;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int (*bme280_reg_read_fn)(struct device *bus,
|
||||||
|
const union bme280_bus_config *bus_config,
|
||||||
|
u8_t start, u8_t *buf, int size);
|
||||||
|
typedef int (*bme280_reg_write_fn)(struct device *bus,
|
||||||
|
const union bme280_bus_config *bus_config,
|
||||||
|
u8_t reg, u8_t val);
|
||||||
|
|
||||||
|
struct bme280_reg_io {
|
||||||
|
bme280_reg_read_fn read;
|
||||||
|
bme280_reg_write_fn write;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct bme280_data *to_data(struct device *dev)
|
||||||
|
{
|
||||||
|
return dev->driver_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const struct bme280_config *to_config(struct device *dev)
|
||||||
|
{
|
||||||
|
return dev->config->config_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct device *to_bus(struct device *dev)
|
||||||
|
{
|
||||||
|
return to_data(dev)->bus;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const union bme280_bus_config *to_bus_config(struct device *dev)
|
||||||
|
{
|
||||||
|
return &to_config(dev)->bus_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BME280_BUS_SPI
|
||||||
|
static inline const struct spi_config *
|
||||||
|
to_spi_config(const union bme280_bus_config *bus_config)
|
||||||
|
{
|
||||||
|
return &bus_config->spi_cfg->spi_cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bme280_reg_read_spi(struct device *bus,
|
||||||
|
const union bme280_bus_config *bus_config,
|
||||||
|
u8_t start, u8_t *buf, int size)
|
||||||
{
|
{
|
||||||
#if DT_ANY_INST_ON_BUS(i2c)
|
|
||||||
return i2c_burst_read(data->i2c_master, data->i2c_slave_addr,
|
|
||||||
start, buf, size);
|
|
||||||
#elif DT_ANY_INST_ON_BUS(spi)
|
|
||||||
u8_t addr;
|
u8_t addr;
|
||||||
const struct spi_buf tx_buf = {
|
const struct spi_buf tx_buf = {
|
||||||
.buf = &addr,
|
.buf = &addr,
|
||||||
|
@ -62,22 +168,20 @@ static int bm280_reg_read(struct bme280_data *data,
|
||||||
addr = (start + i) | 0x80;
|
addr = (start + i) | 0x80;
|
||||||
rx_buf[1].buf = &buf[i];
|
rx_buf[1].buf = &buf[i];
|
||||||
|
|
||||||
ret = spi_transceive(data->spi, &data->spi_cfg, &tx, &rx);
|
ret = spi_transceive(bus, to_spi_config(bus_config), &tx, &rx);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG_DBG("spi_transceive FAIL %d\n", ret);
|
LOG_DBG("spi_transceive FAIL %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bm280_reg_write(struct bme280_data *data, u8_t reg, u8_t val)
|
static int bme280_reg_write_spi(struct device *bus,
|
||||||
|
const union bme280_bus_config *bus_config,
|
||||||
|
u8_t reg, u8_t val)
|
||||||
{
|
{
|
||||||
#if DT_ANY_INST_ON_BUS(i2c)
|
|
||||||
return i2c_reg_write_byte(data->i2c_master, data->i2c_slave_addr,
|
|
||||||
reg, val);
|
|
||||||
#elif DT_ANY_INST_ON_BUS(spi)
|
|
||||||
u8_t cmd[2] = { reg & 0x7F, val };
|
u8_t cmd[2] = { reg & 0x7F, val };
|
||||||
const struct spi_buf tx_buf = {
|
const struct spi_buf tx_buf = {
|
||||||
.buf = cmd,
|
.buf = cmd,
|
||||||
|
@ -89,15 +193,56 @@ static int bm280_reg_write(struct bme280_data *data, u8_t reg, u8_t val)
|
||||||
};
|
};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = spi_write(data->spi, &data->spi_cfg, &tx);
|
ret = spi_write(bus, to_spi_config(bus_config), &tx);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG_DBG("spi_write FAIL %d\n", ret);
|
LOG_DBG("spi_write FAIL %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct bme280_reg_io bme280_reg_io_spi = {
|
||||||
|
.read = bme280_reg_read_spi,
|
||||||
|
.write = bme280_reg_write_spi,
|
||||||
|
};
|
||||||
|
#endif /* BME280_BUS_SPI */
|
||||||
|
|
||||||
|
#if BME280_BUS_I2C
|
||||||
|
static int bme280_reg_read_i2c(struct device *bus,
|
||||||
|
const union bme280_bus_config *bus_config,
|
||||||
|
u8_t start, u8_t *buf, int size)
|
||||||
|
{
|
||||||
|
return i2c_burst_read(bus, bus_config->i2c_addr,
|
||||||
|
start, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bme280_reg_write_i2c(struct device *bus,
|
||||||
|
const union bme280_bus_config *bus_config,
|
||||||
|
u8_t reg, u8_t val)
|
||||||
|
{
|
||||||
|
return i2c_reg_write_byte(bus, bus_config->i2c_addr,
|
||||||
|
reg, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct bme280_reg_io bme280_reg_io_i2c = {
|
||||||
|
.read = bme280_reg_read_i2c,
|
||||||
|
.write = bme280_reg_write_i2c,
|
||||||
|
};
|
||||||
|
#endif /* BME280_BUS_I2C */
|
||||||
|
|
||||||
|
static inline int bme280_reg_read(struct device *dev,
|
||||||
|
u8_t start, u8_t *buf, int size)
|
||||||
|
{
|
||||||
|
return to_config(dev)->reg_io->read(to_bus(dev), to_bus_config(dev),
|
||||||
|
start, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int bme280_reg_write(struct device *dev, u8_t reg, u8_t val)
|
||||||
|
{
|
||||||
|
return to_config(dev)->reg_io->write(to_bus(dev), to_bus_config(dev),
|
||||||
|
reg, val);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compensation code taken from BME280 datasheet, Section 4.2.3
|
* Compensation code taken from BME280 datasheet, Section 4.2.3
|
||||||
* "Compensation formula".
|
* "Compensation formula".
|
||||||
|
@ -163,7 +308,7 @@ static void bme280_compensate_humidity(struct bme280_data *data,
|
||||||
|
|
||||||
static int bme280_sample_fetch(struct device *dev, enum sensor_channel chan)
|
static int bme280_sample_fetch(struct device *dev, enum sensor_channel chan)
|
||||||
{
|
{
|
||||||
struct bme280_data *data = dev->driver_data;
|
struct bme280_data *data = to_data(dev);
|
||||||
u8_t buf[8];
|
u8_t buf[8];
|
||||||
s32_t adc_press, adc_temp, adc_humidity;
|
s32_t adc_press, adc_temp, adc_humidity;
|
||||||
int size = 6;
|
int size = 6;
|
||||||
|
@ -172,14 +317,14 @@ static int bme280_sample_fetch(struct device *dev, enum sensor_channel chan)
|
||||||
__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
|
__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
|
||||||
|
|
||||||
#ifdef CONFIG_BME280_MODE_FORCED
|
#ifdef CONFIG_BME280_MODE_FORCED
|
||||||
ret = bm280_reg_write(data, BME280_REG_CTRL_MEAS, BME280_CTRL_MEAS_VAL);
|
ret = bme280_reg_write(dev, BME280_REG_CTRL_MEAS, BME280_CTRL_MEAS_VAL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
k_sleep(K_MSEC(3));
|
k_sleep(K_MSEC(3));
|
||||||
ret = bm280_reg_read(data, BME280_REG_STATUS, buf, 1);
|
ret = bme280_reg_read(dev, BME280_REG_STATUS, buf, 1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +334,7 @@ static int bme280_sample_fetch(struct device *dev, enum sensor_channel chan)
|
||||||
if (data->chip_id == BME280_CHIP_ID) {
|
if (data->chip_id == BME280_CHIP_ID) {
|
||||||
size = 8;
|
size = 8;
|
||||||
}
|
}
|
||||||
ret = bm280_reg_read(data, BME280_REG_PRESS_MSB, buf, size);
|
ret = bme280_reg_read(dev, BME280_REG_PRESS_MSB, buf, size);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +357,7 @@ static int bme280_channel_get(struct device *dev,
|
||||||
enum sensor_channel chan,
|
enum sensor_channel chan,
|
||||||
struct sensor_value *val)
|
struct sensor_value *val)
|
||||||
{
|
{
|
||||||
struct bme280_data *data = dev->driver_data;
|
struct bme280_data *data = to_data(dev);
|
||||||
|
|
||||||
switch (chan) {
|
switch (chan) {
|
||||||
case SENSOR_CHAN_AMBIENT_TEMP:
|
case SENSOR_CHAN_AMBIENT_TEMP:
|
||||||
|
@ -254,16 +399,18 @@ static const struct sensor_driver_api bme280_api_funcs = {
|
||||||
.channel_get = bme280_channel_get,
|
.channel_get = bme280_channel_get,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int bme280_read_compensation(struct bme280_data *data)
|
static int bme280_read_compensation(struct device *dev)
|
||||||
{
|
{
|
||||||
|
struct bme280_data *data = to_data(dev);
|
||||||
u16_t buf[12];
|
u16_t buf[12];
|
||||||
u8_t hbuf[7];
|
u8_t hbuf[7];
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
err = bm280_reg_read(data, BME280_REG_COMP_START,
|
err = bme280_reg_read(dev, BME280_REG_COMP_START,
|
||||||
(u8_t *)buf, sizeof(buf));
|
(u8_t *)buf, sizeof(buf));
|
||||||
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
LOG_DBG("COMP_START read failed: %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,14 +429,16 @@ static int bme280_read_compensation(struct bme280_data *data)
|
||||||
data->dig_p9 = sys_le16_to_cpu(buf[11]);
|
data->dig_p9 = sys_le16_to_cpu(buf[11]);
|
||||||
|
|
||||||
if (data->chip_id == BME280_CHIP_ID) {
|
if (data->chip_id == BME280_CHIP_ID) {
|
||||||
err = bm280_reg_read(data, BME280_REG_HUM_COMP_PART1,
|
err = bme280_reg_read(dev, BME280_REG_HUM_COMP_PART1,
|
||||||
&data->dig_h1, 1);
|
&data->dig_h1, 1);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
LOG_DBG("HUM_COMP_PART1 read failed: %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bm280_reg_read(data, BME280_REG_HUM_COMP_PART2, hbuf, 7);
|
err = bme280_reg_read(dev, BME280_REG_HUM_COMP_PART2, hbuf, 7);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
LOG_DBG("HUM_COMP_PART2 read failed: %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,113 +454,226 @@ static int bme280_read_compensation(struct bme280_data *data)
|
||||||
|
|
||||||
static int bme280_chip_init(struct device *dev)
|
static int bme280_chip_init(struct device *dev)
|
||||||
{
|
{
|
||||||
struct bme280_data *data = (struct bme280_data *) dev->driver_data;
|
struct bme280_data *data = to_data(dev);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = bm280_reg_read(data, BME280_REG_ID, &data->chip_id, 1);
|
err = bme280_reg_read(dev, BME280_REG_ID, &data->chip_id, 1);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
LOG_DBG("ID read failed: %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->chip_id == BME280_CHIP_ID) {
|
if (data->chip_id == BME280_CHIP_ID) {
|
||||||
LOG_DBG("BME280 chip detected");
|
LOG_DBG("ID OK");
|
||||||
} else if (data->chip_id == BMP280_CHIP_ID_MP ||
|
} else if (data->chip_id == BMP280_CHIP_ID_MP ||
|
||||||
data->chip_id == BMP280_CHIP_ID_SAMPLE_1) {
|
data->chip_id == BMP280_CHIP_ID_SAMPLE_1) {
|
||||||
LOG_DBG("BMP280 chip detected");
|
LOG_DBG("ID OK (BMP280)");
|
||||||
} else {
|
} else {
|
||||||
LOG_DBG("bad chip id 0x%x", data->chip_id);
|
LOG_DBG("bad chip id 0x%x", data->chip_id);
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bme280_read_compensation(data);
|
err = bme280_read_compensation(dev);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->chip_id == BME280_CHIP_ID) {
|
if (data->chip_id == BME280_CHIP_ID) {
|
||||||
err = bm280_reg_write(data, BME280_REG_CTRL_HUM,
|
err = bme280_reg_write(dev, BME280_REG_CTRL_HUM,
|
||||||
BME280_HUMIDITY_OVER);
|
BME280_HUMIDITY_OVER);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
LOG_DBG("CTRL_HUM write failed: %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bm280_reg_write(data, BME280_REG_CTRL_MEAS, BME280_CTRL_MEAS_VAL);
|
err = bme280_reg_write(dev, BME280_REG_CTRL_MEAS,
|
||||||
|
BME280_CTRL_MEAS_VAL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
LOG_DBG("CTRL_MEAS write failed: %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bm280_reg_write(data, BME280_REG_CONFIG, BME280_CONFIG_VAL);
|
err = bme280_reg_write(dev, BME280_REG_CONFIG,
|
||||||
|
BME280_CONFIG_VAL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
LOG_DBG("CONFIG write failed: %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DT_ANY_INST_ON_BUS(spi)
|
#if BME280_BUS_SPI
|
||||||
static inline int bme280_spi_init(struct bme280_data *data)
|
static inline int bme280_is_on_spi(struct device *dev)
|
||||||
{
|
{
|
||||||
data->spi = device_get_binding(DT_INST_BUS_LABEL(0));
|
return to_config(dev)->reg_io == &bme280_reg_io_spi;
|
||||||
if (!data->spi) {
|
}
|
||||||
LOG_DBG("spi device not found: %s",
|
|
||||||
DT_INST_BUS_LABEL(0));
|
static inline int bme280_spi_init(struct device *dev)
|
||||||
return -EINVAL;
|
{
|
||||||
|
struct bme280_data *data = to_data(dev);
|
||||||
|
const struct bme280_spi_cfg *spi_cfg = to_bus_config(dev)->spi_cfg;
|
||||||
|
|
||||||
|
if (spi_cfg->cs_gpios_label != NULL) {
|
||||||
|
data->spi_cs.gpio_dev = device_get_binding(
|
||||||
|
spi_cfg->cs_gpios_label);
|
||||||
|
if (!data->spi_cs.gpio_dev) {
|
||||||
|
LOG_DBG("can't get GPIO SPI CS device %s",
|
||||||
|
spi_cfg->cs_gpios_label);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG_DBG("no chip select set");
|
||||||
}
|
}
|
||||||
|
|
||||||
data->spi_cfg.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB |
|
return 0;
|
||||||
SPI_MODE_CPOL | SPI_MODE_CPHA;
|
}
|
||||||
data->spi_cfg.frequency = DT_INST_PROP(0, spi_max_frequency);
|
#else
|
||||||
data->spi_cfg.slave = DT_INST_REG_ADDR(0);
|
static inline int bme280_is_on_spi(struct device *dev)
|
||||||
|
{
|
||||||
#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
|
return 0;
|
||||||
data->spi_cs_control.gpio_dev =
|
}
|
||||||
device_get_binding(DT_INST_SPI_DEV_CS_GPIOS_LABEL(0));
|
|
||||||
if (!data->spi_cs_control.gpio_dev) {
|
|
||||||
LOG_ERR("Unable to get GPIO SPI CS device");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->spi_cs_control.gpio_pin = DT_INST_SPI_DEV_CS_GPIOS_PIN(0);
|
|
||||||
data->spi_cs_control.delay = 0U;
|
|
||||||
|
|
||||||
data->spi_cfg.cs = &data->spi_cs_control;
|
|
||||||
#endif /* DT_INST_SPI_DEV_HAS_CS_GPIOS(0) */
|
|
||||||
|
|
||||||
|
static inline int bme280_spi_init(struct device *dev)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int bme280_init(struct device *dev)
|
int bme280_init(struct device *dev)
|
||||||
{
|
{
|
||||||
struct bme280_data *data = dev->driver_data;
|
const char *name = dev->config->name;
|
||||||
|
struct bme280_data *data = to_data(dev);
|
||||||
|
const struct bme280_config *config = to_config(dev);
|
||||||
|
int rc;
|
||||||
|
|
||||||
#if DT_ANY_INST_ON_BUS(i2c)
|
LOG_DBG("initializing %s", name);
|
||||||
data->i2c_master = device_get_binding(DT_INST_BUS_LABEL(0));
|
|
||||||
if (!data->i2c_master) {
|
data->bus = device_get_binding(config->bus_label);
|
||||||
LOG_DBG("i2c master not found: %s",
|
if (!data->bus) {
|
||||||
DT_INST_BUS_LABEL(0));
|
LOG_DBG("bus \"%s\" not found", config->bus_label);
|
||||||
return -EINVAL;
|
rc = -EINVAL;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->i2c_slave_addr = DT_INST_REG_ADDR(0);
|
if (bme280_is_on_spi(dev)) {
|
||||||
#elif DT_ANY_INST_ON_BUS(spi)
|
rc = bme280_spi_init(dev);
|
||||||
if (bme280_spi_init(data) < 0) {
|
if (rc < 0) {
|
||||||
LOG_DBG("spi master not found: %s",
|
rc = -EINVAL;
|
||||||
DT_INST_BUS_LABEL(0));
|
goto done;
|
||||||
return -EINVAL;
|
}
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (bme280_chip_init(dev) < 0) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
rc = bme280_chip_init(dev);
|
||||||
|
if (rc < 0) {
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (rc == 0) {
|
||||||
|
LOG_DBG("%s OK", name);
|
||||||
|
} else {
|
||||||
|
LOG_DBG("%s failed", name);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct bme280_data bme280_data;
|
/*
|
||||||
|
* Device creation macro, shared by BME280_DEFINE_SPI() and
|
||||||
|
* BME280_DEFINE_I2C().
|
||||||
|
*/
|
||||||
|
|
||||||
DEVICE_AND_API_INIT(bme280, DT_INST_LABEL(0), bme280_init, &bme280_data,
|
#define BME280_DEVICE_INIT(inst) \
|
||||||
NULL, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,
|
DEVICE_AND_API_INIT(bme280_##inst, \
|
||||||
&bme280_api_funcs);
|
DT_INST_LABEL(inst), \
|
||||||
|
bme280_init, \
|
||||||
|
&bme280_data_##inst, \
|
||||||
|
&bme280_config_##inst, \
|
||||||
|
POST_KERNEL, \
|
||||||
|
CONFIG_SENSOR_INIT_PRIORITY, \
|
||||||
|
&bme280_api_funcs)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Instantiation macros used when a device is on a SPI bus.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BME280_HAS_CS(inst) DT_INST_SPI_DEV_HAS_CS_GPIOS(inst)
|
||||||
|
|
||||||
|
#define BME280_DATA_SPI_CS(inst) \
|
||||||
|
{ .spi_cs = { .gpio_pin = DT_INST_SPI_DEV_CS_GPIOS_PIN(inst), }, }
|
||||||
|
|
||||||
|
#define BME280_DATA_SPI(inst) \
|
||||||
|
COND_CODE_1(BME280_HAS_CS(inst), \
|
||||||
|
(BME280_DATA_SPI_CS(inst)), \
|
||||||
|
({}))
|
||||||
|
|
||||||
|
#define BME280_SPI_CS_PTR(inst) \
|
||||||
|
COND_CODE_1(BME280_HAS_CS(inst), \
|
||||||
|
(&(bme280_data_##inst.spi_cs)), \
|
||||||
|
(NULL))
|
||||||
|
|
||||||
|
#define BME280_SPI_CS_LABEL(inst) \
|
||||||
|
COND_CODE_1(BME280_HAS_CS(inst), \
|
||||||
|
(DT_INST_SPI_DEV_CS_GPIOS_LABEL(inst)), (NULL))
|
||||||
|
|
||||||
|
#define BME280_SPI_CFG(inst) \
|
||||||
|
(&(struct bme280_spi_cfg) { \
|
||||||
|
.spi_cfg = { \
|
||||||
|
.frequency = \
|
||||||
|
DT_INST_PROP(inst, spi_max_frequency), \
|
||||||
|
.operation = (SPI_WORD_SET(8) | \
|
||||||
|
SPI_TRANSFER_MSB | \
|
||||||
|
SPI_MODE_CPOL | \
|
||||||
|
SPI_MODE_CPHA), \
|
||||||
|
.slave = DT_INST_REG_ADDR(inst), \
|
||||||
|
.cs = BME280_SPI_CS_PTR(inst), \
|
||||||
|
}, \
|
||||||
|
.cs_gpios_label = BME280_SPI_CS_LABEL(inst), \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define BME280_CONFIG_SPI(inst) \
|
||||||
|
{ \
|
||||||
|
.bus_label = DT_INST_BUS_LABEL(inst), \
|
||||||
|
.reg_io = &bme280_reg_io_spi, \
|
||||||
|
.bus_config = { .spi_cfg = BME280_SPI_CFG(inst) } \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BME280_DEFINE_SPI(inst) \
|
||||||
|
static struct bme280_data bme280_data_##inst = \
|
||||||
|
BME280_DATA_SPI(inst); \
|
||||||
|
static const struct bme280_config bme280_config_##inst = \
|
||||||
|
BME280_CONFIG_SPI(inst); \
|
||||||
|
BME280_DEVICE_INIT(inst)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Instantiation macros used when a device is on an I2C bus.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BME280_CONFIG_I2C(inst) \
|
||||||
|
{ \
|
||||||
|
.bus_label = DT_INST_BUS_LABEL(inst), \
|
||||||
|
.reg_io = &bme280_reg_io_i2c, \
|
||||||
|
.bus_config = { .i2c_addr = DT_INST_REG_ADDR(inst), } \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BME280_DEFINE_I2C(inst) \
|
||||||
|
static struct bme280_data bme280_data_##inst; \
|
||||||
|
static const struct bme280_config bme280_config_##inst = \
|
||||||
|
BME280_CONFIG_I2C(inst); \
|
||||||
|
BME280_DEVICE_INIT(inst)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main instantiation macro. Use of COND_CODE_1() selects the right
|
||||||
|
* bus-specific macro at preprocessor time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BME280_DEFINE(inst) \
|
||||||
|
COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
|
||||||
|
(BME280_DEFINE_SPI(inst)), \
|
||||||
|
(BME280_DEFINE_I2C(inst)))
|
||||||
|
|
||||||
|
DT_INST_FOREACH(BME280_DEFINE);
|
||||||
|
|
|
@ -108,48 +108,4 @@
|
||||||
BME280_FILTER | \
|
BME280_FILTER | \
|
||||||
BME280_SPI_3W_DISABLE)
|
BME280_SPI_3W_DISABLE)
|
||||||
|
|
||||||
struct bme280_data {
|
|
||||||
#if DT_ANY_INST_ON_BUS(i2c)
|
|
||||||
struct device *i2c_master;
|
|
||||||
u16_t i2c_slave_addr;
|
|
||||||
#elif DT_ANY_INST_ON_BUS(spi)
|
|
||||||
struct device *spi;
|
|
||||||
struct spi_config spi_cfg;
|
|
||||||
#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
|
|
||||||
struct spi_cs_control spi_cs_control;
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#error "BME280 device type not specified"
|
|
||||||
#endif
|
|
||||||
/* Compensation parameters. */
|
|
||||||
u16_t dig_t1;
|
|
||||||
s16_t dig_t2;
|
|
||||||
s16_t dig_t3;
|
|
||||||
u16_t dig_p1;
|
|
||||||
s16_t dig_p2;
|
|
||||||
s16_t dig_p3;
|
|
||||||
s16_t dig_p4;
|
|
||||||
s16_t dig_p5;
|
|
||||||
s16_t dig_p6;
|
|
||||||
s16_t dig_p7;
|
|
||||||
s16_t dig_p8;
|
|
||||||
s16_t dig_p9;
|
|
||||||
u8_t dig_h1;
|
|
||||||
s16_t dig_h2;
|
|
||||||
u8_t dig_h3;
|
|
||||||
s16_t dig_h4;
|
|
||||||
s16_t dig_h5;
|
|
||||||
s8_t dig_h6;
|
|
||||||
|
|
||||||
/* Compensated values. */
|
|
||||||
s32_t comp_temp;
|
|
||||||
u32_t comp_press;
|
|
||||||
u32_t comp_humidity;
|
|
||||||
|
|
||||||
/* Carryover between temperature and pressure/humidity compensation. */
|
|
||||||
s32_t t_fine;
|
|
||||||
|
|
||||||
u8_t chip_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* ZEPHYR_DRIVERS_SENSOR_BME280_BME280_H_ */
|
#endif /* ZEPHYR_DRIVERS_SENSOR_BME280_BME280_H_ */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue