Browse Source

drivers: sensor: Add HS400x driver

Adds Renesas HS400x temperature and humidity sensors driver.
Signed-off-by: Mariëlle Korthout <marielle.korthout.jc@renesas.com>
pull/83256/head
Mariëlle Korthout 9 months ago committed by Benjamin Cabé
parent
commit
4fa94f6742
  1. 1
      drivers/sensor/renesas/CMakeLists.txt
  2. 1
      drivers/sensor/renesas/Kconfig
  3. 5
      drivers/sensor/renesas/hs400x/CMakeLists.txt
  4. 21
      drivers/sensor/renesas/hs400x/Kconfig
  5. 166
      drivers/sensor/renesas/hs400x/hs400x.c
  6. 10
      dts/bindings/sensor/renesas,hs400x.yaml

1
drivers/sensor/renesas/CMakeLists.txt

@ -3,5 +3,6 @@ @@ -3,5 +3,6 @@
# zephyr-keep-sorted-start
add_subdirectory_ifdef(CONFIG_HS300X hs300x)
add_subdirectory_ifdef(CONFIG_HS400X hs400x)
add_subdirectory_ifdef(CONFIG_ISL29035 isl29035)
# zephyr-keep-sorted-stop

1
drivers/sensor/renesas/Kconfig

@ -3,5 +3,6 @@ @@ -3,5 +3,6 @@
# zephyr-keep-sorted-start
source "drivers/sensor/renesas/hs300x/Kconfig"
source "drivers/sensor/renesas/hs400x/Kconfig"
source "drivers/sensor/renesas/isl29035/Kconfig"
# zephyr-keep-sorted-stop

5
drivers/sensor/renesas/hs400x/CMakeLists.txt

@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_library()
zephyr_library_sources(hs400x.c)

21
drivers/sensor/renesas/hs400x/Kconfig

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
# HS400X temperature and humidity sensor
# Copyright (c) 2024 Renesas Electronics Corporation
# SPDX-License-Identifier: Apache-2.0
config HS400X
bool "HS400x sensor"
default y
depends on DT_HAS_RENESAS_HS400X_ENABLED
help
Enable driver for HS400x temperature and humidity sensors.
if HS400X
config HS400X_CRC
bool "HS400X CRC check"
select CRC
help
Verify the checksum byte from measurements
endif # HS400x

166
drivers/sensor/renesas/hs400x/hs400x.c

@ -0,0 +1,166 @@ @@ -0,0 +1,166 @@
/*
* Copyright (c) 2024 Renesas Electronics Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT renesas_hs400x
#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/crc.h>
#define CRC_POLYNOMIAL 0x1D
#define CRC_INITIAL 0xFF
LOG_MODULE_REGISTER(HS400X, CONFIG_SENSOR_LOG_LEVEL);
struct hs400x_config {
struct i2c_dt_spec bus;
};
struct hs400x_data {
int16_t t_sample;
uint16_t rh_sample;
};
static int hs400x_read_sample(const struct device *dev, uint16_t *t_sample, uint16_t *rh_sample)
{
const struct hs400x_config *cfg = dev->config;
uint8_t rx_buf[5];
int rc;
rc = i2c_read_dt(&cfg->bus, rx_buf, sizeof(rx_buf));
if (rc < 0) {
LOG_ERR("Failed to read data from device.");
return rc;
}
*rh_sample = sys_get_be16(rx_buf);
*t_sample = sys_get_be16(&rx_buf[2]);
/*
* The sensor sends a checkum after each measurement. See datasheet "CRC Checksum
* Calculation" section for more details on checking the checksum.
*/
#if CONFIG_HS400X_CRC
uint8_t crc = crc8(rx_buf, 4, CRC_POLYNOMIAL, CRC_INITIAL, 0);
if (crc != rx_buf[4]) {
LOG_ERR("CRC check failed: computed=%u,expected=%u", crc, rx_buf[4]);
return -EIO;
}
#endif
return 0;
}
static int hs400x_sample_fetch(const struct device *dev, enum sensor_channel chan)
{
struct hs400x_data *data = dev->data;
const struct hs400x_config *cfg = dev->config;
int rc;
uint8_t no_hold_measurement = 0xF5;
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_AMBIENT_TEMP &&
chan != SENSOR_CHAN_HUMIDITY) {
return -ENOTSUP;
}
rc = i2c_write_dt(&cfg->bus, (const uint8_t *)&no_hold_measurement, 1);
if (rc < 0) {
LOG_ERR("Failed to send measurement.");
return rc;
}
/*
* According to datasheet maximum time to make temperature and humidity
* measurements is 33ms, add a little safety margin...
*/
k_msleep(50);
rc = hs400x_read_sample(dev, &data->t_sample, &data->rh_sample);
if (rc < 0) {
LOG_ERR("Failed to fetch data.");
return rc;
}
return 0;
}
static void hs400x_temp_convert(struct sensor_value *val, int16_t raw)
{
int32_t micro_c;
/*
* Convert to micro Celsius. See datasheet "Calculating Humidity and
* Temperature Output" section for more details on processing sample data.
*/
micro_c = (((int64_t)raw * 165000000) / 16383) - 40000000;
val->val1 = micro_c / 1000000;
val->val2 = micro_c % 1000000;
}
static void hs400x_rh_convert(struct sensor_value *val, uint16_t raw)
{
int32_t micro_rh;
/*
* Convert to micro %RH. See datasheet "Calculating Humidity and
* Temperature Output" section for more details on processing sample data.
*/
micro_rh = ((uint64_t)raw * 100000000) / 16383;
val->val1 = micro_rh / 1000000;
val->val2 = micro_rh % 1000000;
}
static int hs400x_channel_get(const struct device *dev, enum sensor_channel chan,
struct sensor_value *val)
{
const struct hs400x_data *data = dev->data;
if (chan == SENSOR_CHAN_AMBIENT_TEMP) {
hs400x_temp_convert(val, data->t_sample);
} else if (chan == SENSOR_CHAN_HUMIDITY) {
hs400x_rh_convert(val, data->rh_sample);
} else {
return -ENOTSUP;
}
return 0;
}
static int hs400x_init(const struct device *dev)
{
const struct hs400x_config *cfg = dev->config;
if (!i2c_is_ready_dt(&cfg->bus)) {
LOG_ERR("I2C dev %s not ready", cfg->bus.bus->name);
return -ENODEV;
}
return 0;
}
static DEVICE_API(sensor, hs400x_driver_api) = {
.sample_fetch = hs400x_sample_fetch,
.channel_get = hs400x_channel_get,
};
#define DEFINE_HS400X(n) \
static struct hs400x_data hs400x_data_##n; \
\
static const struct hs400x_config hs400x_config_##n = {.bus = I2C_DT_SPEC_INST_GET(n)}; \
\
SENSOR_DEVICE_DT_INST_DEFINE(n, hs400x_init, NULL, &hs400x_data_##n, &hs400x_config_##n, \
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
&hs400x_driver_api);
DT_INST_FOREACH_STATUS_OKAY(DEFINE_HS400X)

10
dts/bindings/sensor/renesas,hs400x.yaml

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
#
# Copyright (c) 2024 Renesas Electronics Corporation
#
# SPDX-License-Identifier: Apache-2.0
description: Renesas HS400x humidity and temperature sensor
compatible: "renesas,hs400x"
include: [sensor-device.yaml, i2c-device.yaml]
Loading…
Cancel
Save