1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/drivers/include/ccs811.h
2021-12-04 13:43:31 +01:00

408 lines
15 KiB
C

/*
* Copyright (C) 2018 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.
*/
/**
* @ingroup drivers_ccs811
* @brief Device Driver for AMS CCS811 digital gas sensor
* @author Gunar Schorcht <gunar@schorcht.net>
* @file
* @{
*/
#ifndef CCS811_H
#define CCS811_H
#include <stdint.h>
#include "periph/gpio.h"
#include "periph/i2c.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @name CCS811 I2C addresses
* @{
*/
#define CCS811_I2C_ADDRESS_1 (0x5A) /**< default */
#define CCS811_I2C_ADDRESS_2 (0x5B)
/** @} */
/**
* @name CCS811 IAQ value ranges
* @{
*/
#define CCS811_ECO2_RANGE_MIN (400) /**< eCO2 min in ppm */
#define CCS811_ECO2_RANGE_MAX (8192) /**< eCO2 max in ppm */
#define CCS811_TVOC_RANGE_MIN (0) /**< TVOC min in ppb */
#define CCS811_TVOC_RANGE_MAX (1187) /**< TVOC min in ppb */
/** @} */
/**
* @brief Driver error codes (returned as negative values)
*/
typedef enum {
CCS811_OK, /**< no error */
CCS811_ERROR_I2C, /**< I2C communication failure */
CCS811_ERROR_NO_DEV, /**< device not available */
CCS811_ERROR_NO_APP, /**< could not start application */
CCS811_ERROR_NO_NEW_DATA, /**< no new data (last valid data returned) */
CCS811_ERROR_NO_IAQ_DATA, /**< IAQ data not available in this mode */
CCS811_ERROR_WRITE_REG_INV, /**< invalid register address on write */
CCS811_ERROR_READ_REG_INV, /**< invalid register address on read */
CCS811_ERROR_MEASMODE_INV, /**< invalid measurement mode */
CCS811_ERROR_THRESH_INV, /**< invalid threshold parameters */
CCS811_ERROR_MAX_RESISTANCE, /**< maximum sensor resistance exceeded */
CCS811_ERROR_HEATER_FAULT, /**< heater current not in range */
CCS811_ERROR_HEATER_SUPPLY, /**< heater voltage not applied correctly */
CCS811_ERROR_NO_INT_PIN, /**< nINT signal pin not configured */
CCS811_ERROR_NO_WAKE_PIN, /**< nWAKE signal pin not configured */
CCS811_ERROR_NO_RESET_PIN, /**< nRESET signal pin not configured */
CCS811_ERROR_NOT_SUPPORTED, /**< function is not supported */
} ccs811_error_codes_t;
/**
* @brief CCS811 operation modes
*/
typedef enum {
CCS811_MODE_IDLE = 0, /**< Idle, low current mode */
CCS811_MODE_1S = 1, /**< Constant Power mode, IAQ values every 1 s */
CCS811_MODE_10S = 2, /**< Pulse Heating mode, IAQ values every 10 s */
CCS811_MODE_60S = 3, /**< Low Power Pulse Heating, IAQ values every 60 s */
CCS811_MODE_250MS = 4 /**< Constant Power mode, only RAW data every 250 ms */
} ccs811_mode_t;
/**
* @brief CCS811 interrupt mode
*/
typedef enum {
CCS811_INT_NONE = 0, /**< interrupt generation is disabled (default) */
CCS811_INT_DATA_READY, /**< nINT signal when new data are reade to read */
CCS811_INT_THRESHOLD, /**< nINT signal when new data reach thresholds */
} ccs811_int_mode_t;
/**
* @brief CCS811 device initialization parameters
*/
typedef struct {
i2c_t i2c_dev; /**< I2C device, clock stretching required (default I2C_DEV(0)) */
uint8_t i2c_addr; /**< I2C address (default CCS811_I2C_ADDRESS_1) */
ccs811_mode_t mode; /**< measurement mode used (default #CCS811_MODE_IDLE) */
#if MODULE_CCS811_FULL || DOXYGEN
gpio_t int_pin; /**< nINT signal pin (default GPIO_PIN(0, 0) */
ccs811_int_mode_t int_mode; /**< interrupt mode used (default #CCS811_INT_NONE) */
#endif
gpio_t wake_pin; /**< nWAKE signal pin (default GPIO_UNDEF) */
gpio_t reset_pin; /**< nRESET signal pin (default GPIO_UNDEF) */
} ccs811_params_t;
/**
* @brief CCS811 sensor device data structure
*/
typedef struct {
ccs811_params_t params; /**< device initialization parameters */
} ccs811_t;
/**
* @brief Initialize a CCS811 sensor device
*
* The function resets the CCS811 sensor, checks its availability and
* initializes it according to the given configuration parameters.
*
* If #ccs811_params_t::reset_pin is configured
* - the pin is used for the hardware reset of the sensor, otherwise
* only a software reset is tried, and
* - the #ccs811_init function can be used at any time to reset the sensor.
*
* If #ccs811_params_t::wake_pin is configured, it use to switch the sensor
* into the sleep mode while the I2C interface is not used.
*
* @param[in] dev Device descriptor of CCS811 device to be initialized
* @param[in] params Configuration parameters used by initialization
*
* @note The I2C implementation of the MCU has to support clock stretching
* to get CCS811 working.
*
* @retval CCS811_OK on success
* @retval CCS811_ERROR_* on error, see #ccs811_error_codes_t
*/
int ccs811_init (ccs811_t *dev, const ccs811_params_t *params);
/**
* @brief Read IAQ sensor values and/or RAW sensor data
*
* The function reads the IAQ sensor values (TVOC and eCO2) and/or the raw
* sensor data. For either \p iaq_tvoc2, \p iaq_eco2, \p raw_i, or \p raw_v
* also `NULL` can be passed, if their value are not of interest.
*
* @note
* - If the function is called and no new data are available, the function
* returns the results of the last measurement.
* - The data-ready status function #ccs811_data_ready or the data-ready
* interrupt (#CCS811_INT_DATA_READY) can be used to determine whether
* new data are available.
* - In #CCS811_MODE_250MS, only RAW data are available. In
* that case, the function fails with error_code #CCS811_ERROR_NO_IAQ_DATA
* if \p iaq_tvoc and \p iaq_eco2 parameters are not `NULL`.
*
* @param[in] dev Device descriptor of CCS811 device to read from
* @param[out] iaq_tvoc TVOC total volatile organic compound (0..1187 ppb)
* @param[out] iaq_eco2 eCO2 equivalent CO2 (400 - 8192 ppm)
* @param[out] raw_i Current through the sensor used for measuring (0..63 uA)
* @param[out] raw_v Voltage across the sensor measured (0..1023 = 1.65 V)
*
* @retval CCS811_OK on success and new data are returned
* @retval CCS811_ERROR_* otherwise, see #ccs811_error_codes_t.
*/
int ccs811_read_iaq (const ccs811_t *dev,
uint16_t *iaq_tvoc, uint16_t *iaq_eco2,
uint16_t *raw_i, uint16_t *raw_v);
#if MODULE_CCS811_FULL || DOXYGEN
/**
* @brief Read the resistance of connected NTC thermistor
*
* CCS811 supports an external interface for connecting a negative thermal
* coefficient thermistor (R_NTC) to provide a cost effective and power
* efficient means of calculating the local ambient temperature. The sensor
* measures the voltage V_NTC across the R_NTC as well as the voltage V_REF
* across a connected reference resistor (R_REF).
*
* The function returns the current resistance of R_NTC using the equation
*
* R_NTC = R_REF / V_REF * V_NTC
*
* Using the data sheet of the NTC, the ambient temperature can be calculated.
*
* @param[in] dev Device descriptor of CCS811 device to read from
* @param[in] r_ref Resistance of R_REF in Ohm
* @param[out] r_ntc Resistance of R_NTC in Ohm
*
* @retval CCS811_OK on success
* @retval CCS811_ERROR_* on error, see #ccs811_error_codes_t
*/
int ccs811_read_ntc (const ccs811_t *dev, uint32_t r_ref, uint32_t *r_ntc);
#endif /* MODULE_CCS811_FULL || DOXYGEN */
/**
* @brief Data-ready status function
*
* The function reads the status register and returns CSS811_OK when new
* data are available. The function is useful for polling the sensor.
*
* @param[in] dev Device descriptor of CCS811 device to read from
*
* @retval CCS811_OK when new data are available
* @retval CCS811_ERROR_NO_NEW_DATA when no new data are available
* @retval CCS811_ERROR_* otherwise, see #ccs811_error_codes_t.
*/
int ccs811_data_ready (const ccs811_t *dev);
/**
* @brief Power down the sensor
*
* The feature disables sensor measurements by entering idle mode
* (#CCS811_MODE_IDLE). In addition, the function sets the low active
* signal ** nWAKE ** to high to completely deactivate the sensor.
* The sensor is then no longer accessible via I2C. The last sensor
* measurement mode is saved.
*
* The low active **nWAKE** signal pin has to be configured
* (#ccs811_params_t::wake_pin) accordingly. Otherwise, the function fails
* and returns with #CCS811_ERROR_NO_WAKE_PIN.
*
* @param[in] dev Device descriptor of CCS811 device to read from
*
* @retval CCS811_OK on success
* @retval CCS811_ERROR_NO_WAKE_PIN #ccs811_params_t::wake_pin not configured
* @retval CCS811_ERROR_* on error, see #ccs811_error_codes_t
*/
int ccs811_power_down (ccs811_t *dev);
/**
* @brief Power up the sensor
*
* The function sets the low active signal ** nWAKE ** to low to activate the
* sensor and switches back from the idle mode (#CCS811_MODE_IDLE) to the
* last measurement mode.
*
* The low active **nWAKE** signal pin has to be configured
* (#ccs811_params_t::wake_pin) accordingly. Otherwise, the function fails
* and returns with #CCS811_ERROR_NO_WAKE_PIN.
*
* @note It may take several minutes before accurate readings are generated
* when the sensor switches back from idle mode to the previous
* measurement mode.
*
* @param[in] dev Device descriptor of CCS811 device to read from
*
* @retval CCS811_OK on success
* @retval CCS811_ERROR_NO_WAKE_PIN #ccs811_params_t::wake_pin not configured
* @retval CCS811_ERROR_* on error, see #ccs811_error_codes_t
*/
int ccs811_power_up (ccs811_t *dev);
/**
* @brief Set the operation mode of the sensor
*
* The function sets the operating mode of the sensor.
*
* The sensor starts periodic measurements with the specified period if the
* \p mode parameter is either
*
* - #CCS811_MODE_1S,
* - #CCS811_MODE_10S,
* - #CCS811_MODE_60S, or
* - #CCS811_MODE_250MS.
*
* The #ccs811_read_iaq function can then be used to get sensor data at the
* same rate to get the results.
*
* In case, the \p mode parameter is #CCS811_MODE_IDLE, the sensor does not
* perform any measurements.
*
* @note
* - In #CCS811_MODE_250MS, only raw data are available. IAQ values would
* have to be calculated by the host in this mode.
* - Mode timings (the period) are subject to typical 2% tolerance due to
* accuracy of internal sensor clock.
* - After setting the sensor mode, the sensor needs up to 20 minutes, before
* accurate readings are generated.
* - When the sensor operating mode is changed to a new mode with
* a lower sample rate, e.g., from #CCS811_MODE_60S to #CCS811_MODE_1S, it
* should be placed in #CCS811_MODE_IDLE for at least 10 minutes before
* enabling the new mode.
*
* @param[in] dev Device descriptor of CCS811 device
* @param[in] mode CCS811 operation mode
*
* @retval CCS811_OK on success
* @retval CCS811_ERROR_* on error, see #ccs811_error_codes_t
*/
int ccs811_set_mode (ccs811_t *dev, ccs811_mode_t mode);
#if MODULE_CCS811_FULL || DOXYGEN
/**
* @brief Enable/disable data ready or threshold interrupt signal **nINT**
*
* CCS811 can trigger either
*
* - a data-ready interrupt (#CCS811_INT_DATA_READY) when new data become
* available or
* - a threshold interrupt (#CCS811_INT_THRESHOLD) if the new eCO2 data
* exceed defined thresholds (see #ccs811_set_eco2_thresholds).
*
* As soon as an interrupt condition occurs, the signal **nINT** is driven
* low. It stops being driven low when the sensor data is read with the
* #ccs811_read_iaq function. #ccs811_params_t::int_pin parameter has
* to be configured.
*
* With #CCS811_INT_NONE (the default), interrupt generation is disabled.
* The interrupt generation is disabled by default.
*
* @param[in] dev Device descriptor of CCS811 device
* @param[in] mode Enable the interrupt if true, otherwise disable it
*
* @retval CCS811_OK on success
* @retval CCS811_ERROR_NO_INT_PIN #ccs811_params_t::int_pin not configured
* @retval CCS811_ERROR_* on error, see #ccs811_error_codes_t
*/
int ccs811_set_int_mode (ccs811_t *dev, ccs811_int_mode_t mode);
/**
* @brief Set environmental data
*
* If information about the environment are available from another sensor,
* they can be used by CCS811 to compensate gas readings due to
* temperature and humidity changes.
*
* @param[in] dev Device descriptor of CCS811 device
* @param[in] temp Temperature [hundredths of a degree Celsius]
* @param[in] hum Relative Humidity [hundredths of a percent]
*
* @retval CCS811_OK on success
* @retval CCS811_ERROR_* on error, see #ccs811_error_codes_t
*/
int ccs811_set_environmental_data (const ccs811_t *dev,
int16_t temp, int16_t hum);
/**
* @brief Set eCO2 thresholds for threshold interrupts
*
* Threshold interrupts, if enabled (#ccs811_int_mode_t), are generated when
* new eCO2 value moves from the current range (LOW, MEDIUM or HIGH) to
* another range by more than one hysteresis value. The hysteresis is used
* to prevent multiple interrupts near a threshold.
*
* Ranges are defined as following:
*
* Name | Range | Value | Default
* :------|:------------------------------------------|:-------|:-------
* LOW | below the \p low parameter | > 400 | 1500
* MEDIUM | between the \p low and \p high parameters | | |
* HIGH | above the value of the \p high parameter | < 8192 | 2500
*
* @param[in] dev Device descriptor of CCS811 device
* @param[in] low Threshold LOW to MEDIUM
* @param[in] high Threshold MEDIUM to HIGH
* @param[in] hyst Hysteresis value (default 50)
*
* @retval CCS811_OK on success
* @retval CCS811_ERROR_* on error, see #ccs811_error_codes_t
*/
int ccs811_set_eco2_thresholds (const ccs811_t *dev,
uint16_t low, uint16_t high, uint8_t hyst);
/**
* @brief Get the current baseline value from sensor
*
* The sensor supports automatic baseline correction over a minimum time of
* 24 hours. Using this function, the current baseline value can be saved
* before the sensor is powered down. This baseline can then be restored using
* the #ccs811_set_baseline function after sensor is powered up again to
* continue the automatic baseline process.
*
* @param[in] dev Device descriptor of CCS811 device
* @param[in] baseline Current baseline value
*
* @retval CCS811_OK on success
* @retval CCS811_ERROR_* on error, see #ccs811_error_codes_t
*/
int ccs811_get_baseline (const ccs811_t *dev, uint16_t *baseline);
/**
* @brief Write a previously stored baseline value to the sensor
*
* The sensor supports automatic baseline correction over a minimum time of
* 24 hours. Using this function, a previously saved baseline
* (#ccs811_get_baseline) value can be restored after the sensor is powered
* up to continue the automatic baseline process.
*
* @note The baseline must be written after the conditioning period
* of 20 min after power up.
*
* @param[in] dev Device descriptor of CCS811 device
* @param[in] baseline Stored baseline value
*
* @retval CCS811_OK on success
* @retval CCS811_ERROR_* on error, see #ccs811_error_codes_t
*/
int ccs811_set_baseline (const ccs811_t *dev, uint16_t baseline);
#endif /* MODULE_CCS811_FULL || DOXYGEN */
#ifdef __cplusplus
}
#endif
#endif /* CCS811_H */
/** @} */