Skip to content
Permalink
Browse files

drivers: sensor: ams_iAQcore: Implemented ASM Indoor Air Quality Sensor

Implementation of AMS (Austria Micro Systems) Indoor Air Quality Sensor

Signed-off-by: Alexander Wachter <alexander.wachter@student.tugraz.at>
  • Loading branch information...
alexanderwachter authored and MaureenHelm committed Oct 5, 2018
1 parent 4f23741 commit 3c70a3832dab5e6d34a80e1cc202206c17fa8530
@@ -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)
@@ -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"
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_library()

zephyr_library_sources_ifdef(CONFIG_AMS_IAQ_CORE iAQcore.c)
@@ -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
@@ -0,0 +1,117 @@
/*
* Copyright (c) 2018 Alexander Wachter.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <device.h>
#include <i2c.h>
#include <kernel.h>
#include <misc/byteorder.h>
#include <misc/util.h>
#include <sensor.h>
#include <misc/__assert.h>
#include <logging/log.h>

#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);
@@ -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 <device.h>
#include <misc/util.h>

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_ */
@@ -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"

...
@@ -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,

0 comments on commit 3c70a38

Please sign in to comment.
You can’t perform that action at this time.