drivers: sensor: ccs811: support triggers
Add the standard suite of trigger configuration options. Add driver support for the DATA_READY and THRESHOLD triggers. Note cross-module dependency as configuring the trigger requires a controlled modification of the sensor registers and the sensor driver API doesn't support this. Signed-off-by: Peter A. Bigot <pab@pabigot.com>
This commit is contained in:
parent
29c5f30ed2
commit
403a7ab2c5
5 changed files with 373 additions and 41 deletions
|
@ -3,3 +3,4 @@
|
|||
zephyr_library()
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_CCS811 ccs811.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CCS811_TRIGGER ccs811_trigger.c)
|
||||
|
|
|
@ -33,4 +33,42 @@ config CCS811_DRIVE_MODE_3
|
|||
|
||||
endchoice
|
||||
|
||||
config CCS811_TRIGGER
|
||||
bool
|
||||
|
||||
choice
|
||||
prompt "Trigger mode"
|
||||
default CCS811_TRIGGER_NONE
|
||||
help
|
||||
Specify the type of triggering to be used by the driver.
|
||||
|
||||
config CCS811_TRIGGER_NONE
|
||||
bool "No trigger"
|
||||
|
||||
config CCS811_TRIGGER_GLOBAL_THREAD
|
||||
bool "Use global thread"
|
||||
depends on GPIO
|
||||
select CCS811_TRIGGER
|
||||
|
||||
config CCS811_TRIGGER_OWN_THREAD
|
||||
bool "Use own thread"
|
||||
depends on GPIO
|
||||
select CCS811_TRIGGER
|
||||
|
||||
endchoice
|
||||
|
||||
config CCS811_THREAD_PRIORITY
|
||||
int "Thread priority"
|
||||
depends on CCS811_TRIGGER_OWN_THREAD
|
||||
default 10
|
||||
help
|
||||
Priority of thread used by the driver to handle interrupts.
|
||||
|
||||
config CCS811_THREAD_STACK_SIZE
|
||||
int "Thread stack size"
|
||||
depends on CCS811_TRIGGER_OWN_THREAD
|
||||
default 1024
|
||||
help
|
||||
Stack size of thread used by the driver to handle interrupts.
|
||||
|
||||
endif # CCS811
|
||||
|
|
|
@ -23,7 +23,7 @@ LOG_MODULE_REGISTER(CCS811, CONFIG_SENSOR_LOG_LEVEL);
|
|||
static void set_wake(struct ccs811_data *drv_data, bool enable)
|
||||
{
|
||||
/* Always active-low */
|
||||
gpio_pin_write(drv_data->gpio, DT_INST_0_AMS_CCS811_WAKE_GPIOS_PIN, !enable);
|
||||
gpio_pin_write(drv_data->wake_gpio, DT_INST_0_AMS_CCS811_WAKE_GPIOS_PIN, !enable);
|
||||
if (enable) {
|
||||
k_busy_wait(50); /* t_WAKE = 50 us */
|
||||
} else {
|
||||
|
@ -170,6 +170,10 @@ static int ccs811_channel_get(struct device *dev,
|
|||
}
|
||||
|
||||
static const struct sensor_driver_api ccs811_driver_api = {
|
||||
#ifdef CONFIG_CCS811_TRIGGER
|
||||
.attr_set = ccs811_attr_set,
|
||||
.trigger_set = ccs811_trigger_set,
|
||||
#endif
|
||||
.sample_fetch = ccs811_sample_fetch,
|
||||
.channel_get = ccs811_channel_get,
|
||||
};
|
||||
|
@ -222,6 +226,65 @@ static int switch_to_app_mode(struct device *i2c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CCS811_TRIGGER
|
||||
|
||||
int ccs811_mutate_meas_mode(struct device *dev,
|
||||
u8_t set,
|
||||
u8_t clear)
|
||||
{
|
||||
struct ccs811_data *drv_data = dev->driver_data;
|
||||
int rc = 0;
|
||||
u8_t mode = set | (drv_data->mode & ~clear);
|
||||
|
||||
/*
|
||||
* Changing drive mode of a running system has preconditions.
|
||||
* Only allow changing the interrupt generation.
|
||||
*/
|
||||
if ((set | clear) & ~(CCS811_MODE_DATARDY | CCS811_MODE_THRESH)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mode != drv_data->mode) {
|
||||
set_wake(drv_data, true);
|
||||
rc = i2c_reg_write_byte(drv_data->i2c, DT_INST_0_AMS_CCS811_BASE_ADDRESS,
|
||||
CCS811_REG_MEAS_MODE,
|
||||
mode);
|
||||
LOG_DBG("CCS811 meas mode change %02x to %02x got %d",
|
||||
drv_data->mode, mode, rc);
|
||||
if (rc < 0) {
|
||||
LOG_ERR("Failed to set mode");
|
||||
rc = -EIO;
|
||||
} else {
|
||||
drv_data->mode = mode;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
set_wake(drv_data, false);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ccs811_set_thresholds(struct device *dev)
|
||||
{
|
||||
struct ccs811_data *drv_data = dev->driver_data;
|
||||
const u8_t buf[5] = {
|
||||
CCS811_REG_THRESHOLDS,
|
||||
drv_data->co2_l2m >> 8,
|
||||
drv_data->co2_l2m,
|
||||
drv_data->co2_m2h >> 8,
|
||||
drv_data->co2_m2h,
|
||||
};
|
||||
int rc;
|
||||
|
||||
set_wake(drv_data, true);
|
||||
rc = i2c_write(drv_data->i2c, buf, sizeof(buf), DT_INST_0_AMS_CCS811_BASE_ADDRESS);
|
||||
set_wake(drv_data, false);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CCS811_TRIGGER */
|
||||
|
||||
int ccs811_init(struct device *dev)
|
||||
{
|
||||
struct ccs811_data *drv_data = dev->driver_data;
|
||||
|
@ -229,6 +292,7 @@ int ccs811_init(struct device *dev)
|
|||
u8_t hw_id;
|
||||
int status;
|
||||
|
||||
*drv_data = (struct ccs811_data){ 0 };
|
||||
drv_data->i2c = device_get_binding(DT_INST_0_AMS_CCS811_BUS_NAME);
|
||||
if (drv_data->i2c == NULL) {
|
||||
LOG_ERR("Failed to get pointer to %s device!",
|
||||
|
@ -236,65 +300,56 @@ int ccs811_init(struct device *dev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct device *gpio = NULL;
|
||||
(void)gpio;
|
||||
#ifdef DT_INST_0_AMS_CCS811_WAKE_GPIOS_CONTROLLER
|
||||
gpio = device_get_binding(DT_INST_0_AMS_CCS811_WAKE_GPIOS_CONTROLLER);
|
||||
if (gpio == NULL) {
|
||||
drv_data->wake_gpio = device_get_binding(DT_INST_0_AMS_CCS811_WAKE_GPIOS_CONTROLLER);
|
||||
if (drv_data->wake_gpio == NULL) {
|
||||
LOG_ERR("Failed to get pointer to WAKE device: %s",
|
||||
DT_INST_0_AMS_CCS811_WAKE_GPIOS_CONTROLLER);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
drv_data->gpio = gpio;
|
||||
/*
|
||||
* Wakeup pin should be pulled low before initiating
|
||||
* any I2C transfer. If it has been tied to GND by
|
||||
* default, skip this part.
|
||||
*/
|
||||
gpio_pin_configure(drv_data->wake_gpio, DT_INST_0_AMS_CCS811_WAKE_GPIOS_PIN,
|
||||
GPIO_DIR_OUT);
|
||||
|
||||
set_wake(drv_data, true);
|
||||
k_sleep(1);
|
||||
#endif
|
||||
#ifdef DT_INST_0_AMS_CCS811_RESET_GPIOS_CONTROLLER
|
||||
gpio = device_get_binding(DT_INST_0_AMS_CCS811_RESET_GPIOS_CONTROLLER);
|
||||
if (gpio == NULL) {
|
||||
drv_data->reset_gpio = device_get_binding(DT_INST_0_AMS_CCS811_RESET_GPIOS_CONTROLLER);
|
||||
if (drv_data->reset_gpio == NULL) {
|
||||
LOG_ERR("Failed to get pointer to RESET device: %s",
|
||||
DT_INST_0_AMS_CCS811_RESET_GPIOS_CONTROLLER);
|
||||
return -EINVAL;
|
||||
}
|
||||
gpio_pin_configure(drv_data->reset_gpio, DT_INST_0_AMS_CCS811_RESET_GPIOS_PIN,
|
||||
GPIO_DIR_OUT);
|
||||
gpio_pin_write(drv_data->reset_gpio, DT_INST_0_AMS_CCS811_RESET_GPIOS_PIN, 1);
|
||||
|
||||
if (drv_data->gpio == NULL) {
|
||||
drv_data->gpio = gpio;
|
||||
} else if (drv_data->gpio != gpio) {
|
||||
LOG_ERR("Crossing GPIO devices not supported");
|
||||
k_sleep(1);
|
||||
#endif
|
||||
|
||||
#ifdef DT_INST_0_AMS_CCS811_IRQ_GPIOS_CONTROLLER
|
||||
drv_data->int_gpio = device_get_binding(DT_INST_0_AMS_CCS811_IRQ_GPIOS_CONTROLLER);
|
||||
if (drv_data->int_gpio == NULL) {
|
||||
LOG_ERR("Failed to get pointer to INT device: %s",
|
||||
DT_INST_0_AMS_CCS811_IRQ_GPIOS_CONTROLLER);
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (drv_data->gpio) {
|
||||
#ifdef DT_INST_0_AMS_CCS811_RESET_GPIOS_PIN
|
||||
gpio_pin_configure(drv_data->gpio, DT_INST_0_AMS_CCS811_RESET_GPIOS_PIN,
|
||||
GPIO_DIR_OUT);
|
||||
gpio_pin_write(drv_data->gpio, DT_INST_0_AMS_CCS811_RESET_GPIOS_PIN, 1);
|
||||
|
||||
k_sleep(K_MSEC(1));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Wakeup pin should be pulled low before initiating
|
||||
* any I2C transfer. If it has been tied to GND by
|
||||
* default, skip this part.
|
||||
*/
|
||||
#ifdef DT_INST_0_AMS_CCS811_WAKE_GPIOS_PIN
|
||||
gpio_pin_configure(drv_data->gpio, DT_INST_0_AMS_CCS811_WAKE_GPIOS_PIN,
|
||||
GPIO_DIR_OUT);
|
||||
|
||||
set_wake(drv_data, true);
|
||||
k_sleep(K_MSEC(1));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Reset the device. This saves having to deal with detecting
|
||||
* and validating any errors or configuration inconsistencies
|
||||
* after a reset that left the device running.
|
||||
*/
|
||||
#ifdef DT_INST_0_AMS_CCS811_RESET_GPIOS_PIN
|
||||
gpio_pin_write(drv_data->gpio, DT_INST_0_AMS_CCS811_RESET_GPIOS_PIN, 0);
|
||||
k_busy_wait(15); /* t_RESET */
|
||||
gpio_pin_write(drv_data->gpio, DT_INST_0_AMS_CCS811_RESET_GPIOS_PIN, 1);
|
||||
gpio_pin_write(drv_data->reset_gpio, DT_INST_0_AMS_CCS811_RESET_GPIOS_PIN, 0);
|
||||
k_busy_wait(15); /* t_RESET */
|
||||
gpio_pin_write(drv_data->reset_gpio, DT_INST_0_AMS_CCS811_RESET_GPIOS_PIN, 1);
|
||||
#else
|
||||
{
|
||||
static u8_t const reset_seq[] = {
|
||||
|
@ -347,6 +402,7 @@ int ccs811_init(struct device *dev)
|
|||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
drv_data->mode = meas_mode;
|
||||
|
||||
/* Check for error */
|
||||
status = fetch_status(drv_data->i2c);
|
||||
|
@ -362,6 +418,11 @@ int ccs811_init(struct device *dev)
|
|||
goto out;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CCS811_TRIGGER
|
||||
ret = ccs811_init_interrupt(dev);
|
||||
LOG_DBG("CCS811 interrupt init got %d", ret);
|
||||
#endif
|
||||
|
||||
out:
|
||||
set_wake(drv_data, false);
|
||||
return ret;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#define CCS811_REG_MEAS_MODE 0x01
|
||||
#define CCS811_REG_ALG_RESULT_DATA 0x02
|
||||
#define CCS811_REG_RAW_DATA 0x03
|
||||
#define CCS811_REG_THRESHOLDS 0x10
|
||||
#define CCS811_REG_HW_ID 0x20
|
||||
#define CCS811_REG_HW_VERSION 0x21
|
||||
#define CCS811_REG_HW_VERSION_MASK 0xF0
|
||||
|
@ -38,19 +39,73 @@
|
|||
#define CCS811_MODE_IAQ_10SEC 0x20
|
||||
#define CCS811_MODE_IAQ_60SEC 0x30
|
||||
#define CCS811_MODE_RAW_DATA 0x40
|
||||
#define CCS811_MODE_DATARDY 0x08
|
||||
#define CCS811_MODE_THRESH 0x04
|
||||
|
||||
#define CCS811_VOLTAGE_SCALE 1613
|
||||
|
||||
#define CCS811_VOLTAGE_MASK 0x3FF
|
||||
|
||||
#define CCS811_CO2_MIN_PPM 400
|
||||
#define CCS811_CO2_MAX_PPM 32767
|
||||
|
||||
struct ccs811_data {
|
||||
struct device *i2c;
|
||||
struct device *gpio;
|
||||
#ifdef DT_INST_0_AMS_CCS811_IRQ_GPIOS_CONTROLLER
|
||||
struct device *int_gpio;
|
||||
#ifdef CONFIG_CCS811_TRIGGER
|
||||
/*
|
||||
* DATARDY is configured through SENSOR_CHAN_ALL.
|
||||
* THRESH would be configured through SENSOR_CHAN_CO2.
|
||||
*/
|
||||
struct gpio_callback gpio_cb;
|
||||
sensor_trigger_handler_t handler;
|
||||
struct sensor_trigger trigger;
|
||||
#if defined(CONFIG_CCS811_TRIGGER_OWN_THREAD)
|
||||
K_THREAD_STACK_MEMBER(thread_stack, CONFIG_CCS811_THREAD_STACK_SIZE);
|
||||
struct k_sem gpio_sem;
|
||||
struct k_thread thread;
|
||||
#elif defined(CONFIG_CCS811_TRIGGER_GLOBAL_THREAD)
|
||||
struct k_work work;
|
||||
struct device *dev;
|
||||
#endif
|
||||
u16_t co2_l2m;
|
||||
u16_t co2_m2h;
|
||||
#endif /* CONFIG_CCS811_TRIGGER */
|
||||
#endif
|
||||
#ifdef DT_INST_0_AMS_CCS811_RESET_GPIOS_CONTROLLER
|
||||
struct device *reset_gpio;
|
||||
#endif
|
||||
#ifdef DT_INST_0_AMS_CCS811_WAKE_GPIOS_CONTROLLER
|
||||
struct device *wake_gpio;
|
||||
#endif
|
||||
u16_t co2;
|
||||
u16_t voc;
|
||||
u16_t resistance;
|
||||
u8_t status;
|
||||
u8_t error;
|
||||
u16_t resistance;
|
||||
u8_t mode;
|
||||
};
|
||||
|
||||
#endif /* _SENSOR_CCS811_ */
|
||||
#ifdef CONFIG_CCS811_TRIGGER
|
||||
|
||||
int ccs811_mutate_meas_mode(struct device *dev,
|
||||
u8_t set,
|
||||
u8_t clear);
|
||||
|
||||
int ccs811_set_thresholds(struct device *dev);
|
||||
|
||||
int ccs811_attr_set(struct device *dev,
|
||||
enum sensor_channel chan,
|
||||
enum sensor_attribute attr,
|
||||
const struct sensor_value *val);
|
||||
|
||||
int ccs811_trigger_set(struct device *dev,
|
||||
const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler);
|
||||
|
||||
int ccs811_init_interrupt(struct device *dev);
|
||||
|
||||
#endif /* CONFIG_CCS811_TRIGGER */
|
||||
|
||||
#endif /* _SENSOR_CCS811_ */
|
||||
|
|
177
drivers/sensor/ccs811/ccs811_trigger.c
Normal file
177
drivers/sensor/ccs811/ccs811_trigger.c
Normal file
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Peter Bigot Consulting, LLC
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <sensor.h>
|
||||
#include "ccs811.h"
|
||||
|
||||
#define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_DECLARE(CCS811);
|
||||
|
||||
int ccs811_attr_set(struct device *dev,
|
||||
enum sensor_channel chan,
|
||||
enum sensor_attribute attr,
|
||||
const struct sensor_value *thr)
|
||||
{
|
||||
struct ccs811_data *drv_data = dev->driver_data;
|
||||
int rc;
|
||||
|
||||
if (chan != SENSOR_CHAN_CO2) {
|
||||
rc = -ENOTSUP;
|
||||
} else if (attr == SENSOR_ATTR_LOWER_THRESH) {
|
||||
rc = -EINVAL;
|
||||
if ((thr->val1 >= CCS811_CO2_MIN_PPM)
|
||||
&& (thr->val1 <= CCS811_CO2_MAX_PPM)) {
|
||||
drv_data->co2_l2m = thr->val1;
|
||||
rc = 0;
|
||||
}
|
||||
} else if (attr == SENSOR_ATTR_UPPER_THRESH) {
|
||||
rc = -EINVAL;
|
||||
if ((thr->val1 >= CCS811_CO2_MIN_PPM)
|
||||
&& (thr->val1 <= CCS811_CO2_MAX_PPM)) {
|
||||
drv_data->co2_m2h = thr->val1;
|
||||
rc = 0;
|
||||
}
|
||||
} else {
|
||||
rc = -ENOTSUP;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void gpio_callback(struct device *dev,
|
||||
struct gpio_callback *cb,
|
||||
u32_t pins)
|
||||
{
|
||||
struct ccs811_data *drv_data =
|
||||
CONTAINER_OF(cb, struct ccs811_data, gpio_cb);
|
||||
|
||||
ARG_UNUSED(pins);
|
||||
|
||||
gpio_pin_disable_callback(dev, DT_INST_0_AMS_CCS811_IRQ_GPIOS_PIN);
|
||||
|
||||
#if defined(CONFIG_CCS811_TRIGGER_OWN_THREAD)
|
||||
k_sem_give(&drv_data->gpio_sem);
|
||||
#elif defined(CONFIG_CCS811_TRIGGER_GLOBAL_THREAD)
|
||||
k_work_submit(&drv_data->work);
|
||||
#else
|
||||
#error Unhandled trigger configuration
|
||||
#endif
|
||||
}
|
||||
|
||||
static void thread_cb(void *arg)
|
||||
{
|
||||
struct device *dev = arg;
|
||||
struct ccs811_data *drv_data = dev->driver_data;
|
||||
|
||||
if (drv_data->handler != NULL) {
|
||||
drv_data->handler(dev, &drv_data->trigger);
|
||||
}
|
||||
|
||||
gpio_pin_enable_callback(drv_data->int_gpio, DT_INST_0_AMS_CCS811_IRQ_GPIOS_PIN);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CCS811_TRIGGER_OWN_THREAD
|
||||
static void datardy_thread(int dev_ptr, int unused)
|
||||
{
|
||||
struct device *dev = INT_TO_POINTER(dev_ptr);
|
||||
struct ccs811_data *drv_data = dev->driver_data;
|
||||
|
||||
ARG_UNUSED(unused);
|
||||
|
||||
while (1) {
|
||||
k_sem_take(&drv_data->gpio_sem, K_FOREVER);
|
||||
thread_cb(dev);
|
||||
}
|
||||
}
|
||||
#elif defined(CONFIG_CCS811_TRIGGER_GLOBAL_THREAD)
|
||||
static void work_cb(struct k_work *work)
|
||||
{
|
||||
struct ccs811_data *drv_data =
|
||||
CONTAINER_OF(work, struct ccs811_data, work);
|
||||
|
||||
thread_cb(drv_data->dev);
|
||||
}
|
||||
#else
|
||||
#error Unhandled trigger configuration
|
||||
#endif
|
||||
|
||||
int ccs811_trigger_set(struct device *dev,
|
||||
const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler)
|
||||
{
|
||||
struct ccs811_data *drv_data = dev->driver_data;
|
||||
u8_t drdy_thresh = CCS811_MODE_THRESH | CCS811_MODE_DATARDY;
|
||||
int rc;
|
||||
|
||||
LOG_DBG("CCS811 trigger set");
|
||||
gpio_pin_disable_callback(drv_data->int_gpio, DT_INST_0_AMS_CCS811_IRQ_GPIOS_PIN);
|
||||
if (trig->type == SENSOR_TRIG_DATA_READY) {
|
||||
rc = ccs811_mutate_meas_mode(dev, CCS811_MODE_DATARDY,
|
||||
CCS811_MODE_THRESH);
|
||||
} else if (trig->type == SENSOR_TRIG_THRESHOLD) {
|
||||
rc = -EINVAL;
|
||||
if ((drv_data->co2_l2m >= CCS811_CO2_MIN_PPM)
|
||||
&& (drv_data->co2_l2m <= CCS811_CO2_MAX_PPM)
|
||||
&& (drv_data->co2_m2h >= CCS811_CO2_MIN_PPM)
|
||||
&& (drv_data->co2_m2h <= CCS811_CO2_MAX_PPM)
|
||||
&& (drv_data->co2_l2m <= drv_data->co2_m2h)) {
|
||||
rc = ccs811_set_thresholds(dev);
|
||||
}
|
||||
if (rc == 0) {
|
||||
rc = ccs811_mutate_meas_mode(dev, drdy_thresh, 0);
|
||||
}
|
||||
} else {
|
||||
rc = -ENOTSUP;
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
drv_data->handler = handler;
|
||||
drv_data->trigger = *trig;
|
||||
gpio_pin_enable_callback(drv_data->int_gpio,
|
||||
DT_INST_0_AMS_CCS811_IRQ_GPIOS_PIN);
|
||||
} else {
|
||||
(void)ccs811_mutate_meas_mode(dev, 0, drdy_thresh);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ccs811_init_interrupt(struct device *dev)
|
||||
{
|
||||
struct ccs811_data *drv_data = dev->driver_data;
|
||||
|
||||
#ifndef DT_INST_0_AMS_CCS811_IRQ_GPIOS_PIN
|
||||
return -EINVAL;
|
||||
#endif
|
||||
gpio_pin_configure(drv_data->int_gpio, DT_INST_0_AMS_CCS811_IRQ_GPIOS_PIN,
|
||||
GPIO_DIR_IN | GPIO_INT | GPIO_INT_LEVEL |
|
||||
GPIO_INT_ACTIVE_LOW | GPIO_PUD_PULL_UP |
|
||||
GPIO_INT_DEBOUNCE);
|
||||
|
||||
gpio_init_callback(&drv_data->gpio_cb, gpio_callback,
|
||||
BIT(DT_INST_0_AMS_CCS811_IRQ_GPIOS_PIN));
|
||||
|
||||
if (gpio_add_callback(drv_data->int_gpio, &drv_data->gpio_cb) < 0) {
|
||||
LOG_DBG("Failed to set gpio callback!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_CCS811_TRIGGER_OWN_THREAD)
|
||||
k_sem_init(&drv_data->gpio_sem, 0, UINT_MAX);
|
||||
|
||||
k_thread_create(&drv_data->thread, drv_data->thread_stack,
|
||||
CONFIG_CCS811_THREAD_STACK_SIZE,
|
||||
(k_thread_entry_t)datardy_thread, dev,
|
||||
0, NULL, K_PRIO_COOP(CONFIG_CCS811_THREAD_PRIORITY),
|
||||
0, 0);
|
||||
#elif defined(CONFIG_CCS811_TRIGGER_GLOBAL_THREAD)
|
||||
drv_data->work.handler = work_cb;
|
||||
drv_data->dev = dev;
|
||||
#else
|
||||
#error Unhandled trigger configuration
|
||||
#endif
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue