Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers: sensor: Added support for htu21d sensor #3

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@
/drivers/sensor/ams_iAQcore/ @alexanderwachter
/drivers/sensor/ens210/ @alexanderwachter
/drivers/sensor/hts*/ @avisconti
/drivers/sensor/htu21d*/ @arun-mani-tech
/drivers/sensor/ina23*/ @bbilas
/drivers/sensor/lis*/ @avisconti
/drivers/sensor/lps*/ @avisconti
Expand Down Expand Up @@ -535,6 +536,7 @@
/dts/bindings/*/raspberrypi*pico* @yonsch
/dts/bindings/*/st* @erwango
/dts/bindings/sensor/ams* @alexanderwachter
/dts/bindings/sensor/te,htu21d.yaml @arun-mani-tech
/dts/bindings/*/sifive* @mateusz-holenko @kgugala @pgielda
/dts/bindings/*/litex* @mateusz-holenko @kgugala @pgielda
/dts/bindings/*/vexriscv* @mateusz-holenko @kgugala @pgielda
Expand Down Expand Up @@ -688,6 +690,7 @@
/samples/net/sockets/coap_*/ @rlubos
/samples/net/sockets/ @rlubos @tbursztyka @pfalcon
/samples/sensor/ @MaureenHelm
/samples/sensor/htu21d @arun-mani-tech
/samples/shields/ @avisconti
/samples/subsys/logging/ @nordic-krch @jakub-uC
/samples/subsys/logging/syst/ @dcpleung
Expand Down
1 change: 1 addition & 0 deletions drivers/sensor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ add_subdirectory_ifdef(CONFIG_SX9500 sx9500)
add_subdirectory_ifdef(CONFIG_TH02 th02)
add_subdirectory_ifdef(CONFIG_TMP007 tmp007)
add_subdirectory_ifdef(CONFIG_TMP108 tmp108)
add_subdirectory_ifdef(CONFIG_HTU21D htu21d)
add_subdirectory_ifdef(CONFIG_TMP112 tmp112)
add_subdirectory_ifdef(CONFIG_TMP116 tmp116)
add_subdirectory_ifdef(CONFIG_VCNL4040 vcnl4040)
Expand Down
2 changes: 2 additions & 0 deletions drivers/sensor/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ source "drivers/sensor/lps22hh/Kconfig"

source "drivers/sensor/lps25hb/Kconfig"

source "drivers/sensor/htu21d/Kconfig"

source "drivers/sensor/lsm303dlhc_magn/Kconfig"

source "drivers/sensor/lsm6ds0/Kconfig"
Expand Down
7 changes: 7 additions & 0 deletions drivers/sensor/htu21d/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright (c) 2022 Linumiz
#
# SPDX-License-Identifier: Apache-2.0

zephyr_library()

zephyr_library_sources(htu21d.c)
23 changes: 23 additions & 0 deletions drivers/sensor/htu21d/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# HTU21D temperature & humidity sensor configuration option
#
# Copyright (c) 2022 Linumiz
# Author: Arunmani <arunmani@linumiz.com>
#
# SPDX-License-Identifier: Apache-2.0


config HTU21D
bool "Enable htu21d sensor"
default y
depends on DT_HAS_TE_HTU21D_ENABLED
depends on I2C
help
Enable driver for HTU21D sensor.

if HTU21D

config HTU21D_NH_MASTER
bool "Allow no hold master mode"
arun-mani-tech marked this conversation as resolved.
Show resolved Hide resolved
help
To activate no hold master mode
endif
186 changes: 186 additions & 0 deletions drivers/sensor/htu21d/htu21d.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/* HTU21D temperature & humidity sensor with i2c
*
* Copyright (c) 2022 Linumiz
* Author: Arunmani <arunmani@linumiz.com>
*
* SPDX-License-Identifier: Apache-2.0
*/

#define DT_DRV_COMPAT te_htu21d

#include <zephyr/kernel.h>
#include <stdio.h>
#include <zephyr/sys/printk.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(htu21d, CONFIG_SENSOR_LOG_LEVEL);

#include "htu21d.h"

#define HTU21D_MODIFIER ((float)(0xFFFF))
#define HTU21D_TEMP_MULTIPLIER 175.72
#define HTU21D_TEMP_OFFSET -46.85
#define HTU21D_HUM_MULTIPILER 125.0
#define HTU21D_HUM_ADD -6.0
#define HTU21D_DECIMAL 10000
#define HTU21D_MICRO 100

