56#include <util/delay.h>
61#define CCS811_ADDRESS_W 0xB4
62#define CCS811_ADDRESS_R 0xB5
65#define STATUS_REG 0x00
66#define MEAS_MODE_REG 0x01
67#define ALG_RESULT_DATA_REG 0x02
68#define RAW_DATA_REG 0x03
69#define ENV_DATA_REG 0x05
70#define THRESHOLDS_REG 0x10
71#define BASELINE_REG 0x11
73#define HW_VERSION_REG 0x21
74#define FW_BOOT_VERSION_REG 0x23
75#define FW_APP_VERSION_REG 0x24
76#define INTERNAL_STATE_REG 0xA0
77#define ERROR_ID_REG 0xE0
78#define SW_RESET_REG 0xFF
81#define ALG_RESULT_DATA_SIZE 8
83#define RAW_DATA_SIZE 2
84#define ENV_DATA_SIZE 4
85#define THRESHOLDS_SIZE 5
86#define BASELINE_SIZE 2
87#define FW_BOOT_VERSION_SIZE 2
88#define FW_APP_VERSION_SIZE 2
89#define SW_RESET_SIZE 4
96#define HEATER_SUPPLY 5
98#define MAX_RESISTANCE 3
99#define MEASMODE_INVALID 2
100#define READ_REG_INVALID 1
101#define WRITE_REG_INVALID 0
104#define DRIVE_MODE_BITS 4
105#define INT_DATARDY_BIT 3
106#define INT_THRESH_BIT 2
110#define APP_ERASE_BIT 6
111#define APP_VERIFY_BIT 5
112#define APP_VALID_BIT 4
113#define DATA_READY_BIT 3
116#define BUS_SPEED_100KHZ 100000U
117#define ATTEMPTS_MAX 10
118#define CCS811_ID 0x81
122static uint8_t read_buffer[10];
125uint8_t ccs811_read_byte(uint8_t reg);
126void ccs811_burst_read(uint8_t reg, uint8_t length);
127uint16_t ccs811_read_word(uint8_t reg);
128void ccs811_write_byte(uint8_t reg, uint8_t
byte);
129uint8_t ccs811_get_status(
void);
135 p_config_global = p_config;
138 if (ccs811_read_byte(HW_ID_REG) == CCS811_ID)
140 uint8_t status = ccs811_get_status();
141 if (bit_is_set(status, APP_VALID_BIT))
150 byte |= (p_config_global->drive_mode << DRIVE_MODE_BITS);
151 byte |= (p_config_global->interrupt_dataready << INT_DATARDY_BIT);
152 byte |= (p_config_global->interrupt_threshold <<INT_THRESH_BIT);
154 for (uint8_t count = 0; count < ATTEMPTS_MAX; ++count)
156 ccs811_write_byte(MEAS_MODE_REG,
byte);
158 uint8_t mode = ccs811_read_byte(MEAS_MODE_REG);
163 if (count == (ATTEMPTS_MAX - 1))
184 uint16_t data = ccs811_read_word(ALG_RESULT_DATA_REG);
192 ccs811_burst_read(ALG_RESULT_DATA_REG, ETVOC_SIZE);
193 uint8_t msb = read_buffer[ETVOC_SIZE - 2];
194 data = read_buffer[ETVOC_SIZE - 1];
203 uint8_t status = ccs811_get_status();
204 if (bit_is_set(status, DATA_READY_BIT))
213 ccs811_burst_read(ALG_RESULT_DATA_REG, ALG_RESULT_DATA_SIZE);
234 uint8_t error = ccs811_read_byte(ERROR_ID_REG);
235 if (bit_is_set(error, HEATER_SUPPLY))
237 msg =
"Heater Supply";
239 else if (bit_is_set(error, HEATER_FAULT))
241 msg =
"Heater Fault";
243 else if (bit_is_set(error, MAX_RESISTANCE))
245 msg =
"Max Resistance";
247 else if (bit_is_set(error, MEASMODE_INVALID))
249 msg =
"Invalid Meas Mode";
251 else if (bit_is_set(error, READ_REG_INVALID))
253 msg =
"Read Reg Invalid";
255 else if (bit_is_set(error, WRITE_REG_INVALID))
257 msg =
"Write Reg Invalid";
261 msg =
"Unknown Error";
271uint8_t ccs811_get_status(
void)
273 uint8_t status = ccs811_read_byte(STATUS_REG);
277void ccs811_write_byte(uint8_t reg, uint8_t
byte)
286uint8_t ccs811_read_byte(uint8_t reg)
300void ccs811_burst_read(uint8_t reg, uint8_t length)
308 for (uint8_t i = 0; i < length; ++i)
315uint16_t ccs811_read_word(uint8_t reg)
void init_i2c(uint32_t bus_speed)
Sets pullups and initializes i2c clock to desired bus speed.
uint8_t i2c_read_no_ack(void)
Read in from slave, sending NOACK when done (no TWEA).
uint8_t i2c_read_ack(void)
Read in from slave, sending ACK when done (sets TWEA).
void i2c_stop(void)
Sends a stop condition (sets TWSTO).
void i2c_send(uint8_t data)
Loads data, sends it out, waiting for completion.
void i2c_start(void)
Sends a start condition (sets TWSTA).
void ccs811_update_env_data(uint8_t humidity, uint8_t temp)
(Optional) Write environmental data from another sensor to the CCS811.
uint16_t ccs811_get_etvoc_level(void)
Read eTVOC (equivalent total volatile organic compounds) level from sensor.
uint16_t ccs811_get_eco2_level(void)
Read eCO2 (equivalent carbon dioxide) level from sensor.
char * ccs811_error_to_string(void)
For error handling/logging.
uint8_t init_ccs811(ccs811_config_t *p_config)
Initialisation routine (run once at startup).
void ccs811_get_alg_result_data(void)
Perform a read operation on all 8 bytes of ALG_RESULT_REGISTER.
bool ccs811_data_ready_check(void)
Read the status register and check if the data ready flag is set.
Driver for the CCS811 gas sensor .
I2C communications driver for AVR MCU's.
Config object, to be instantiated and values assigned to members before passing the object address in...