Skip to content

Commit 4fa94f6

Browse files
TotallyOriginalUsernamekartben
authored andcommitted
drivers: sensor: Add HS400x driver
Adds Renesas HS400x temperature and humidity sensors driver. Signed-off-by: Mariëlle Korthout <[email protected]>
1 parent 997f6d4 commit 4fa94f6

File tree

6 files changed

+204
-0
lines changed

6 files changed

+204
-0
lines changed

drivers/sensor/renesas/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33

44
# zephyr-keep-sorted-start
55
add_subdirectory_ifdef(CONFIG_HS300X hs300x)
6+
add_subdirectory_ifdef(CONFIG_HS400X hs400x)
67
add_subdirectory_ifdef(CONFIG_ISL29035 isl29035)
78
# zephyr-keep-sorted-stop

drivers/sensor/renesas/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33

44
# zephyr-keep-sorted-start
55
source "drivers/sensor/renesas/hs300x/Kconfig"
6+
source "drivers/sensor/renesas/hs400x/Kconfig"
67
source "drivers/sensor/renesas/isl29035/Kconfig"
78
# zephyr-keep-sorted-stop
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
zephyr_library()
4+
5+
zephyr_library_sources(hs400x.c)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# HS400X temperature and humidity sensor
2+
3+
# Copyright (c) 2024 Renesas Electronics Corporation
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
config HS400X
7+
bool "HS400x sensor"
8+
default y
9+
depends on DT_HAS_RENESAS_HS400X_ENABLED
10+
help
11+
Enable driver for HS400x temperature and humidity sensors.
12+
13+
if HS400X
14+
15+
config HS400X_CRC
16+
bool "HS400X CRC check"
17+
select CRC
18+
help
19+
Verify the checksum byte from measurements
20+
21+
endif # HS400x
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
* Copyright (c) 2024 Renesas Electronics Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT renesas_hs400x
8+
9+
#include <zephyr/device.h>
10+
#include <zephyr/drivers/i2c.h>
11+
#include <zephyr/kernel.h>
12+
#include <zephyr/drivers/sensor.h>
13+
#include <zephyr/sys/__assert.h>
14+
#include <zephyr/logging/log.h>
15+
#include <zephyr/sys/byteorder.h>
16+
#include <zephyr/sys/crc.h>
17+
18+
#define CRC_POLYNOMIAL 0x1D
19+
#define CRC_INITIAL 0xFF
20+
21+
LOG_MODULE_REGISTER(HS400X, CONFIG_SENSOR_LOG_LEVEL);
22+
23+
struct hs400x_config {
24+
struct i2c_dt_spec bus;
25+
};
26+
27+
struct hs400x_data {
28+
int16_t t_sample;
29+
uint16_t rh_sample;
30+
};
31+
32+
static int hs400x_read_sample(const struct device *dev, uint16_t *t_sample, uint16_t *rh_sample)
33+
{
34+
const struct hs400x_config *cfg = dev->config;
35+
uint8_t rx_buf[5];
36+
int rc;
37+
38+
rc = i2c_read_dt(&cfg->bus, rx_buf, sizeof(rx_buf));
39+
if (rc < 0) {
40+
LOG_ERR("Failed to read data from device.");
41+
return rc;
42+
}
43+
44+
*rh_sample = sys_get_be16(rx_buf);
45+
*t_sample = sys_get_be16(&rx_buf[2]);
46+
47+
/*
48+
* The sensor sends a checkum after each measurement. See datasheet "CRC Checksum
49+
* Calculation" section for more details on checking the checksum.
50+
*/
51+
#if CONFIG_HS400X_CRC
52+
uint8_t crc = crc8(rx_buf, 4, CRC_POLYNOMIAL, CRC_INITIAL, 0);
53+
54+
if (crc != rx_buf[4]) {
55+
LOG_ERR("CRC check failed: computed=%u,expected=%u", crc, rx_buf[4]);
56+
return -EIO;
57+
}
58+
#endif
59+
60+
return 0;
61+
}
62+
63+
static int hs400x_sample_fetch(const struct device *dev, enum sensor_channel chan)
64+
{
65+
struct hs400x_data *data = dev->data;
66+
const struct hs400x_config *cfg = dev->config;
67+
int rc;
68+
uint8_t no_hold_measurement = 0xF5;
69+
70+
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_AMBIENT_TEMP &&
71+
chan != SENSOR_CHAN_HUMIDITY) {
72+
return -ENOTSUP;
73+
}
74+
75+
rc = i2c_write_dt(&cfg->bus, (const uint8_t *)&no_hold_measurement, 1);
76+
if (rc < 0) {
77+
LOG_ERR("Failed to send measurement.");
78+
return rc;
79+
}
80+
81+
/*
82+
* According to datasheet maximum time to make temperature and humidity
83+
* measurements is 33ms, add a little safety margin...
84+
*/
85+
k_msleep(50);
86+
87+
rc = hs400x_read_sample(dev, &data->t_sample, &data->rh_sample);
88+
if (rc < 0) {
89+
LOG_ERR("Failed to fetch data.");
90+
return rc;
91+
}
92+
93+
return 0;
94+
}
95+
96+
static void hs400x_temp_convert(struct sensor_value *val, int16_t raw)
97+
{
98+
int32_t micro_c;
99+
100+
/*
101+
* Convert to micro Celsius. See datasheet "Calculating Humidity and
102+
* Temperature Output" section for more details on processing sample data.
103+
*/
104+
micro_c = (((int64_t)raw * 165000000) / 16383) - 40000000;
105+
106+
val->val1 = micro_c / 1000000;
107+
val->val2 = micro_c % 1000000;
108+
}
109+
110+
static void hs400x_rh_convert(struct sensor_value *val, uint16_t raw)
111+
{
112+
int32_t micro_rh;
113+
114+
/*
115+
* Convert to micro %RH. See datasheet "Calculating Humidity and
116+
* Temperature Output" section for more details on processing sample data.
117+
*/
118+
micro_rh = ((uint64_t)raw * 100000000) / 16383;
119+
120+
val->val1 = micro_rh / 1000000;
121+
val->val2 = micro_rh % 1000000;
122+
}
123+
124+
static int hs400x_channel_get(const struct device *dev, enum sensor_channel chan,
125+
struct sensor_value *val)
126+
{
127+
const struct hs400x_data *data = dev->data;
128+
129+
if (chan == SENSOR_CHAN_AMBIENT_TEMP) {
130+
hs400x_temp_convert(val, data->t_sample);
131+
} else if (chan == SENSOR_CHAN_HUMIDITY) {
132+
hs400x_rh_convert(val, data->rh_sample);
133+
} else {
134+
return -ENOTSUP;
135+
}
136+
137+
return 0;
138+
}
139+
140+
static int hs400x_init(const struct device *dev)
141+
{
142+
const struct hs400x_config *cfg = dev->config;
143+
144+
if (!i2c_is_ready_dt(&cfg->bus)) {
145+
LOG_ERR("I2C dev %s not ready", cfg->bus.bus->name);
146+
return -ENODEV;
147+
}
148+
149+
return 0;
150+
}
151+
152+
static DEVICE_API(sensor, hs400x_driver_api) = {
153+
.sample_fetch = hs400x_sample_fetch,
154+
.channel_get = hs400x_channel_get,
155+
};
156+
157+
#define DEFINE_HS400X(n) \
158+
static struct hs400x_data hs400x_data_##n; \
159+
\
160+
static const struct hs400x_config hs400x_config_##n = {.bus = I2C_DT_SPEC_INST_GET(n)}; \
161+
\
162+
SENSOR_DEVICE_DT_INST_DEFINE(n, hs400x_init, NULL, &hs400x_data_##n, &hs400x_config_##n, \
163+
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
164+
&hs400x_driver_api);
165+
166+
DT_INST_FOREACH_STATUS_OKAY(DEFINE_HS400X)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#
2+
# Copyright (c) 2024 Renesas Electronics Corporation
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
description: Renesas HS400x humidity and temperature sensor
7+
8+
compatible: "renesas,hs400x"
9+
10+
include: [sensor-device.yaml, i2c-device.yaml]

0 commit comments

Comments
 (0)