drivers: sensor: bme680: Add SPI interface

This enables the SPI interface for the BME680 sensor driver.

Signed-off-by: Leonard Pollak <leonardp@tr-host.de>
This commit is contained in:
Leonard Pollak 2022-02-20 10:09:56 +01:00 committed by Carles Cufí
commit 35b55175cc
7 changed files with 308 additions and 28 deletions

View file

@ -11,33 +11,49 @@
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT bosch_bme680
#include "bme680.h"
#include <drivers/gpio.h>
#include <drivers/i2c.h>
#include <init.h>
#include <kernel.h>
#include <sys/byteorder.h>
#include <sys/__assert.h>
#include <drivers/sensor.h>
#include <logging/log.h>
#include "bme680.h"
LOG_MODULE_REGISTER(bme680, CONFIG_SENSOR_LOG_LEVEL);
static int bme680_reg_read(const struct device *dev, uint8_t start,
uint8_t *buf, int size)
#if BME680_BUS_SPI
static inline bool bme680_is_on_spi(const struct device *dev)
{
const struct bme680_config *config = dev->config;
return i2c_burst_read_dt(&config->bus, start, buf, size);
return config->bus_io == &bme680_bus_io_spi;
}
#endif
static inline int bme680_bus_check(const struct device *dev)
{
const struct bme680_config *config = dev->config;
return config->bus_io->check(&config->bus);
}
static int bme680_reg_write(const struct device *dev, uint8_t reg, uint8_t val)
static inline int bme680_reg_read(const struct device *dev,
uint8_t start, uint8_t *buf, int size)
{
const struct bme680_config *config = dev->config;
return i2c_reg_write_byte_dt(&config->bus, reg, val);
return config->bus_io->read(dev, start, buf, size);
}
static inline int bme680_reg_write(const struct device *dev, uint8_t reg,
uint8_t val)
{
const struct bme680_config *config = dev->config;
return config->bus_io->write(dev, reg, val);
}
static void bme680_calc_temp(struct bme680_data *data, uint32_t adc_temp)
@ -346,14 +362,23 @@ static int bme680_read_compensation(const struct device *dev)
static int bme680_init(const struct device *dev)
{
struct bme680_data *data = dev->data;
const struct bme680_config *config = dev->config;
int err;
if (!device_is_ready(config->bus.bus)) {
LOG_ERR("I2C master %s not ready", config->bus.bus->name);
return -EINVAL;
err = bme680_bus_check(dev);
if (err < 0) {
LOG_ERR("Bus not ready for '%s'", dev->name);
return err;
}
#if BME680_BUS_SPI
if (bme680_is_on_spi(dev)) {
err = bme680_reg_read(dev, BME680_REG_MEM_PAGE, &data->mem_page, 1);
if (err < 0) {
return err;
}
}
#endif
err = bme680_reg_read(dev, BME680_REG_CHIP_ID, &data->chip_id, 1);
if (err < 0) {
return err;
@ -410,12 +435,39 @@ static const struct sensor_driver_api bme680_api_funcs = {
.channel_get = bme680_channel_get,
};
static struct bme680_data bme680_data;
/* Initializes a struct bme680_config for an instance on a SPI bus. */
#define BME680_CONFIG_SPI(inst) \
{ \
.bus.spi = SPI_DT_SPEC_INST_GET( \
inst, BME680_SPI_OPERATION, 0), \
.bus_io = &bme680_bus_io_spi, \
}
static const struct bme680_config bme680_config = {
.bus = I2C_DT_SPEC_INST_GET(0)
};
/* Initializes a struct bme680_config for an instance on an I2C bus. */
#define BME680_CONFIG_I2C(inst) \
{ \
.bus.i2c = I2C_DT_SPEC_INST_GET(inst), \
.bus_io = &bme680_bus_io_i2c, \
}
DEVICE_DT_INST_DEFINE(0, bme680_init, NULL, &bme680_data,
&bme680_config, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,
&bme680_api_funcs);
/*
* Main instantiation macro, which selects the correct bus-specific
* instantiation macros for the instance.
*/
#define BME680_DEFINE(inst) \
static struct bme680_data bme680_data_##inst; \
static const struct bme680_config bme680_config_##inst = \
COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
(BME680_CONFIG_SPI(inst)), \
(BME680_CONFIG_I2C(inst))); \
DEVICE_DT_INST_DEFINE(inst, \
bme680_init, \
NULL, \
&bme680_data_##inst, \
&bme680_config_##inst, \
POST_KERNEL, \
CONFIG_SENSOR_INIT_PRIORITY, \
&bme680_api_funcs);
/* Create the struct device for every status "okay" node in the devicetree. */
DT_INST_FOREACH_STATUS_OKAY(BME680_DEFINE)