drivers: sensor: hs300x: Add driver for Renesas HS300x sensors
Adds support for Renesas HS3001 and HS3003 temperature/humidity sensors connected via an I2C bus. Signed-off-by: Ian Morris <ian.d.morris@outlook.com>
This commit is contained in:
parent
ce3ba0dfd2
commit
4c92419546
7 changed files with 194 additions and 0 deletions
|
@ -47,6 +47,7 @@ add_subdirectory_ifdef(CONFIG_HAS_STMEMSC stmemsc)
|
|||
add_subdirectory_ifdef(CONFIG_HM330X hm330x)
|
||||
add_subdirectory_ifdef(CONFIG_HMC5883L hmc5883l)
|
||||
add_subdirectory_ifdef(CONFIG_HP206C hp206c)
|
||||
add_subdirectory_ifdef(CONFIG_HS300X hs300x)
|
||||
add_subdirectory_ifdef(CONFIG_HTS221 hts221)
|
||||
add_subdirectory_ifdef(CONFIG_I3G4250D i3g4250d)
|
||||
add_subdirectory_ifdef(CONFIG_ICM42605 icm42605)
|
||||
|
|
|
@ -119,6 +119,7 @@ source "drivers/sensor/grow_r502a/Kconfig"
|
|||
source "drivers/sensor/hm330x/Kconfig"
|
||||
source "drivers/sensor/hmc5883l/Kconfig"
|
||||
source "drivers/sensor/hp206c/Kconfig"
|
||||
source "drivers/sensor/hs300x/Kconfig"
|
||||
source "drivers/sensor/hts221/Kconfig"
|
||||
source "drivers/sensor/i3g4250d/Kconfig"
|
||||
source "drivers/sensor/icm42605/Kconfig"
|
||||
|
|
5
drivers/sensor/hs300x/CMakeLists.txt
Normal file
5
drivers/sensor/hs300x/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources(hs300x.c)
|
12
drivers/sensor/hs300x/Kconfig
Normal file
12
drivers/sensor/hs300x/Kconfig
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Renesas HS300x temperature and humidity sensor configuration options
|
||||
|
||||
# Copyright (c) 2023 Ian Morris
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config HS300X
|
||||
bool "HS300x Temperature and Humidity Sensor"
|
||||
default y
|
||||
depends on DT_HAS_RENESAS_HS300X_ENABLED
|
||||
select I2C
|
||||
help
|
||||
Enable driver for HS300x temperature and humidity sensors.
|
160
drivers/sensor/hs300x/hs300x.c
Normal file
160
drivers/sensor/hs300x/hs300x.c
Normal file
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Ian Morris
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT renesas_hs300x
|
||||
|
||||
#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>
|
||||
|
||||
#define HS300X_STATUS_MASK (BIT(0) | BIT(1))
|
||||
|
||||
LOG_MODULE_REGISTER(HS300X, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
struct hs300x_config {
|
||||
struct i2c_dt_spec bus;
|
||||
};
|
||||
|
||||
struct hs300x_data {
|
||||
int16_t t_sample;
|
||||
uint16_t rh_sample;
|
||||
};
|
||||
|
||||
static int hs300x_read_sample(const struct device *dev, uint16_t *t_sample, uint16_t *rh_sample)
|
||||
{
|
||||
const struct hs300x_config *cfg = dev->config;
|
||||
uint8_t rx_buf[4];
|
||||
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;
|
||||
}
|
||||
|
||||
if ((rx_buf[3] & HS300X_STATUS_MASK) != 0) {
|
||||
LOG_ERR("Stale data");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
*rh_sample = sys_get_be16(rx_buf);
|
||||
*t_sample = sys_get_be16(&rx_buf[2]);
|
||||
|
||||
/* Remove status bits (only present in temperature value)*/
|
||||
*t_sample >>= 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hs300x_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
||||
{
|
||||
struct hs300x_data *data = dev->data;
|
||||
const struct hs300x_config *cfg = dev->config;
|
||||
int rc;
|
||||
|
||||
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_AMBIENT_TEMP &&
|
||||
chan != SENSOR_CHAN_HUMIDITY) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initiate a measurement simply by sending 7-bit address followed
|
||||
* by an eighth bit set to 0 (write) and NO data.
|
||||
*/
|
||||
rc = i2c_write_dt(&cfg->bus, NULL, 0);
|
||||
if (rc < 0) {
|
||||
LOG_ERR("Failed to start 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 = hs300x_read_sample(dev, &data->t_sample, &data->rh_sample);
|
||||
if (rc < 0) {
|
||||
LOG_ERR("Failed to fetch data.");
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hs300x_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 hs300x_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 hs300x_channel_get(const struct device *dev, enum sensor_channel chan,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
const struct hs300x_data *data = dev->data;
|
||||
|
||||
if (chan == SENSOR_CHAN_AMBIENT_TEMP) {
|
||||
hs300x_temp_convert(val, data->t_sample);
|
||||
} else if (chan == SENSOR_CHAN_HUMIDITY) {
|
||||
hs300x_rh_convert(val, data->rh_sample);
|
||||
} else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hs300x_init(const struct device *dev)
|
||||
{
|
||||
const struct hs300x_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 const struct sensor_driver_api hs300x_driver_api = {.sample_fetch = hs300x_sample_fetch,
|
||||
.channel_get = hs300x_channel_get};
|
||||
|
||||
#define DEFINE_HS300X(n) \
|
||||
static struct hs300x_data hs300x_data_##n; \
|
||||
\
|
||||
static const struct hs300x_config hs300x_config_##n = {.bus = I2C_DT_SPEC_INST_GET(n)}; \
|
||||
\
|
||||
SENSOR_DEVICE_DT_INST_DEFINE(n, hs300x_init, NULL, &hs300x_data_##n, &hs300x_config_##n, \
|
||||
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
|
||||
&hs300x_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(DEFINE_HS300X)
|
10
dts/bindings/sensor/renesas,hs300x.yaml
Normal file
10
dts/bindings/sensor/renesas,hs300x.yaml
Normal file
|
@ -0,0 +1,10 @@
|
|||
#
|
||||
# Copyright (c) 2023 Ian Morris
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Renesas HS300x humidity and temperature sensor
|
||||
|
||||
compatible: "renesas,hs300x"
|
||||
|
||||
include: [sensor-device.yaml, i2c-device.yaml]
|
|
@ -807,3 +807,8 @@ test_i2c_lps22df: lps22df@79 {
|
|||
drdy-gpios = <&test_gpio 0 0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
test_i2c_hs300x: hs300x@79 {
|
||||
compatible = "renesas,hs300x";
|
||||
reg = <0x79>;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue