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:
Peter Bigot 2019-11-03 12:33:06 -06:00 committed by Carles Cufí
commit a49b364244
11 changed files with 103 additions and 57 deletions

View file

@ -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
};

View file

@ -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 */
};

View file

@ -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;

View file

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

View file

@ -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>;
};
};

View file

@ -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>;
};
};

View file

@ -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>;
};
};

View file

@ -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>;
};
};

View file

@ -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>;
};
};

View file

@ -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));

View file

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