260 lines
8.9 KiB
C
260 lines
8.9 KiB
C
|
/**
|
||
|
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||
|
*
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||
|
* are permitted provided that the following conditions are met:
|
||
|
*
|
||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||
|
* list of conditions and the following disclaimer.
|
||
|
*
|
||
|
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||
|
* Semiconductor ASA integrated circuit in a product or a software update for
|
||
|
* such product, must reproduce the above copyright notice, this list of
|
||
|
* conditions and the following disclaimer in the documentation and/or other
|
||
|
* materials provided with the distribution.
|
||
|
*
|
||
|
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||
|
* contributors may be used to endorse or promote products derived from this
|
||
|
* software without specific prior written permission.
|
||
|
*
|
||
|
* 4. This software, with or without modification, must only be used with a
|
||
|
* Nordic Semiconductor ASA integrated circuit.
|
||
|
*
|
||
|
* 5. Any software provided in binary form under this license must not be reverse
|
||
|
* engineered, decompiled, modified and/or disassembled.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||
|
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||
|
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*
|
||
|
*/
|
||
|
#ifndef CCS811_INTERNAL_H
|
||
|
#define CCS811_INTERNAL_H
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* @brief CCS811 sensor registers.
|
||
|
*/
|
||
|
#define CCS811_REG_STATUS 0x00
|
||
|
#define CCS811_REG_MEAS_MODE 0x01
|
||
|
#define CCS811_REG_ALG_RESULT_DATA 0x02
|
||
|
#define CCS811_REG_RAW_DATA 0x03
|
||
|
#define CCS811_REG_ENV_DATA 0x05
|
||
|
#define CCS811_REG_NTC 0x06
|
||
|
#define CCS811_REG_THRESHOLDS 0x10
|
||
|
#define CCS811_REG_BASELINE 0x11
|
||
|
#define CCS811_REG_HW_ID 0x20
|
||
|
#define CCS811_REG_HW_VER 0x21
|
||
|
#define CCS811_REG_FW_BOOT_VER 0x23
|
||
|
#define CCS811_REG_FW_APP_VER 0x24
|
||
|
#define CCS811_REG_ERROR_ID 0xE0
|
||
|
#define CCS811_REG_SW_RESET 0xFF
|
||
|
#define CCS811_REG_APP_START 0xF4
|
||
|
|
||
|
/**
|
||
|
* @brief CCS811 Default configuration values.
|
||
|
*/
|
||
|
#define CCS811_DEFAULT_HUMIDITY 50
|
||
|
#define CCS811_DEFAULT_TEMPERATURE 25
|
||
|
#define CCS811_DEFAULT_LOW_THR 1500
|
||
|
#define CCS811_DEFAULT_HIGH_THR 2500
|
||
|
#define CCS811_DEFAULT_HYSTERESIS 50
|
||
|
|
||
|
/**
|
||
|
* @brief CCS811 Environment temperature offset.
|
||
|
*/
|
||
|
#define CCS811_TEMPERATURE_OFFSET 25
|
||
|
|
||
|
/**
|
||
|
* @brief Status register bitmasks.
|
||
|
*/
|
||
|
|
||
|
// Bitmasks for FW_MODE.
|
||
|
#define CCS811_FW_MODE_POS 7
|
||
|
#define CCS811_FW_MODE_MASK (1 << CCS811_FW_MODE_POS)
|
||
|
|
||
|
// Bitmasks for APP_VALID.
|
||
|
#define CCS811_APP_VALID_POS 4
|
||
|
#define CCS811_APP_VALID_MASK (1 << CCS811_APP_VALID_POS)
|
||
|
|
||
|
// Bitmasks for DATA_READY.
|
||
|
#define CCS811_DATA_READY_POS 3
|
||
|
#define CCS811_DATA_READY_MASK (1 << CCS811_DATA_READY_POS)
|
||
|
|
||
|
// Bitmasks for ERROR.
|
||
|
#define CCS811_ERROR_POS 0
|
||
|
#define CCS811_ERROR_MASK (1 << CCS811_ERROR_POS)
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Meas mode register bitmasks.
|
||
|
*/
|
||
|
|
||
|
// Register validity mask.
|
||
|
#define CCS811_MEAS_MODE_VALID_MASK 0x83U
|
||
|
|
||
|
// Bitmasks for DRIVE_MODE.
|
||
|
#define CCS811_DRIVE_MODE_POS 4
|
||
|
#define CCS811_DRIVE_MODE_MASK (7 << CCS811_DRIVE_MODE_POS)
|
||
|
|
||
|
// Bitmasks for INTERRUPT.
|
||
|
#define CCS811_INTERRUPT_POS 3
|
||
|
#define CCS811_INTERRUPT_MASK (1 << CCS811_INTERRUPT_MASK)
|
||
|
|
||
|
// Bitmasks for THRESH.
|
||
|
#define CCS811_THRESH_POS 2
|
||
|
#define CCS811_THRESH_MASK (1 << CCS811_THRESH_POS)
|
||
|
|
||
|
/**
|
||
|
* @brief Algorithm results data bytes.
|
||
|
*/
|
||
|
|
||
|
#define CCS811_ALG_RESULT_BYTE_NUM 8
|
||
|
#define CCS811_ALG_ECO2_H_BYTE 0
|
||
|
#define CCS811_ALG_ECO2_L_BYTE 1
|
||
|
#define CCS811_ALG_TVOC_H_BYTE 2
|
||
|
#define CCS811_ALG_TVOC_L_BYTE 3
|
||
|
#define CCS811_ALG_STATUS_BYTE 4
|
||
|
#define CCS811_ALG_ERROR_BYTE 5
|
||
|
#define CCS811_ALG_RAW_DATA1_BYTE 6
|
||
|
#define CCS811_ALG_RAW_DATA2_BYTE 7
|
||
|
|
||
|
/**
|
||
|
* @brief Environment data register.
|
||
|
*/
|
||
|
|
||
|
#define CCS811_ENV_HUMIDITY_H_BYTE 0
|
||
|
|
||
|
// Humidity percent position.
|
||
|
#define CCS811_ENV_HUM_PERCENT_POS 9
|
||
|
|
||
|
// Bitmasks for humidity fraction.
|
||
|
#define CCS811_ENV_HUM_FRACTION_MASK (0x01FF)
|
||
|
|
||
|
|
||
|
// Temperature value position.
|
||
|
#define CCS811_ENV_TEMP_VALUE_POS 9
|
||
|
|
||
|
// Bitmasks for temperature fraction.
|
||
|
#define CCS811_ENV_TEMP_FRACTION_MASK (0x01FF)
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Error register.
|
||
|
*/
|
||
|
|
||
|
// Bitmasks for HEATER_SUPPLY
|
||
|
#define CCS811_ERROR_HEATER_SUPPLY_POS 5
|
||
|
#define CCS811_ERROR_HEATER_SUPPLY_MASK (1 << CCS811_ERROR_HEATER_SUPPLY_POS)
|
||
|
|
||
|
// Bitmasks for HEATER_FAULT
|
||
|
#define CCS811_ERROR_HEATER_FAULT_POS 4
|
||
|
#define CCS811_ERROR_HEATER_FAULT_MASK (1 << CCS811_ERROR_HEATER_FAULT_POS)
|
||
|
|
||
|
// Bitmasks for MAX_RESISTANCE
|
||
|
#define CCS811_ERROR_MAX_RESISTANCE_POS 3
|
||
|
#define CCS811_ERROR_MAX_RESISTANCE_MASK (1 << CCS811_ERROR_MAX_RESISTANCE_POS)
|
||
|
|
||
|
// Bitmasks for MEASMODE_INVALID
|
||
|
#define CCS811_ERROR_MEAS_MODE_POS 2
|
||
|
#define CCS811_ERROR_MEAS_MODE_MASK (1 CCS811_ERROR_MEAS_MODE_POS)
|
||
|
|
||
|
// Bitmasks for READ_REG
|
||
|
#define CCS811_ERROR_READ_REG_POS 1
|
||
|
#define CCS811_ERROR_READ_REG_MASK (1 << CCS811_ERROR_READ_REG_POS)
|
||
|
|
||
|
// Bitmasks for WRITE_REG
|
||
|
#define CCS811_ERROR_WRITE_REG_POS 0
|
||
|
#define CCS811_ERROR_WRITE_REG_MASK (1 << CCS811_ERROR_WRITE_REG_POS)
|
||
|
|
||
|
/**
|
||
|
* @brief Software reset register.
|
||
|
*/
|
||
|
#define CCS811_SW_RESET_BYTE0 0x11
|
||
|
#define CCS811_SW_RESET_BYTE1 0xE5
|
||
|
#define CCS811_SW_RESET_BYTE2 0x72
|
||
|
#define CCS811_SW_RESET_BYTE3 0x8A
|
||
|
|
||
|
/**
|
||
|
* @brief Structure holding sensor instance
|
||
|
*/
|
||
|
typedef struct
|
||
|
{
|
||
|
nrf_twi_sensor_t * const p_sensor_data;
|
||
|
uint8_t const sensor_addr;
|
||
|
} ccs811_instance_t;
|
||
|
|
||
|
/**
|
||
|
* @brief Macro that creates sensor instance.
|
||
|
*/
|
||
|
#define CCS811_INTERNAL_INSTANCE_DEF(_ccs811_inst_name, _p_twi_sensor, _sensor_address) \
|
||
|
static ccs811_instance_t _ccs811_inst_name = \
|
||
|
{ \
|
||
|
.p_sensor_data = _p_twi_sensor, \
|
||
|
.sensor_addr = _sensor_address, \
|
||
|
}
|
||
|
|
||
|
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
||
|
|
||
|
__STATIC_INLINE ret_code_t ccs811_status_read(ccs811_instance_t const * p_instance,
|
||
|
nrf_twi_sensor_reg_cb_t user_cb,
|
||
|
uint8_t * p_reg_val)
|
||
|
{
|
||
|
ASSERT(p_instance != NULL);
|
||
|
ASSERT(p_reg_val != NULL);
|
||
|
return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
|
||
|
p_instance->sensor_addr,
|
||
|
CCS811_REG_STATUS,
|
||
|
user_cb,
|
||
|
p_reg_val,
|
||
|
1);
|
||
|
}
|
||
|
|
||
|
__STATIC_INLINE ret_code_t ccs811_hw_id_read(ccs811_instance_t const * p_instance,
|
||
|
nrf_twi_sensor_reg_cb_t user_cb,
|
||
|
uint8_t * p_reg_val)
|
||
|
{
|
||
|
ASSERT(p_instance != NULL);
|
||
|
ASSERT(p_reg_val != NULL);
|
||
|
return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
|
||
|
p_instance->sensor_addr,
|
||
|
CCS811_REG_HW_ID,
|
||
|
user_cb,
|
||
|
p_reg_val,
|
||
|
1);
|
||
|
}
|
||
|
|
||
|
__STATIC_INLINE ret_code_t ccs811_error_read(ccs811_instance_t const * p_instance,
|
||
|
nrf_twi_sensor_reg_cb_t user_cb,
|
||
|
uint8_t * p_reg_val)
|
||
|
{
|
||
|
ASSERT(p_instance != NULL);
|
||
|
ASSERT(p_reg_val != NULL);
|
||
|
return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
|
||
|
p_instance->sensor_addr,
|
||
|
CCS811_REG_ERROR_ID,
|
||
|
user_cb,
|
||
|
p_reg_val,
|
||
|
1);
|
||
|
}
|
||
|
|
||
|
#endif //SUPPRESS_INLINE_IMPLEMENTATION
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif // CCS811_INTERNAL_H
|