struct htu21d_data {
int32_t temp;
int32_t humidity;
};

struct htu21d_dev_config {
struct i2c_dt_spec bus;
};

static int send_device_cmd(const struct device *dev, uint16_t *val, uint8_t cmd)
{
int ret;
arun-mani-tech marked this conversation as resolved.
Show resolved Hide resolved
const struct htu21d_dev_config *cfg = dev->config;

/*to write register address*/
ret = i2c_write_dt(&cfg->bus, &cmd, sizeof(cmd));
if (ret != 0) {
return ret;
}

/*read values*/
ret = i2c_read_dt(&cfg->bus, (uint8_t *)val, sizeof(*val));
if (ret != 0) {
return ret;
}

if (IS_ENABLED(CONFIG_HTU21D_NH_MASTER)) {
k_sleep(K_MSEC(MEASURE_WAIT_MS));
}

*val = sys_get_be16((uint8_t *)val);

return 0;
}

static int htu21d_sample_fetch(const struct device *dev,
enum sensor_channel chan)
{
struct htu21d_data *drv_data = dev->data;
uint16_t value;
int ret;
drv_data->temp = 0U;
drv_data->humidity = 0U;

switch (chan) {
case SENSOR_CHAN_AMBIENT_TEMP:
/* Trigger Temperature Measurement*/
ret = send_device_cmd(dev, &value,
(IS_ENABLED(CONFIG_HTU21D_NH_MASTER)
? HTU21D_READ_TEMP_NH :
HTU21D_READ_TEMP_H));
if (ret)
return ret;

drv_data->temp = value;
break;
arun-mani-tech marked this conversation as resolved.
Show resolved Hide resolved
case SENSOR_CHAN_HUMIDITY:
/* Trigger Humidity Measurement*/
ret = send_device_cmd(dev, &value,
(IS_ENABLED(CONFIG_HTU21D_NH_MASTER)
? HTU21D_READ_HUMID_NH :
HTU21D_READ_HUMID_H));
if (ret)
return ret;

drv_data->humidity = value;
break;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

default:
return -ENOTSUP;
}
return 0;
}

static int htu21d_channel_get(const struct device *dev,
enum sensor_channel chan,
arun-mani-tech marked this conversation as resolved.
Show resolved Hide resolved
struct sensor_value *val)
{
struct htu21d_data *drv_data = dev->data;
double result;
float float_val;

switch (chan) {
case SENSOR_CHAN_AMBIENT_TEMP:
double sensor_tmp_val;
int32_t temp_val;

temp_val = drv_data->temp;

sensor_tmp_val = temp_val/HTU21D_MODIFIER;

/*temperature calc*/
/* Temp = -46.85 + 175.72 * temp_val/2^16 */
result = HTU21D_TEMP_OFFSET +
(HTU21D_TEMP_MULTIPLIER * sensor_tmp_val);
val->val1 = (int)result;
float_val = (result - (int)result)*HTU21D_DECIMAL;
val->val2 = (int)float_val/HTU21D_MICRO;
break;
case SENSOR_CHAN_HUMIDITY:
int32_t humidity_val;
double sensor_humidity_val;

humidity_val = drv_data->humidity;
sensor_humidity_val = humidity_val/HTU21D_MODIFIER;

/*humidity calc*/
/* RH = -6 + 125 * humidity_val/2^16 */
result = HTU21D_HUM_ADD +
(HTU21D_HUM_MULTIPILER *
sensor_humidity_val);
val->val1 = (int)result;
float_val = (result-(int)result)*HTU21D_DECIMAL;
val->val2 = (int)float_val/HTU21D_MICRO;
break;
default:
return -ENOTSUP;
}
return 0;
}

static const struct sensor_driver_api htu21d_driver_api = {
.sample_fetch = htu21d_sample_fetch,
.channel_get = htu21d_channel_get,
};

static int htu21d_init(const struct device *dev)
{
const struct htu21d_dev_config *cfg = dev->config;

if (!device_is_ready(cfg->bus.bus)) {
LOG_ERR("I2C dev %s not ready", cfg->bus.bus->name);
return -EINVAL;
}

/*HTU21D reset*/
i2c_write_dt(&cfg->bus, (uint8_t *)HTU21D_SOFT_RESET, sizeof(HTU21D_SOFT_RESET));

return 0;
}

