/* * Copyright (c) 2018 Peter Bigot Consulting, LLC * Copyright (c) 2018 Linaro Ltd. * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include static bool app_fw_2; static const char *now_str(void) { static char buf[16]; /* ...HH:MM:SS.MMM */ uint32_t now = k_uptime_get_32(); unsigned int ms = now % MSEC_PER_SEC; unsigned int s; unsigned int min; unsigned int h; now /= MSEC_PER_SEC; s = now % 60U; now /= 60U; min = now % 60U; now /= 60U; h = now; snprintf(buf, sizeof(buf), "%u:%02u:%02u.%03u", h, min, s, ms); return buf; } static int do_fetch(const struct device *dev) { struct sensor_value co2, tvoc, voltage, current; int rc = 0; int baseline = -1; #ifdef CONFIG_APP_MONITOR_BASELINE rc = ccs811_baseline_fetch(dev); if (rc >= 0) { baseline = rc; rc = 0; } #endif if (rc == 0) { rc = sensor_sample_fetch(dev); } if (rc == 0) { const struct ccs811_result_type *rp = ccs811_result(dev); sensor_channel_get(dev, SENSOR_CHAN_CO2, &co2); sensor_channel_get(dev, SENSOR_CHAN_VOC, &tvoc); sensor_channel_get(dev, SENSOR_CHAN_VOLTAGE, &voltage); sensor_channel_get(dev, SENSOR_CHAN_CURRENT, ¤t); printk("\n[%s]: CCS811: %u ppm eCO2; %u ppb eTVOC\n", now_str(), co2.val1, tvoc.val1); printk("Voltage: %d.%06dV; Current: %d.%06dA\n", voltage.val1, voltage.val2, current.val1, current.val2); #ifdef CONFIG_APP_MONITOR_BASELINE printk("BASELINE %04x\n", baseline); #endif if (app_fw_2 && !(rp->status & CCS811_STATUS_DATA_READY)) { printk("STALE DATA\n"); } if (rp->status & CCS811_STATUS_ERROR) { printk("ERROR: %02x\n", rp->error); } } return rc; } #ifndef CONFIG_CCS811_TRIGGER_NONE static void trigger_handler(const struct device *dev, const struct sensor_trigger *trig) { int rc = do_fetch(dev); if (rc == 0) { printk("Triggered fetch got %d\n", rc); } else if (-EAGAIN == rc) { printk("Triggered fetch got stale data\n"); } else { printk("Triggered fetch failed: %d\n", rc); } } #endif /* !CONFIG_CCS811_TRIGGER_NONE */ static void do_main(const struct device *dev) { while (true) { int rc = do_fetch(dev); if (rc == 0) { printk("Timed fetch got %d\n", rc); } else if (-EAGAIN == rc) { printk("Timed fetch got stale data\n"); } else { printk("Timed fetch failed: %d\n", rc); break; } k_msleep(1000); } } int main(void) { const struct device *const dev = DEVICE_DT_GET_ONE(ams_ccs811); struct ccs811_configver_type cfgver; int rc; if (!device_is_ready(dev)) { printk("Device %s is not ready\n", dev->name); return 0; } printk("device is %p, name is %s\n", dev, dev->name); rc = ccs811_configver_fetch(dev, &cfgver); if (rc == 0) { printk("HW %02x; FW Boot %04x App %04x ; mode %02x\n", cfgver.hw_version, cfgver.fw_boot_version, cfgver.fw_app_version, cfgver.mode); app_fw_2 = (cfgver.fw_app_version >> 8) > 0x11; } #ifdef CONFIG_APP_USE_ENVDATA struct sensor_value temp = { CONFIG_APP_ENV_TEMPERATURE }; struct sensor_value humidity = { CONFIG_APP_ENV_HUMIDITY }; rc = ccs811_envdata_update(dev, &temp, &humidity); printk("ENV_DATA set for %d Cel, %d %%RH got %d\n", temp.val1, humidity.val1, rc); #endif #ifdef CONFIG_CCS811_TRIGGER struct sensor_trigger trig = { 0 }; #ifdef CONFIG_APP_TRIGGER_ON_THRESHOLD printk("Triggering on threshold:\n"); if (rc == 0) { struct sensor_value thr = { .val1 = CONFIG_APP_CO2_MEDIUM_PPM, }; rc = sensor_attr_set(dev, SENSOR_CHAN_CO2, SENSOR_ATTR_LOWER_THRESH, &thr); printk("L/M threshold to %d got %d\n", thr.val1, rc); } if (rc == 0) { struct sensor_value thr = { .val1 = CONFIG_APP_CO2_HIGH_PPM, }; rc = sensor_attr_set(dev, SENSOR_CHAN_CO2, SENSOR_ATTR_UPPER_THRESH, &thr); printk("M/H threshold to %d got %d\n", thr.val1, rc); } trig.type = SENSOR_TRIG_THRESHOLD; trig.chan = SENSOR_CHAN_CO2; #elif defined(CONFIG_APP_TRIGGER_ON_DATAREADY) printk("Triggering on data ready\n"); trig.type = SENSOR_TRIG_DATA_READY; trig.chan = SENSOR_CHAN_ALL; #else #error Unhandled trigger on #endif if (rc == 0) { rc = sensor_trigger_set(dev, &trig, trigger_handler); } if (rc == 0) { #ifdef CONFIG_APP_TRIGGER_ON_DATAREADY while (true) { k_sleep(K_FOREVER); } #endif } printk("Trigger installation got: %d\n", rc); #endif /* CONFIG_CCS811_TRIGGER */ if (rc == 0) { do_main(dev); } return 0; }