drivers: sensor: sht3xd: convert to new GPIO APIO
Update ALERT active level in all devicetree files. Capture GPIO flags in static configuration. Add internal API to enable and disable interrupt, to release the handlers when an alert occurs, and to re-enable the signal when the handler completes. Check for alerts received during periods when the interrupt was disabled. Extend the example to handle both above and below range triggers and alerts that are present on startup. Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
parent
5e397842af
commit
a49b364244
11 changed files with 103 additions and 57 deletions
|
@ -232,6 +232,7 @@ static const struct sht3xd_config sht3xd0_cfg = {
|
|||
.base_address = DT_INST_0_SENSIRION_SHT3XD_BASE_ADDRESS,
|
||||
#ifdef CONFIG_SHT3XD_TRIGGER
|
||||
.alert_pin = DT_INST_0_SENSIRION_SHT3XD_ALERT_GPIOS_PIN,
|
||||
.alert_flags = DT_INST_0_SENSIRION_SHT3XD_ALERT_GPIOS_FLAGS,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -51,7 +51,8 @@ struct sht3xd_config {
|
|||
|
||||
u8_t base_address;
|
||||
#ifdef CONFIG_SHT3XD_TRIGGER
|
||||
s8_t alert_pin;
|
||||
u8_t alert_pin;
|
||||
u8_t alert_flags;
|
||||
#endif /* CONFIG_SHT3XD_TRIGGER */
|
||||
};
|
||||
|
||||
|
|
|
@ -81,35 +81,86 @@ int sht3xd_attr_set(struct device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline void setup_alert(struct device *dev,
|
||||
bool enable)
|
||||
{
|
||||
struct sht3xd_data *data = (struct sht3xd_data *)dev->driver_data;
|
||||
const struct sht3xd_config *cfg =
|
||||
(const struct sht3xd_config *)dev->config->config_info;
|
||||
unsigned int flags = enable
|
||||
? GPIO_INT_EDGE_TO_ACTIVE
|
||||
: GPIO_INT_DISABLE;
|
||||
|
||||
gpio_pin_interrupt_configure(data->alert_gpio, cfg->alert_pin, flags);
|
||||
}
|
||||
|
||||
static inline void handle_alert(struct device *dev)
|
||||
{
|
||||
setup_alert(dev, false);
|
||||
|
||||
#if defined(CONFIG_SHT3XD_TRIGGER_OWN_THREAD)
|
||||
struct sht3xd_data *data = (struct sht3xd_data *)dev->driver_data;
|
||||
|
||||
k_sem_give(&data->gpio_sem);
|
||||
#elif defined(CONFIG_SHT3XD_TRIGGER_GLOBAL_THREAD)
|
||||
struct sht3xd_data *data = (struct sht3xd_data *)dev->driver_data;
|
||||
|
||||
k_work_submit(&data->work);
|
||||
#endif
|
||||
}
|
||||
|
||||
int sht3xd_trigger_set(struct device *dev,
|
||||
const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler)
|
||||
{
|
||||
struct sht3xd_data *data = (struct sht3xd_data *)dev->driver_data;
|
||||
const struct sht3xd_config *cfg =
|
||||
(const struct sht3xd_config *)dev->config->config_info;
|
||||
|
||||
setup_alert(dev, false);
|
||||
|
||||
if (trig->type != SENSOR_TRIG_THRESHOLD) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
data->handler = handler;
|
||||
if (handler == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->trigger = *trig;
|
||||
|
||||
setup_alert(dev, true);
|
||||
|
||||
/* If ALERT is active we probably won't get the rising edge,
|
||||
* so invoke the callback manually.
|
||||
*/
|
||||
if (gpio_pin_get(data->alert_gpio, cfg->alert_pin)) {
|
||||
handle_alert(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sht3xd_gpio_callback(struct device *dev,
|
||||
struct gpio_callback *cb, u32_t pins)
|
||||
{
|
||||
struct sht3xd_data *data =
|
||||
CONTAINER_OF(cb, struct sht3xd_data, alert_cb);
|
||||
const struct sht3xd_config *cfg = data->dev->config->config_info;
|
||||
|
||||
ARG_UNUSED(pins);
|
||||
|
||||
gpio_pin_disable_callback(dev, cfg->alert_pin);
|
||||
|
||||
#if defined(CONFIG_SHT3XD_TRIGGER_OWN_THREAD)
|
||||
k_sem_give(&data->gpio_sem);
|
||||
#elif defined(CONFIG_SHT3XD_TRIGGER_GLOBAL_THREAD)
|
||||
k_work_submit(&data->work);
|
||||
#endif
|
||||
handle_alert(data->dev);
|
||||
}
|
||||
|
||||
static void sht3xd_thread_cb(void *arg)
|
||||
{
|
||||
struct device *dev = arg;
|
||||
struct sht3xd_data *data = dev->driver_data;
|
||||
const struct sht3xd_config *cfg = dev->config->config_info;
|
||||
struct device *dev = (struct device *)arg;
|
||||
struct sht3xd_data *data = (struct sht3xd_data *)dev->driver_data;
|
||||
|
||||
if (data->handler != NULL) {
|
||||
data->handler(dev, &data->trigger);
|
||||
}
|
||||
|
||||
gpio_pin_enable_callback(data->alert_gpio, cfg->alert_pin);
|
||||
setup_alert(dev, true);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SHT3XD_TRIGGER_OWN_THREAD
|
||||
|
@ -137,25 +188,6 @@ static void sht3xd_work_cb(struct k_work *work)
|
|||
}
|
||||
#endif
|
||||
|
||||
int sht3xd_trigger_set(struct device *dev,
|
||||
const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler)
|
||||
{
|
||||
struct sht3xd_data *data = dev->driver_data;
|
||||
const struct sht3xd_config *cfg = dev->config->config_info;
|
||||
|
||||
if (trig->type != SENSOR_TRIG_THRESHOLD) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
gpio_pin_disable_callback(data->alert_gpio, cfg->alert_pin);
|
||||
data->handler = handler;
|
||||
data->trigger = *trig;
|
||||
gpio_pin_enable_callback(data->alert_gpio, cfg->alert_pin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sht3xd_init_interrupt(struct device *dev)
|
||||
{
|
||||
struct sht3xd_data *data = dev->driver_data;
|
||||
|
@ -172,9 +204,7 @@ int sht3xd_init_interrupt(struct device *dev)
|
|||
data->alert_gpio = gpio;
|
||||
|
||||
rc = gpio_pin_configure(gpio, cfg->alert_pin,
|
||||
GPIO_DIR_IN | GPIO_INT |
|
||||
GPIO_INT_EDGE | GPIO_INT_DOUBLE_EDGE |
|
||||
GPIO_INT_ACTIVE_HIGH | GPIO_INT_DEBOUNCE);
|
||||
GPIO_INPUT | cfg->alert_flags);
|
||||
if (rc != 0) {
|
||||
LOG_DBG("Failed to configure alert pin %u!", cfg->alert_pin);
|
||||
return -EIO;
|
||||
|
|
|
@ -11,4 +11,9 @@ properties:
|
|||
alert-gpios:
|
||||
type: phandle-array
|
||||
required: false
|
||||
description: ALERT pin
|
||||
description: >
|
||||
ALERT pin.
|
||||
|
||||
This pin signals active high when produced by the sensor. The
|
||||
property value should ensure the flags properly describe the
|
||||
signal that is presented to the driver.
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
compatible = "sensirion,sht3xd";
|
||||
reg = <0x44>;
|
||||
label = "SHT3XD";
|
||||
alert-gpios = <&gpiof 6 GPIO_INT_ACTIVE_HIGH>;
|
||||
alert-gpios = <&gpiof 6 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
compatible = "sensirion,sht3xd";
|
||||
reg = <0x44>;
|
||||
label = "SHT3XD";
|
||||
alert-gpios = <&gpioe 26 GPIO_INT_ACTIVE_HIGH>;
|
||||
alert-gpios = <&gpioe 26 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
compatible = "sensirion,sht3xd";
|
||||
reg = <0x44>;
|
||||
label = "SHT3XD";
|
||||
alert-gpios = <&gpio0 2 GPIO_INT_ACTIVE_HIGH>;
|
||||
alert-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
compatible = "sensirion,sht3xd";
|
||||
reg = <0x44>;
|
||||
label = "SHT3XD";
|
||||
alert-gpios = <&gpio1 10 GPIO_INT_ACTIVE_HIGH>;
|
||||
alert-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
compatible = "sensirion,sht3xd";
|
||||
reg = <0x44>;
|
||||
label = "SHT3XD";
|
||||
alert-gpios = <&gpioa 9 GPIO_INT_ACTIVE_HIGH>;
|
||||
alert-gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
#include <drivers/sensor.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ALERT_HUMIDITY 40
|
||||
#define ALERT_HUMIDITY_LO 50
|
||||
#define ALERT_HUMIDITY_HI 60
|
||||
|
||||
#ifdef CONFIG_SHT3XD_TRIGGER
|
||||
static volatile bool alerted;
|
||||
|
@ -36,8 +37,8 @@ void main(void)
|
|||
.type = SENSOR_TRIG_THRESHOLD,
|
||||
.chan = SENSOR_CHAN_HUMIDITY,
|
||||
};
|
||||
struct sensor_value lo_thr = { 0 };
|
||||
struct sensor_value hi_thr = { ALERT_HUMIDITY };
|
||||
struct sensor_value lo_thr = { ALERT_HUMIDITY_LO };
|
||||
struct sensor_value hi_thr = { ALERT_HUMIDITY_HI };
|
||||
bool last_alerted = false;
|
||||
|
||||
rc = sensor_attr_set(dev, SENSOR_CHAN_HUMIDITY,
|
||||
|
@ -56,17 +57,6 @@ void main(void)
|
|||
while (true) {
|
||||
struct sensor_value temp, hum;
|
||||
|
||||
#ifdef CONFIG_SHT3XD_TRIGGER
|
||||
if (alerted != last_alerted) {
|
||||
static const char *const alert_str[] = {
|
||||
"below",
|
||||
"above",
|
||||
};
|
||||
printf("Humidity %s %d!\n", alert_str[alerted],
|
||||
hi_thr.val1);
|
||||
last_alerted = alerted;
|
||||
}
|
||||
#endif
|
||||
rc = sensor_sample_fetch(dev);
|
||||
if (rc == 0) {
|
||||
rc = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP,
|
||||
|
@ -80,6 +70,23 @@ void main(void)
|
|||
printf("SHT3XD: failed: %d\n", rc);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SHT3XD_TRIGGER
|
||||
if (alerted != last_alerted) {
|
||||
if (lo_thr.val1 > hum.val1) {
|
||||
printf("ALERT: humidity %d < %d\n",
|
||||
hum.val1, lo_thr.val1);
|
||||
} else if (hi_thr.val1 < hum.val1) {
|
||||
printf("ALERT: humidity %d > %d\n",
|
||||
hum.val1, hi_thr.val1);
|
||||
} else {
|
||||
printf("ALERT: humidity %d <= %d <= %d\n",
|
||||
lo_thr.val1, hum.val1, hi_thr.val1);
|
||||
}
|
||||
last_alerted = alerted;
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("SHT3XD: %.2f Cel ; %0.2f %%RH\n",
|
||||
sensor_value_to_double(&temp),
|
||||
sensor_value_to_double(&hum));
|
||||
|
|
|
@ -8,4 +8,6 @@ CONFIG_STDOUT_CONSOLE=y
|
|||
CONFIG_I2C=y
|
||||
CONFIG_SENSOR=y
|
||||
CONFIG_SHT3XD=y
|
||||
CONFIG_LOG=y
|
||||
CONFIG_SENSOR_LOG_LEVEL_DBG=y
|
||||
CONFIG_SHT3XD_TRIGGER_GLOBAL_THREAD=y
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue