From ac5acb9530be89163bf0155004abea10bcee7516 Mon Sep 17 00:00:00 2001 From: "Peter A. Bigot" Date: Fri, 23 Nov 2018 07:16:36 -0600 Subject: [PATCH] drivers: sensor: ccs811: provide API to fetch configuration and versions The application may want to know the configured mode without inspecting Kconfig macros; this is important for proper management of BASELINE which is mode-dependent. It also may need to know the version of the hardware and firmware, as the behavior of application firmware 2.0 is significantly better than version 1.1. Signed-off-by: Peter A. Bigot --- drivers/sensor/ccs811/ccs811.c | 45 +++++++++++++++++++++++++++++++++ drivers/sensor/ccs811/ccs811.h | 5 ++-- include/drivers/sensor/ccs811.h | 26 +++++++++++++++++++ 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/drivers/sensor/ccs811/ccs811.c b/drivers/sensor/ccs811/ccs811.c index 8e4d1e11dbb..29caa9fc233 100644 --- a/drivers/sensor/ccs811/ccs811.c +++ b/drivers/sensor/ccs811/ccs811.c @@ -77,6 +77,51 @@ const struct ccs811_result_type *ccs811_result(struct device *dev) return &drv_data->result; } +int ccs811_configver_fetch(struct device *dev, + struct ccs811_configver_type *ptr) +{ + struct ccs811_data *drv_data = dev->driver_data; + u8_t cmd; + int rc; + + if (!ptr) { + return -EINVAL; + } + + set_wake(drv_data, true); + cmd = CCS811_REG_HW_VERSION; + rc = i2c_write_read(drv_data->i2c, DT_INST_0_AMS_CCS811_BASE_ADDRESS, + &cmd, sizeof(cmd), + &ptr->hw_version, sizeof(ptr->hw_version)); + if (rc == 0) { + cmd = CCS811_REG_FW_BOOT_VERSION; + rc = i2c_write_read(drv_data->i2c, DT_INST_0_AMS_CCS811_BASE_ADDRESS, + &cmd, sizeof(cmd), + (u8_t *)&ptr->fw_boot_version, + sizeof(ptr->fw_boot_version)); + ptr->fw_boot_version = sys_be16_to_cpu(ptr->fw_boot_version); + } + + if (rc == 0) { + cmd = CCS811_REG_FW_APP_VERSION; + rc = i2c_write_read(drv_data->i2c, DT_INST_0_AMS_CCS811_BASE_ADDRESS, + &cmd, sizeof(cmd), + (u8_t *)&ptr->fw_app_version, + sizeof(ptr->fw_app_version)); + ptr->fw_app_version = sys_be16_to_cpu(ptr->fw_app_version); + } + if (rc == 0) { + LOG_INF("HW %x FW %x APP %x", + ptr->hw_version, ptr->fw_boot_version, + ptr->fw_app_version); + } + + set_wake(drv_data, false); + ptr->mode = drv_data->mode & CCS811_MODE_MSK; + + return rc; +} + int ccs811_baseline_fetch(struct device *dev) { const u8_t cmd = CCS811_REG_BASELINE; diff --git a/drivers/sensor/ccs811/ccs811.h b/drivers/sensor/ccs811/ccs811.h index c8618d11dc4..bb58b677f5a 100644 --- a/drivers/sensor/ccs811/ccs811.h +++ b/drivers/sensor/ccs811/ccs811.h @@ -23,12 +23,13 @@ #define CCS811_REG_BASELINE 0x11 #define CCS811_REG_HW_ID 0x20 #define CCS811_REG_HW_VERSION 0x21 -#define CCS811_REG_HW_VERSION_MASK 0xF0 +#define CCS811_REG_FW_BOOT_VERSION 0x23 +#define CCS811_REG_FW_APP_VERSION 0x24 #define CCS811_REG_ERROR_ID 0xE0 #define CCS811_REG_APP_START 0xF4 #define CCS881_HW_ID 0x81 -#define CCS811_HW_VERSION 0x10 +#define CCS811_HW_VERSION_MSK 0xF0 /* Measurement modes */ #define CCS811_MODE_RAW_DATA 0x40 diff --git a/include/drivers/sensor/ccs811.h b/include/drivers/sensor/ccs811.h index c51d8e52866..821880e0565 100644 --- a/include/drivers/sensor/ccs811.h +++ b/include/drivers/sensor/ccs811.h @@ -42,6 +42,7 @@ extern "C" { #define CCS811_MODE_IAQ_10SEC 0x20 #define CCS811_MODE_IAQ_60SEC 0x30 #define CCS811_MODE_IAQ_250MSEC 0x40 +#define CCS811_MODE_MSK 0x70 /** @brief Information collected from the sensor on each fetch. */ struct ccs811_result_type { @@ -81,6 +82,31 @@ struct ccs811_result_type { */ const struct ccs811_result_type *ccs811_result(struct device *dev); +/** + * @brief Get information about static CCS811 state. + * + * This includes the configured operating mode as well as hardware and + * firmware versions. + */ +struct ccs811_configver_type { + u16_t fw_boot_version; + u16_t fw_app_version; + u8_t hw_version; + u8_t mode; +}; + +/** + * @brief Fetch operating mode and version information. + * + * @param dev Pointer to the sensor device + * + * @param ptr Pointer to where the returned information should be stored + * + * @return 0 on success, or a negative errno code on failure. + */ +int ccs811_configver_fetch(struct device *dev, + struct ccs811_configver_type *ptr); + /** * @brief Fetch the current value of the BASELINE register. *