drivers: sensors: ti_hdc20xx: add support for DRDY/INT pin
Add optional support for the DRDY/INT pin. This avoids waiting a fixed time for the temperature and humidity conversion to finish. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
28f9a7614b
commit
117090c1a2
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <drivers/i2c.h>
|
||||
#include <drivers/sensor.h>
|
||||
#include <sys/byteorder.h>
|
||||
|
@ -16,6 +17,7 @@ LOG_MODULE_REGISTER(TI_HDC20XX, CONFIG_SENSOR_LOG_LEVEL);
|
|||
/* Register addresses */
|
||||
#define TI_HDC20XX_REG_TEMP 0x00
|
||||
#define TI_HDC20XX_REG_HUMIDITY 0x02
|
||||
#define TI_HDC20XX_REG_INT_EN 0x07
|
||||
#define TI_HDC20XX_REG_CONFIG 0x0E
|
||||
#define TI_HDC20XX_REG_MEAS_CFG 0x0F
|
||||
#define TI_HDC20XX_REG_MANUFACTURER_ID 0xFC
|
||||
|
@ -26,7 +28,9 @@ LOG_MODULE_REGISTER(TI_HDC20XX, CONFIG_SENSOR_LOG_LEVEL);
|
|||
#define TI_HDC20XX_DEVICE_ID 0x07D0
|
||||
|
||||
/* Register bits */
|
||||
#define TI_HDC20XX_BIT_INT_EN_DRDY_EN 0x80
|
||||
#define TI_HDC20XX_BIT_CONFIG_SOFT_RES 0x80
|
||||
#define TI_HDC20XX_BIT_CONFIG_DRDY_INT_EN 0x04
|
||||
|
||||
/* Reset time: not in the datasheet, but found by trial and error */
|
||||
#define TI_HDC20XX_RESET_TIME K_MSEC(1)
|
||||
|
@ -41,13 +45,27 @@ LOG_MODULE_REGISTER(TI_HDC20XX, CONFIG_SENSOR_LOG_LEVEL);
|
|||
|
||||
struct ti_hdc20xx_config {
|
||||
struct i2c_dt_spec bus;
|
||||
struct gpio_dt_spec gpio_int;
|
||||
};
|
||||
|
||||
struct ti_hdc20xx_data {
|
||||
struct gpio_callback cb_int;
|
||||
struct k_sem sem_int;
|
||||
|
||||
uint16_t t_sample;
|
||||
uint16_t rh_sample;
|
||||
};
|
||||
|
||||
static void ti_hdc20xx_int_callback(const struct device *dev,
|
||||
struct gpio_callback *cb, uint32_t pins)
|
||||
{
|
||||
struct ti_hdc20xx_data *data = CONTAINER_OF(cb, struct ti_hdc20xx_data, cb_int);
|
||||
|
||||
ARG_UNUSED(pins);
|
||||
|
||||
k_sem_give(&data->sem_int);
|
||||
}
|
||||
|
||||
static int ti_hdc20xx_sample_fetch(const struct device *dev,
|
||||
enum sensor_channel chan)
|
||||
{
|
||||
|
@ -66,7 +84,11 @@ static int ti_hdc20xx_sample_fetch(const struct device *dev,
|
|||
}
|
||||
|
||||
/* wait for the conversion to finish */
|
||||
k_sleep(TI_HDC20XX_CONVERSION_TIME);
|
||||
if (config->gpio_int.port) {
|
||||
k_sem_take(&data->sem_int, K_FOREVER);
|
||||
} else {
|
||||
k_sleep(TI_HDC20XX_CONVERSION_TIME);
|
||||
}
|
||||
|
||||
/* temperature and humidity registers are consecutive, read them in the same burst */
|
||||
rc = i2c_burst_read_dt(&config->bus, TI_HDC20XX_REG_TEMP, (uint8_t *)buf, sizeof(buf));
|
||||
|
@ -136,6 +158,7 @@ static int ti_hdc20xx_reset(const struct device *dev)
|
|||
static int ti_hdc20xx_init(const struct device *dev)
|
||||
{
|
||||
const struct ti_hdc20xx_config *config = dev->config;
|
||||
struct ti_hdc20xx_data *data = dev->data;
|
||||
uint16_t buf[2];
|
||||
int rc;
|
||||
|
||||
|
@ -167,6 +190,54 @@ static int ti_hdc20xx_init(const struct device *dev)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* Configure the interrupt GPIO if available */
|
||||
if (config->gpio_int.port) {
|
||||
if (!device_is_ready(config->gpio_int.port)) {
|
||||
LOG_ERR("Cannot get pointer to gpio interrupt device");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rc = gpio_pin_configure_dt(&config->gpio_int, GPIO_INPUT);
|
||||
if (rc) {
|
||||
LOG_ERR("Failed to configure interrupt pin");
|
||||
return rc;
|
||||
}
|
||||
|
||||
gpio_init_callback(&data->cb_int, ti_hdc20xx_int_callback,
|
||||
BIT(config->gpio_int.pin));
|
||||
|
||||
rc = gpio_add_callback(config->gpio_int.port, &data->cb_int);
|
||||
if (rc) {
|
||||
LOG_ERR("Failed to set interrupt callback");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = gpio_pin_interrupt_configure_dt(&config->gpio_int, GPIO_INT_EDGE_TO_ACTIVE);
|
||||
if (rc) {
|
||||
LOG_ERR("Failed to configure interrupt");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Initialize the semaphore */
|
||||
k_sem_init(&data->sem_int, 0, K_SEM_MAX_LIMIT);
|
||||
|
||||
/* Enable the data ready interrupt */
|
||||
rc = i2c_reg_write_byte_dt(&config->bus, TI_HDC20XX_REG_INT_EN,
|
||||
TI_HDC20XX_BIT_INT_EN_DRDY_EN);
|
||||
if (rc) {
|
||||
LOG_ERR("Failed to enable the data ready interrupt");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Enable the interrupt pin with level sensitive active low polarity */
|
||||
rc = i2c_reg_write_byte_dt(&config->bus, TI_HDC20XX_REG_CONFIG,
|
||||
TI_HDC20XX_BIT_CONFIG_DRDY_INT_EN);
|
||||
if (rc) {
|
||||
LOG_ERR("Failed to enable the interrupt pin");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -175,6 +246,7 @@ static int ti_hdc20xx_init(const struct device *dev)
|
|||
static struct ti_hdc20xx_data ti_hdc20xx_data_##compat##inst; \
|
||||
static const struct ti_hdc20xx_config ti_hdc20xx_config_##compat##inst = { \
|
||||
.bus = I2C_DT_SPEC_GET(DT_INST(inst, compat)), \
|
||||
.gpio_int = GPIO_DT_SPEC_GET_OR(DT_INST(inst, compat), int_gpios, {0}), \
|
||||
}; \
|
||||
DEVICE_DT_DEFINE(DT_INST(inst, compat), \
|
||||
ti_hdc20xx_init, \
|
||||
|
|
|
@ -6,3 +6,13 @@ description: Texas Instruments HDC20XX Temperature and Humidity Sensor
|
|||
compatible: "ti,hdc20xx"
|
||||
|
||||
include: i2c-device.yaml
|
||||
|
||||
properties:
|
||||
int-gpios:
|
||||
type: phandle-array
|
||||
required: false
|
||||
description: DRDY/INT pin.
|
||||
|
||||
The DRDY/INT pin of HDC20xx sensor is open-drain, active low. If
|
||||
connected directly the MCU pin should be configured as pull-up
|
||||
as pull-up, active low.
|
||||
|
|
Loading…
Reference in a new issue