diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 69f73209d20..3d9cd47958a 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -5,6 +5,7 @@ add_subdirectory_ifdef(CONFIG_ADXL362 adxl362) add_subdirectory_ifdef(CONFIG_ADXL372 adxl372) add_subdirectory_ifdef(CONFIG_AK8975 ak8975) add_subdirectory_ifdef(CONFIG_AMG88XX amg88xx) +add_subdirectory_ifdef(CONFIG_AMS_IAQ_CORE ams_iAQcore) add_subdirectory_ifdef(CONFIG_APDS9960 apds9960) add_subdirectory_ifdef(CONFIG_BMA280 bma280) add_subdirectory_ifdef(CONFIG_BMC150_MAGN bmc150_magn) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 4441d94c76a..f030431ac4b 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -35,6 +35,8 @@ source "drivers/sensor/ak8975/Kconfig" source "drivers/sensor/amg88xx/Kconfig" +source "drivers/sensor/ams_iAQcore/Kconfig" + source "drivers/sensor/apds9960/Kconfig" source "drivers/sensor/bma280/Kconfig" diff --git a/drivers/sensor/ams_iAQcore/CMakeLists.txt b/drivers/sensor/ams_iAQcore/CMakeLists.txt new file mode 100644 index 00000000000..df0ee12e6db --- /dev/null +++ b/drivers/sensor/ams_iAQcore/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_AMS_IAQ_CORE iAQcore.c) diff --git a/drivers/sensor/ams_iAQcore/Kconfig b/drivers/sensor/ams_iAQcore/Kconfig new file mode 100644 index 00000000000..46c4d42c1c1 --- /dev/null +++ b/drivers/sensor/ams_iAQcore/Kconfig @@ -0,0 +1,23 @@ +# Kconfig - iAQ-core Digital VOC sensor configuration options + +# +# Copyright (c) 2018 Alexander Wachter +# +# SPDX-License-Identifier: Apache-2.0 +# + +menuconfig AMS_IAQ_CORE + bool "iAQ-core Digital VOC sensor" + depends on I2C && HAS_DTS_I2C + help + Enable driver for iAQ-core Digital VOC sensor. + +if AMS_IAQ_CORE + +config IAQ_CORE_MAX_READ_RETRIES + int "Number of read retries" + default 4 + help + Number of retries when reading failed or device not ready. + +endif # AMS_IAQ_CORE diff --git a/drivers/sensor/ams_iAQcore/iAQcore.c b/drivers/sensor/ams_iAQcore/iAQcore.c new file mode 100644 index 00000000000..650d6f07429 --- /dev/null +++ b/drivers/sensor/ams_iAQcore/iAQcore.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2018 Alexander Wachter. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iAQcore.h" + +#define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL +LOG_MODULE_REGISTER(IAQ_CORE); + +static int iaqcore_sample_fetch(struct device *dev, enum sensor_channel chan) +{ + struct iaq_core_data *drv_data = dev->driver_data; + struct iaq_registers buf; + struct i2c_msg msg; + int ret, tries; + + __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); + + msg.buf = (u8_t *)&buf; + msg.len = sizeof(struct iaq_registers); + msg.flags = I2C_MSG_READ | I2C_MSG_STOP; + + for (tries = 0; tries < CONFIG_IAQ_CORE_MAX_READ_RETRIES; tries++) { + + ret = i2c_transfer(drv_data->i2c, &msg, 1, + DT_AMS_IAQCORE_0_BASE_ADDRESS); + if (ret < 0) { + LOG_ERR("Failed to read registers data [%d].", ret); + return -EIO; + } + + drv_data->status = buf.status; + + if (buf.status == 0x00) { + drv_data->co2 = sys_be16_to_cpu(buf.co2_pred); + drv_data->voc = sys_be16_to_cpu(buf.voc); + drv_data->status = buf.status; + drv_data->resistance = sys_be32_to_cpu(buf.resistance); + + return 0; + } + + k_sleep(100); + } + + if (drv_data->status == 0x01) { + LOG_INF("Sensor data not available"); + } + + if (drv_data->status == 0x80) { + LOG_ERR("Sensor Error"); + } + + return -EIO; +} + +static int iaqcore_channel_get(struct device *dev, + enum sensor_channel chan, + struct sensor_value *val) +{ + struct iaq_core_data *drv_data = dev->driver_data; + + switch (chan) { + case SENSOR_CHAN_CO2: + val->val1 = drv_data->co2; + val->val2 = 0; + break; + case SENSOR_CHAN_VOC: + val->val1 = drv_data->voc; + val->val2 = 0; + break; + case SENSOR_CHAN_RESISTANCE: + val->val1 = drv_data->resistance; + val->val2 = 0; + break; + default: + return -ENOTSUP; + } + + return 0; +} + +static const struct sensor_driver_api iaq_core_driver_api = { + .sample_fetch = iaqcore_sample_fetch, + .channel_get = iaqcore_channel_get, +}; + +static int iaq_core_init(struct device *dev) +{ + struct iaq_core_data *drv_data = dev->driver_data; + + drv_data->i2c = device_get_binding(DT_AMS_IAQCORE_0_BUS_NAME); + if (drv_data->i2c == NULL) { + LOG_ERR("Failed to get pointer to %s device!", + DT_AMS_IAQCORE_0_BUS_NAME); + return -EINVAL; + } + + return 0; +} + +static struct iaq_core_data iaq_core_driver; + +DEVICE_AND_API_INIT(iaq_core, DT_AMS_IAQCORE_0_LABEL, iaq_core_init, + &iaq_core_driver, NULL, POST_KERNEL, + CONFIG_SENSOR_INIT_PRIORITY, &iaq_core_driver_api); diff --git a/drivers/sensor/ams_iAQcore/iAQcore.h b/drivers/sensor/ams_iAQcore/iAQcore.h new file mode 100644 index 00000000000..e66dec2b15f --- /dev/null +++ b/drivers/sensor/ams_iAQcore/iAQcore.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018 Alexander Wachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_AMS_IAQCORE_IAQCORE_H_ +#define ZEPHYR_DRIVERS_SENSOR_AMS_IAQCORE_IAQCORE_H_ + +#include +#include + +struct iaq_registers { + u16_t co2_pred; + u8_t status; + s32_t resistance; + u16_t voc; +} __packed; + +struct iaq_core_data { + struct device *i2c; + u16_t co2; + u16_t voc; + u8_t status; + s32_t resistance; +}; + +#endif /* ZEPHYR_DRIVERS_SENSOR_AMS_IAQCORE_IAQCORE_H_ */ diff --git a/dts/bindings/sensor/ams,iaqcore.yaml b/dts/bindings/sensor/ams,iaqcore.yaml new file mode 100644 index 00000000000..fd19c14490b --- /dev/null +++ b/dts/bindings/sensor/ams,iaqcore.yaml @@ -0,0 +1,21 @@ +# +# Copyright (c) 2018, Alexander Wachter +# +# SPDX-License-Identifier: Apache-2.0 +# +--- +title: AMS (Austria Mikro Systeme) Indoor Air Quality Sensor iAQ-core +version: 0.1 + +description: > + This binding gives a base representation of iAQ-core indoor air quality + sensor + +inherits: + !include i2c-device.yaml + +properties: + compatible: + constraint: "ams,iaqcore" + +... diff --git a/include/sensor.h b/include/sensor.h index 972f84b5561..f12d409e016 100644 --- a/include/sensor.h +++ b/include/sensor.h @@ -119,6 +119,8 @@ enum sensor_channel { SENSOR_CHAN_VOLTAGE, /** Current, in amps **/ SENSOR_CHAN_CURRENT, + /** Resistance , in Ohm **/ + SENSOR_CHAN_RESISTANCE, /** Angular rotation, in degrees */ SENSOR_CHAN_ROTATION,