#define HTU21D_DEFINE(inst) \
static struct htu21d_data htu21d_drv_data_##inst; \
static const struct htu21d_dev_config htu21d_config_##inst = { \
.bus = I2C_DT_SPEC_INST_GET(inst) \
}; \
DEVICE_DT_INST_DEFINE(inst, \
htu21d_init, \
NULL, \
&htu21d_drv_data_##inst, \
&htu21d_config_##inst, \
POST_KERNEL, \
CONFIG_SENSOR_INIT_PRIORITY, \
&htu21d_driver_api);

DT_INST_FOREACH_STATUS_OKAY(HTU21D_DEFINE)

19 changes: 19 additions & 0 deletions drivers/sensor/htu21d/htu21d.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* HTU21D temperature & humidity sensor with i2c
*
* Copyright (c) 2022 Linumiz
* Author: Arunmani <arunmani@linumiz.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_DRIVERS_SENSOR_HTU21D_H_
#define ZEPHYR_DRIVERS_SENSOR_HTU21D_H_

#define HTU21D_READ_TEMP_H 0xE3
#define HTU21D_READ_HUMID_H 0xE5
#define HTU21D_READ_TEMP_NH 0xF3
#define HTU21D_READ_HUMID_NH 0xF5
#define HTU21D_SOFT_RESET 0xFE
#define MEASURE_WAIT_MS 50


#endif /* ZEPHYR_DRIVERS_SENSOR_HTU21D_H_ */
10 changes: 10 additions & 0 deletions dts/bindings/sensor/te,htu21d.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#
# Copyright (c) 2022 Linumiz
#
# SPDX-License-Identifier: Apache-2.0
#
description: htu21d temperature and humidity sensor.

compatible: "te,htu21d"

include: i2c-device.yaml
1 change: 1 addition & 0 deletions dts/bindings/vendor-prefixes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,7 @@ truly Truly Semiconductors Limited
visionox Visionox
tsd Theobroma Systems Design und Consulting GmbH
tyan Tyan Computer Corporation
te Tyco Electronics
u-blox u-blox
u-boot U-Boot bootloader
ucrobotics uCRobotics
Expand Down
8 changes: 8 additions & 0 deletions samples/sensor/htu21d/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(htu21d)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
8 changes: 8 additions & 0 deletions samples/sensor/htu21d/boards/nrf52840dk_nrf52840.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
&i2c1 {
status = "okay";
htu21d@1a {
compatible = "te,htu21d";
reg = <0x40>;
label = "HTU21D";
};
};
4 changes: 4 additions & 0 deletions samples/sensor/htu21d/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CONFIG_STDOUT_CONSOLE=y
CONFIG_I2C=y
CONFIG_SENSOR=y
CONFIG_ASSERT=y
56 changes: 56 additions & 0 deletions samples/sensor/htu21d/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2020 Linumiz
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/__assert.h>

void main(void)
{
int ret;
struct sensor_value temp_value, hum_value;
const struct device *dev = DEVICE_DT_GET_ANY(te_htu21d);

__ASSERT(dev != NULL, "Failed to get device binding");
__ASSERT(device_is_ready(dev), "Device %s is not ready", dev->name);
printk("device name is %s\n", dev->name);

/*temperature*/
ret = sensor_sample_fetch_chan(dev, SENSOR_CHAN_AMBIENT_TEMP);
if (ret) {
printk("sensor_sample_fetch failed ret %d\n", ret);
return;
}
ret = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp_value);
if (ret) {
printk("sensor_channel_get failed ret %d\n", ret);
return;
}
printk("temp is %d (%d micro)\n", temp_value.val1,
temp_value.val2);
k_sleep(K_MSEC(1000));

/*humidity*/
ret = sensor_sample_fetch_chan(dev, SENSOR_CHAN_HUMIDITY);
if (ret) {
printk("sensor_sample_fetch failed ret %d\n", ret);
return;
}

ret = sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, &hum_value);
if (ret) {
printk("sensor_channel_get failed ret %d\n", ret);
return;
}

printk("humidity is %d (%d micro)\n", hum_value.val1,
hum_value.val2);
k_sleep(K_MSEC(1000));
}