Add CCS811 driver
This commit is contained in:
102
include/mgos_ccs811.h
Normal file
102
include/mgos_ccs811.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mgos.h"
|
||||
#include "mgos_i2c.h"
|
||||
|
||||
#define MGOS_CCS811_READ_DELAY (2)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct mgos_ccs811;
|
||||
struct mgos_ccs811_stats {
|
||||
double last_read_time; // value of mg_time() upon last call to _read()
|
||||
uint32_t read; // calls to _read()
|
||||
uint32_t read_success; // successful _read()
|
||||
uint32_t read_success_cached; // calls to _read() which were cached
|
||||
// Note: read_errors := read - read_success - read_success_cached
|
||||
double read_success_usecs; // time spent in successful uncached _read()
|
||||
};
|
||||
|
||||
// Drive modes
|
||||
enum mgos_ccs811_drive_mode_t {
|
||||
CCS811_DRIVE_MODE_IDLE = 0x00,
|
||||
CCS811_DRIVE_MODE_1SEC = 0x01,
|
||||
CCS811_DRIVE_MODE_10SEC = 0x02,
|
||||
CCS811_DRIVE_MODE_60SEC = 0x03,
|
||||
CCS811_DRIVE_MODE_250MS = 0x04,
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize a CCS811 on the I2C bus `i2c` at address specified in `i2caddr`
|
||||
* parameter (default CCS811 is on address 0x5A). The sensor will be polled for
|
||||
* validity, upon success a new `struct mgos_ccs811` is allocated and
|
||||
* returned. If the device could not be found, NULL is returned.
|
||||
*/
|
||||
struct mgos_ccs811 *mgos_ccs811_create(struct mgos_i2c *i2c, uint8_t i2caddr);
|
||||
|
||||
/*
|
||||
* Destroy the data structure associated with a CCS811 device. The reference
|
||||
* to the pointer of the `struct mgos_ccs811` has to be provided, and upon
|
||||
* successful destruction, its associated memory will be freed and the pointer
|
||||
* set to NULL.
|
||||
*/
|
||||
void mgos_ccs811_destroy(struct mgos_ccs811 **sensor);
|
||||
|
||||
/*
|
||||
* The sensor will be polled for its temperature and humidity data. If the poll
|
||||
* has occured in the last `MGOS_CCS811_READ_DELAY` seconds, the cached data is
|
||||
* used (so as not to repeatedly poll the bus upon subsequent calls).
|
||||
*/
|
||||
bool mgos_ccs811_read(struct mgos_ccs811 *sensor);
|
||||
|
||||
/*
|
||||
* Set the drive mode of the CCS811 sensor based on the `mode` argument
|
||||
* Returns true on success, false otherwise.
|
||||
*/
|
||||
bool mgos_ccs811_setDriveMode(struct mgos_ccs811 *sensor, enum mgos_ccs811_drive_mode_t mode);
|
||||
|
||||
/*
|
||||
* Retrieve the current drive mode (which will be one of `enum mgos_ccs811_drive_mode_t`
|
||||
* values into the byte pointed to by `mode`.
|
||||
* Returns true on success, false otherwise.
|
||||
*/
|
||||
bool mgos_ccs811_getDriveMode(struct mgos_ccs811 *sensor, uint8_t *mode);
|
||||
|
||||
/*
|
||||
*
|
||||
* Returns a value on success, NAN otherwise.
|
||||
*/
|
||||
float mgos_ccs811_get_eco2(struct mgos_ccs811 *sensor);
|
||||
|
||||
/*
|
||||
*
|
||||
* Returns a value on success, NAN otherwise.
|
||||
*/
|
||||
float mgos_ccs811_get_tvoc(struct mgos_ccs811 *sensor);
|
||||
|
||||
/*
|
||||
* Initialization function for MGOS -- currently a noop.
|
||||
*/
|
||||
bool mgos_ccs811_i2c_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
121
src/main.c
121
src/main.c
@ -20,103 +20,124 @@
|
||||
#include "mgos_si7021.h"
|
||||
#include "mgos_htu21df.h"
|
||||
#include "mgos_mcp9808.h"
|
||||
#include "mgos_ccs811.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#define I2CBUSNR 5
|
||||
#define I2CBUSNR 5
|
||||
|
||||
void i2c_scanner(struct mgos_i2c *i2c) {
|
||||
int i;
|
||||
|
||||
if (!i2c) {
|
||||
LOG(LL_ERROR, ("No global I2C bus configured"));
|
||||
return;
|
||||
}
|
||||
|
||||
for(i=0x3; i<0x77; i++) {
|
||||
for (i = 0x3; i < 0x77; i++) {
|
||||
bool ret;
|
||||
ret=mgos_i2c_read(i2c, i, NULL, 0, true);
|
||||
if (ret)
|
||||
LOG(LL_INFO, ("I2C Address 0x%02x %s", i, ret?"true":"false"));
|
||||
ret = mgos_i2c_read(i2c, i, NULL, 0, true);
|
||||
if (ret) {
|
||||
LOG(LL_INFO, ("I2C Address 0x%02x %s", i, ret ? "true" : "false"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool i2c_dumpregs(struct mgos_i2c *i2c, uint8_t i2caddr) {
|
||||
uint16_t reg;
|
||||
int value;
|
||||
int value;
|
||||
|
||||
for(reg=0; reg<256; reg++) {
|
||||
value=mgos_i2c_read_reg_b(i2c, i2caddr, reg);
|
||||
if (value<0) {
|
||||
for (reg = 0; reg < 256; reg++) {
|
||||
value = mgos_i2c_read_reg_b(i2c, i2caddr, reg);
|
||||
if (value < 0) {
|
||||
printf(" XX");
|
||||
}
|
||||
else {
|
||||
}else {
|
||||
printf(" %02x", value);
|
||||
}
|
||||
if (reg%16==15) printf("\n");
|
||||
if (reg % 16 == 15) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool do_ccs811(struct mgos_ccs811 *sensor) {
|
||||
float eco2, tvoc;
|
||||
|
||||
if (!sensor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
eco2 = mgos_ccs811_get_eco2(sensor);
|
||||
tvoc = mgos_ccs811_get_tvoc(sensor);
|
||||
LOG(LL_INFO, ("eCO2=%.0fppm TVOC=%.0fppb", eco2, tvoc));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool do_sht31(struct mgos_sht31 *sensor) {
|
||||
float temp, humid;
|
||||
|
||||
if (!sensor) return false;
|
||||
if (!sensor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
temp=mgos_sht31_getTemperature(sensor);
|
||||
humid=mgos_sht31_getHumidity(sensor);
|
||||
temp = mgos_sht31_getTemperature(sensor);
|
||||
humid = mgos_sht31_getHumidity(sensor);
|
||||
LOG(LL_INFO, ("temperature=%.2fC humidity=%.1f%%", temp, humid));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool do_si7021(struct mgos_si7021 *sensor) {
|
||||
float temp, humid;
|
||||
|
||||
if (!sensor) return false;
|
||||
if (!sensor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
temp=mgos_si7021_getTemperature(sensor);
|
||||
humid=mgos_si7021_getHumidity(sensor);
|
||||
temp = mgos_si7021_getTemperature(sensor);
|
||||
humid = mgos_si7021_getHumidity(sensor);
|
||||
LOG(LL_INFO, ("temperature=%.2fC humidity=%.1f%%", temp, humid));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool do_htu21df(struct mgos_htu21df *sensor) {
|
||||
float temp, humid;
|
||||
|
||||
if (!sensor) return false;
|
||||
if (!sensor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
temp=mgos_htu21df_getTemperature(sensor);
|
||||
humid=mgos_htu21df_getHumidity(sensor);
|
||||
temp = mgos_htu21df_getTemperature(sensor);
|
||||
humid = mgos_htu21df_getHumidity(sensor);
|
||||
LOG(LL_INFO, ("temperature=%.2fC humidity=%.1f%%", temp, humid));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool do_mcp9808(struct mgos_mcp9808 *sensor) {
|
||||
float temp;
|
||||
|
||||
if (!sensor) return false;
|
||||
if (!sensor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
temp=mgos_mcp9808_getTemperature(sensor);
|
||||
temp = mgos_mcp9808_getTemperature(sensor);
|
||||
LOG(LL_INFO, ("temperature=%.2fC", temp));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
struct mgos_i2c *i2c;
|
||||
struct mgos_si7021 *si7021;
|
||||
struct mgos_sht31 *sht31;
|
||||
struct mgos_i2c * i2c;
|
||||
struct mgos_si7021 * si7021;
|
||||
struct mgos_sht31 * sht31;
|
||||
struct mgos_htu21df *htu21df;
|
||||
struct mgos_mcp9808 *mcp9808;
|
||||
struct mgos_ccs811 * ccs811;
|
||||
|
||||
if (!mgos_i2c_open(I2CBUSNR)) {
|
||||
LOG(LL_ERROR, ("Cannot open I2C bus %u", I2CBUSNR));
|
||||
@ -129,23 +150,32 @@ int main() {
|
||||
|
||||
i2c_scanner(i2c);
|
||||
|
||||
if (!(sht31 = mgos_sht31_create(i2c, 0x44)))
|
||||
LOG(LL_ERROR, ("Cannot create SHT31 device"));
|
||||
/*
|
||||
* if (!(sht31 = mgos_sht31_create(i2c, 0x44)))
|
||||
* LOG(LL_ERROR, ("Cannot create SHT31 device"));
|
||||
*
|
||||
* if (!(si7021 = mgos_si7021_create(i2c, 0x40)))
|
||||
* LOG(LL_ERROR, ("Cannot create SI7021 device"));
|
||||
*
|
||||
* if (!(htu21df = mgos_htu21df_create(i2c, 0x40)))
|
||||
* LOG(LL_ERROR, ("Cannot create HTU21DF device"));
|
||||
*
|
||||
* if (!(mcp9808 = mgos_mcp9808_create(i2c, 0x18)))
|
||||
* LOG(LL_ERROR, ("Cannot create MCP9808 device"));
|
||||
*/
|
||||
|
||||
if (!(si7021 = mgos_si7021_create(i2c, 0x40)))
|
||||
LOG(LL_ERROR, ("Cannot create SI7021 device"));
|
||||
|
||||
if (!(htu21df = mgos_htu21df_create(i2c, 0x40)))
|
||||
LOG(LL_ERROR, ("Cannot create HTU21DF device"));
|
||||
|
||||
if (!(mcp9808 = mgos_mcp9808_create(i2c, 0x18)))
|
||||
LOG(LL_ERROR, ("Cannot create MCP9808 device"));
|
||||
if (!(ccs811 = mgos_ccs811_create(i2c, 0x5A))) {
|
||||
LOG(LL_ERROR, ("Cannot create CCS811 device"));
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
do_sht31(sht31);
|
||||
do_si7021(si7021);
|
||||
do_htu21df(htu21df);
|
||||
do_mcp9808(mcp9808);
|
||||
/*
|
||||
* do_sht31(sht31);
|
||||
* do_si7021(si7021);
|
||||
* do_htu21df(htu21df);
|
||||
* do_mcp9808(mcp9808);
|
||||
*/
|
||||
do_ccs811(ccs811);
|
||||
sleep(5);
|
||||
}
|
||||
|
||||
@ -153,6 +183,7 @@ int main() {
|
||||
mgos_si7021_destroy(&si7021);
|
||||
mgos_htu21df_destroy(&htu21df);
|
||||
mgos_mcp9808_destroy(&mcp9808);
|
||||
mgos_ccs811_destroy(&ccs811);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
238
src/mgos_ccs811.c
Normal file
238
src/mgos_ccs811.c
Normal file
@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mgos.h"
|
||||
#include "mgos_ccs811_internal.h"
|
||||
#include "mgos_i2c.h"
|
||||
|
||||
// Datasheet:
|
||||
// https://cdn-shop.adafruit.com/product-files/2857/Sensirion_Humidity_SHT3x_Datasheet_digital-767294.pdf
|
||||
|
||||
// Private functions follow
|
||||
static bool mgos_ccs811_getStatus(struct mgos_ccs811 *sensor, uint8_t *status) {
|
||||
int ret;
|
||||
|
||||
if (!sensor) {
|
||||
return false;
|
||||
}
|
||||
ret = mgos_i2c_read_reg_b(sensor->i2c, sensor->i2caddr, MGOS_CCS811_REG_STATUS);
|
||||
if (ret < 0) {
|
||||
return false;
|
||||
}
|
||||
*status = (uint8_t)ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mgos_ccs811_getMeasMode(struct mgos_ccs811 *sensor, uint8_t *meas_mode) {
|
||||
int ret;
|
||||
|
||||
if (!sensor) {
|
||||
return false;
|
||||
}
|
||||
ret = mgos_i2c_read_reg_b(sensor->i2c, sensor->i2caddr, MGOS_CCS811_REG_MEAS_MODE);
|
||||
if (ret < 0) {
|
||||
return false;
|
||||
}
|
||||
*meas_mode = (uint8_t)ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return true if sensor status register has error-bit set (or upon read failure)
|
||||
|
||||
/*
|
||||
* static bool mgos_ccs811_error(struct mgos_ccs811 *sensor) {
|
||||
* uint8_t status;
|
||||
*
|
||||
* if (!mgos_ccs811_getStatus(sensor, &status))
|
||||
* return true;
|
||||
* // bits -- 7:FW_MODE 6:APP_ERASE 5:APP_VERIFY 4:APP_VALID 3:DATA_READY 0:ERROR
|
||||
* return (status & MGOS_CCS811_STATUS_ERR);
|
||||
* }
|
||||
*/
|
||||
|
||||
// Return true if sensor status register has data-ready set (false upon read failure)
|
||||
static bool mgos_ccs811_dataready(struct mgos_ccs811 *sensor) {
|
||||
uint8_t status;
|
||||
|
||||
if (!mgos_ccs811_getStatus(sensor, &status)) {
|
||||
return false;
|
||||
}
|
||||
return status & MGOS_CCS811_STATUS_DATA_READY;
|
||||
}
|
||||
|
||||
static bool mgos_ccs811_reset(struct mgos_ccs811 *sensor) {
|
||||
uint8_t data[5] = { MGOS_CCS811_REG_SW_RESET, 0x11, 0xE5, 0x72, 0x8A };
|
||||
|
||||
if (!sensor) {
|
||||
return false;
|
||||
}
|
||||
return mgos_i2c_write(sensor->i2c, sensor->i2caddr, data, 5, true);
|
||||
}
|
||||
|
||||
// Private functions end
|
||||
|
||||
// Public functions follow
|
||||
struct mgos_ccs811 *mgos_ccs811_create(struct mgos_i2c *i2c, uint8_t i2caddr) {
|
||||
struct mgos_ccs811 *sensor;
|
||||
int success = 0;
|
||||
int ret;
|
||||
|
||||
if (!i2c) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = mgos_i2c_read_reg_b(i2c, i2caddr, MGOS_CCS811_REG_HW_ID);
|
||||
if (ret != MGOS_CCS811_HW_ID_CODE) {
|
||||
LOG(LL_ERROR, ("Failed to detect CCS811 at I2C 0x%02x", i2caddr));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sensor = calloc(1, sizeof(struct mgos_ccs811));
|
||||
if (!sensor) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(sensor, 0, sizeof(struct mgos_ccs811));
|
||||
sensor->i2caddr = i2caddr;
|
||||
sensor->i2c = i2c;
|
||||
sensor->eco2 = 400;
|
||||
|
||||
// Boot the application on CCS811.
|
||||
mgos_ccs811_reset(sensor);
|
||||
mgos_usleep(2000);
|
||||
|
||||
uint8_t cmd = MGOS_CCS811_BOOTLOADER_REG_APP_START;
|
||||
uint8_t status = MGOS_CCS811_STATUS_ERR;
|
||||
uint8_t drive_mode = CCS811_DRIVE_MODE_IDLE;
|
||||
mgos_i2c_write(sensor->i2c, sensor->i2caddr, &cmd, 1, true);
|
||||
mgos_usleep(2000);
|
||||
|
||||
// Read status (expecting FW_MODE to be set and ERR to be clear)
|
||||
mgos_ccs811_getStatus(sensor, &status);
|
||||
if (!(status & MGOS_CCS811_STATUS_FW_MODE) || (status & MGOS_CCS811_STATUS_ERR)) {
|
||||
LOG(LL_ERROR, ("CCS811 invalid firmware mode, and/or status error"));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mgos_ccs811_setDriveMode(sensor, CCS811_DRIVE_MODE_1SEC);
|
||||
mgos_ccs811_getDriveMode(sensor, &drive_mode);
|
||||
if (drive_mode != CCS811_DRIVE_MODE_1SEC) {
|
||||
LOG(LL_ERROR, ("CCS811 failed to set drive mode"));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
success = 1;
|
||||
LOG(LL_INFO, ("CCS811 created at I2C 0x%02x", i2caddr));
|
||||
exit:
|
||||
if (!success) {
|
||||
free(sensor);
|
||||
sensor = NULL;
|
||||
}
|
||||
return sensor;
|
||||
}
|
||||
|
||||
bool mgos_ccs811_getDriveMode(struct mgos_ccs811 *sensor, uint8_t *mode) {
|
||||
uint8_t meas_mode;
|
||||
|
||||
if (!mgos_ccs811_getMeasMode(sensor, &meas_mode)) {
|
||||
return false;
|
||||
}
|
||||
// bits -- 6:4 DRIVE_MOCE 3: Interrupt enable 2: Int on Threshhold
|
||||
meas_mode >>= 4;
|
||||
meas_mode &= 0x07;
|
||||
*mode = meas_mode;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mgos_ccs811_setDriveMode(struct mgos_ccs811 *sensor, enum mgos_ccs811_drive_mode_t mode) {
|
||||
uint8_t meas_mode;
|
||||
|
||||
// bits -- 6:4 DRIVE_MOCE 3: Interrupt enable 2: Int on Threshhold
|
||||
meas_mode = (mode << 4);
|
||||
return mgos_i2c_write_reg_b(sensor->i2c, sensor->i2caddr, MGOS_CCS811_REG_MEAS_MODE, meas_mode);
|
||||
}
|
||||
|
||||
void mgos_ccs811_destroy(struct mgos_ccs811 **sensor) {
|
||||
if (!*sensor) {
|
||||
return;
|
||||
}
|
||||
free(*sensor);
|
||||
*sensor = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
bool mgos_ccs811_read(struct mgos_ccs811 *sensor) {
|
||||
double start = mg_time();
|
||||
|
||||
if (!sensor || !sensor->i2c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sensor->stats.read++;
|
||||
|
||||
if (start - sensor->stats.last_read_time < MGOS_CCS811_READ_DELAY) {
|
||||
sensor->stats.read_success_cached++;
|
||||
return true;
|
||||
}
|
||||
// Read out sensor data here
|
||||
//
|
||||
if (!mgos_ccs811_dataready(sensor)) {
|
||||
sensor->stats.read_success_cached++;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t data[8];
|
||||
uint8_t cmd = MGOS_CCS811_REG_ALG_RESULT_DATA;
|
||||
|
||||
data[4] = MGOS_CCS811_STATUS_ERR;
|
||||
mgos_i2c_write(sensor->i2c, sensor->i2caddr, &cmd, 1, false);
|
||||
mgos_i2c_read(sensor->i2c, sensor->i2caddr, data, 8, true);
|
||||
|
||||
// bytes 0-1:eco2 2-3:tvoc 4:status 5:error 6-7: raw_data
|
||||
if (data[4] & MGOS_CCS811_STATUS_ERR) {
|
||||
LOG(LL_ERROR, ("Read error 0x%02x", data[5]));
|
||||
return false;
|
||||
}
|
||||
sensor->eco2 = ((uint16_t)data[0] << 8) | ((uint16_t)data[1]);
|
||||
sensor->tvoc = ((uint16_t)data[2] << 8) | ((uint16_t)data[3]);
|
||||
LOG(LL_DEBUG, ("eCO2=%u TVOC=%u", sensor->eco2, sensor->tvoc));
|
||||
|
||||
sensor->stats.read_success++;
|
||||
sensor->stats.read_success_usecs += 1000000 * (mg_time() - start);
|
||||
sensor->stats.last_read_time = start;
|
||||
return true;
|
||||
}
|
||||
|
||||
float mgos_ccs811_get_eco2(struct mgos_ccs811 *sensor) {
|
||||
if (!mgos_ccs811_read(sensor)) {
|
||||
return NAN;
|
||||
}
|
||||
return (float)sensor->eco2;
|
||||
}
|
||||
|
||||
float mgos_ccs811_get_tvoc(struct mgos_ccs811 *sensor) {
|
||||
if (!mgos_ccs811_read(sensor)) {
|
||||
return NAN;
|
||||
}
|
||||
return (float)sensor->tvoc;
|
||||
}
|
||||
|
||||
bool mgos_ccs811_i2c_init(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Public functions end
|
74
src/mgos_ccs811_internal.h
Normal file
74
src/mgos_ccs811_internal.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mgos.h"
|
||||
#include "mgos_i2c.h"
|
||||
#include "mgos_ccs811.h"
|
||||
#include <math.h>
|
||||
|
||||
#define MGOS_SHT31_DEFAULT_I2CADDR (0x5A)
|
||||
|
||||
// Registers
|
||||
#define MGOS_CCS811_REG_STATUS (0x00)
|
||||
#define MGOS_CCS811_REG_MEAS_MODE (0x01)
|
||||
#define MGOS_CCS811_REG_ALG_RESULT_DATA (0x02)
|
||||
#define MGOS_CCS811_REG_RAW_DATA (0x03)
|
||||
#define MGOS_CCS811_REG_ENV_DATA (0x05)
|
||||
#define MGOS_CCS811_REG_NTC (0x06)
|
||||
#define MGOS_CCS811_REG_THRESHOLDS (0x10)
|
||||
#define MGOS_CCS811_REG_BASELINE (0x11)
|
||||
#define MGOS_CCS811_REG_HW_ID (0x20)
|
||||
#define MGOS_CCS811_REG_HW_VERSION (0x21)
|
||||
#define MGOS_CCS811_REG_FW_BOOT_VERSION (0x23)
|
||||
#define MGOS_CCS811_REG_FW_APP_VERSION (0x24)
|
||||
#define MGOS_CCS811_REG_ERROR_ID (0xE0)
|
||||
#define MGOS_CCS811_REG_SW_RESET (0xFF)
|
||||
|
||||
// Bootloader registers
|
||||
#define MGOS_CCS811_BOOTLOADER_REG_APP_ERASE (0xF1)
|
||||
#define MGOS_CCS811_BOOTLOADER_REG_APP_DATA (0xF2)
|
||||
#define MGOS_CCS811_BOOTLOADER_REG_APP_VERIFY (0xF3)
|
||||
#define MGOS_CCS811_BOOTLOADER_REG_APP_START (0xF4)
|
||||
|
||||
// Status register bits
|
||||
#define MGOS_CCS811_STATUS_ERR (0x01)
|
||||
#define MGOS_CCS811_STATUS_DATA_READY (0x08)
|
||||
#define MGOS_CCS811_STATUS_APP_VALID (0x10)
|
||||
#define MGOS_CCS811_STATUS_FW_MODE (0x80)
|
||||
|
||||
// Other defines
|
||||
#define MGOS_CCS811_HW_ID_CODE (0x81)
|
||||
#define MGOS_CCS811_REF_RESISTOR (100000)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct mgos_ccs811 {
|
||||
struct mgos_i2c * i2c;
|
||||
uint8_t i2caddr;
|
||||
struct mgos_ccs811_stats stats;
|
||||
|
||||
float temperature_offset;
|
||||
uint16_t tvoc;
|
||||
uint16_t eco2;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user