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
2 changed files with 83 additions and 1 deletions
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
#include <drivers/gpio.h>
|
||||||
#include <drivers/i2c.h>
|
#include <drivers/i2c.h>
|
||||||
#include <drivers/sensor.h>
|
#include <drivers/sensor.h>
|
||||||
#include <sys/byteorder.h>
|
#include <sys/byteorder.h>
|
||||||
|
@ -16,6 +17,7 @@ LOG_MODULE_REGISTER(TI_HDC20XX, CONFIG_SENSOR_LOG_LEVEL);
|
||||||
/* Register addresses */
|
/* Register addresses */
|
||||||
#define TI_HDC20XX_REG_TEMP 0x00
|
#define TI_HDC20XX_REG_TEMP 0x00
|
||||||
#define TI_HDC20XX_REG_HUMIDITY 0x02
|
#define TI_HDC20XX_REG_HUMIDITY 0x02
|
||||||
|
#define TI_HDC20XX_REG_INT_EN 0x07
|
||||||
#define TI_HDC20XX_REG_CONFIG 0x0E
|
#define TI_HDC20XX_REG_CONFIG 0x0E
|
||||||
#define TI_HDC20XX_REG_MEAS_CFG 0x0F
|
#define TI_HDC20XX_REG_MEAS_CFG 0x0F
|
||||||
#define TI_HDC20XX_REG_MANUFACTURER_ID 0xFC
|
#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
|
#define TI_HDC20XX_DEVICE_ID 0x07D0
|
||||||
|
|
||||||
/* Register bits */
|
/* Register bits */
|
||||||
|
#define TI_HDC20XX_BIT_INT_EN_DRDY_EN 0x80
|
||||||
#define TI_HDC20XX_BIT_CONFIG_SOFT_RES 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 */
|
/* Reset time: not in the datasheet, but found by trial and error */
|
||||||
#define TI_HDC20XX_RESET_TIME K_MSEC(1)
|
#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 ti_hdc20xx_config {
|
||||||
struct i2c_dt_spec bus;
|
struct i2c_dt_spec bus;
|
||||||
|
struct gpio_dt_spec gpio_int;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ti_hdc20xx_data {
|
struct ti_hdc20xx_data {
|
||||||
|
struct gpio_callback cb_int;
|
||||||
|
struct k_sem sem_int;
|
||||||
|
|
||||||
uint16_t t_sample;
|
uint16_t t_sample;
|
||||||
uint16_t rh_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,
|
static int ti_hdc20xx_sample_fetch(const struct device *dev,
|
||||||
enum sensor_channel chan)
|
enum sensor_channel chan)
|
||||||
{
|
{
|
||||||
|
@ -66,7 +84,11 @@ static int ti_hdc20xx_sample_fetch(const struct device *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait for the conversion to finish */
|
/* wait for the conversion to finish */
|
||||||
|
if (config->gpio_int.port) {
|
||||||
|
k_sem_take(&data->sem_int, K_FOREVER);
|
||||||
|
} else {
|
||||||
k_sleep(TI_HDC20XX_CONVERSION_TIME);
|
k_sleep(TI_HDC20XX_CONVERSION_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
/* temperature and humidity registers are consecutive, read them in the same burst */
|
/* 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));
|
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)
|
static int ti_hdc20xx_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct ti_hdc20xx_config *config = dev->config;
|
const struct ti_hdc20xx_config *config = dev->config;
|
||||||
|
struct ti_hdc20xx_data *data = dev->data;
|
||||||
uint16_t buf[2];
|
uint16_t buf[2];
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -167,6 +190,54 @@ static int ti_hdc20xx_init(const struct device *dev)
|
||||||
return rc;
|
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;
|
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 struct ti_hdc20xx_data ti_hdc20xx_data_##compat##inst; \
|
||||||
static const struct ti_hdc20xx_config ti_hdc20xx_config_##compat##inst = { \
|
static const struct ti_hdc20xx_config ti_hdc20xx_config_##compat##inst = { \
|
||||||
.bus = I2C_DT_SPEC_GET(DT_INST(inst, compat)), \
|
.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), \
|
DEVICE_DT_DEFINE(DT_INST(inst, compat), \
|
||||||
ti_hdc20xx_init, \
|
ti_hdc20xx_init, \
|
||||||
|
|
|
@ -6,3 +6,13 @@ description: Texas Instruments HDC20XX Temperature and Humidity Sensor
|
||||||
compatible: "ti,hdc20xx"
|
compatible: "ti,hdc20xx"
|
||||||
|
|
||||||
include: i2c-device.yaml
|
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…
Add table
Add a link
Reference in a new issue