1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/drivers/include/bme680.h
Marian Buschsieweke edc43201db
tree-wide: fix typos in doc and comments
This should not change any generated binary
2023-10-16 12:17:48 +02:00

326 lines
11 KiB
C

/*
* Copyright (C) 2019 Mesotic SAS
* 2020 Gunar Schorcht
*
* 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.
*/
/**
* @defgroup drivers_bme680 BME680 Temperature/Humidity/Pressure/Gas sensor
* @ingroup drivers_sensors
* @brief Driver for the Bosch BME680 sensor
*
* ### Introduction
*
* The driver allows the use of BME680 sensors connected either via I2C or SPI.
* Instead of implementing a complete driver, it simply uses the
* [BME680 vendor driver](https://github.com/BoschSensortec/BME680_driver)
* written and maintained by Bosch Sensortec as a package.
*
* Even though this driver interface provides an easy-to-use API, the vendor's
* driver API can still be used directly. This becomes necessary, for example,
* if the settings of the ambient temperature have to be updated from
* measurements with other sensors for gas measurement.
*
* All functions of the vendor's driver API require a reference to a
* sensor device structure of type `struct bme680_dev`. Use macro
* @ref BME680_SENSOR(dev) for a given device descriptor of type
* @ref bme680_t to the according sensor device structure of type
* `struct bme680_dev`, for example:
*
* ```c
* bme680_t dev;
* ...
* BME680_SENSOR(dev).amb_temp = value_from_other_sensor;
* bme680_set_sensor_settings(BME680_GAS_MEAS_SEL, &BME680_SENSOR(dev));
* ```
*
* Refer to the code documentation at
* [GitHub](https://github.com/BoschSensortec/BME680_driver)
* for detailed information on the API of the vendor driver.
*
* ### Sensor Operation Modes
*
* The BME680 sensor supports only two modes, sleep mode and forced mode, in
* which measurements are taken. After the power-on sequence, the sensor
* automatically starts in sleep mode. To start a measurement, the sensor
* must switch to forced mode. In this mode it performs exactly one
* measurement of temperature, pressure, humidity and gas in this order, the
* so-called TPHG measurement cycle. After executing this TPHG measurement
* cycle, the raw data from the sensor is available and the sensor
* automatically returns to sleep mode
*
* ### Ambient Temperature
*
* The sensor is initialized with a fixed ambient temperature defined by the
* parameter settings in @ref bme680_params. However, precise gas measurements
* require the calculation of the heating resistance based on the ambient
* temperature.
*
* The temperature of the internal temperature sensor is typically higher
* than the actual ambient temperature due to the self-heating of the sensor.
* element. It should therefore not be used to set the ambient temperature
* unless gas measurements are very infrequent and self-heating is negligible.
* Rather another temperature sensor should be used for that purpose.
*
* Function @ref bme680_set_ambient_temp can be used to change the ambient
* temperature.
*
* ### Using the Sensor
*
* Using the BME680 consists of the following steps
*
* 1. Trigger the sensor with @ref bme680_force_measurement to change to the
* forced mode and perform a THPG cycle.
* 2. Wait at least the time returned by @ref bme680_get_duration until the
* THPG cycle is finished.
* 3. Use @ref bme680_get_data to fetch raw sensor data and convert them to the
* resulting sensor values
*
* ### Driver Configuration
*
* BME680 sensors are connected either via I2C or SPI. Which interface is used
* by which BME680 sensor is defined by the parameters in @ref bme680_params.
* The respective driver implementation is enabled by the modules `bme680_i2c`
* and `bme680_spi`. Several BME680 sensors and a mixed configuration of I2C
* and SPI can be used in one application.
* ```
* USEMODULE='bme680_spi bme680_i2c' make BOARD=... -C tests/drivers/bme680
* ```
*
* The vendor driver allows the use of floating point conversions. In order
* to use these floating point conversions, module `bme680_fp` has to
* be enabled:
* ```
* USEMODULE='bme680_fp bme680_i2c' make BOARD=... -C tests/drivers/bme680
* ```
*
* @{
* @file
* @brief Interface definition for the Bosch BME680 sensor
*
* @author Dylan Laduranty <dylan.laduranty@mesotic.com>
* @author Gunar Schorcht <gunar@schorcht.net>
*/
#ifndef BME680_H
#define BME680_H
#include "periph/i2c.h"
#include "periph/spi.h"
#ifdef MODULE_BME680_FP
#define BME680_FLOAT_POINT_COMPENSATION
#endif
#include "bme680_hal.h"
#include "bme680_internal.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief I2C address when SDO pin is LOW
*/
#define BME680_I2C_ADDR_1 (0x76)
/**
* @brief I2C address when SDO pin is HIGH
*/
#define BME680_I2C_ADDR_2 (0x77)
/**
* @brief Converts a BME680 device descriptor to the BME680 sensor device
* structure for the vendor BME680 device driver.
*/
#define BME680_SENSOR(d) (*((struct bme680_dev *)d))
/**
* @brief Named return values
*/
enum {
BME680_NULL_PTR = -1, /**< NULL pointer check failed. */
BME680_COM_FAILED = -2, /**< Communication with the device failed. */
BME680_NO_DEV = -3, /**< Device doesn't exist. */
BME680_INVALID = -4, /**< Invalid value or length. */
BME680_NO_NEW_DATA = -5, /**< No new data. */
};
#ifdef DOXYGEN
/**
* @brief BME680 sensor field data
*/
typedef struct bme680_field_data {
uint8_t status; /**< Status for new data, gas measurement valid and
heater stable. Use `BME680_NEW_DATA_MSK`,
`BME680_GASM_VALID_MSK` and BME680_HEAT_STAB_MSK
to check for the status. */
uint8_t gas_index; /**< Index of used heater profile */
uint8_t meas_index; /**< Measurement index */
#ifndef MODULE_BME680_FP
int16_t temperature; /**< Temperature in degree Celsius x 100 */
uint32_t pressure; /**< Pressure in Pascal */
uint32_t humidity; /**< Relative humidity in percent x 1000 */
uint32_t gas_resistance; /**< Gas resistance in ohms */
#else /* MODULE_BME680_FP */
float temperature; /**< Temperature in degree Celsius */
float pressure; /**< Pressure in Pascal */
float humidity; /**< Relative humidity in percent */
float gas_resistance; /**< Gas resistance in ohms */
#endif /* MODULE_BME680_FP */
};
#endif /* DOXYGEN */
/**
* @brief Shortcut type definition for BME680 sensor field data
*/
typedef struct bme680_field_data bme680_field_data_t;
/**
* @brief Shortcut type definition for BME680 sensor device structure
* @see [struct bme680_dev](https://github.com/BoschSensortec/BME680_driver/blob/9014031fa00a5cc1eea1498c4cd1f94ec4b8ab11/bme680_defs.h#L496-L530)
*/
typedef struct bme680_dev bme680_dev_t;
/**
* @brief BME680 I2C parameters
*/
typedef struct {
i2c_t dev; /**< I2C device which is used */
uint8_t addr; /**< I2C address */
} bme680_intf_i2c_t;
/**
* @brief BME680 SPI parameters
*/
typedef struct {
spi_t dev; /**< SPI device which is used */
gpio_t nss_pin; /**< Chip Select pin */
} bme680_intf_spi_t;
/**
* @brief BME680 Hardware interface parameters union
*/
typedef union {
bme680_intf_i2c_t i2c; /**< I2C specific interface parameters */
bme680_intf_spi_t spi; /**< SPI specific interface parameters */
} bme680_intf_t;
/**
* @brief BME680 device initialization parameters
*/
typedef struct {
uint8_t ifsel; /**< Interface selection */
uint8_t temp_os; /**< Temperature oversampling */
uint8_t hum_os; /**< Humidity oversampling */
uint8_t pres_os; /**< Pressure oversampling */
uint8_t filter; /**< IIR filter coefficient */
uint8_t gas_measure; /**< Enable gas measurement */
uint16_t heater_dur; /**< Heater duration in ms */
uint16_t heater_temp; /**< Heater temperature in °C */
uint8_t power_mode; /**< Power mode (sleep or forced) */
uint8_t settings; /**< Settings used */
bme680_intf_t intf; /**< Hardware interface parameters */
} bme680_params_t;
/**
* @brief BME680 device descriptor
*/
typedef struct {
struct bme680_dev sensor; /**< Inherited device structure from vendor API */
bme680_intf_t intf; /**< Device interface */
} bme680_t;
/**
* @brief References to BME680 sensor devices used by the HAL functions
*/
extern bme680_t *bme680_devs[];
/**
* @brief Number of initialized BME680 sensor devices in bme680_devs
*/
extern unsigned int bme680_devs_numof;
/**
* @brief Initialize the BME680 sensor.
*
* @param[in,out] dev device descriptor of the sensor to initialize
* @param[in] params configuration parameters
*
* @return 0 on success
* @return < 0 on error
*/
int bme680_init(bme680_t *dev, const bme680_params_t *params);
/**
* @brief Force a single TPHG measurement cycle
*
* The function triggers the sensor to start one THPG measurement cycle. The
* duration of the TPHG measurement cycle depends on the selected parameters.
* It can vary from 1.25 ms to 4.5 seconds. The duration of the measurement
* cycle can be determined with the #bme680_get_duration function.
*
* @param[in,out] dev device descriptor of the sensor
*
* @return 0 on success
* @return < 0 on error
*/
int bme680_force_measurement(bme680_t *dev);
/**
* @brief Duration one THPG measurement cycle
*
* This function determines the duration of one THPG measurement cycle
* according to the selected parameter settings. The duration can be used
* to wait for the measurement results once a THPG measurement has been
* started with #bme680_force_measurement.
*
* @param[in,out] dev device descriptor of the sensor
*
* @return duration of one THPG measurement cycle in milliseconds.
* @return < 0 on error
*/
int bme680_get_duration(bme680_t* dev);
/**
* @brief Get results of a TPHG measurement
*
* The function returns the results of a TPHG measurement that has been
* started before with #bme680_force_measurement. For that purpose, the
* function fetches the raw sensor data and converts them into sensor values.
* If the measurement is still running, the function fails and returns
* invalid values.
*
* @param[in,out] dev device descriptor of the sensor
* @param[out] data pointer to a data structure with the field data
*
* @return 0 on success
* @return < 0 on error
*/
int bme680_get_data(bme680_t* dev, bme680_field_data_t *data);
/**
* @brief Set the ambient temperature
*
* The function sets the ambient temperature for the calculation of the heater
* resistance.
*
* @param[in,out] dev device descriptor of the sensor
* @param[in] temp ambient temperature in degC.
*
* @return 0 on success
* @return < 0 on error
*/
int bme680_set_ambient_temp(bme680_t* dev, int8_t temp);
#ifdef __cplusplus
}
#endif
#endif /* BME680_H */
/** @} */