From 0923ae4172f904ae5858cbfa8fd5a81c0116724b Mon Sep 17 00:00:00 2001 From: Vaishali Pathak Date: Thu, 4 Apr 2019 20:07:12 +0530 Subject: [PATCH] drivers: sensors: Add Si7006 temperature/humidity sensor driver Adds driver for Silicon Labs Si7006 chip. Signed-off-by: Vaishali Pathak --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 2 + drivers/sensor/si7006/CMakeLists.txt | 5 + drivers/sensor/si7006/Kconfig | 11 ++ drivers/sensor/si7006/si7006.c | 162 +++++++++++++++++++++++ drivers/sensor/si7006/si7006.h | 28 ++++ dts/bindings/sensor/silabs,si7006.yaml | 18 +++ tests/drivers/build_all/dts_fixup.h | 6 + tests/drivers/build_all/sensors_i_z.conf | 1 + 9 files changed, 234 insertions(+) create mode 100644 drivers/sensor/si7006/CMakeLists.txt create mode 100644 drivers/sensor/si7006/Kconfig create mode 100644 drivers/sensor/si7006/si7006.c create mode 100644 drivers/sensor/si7006/si7006.h create mode 100644 dts/bindings/sensor/silabs,si7006.yaml diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index d9160b76e0d..61333fe6121 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -48,6 +48,7 @@ add_subdirectory_ifdef(CONFIG_PMS7003 pms7003) add_subdirectory_ifdef(CONFIG_QDEC_NRFX qdec_nrfx) add_subdirectory_ifdef(CONFIG_TEMP_NRF5 nrf5) add_subdirectory_ifdef(CONFIG_SHT3XD sht3xd) +add_subdirectory_ifdef(CONFIG_SI7006 si7006) add_subdirectory_ifdef(CONFIG_STTS751 stts751) add_subdirectory_ifdef(CONFIG_SX9500 sx9500) add_subdirectory_ifdef(CONFIG_TH02 th02) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index b1f0affe65e..0bf9a127ba3 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -121,6 +121,8 @@ source "drivers/sensor/qdec_nrfx/Kconfig" source "drivers/sensor/sht3xd/Kconfig" +source "drivers/sensor/si7006/Kconfig" + source "drivers/sensor/stts751/Kconfig" source "drivers/sensor/sx9500/Kconfig" diff --git a/drivers/sensor/si7006/CMakeLists.txt b/drivers/sensor/si7006/CMakeLists.txt new file mode 100644 index 00000000000..837914b054a --- /dev/null +++ b/drivers/sensor/si7006/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + + zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_SI7006 si7006.c) diff --git a/drivers/sensor/si7006/Kconfig b/drivers/sensor/si7006/Kconfig new file mode 100644 index 00000000000..818a924e867 --- /dev/null +++ b/drivers/sensor/si7006/Kconfig @@ -0,0 +1,11 @@ +# +# Copyright (c) 2019 Electronut Labs +# +# SPDX-License-Identifier: Apache-2.0 +# + +config SI7006 + bool "Si7006 Temperature and Humidity Sensor" + depends on (I2C && HAS_DTS_I2C) + help + Enable I2C-based driver for Si7006 Temperature and Humidity Sensor. diff --git a/drivers/sensor/si7006/si7006.c b/drivers/sensor/si7006/si7006.c new file mode 100644 index 00000000000..7896dd1a0e5 --- /dev/null +++ b/drivers/sensor/si7006/si7006.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2019 Electronut Labs + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "si7006.h" + +LOG_MODULE_REGISTER(si7006, CONFIG_SENSOR_LOG_LEVEL); + +struct si7006_data { + struct device *i2c_dev; + u16_t temperature; + u16_t humidity; +}; + +/** + * @brief function to get relative humidity + * + * @return int 0 on success + */ +static int si7006_get_humidity(struct device *i2c_dev, + struct si7006_data *si_data) +{ + int retval; + u8_t hum[2]; + + retval = i2c_burst_read(i2c_dev, DT_INST_0_SILABS_SI7006_BASE_ADDRESS, + SI7006_MEAS_REL_HUMIDITY_MASTER_MODE, hum, sizeof(hum)); + + if (retval == 0) { + si_data->humidity = (hum[0] << 8) | hum[1]; + } else { + LOG_ERR("read register err"); + } + + return retval; +} + +/** + * @brief function to get temperature + * + * @return int 0 on success + */ + +static int si7006_get_temperature(struct device *i2c_dev, + struct si7006_data *si_data) +{ + u8_t temp[2]; + int retval; + + retval = i2c_burst_read(i2c_dev, DT_INST_0_SILABS_SI7006_BASE_ADDRESS, + SI7006_MEAS_TEMP_MASTER_MODE, temp, sizeof(temp)); + + if (retval == 0) { + si_data->temperature = (temp[0] << 8) | temp[1]; + } else { + LOG_ERR("read register err"); + } + + return retval; +} + +/** + * @brief fetch a sample from the sensor + * + * @return 0 + */ +static int si7006_sample_fetch(struct device *dev, enum sensor_channel chan) +{ + int retval; + struct si7006_data *si_data = dev->driver_data; + + retval = si7006_get_temperature(si_data->i2c_dev, si_data); + if (retval == 0) { + retval = si7006_get_humidity(si_data->i2c_dev, si_data); + } + + return retval; +} + +/** + * @brief sensor value get + * + * @return -ENOTSUP for unsupported channels + */ +static int si7006_channel_get(struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct si7006_data *si_data = dev->driver_data; + + if (chan == SENSOR_CHAN_AMBIENT_TEMP) { + + s32_t temp_ucelcius = ((17572 * (s32_t)si_data->temperature) + / 65536) * 10000; + + val->val1 = temp_ucelcius / 1000000; + val->val2 = temp_ucelcius % 1000000; + + LOG_DBG("temperature = val1:%d, val2:%d", val->val1, val->val2); + + return 0; + } else if (chan == SENSOR_CHAN_HUMIDITY) { + + s32_t relative_humidity = (((125 * (s32_t)si_data->humidity) + / 65536) - 6) * 1000000; + + val->val1 = relative_humidity / 1000000; + val->val2 = relative_humidity % 1000000; + + LOG_DBG("humidity = val1:%d, val2:%d", val->val1, val->val2); + + return 0; + } else { + return -ENOTSUP; + } +} + +static const struct sensor_driver_api si7006_api = { + .sample_fetch = &si7006_sample_fetch, + .channel_get = &si7006_channel_get, +}; + +/** + * @brief initiasize the sensor + * + * @return 0 for success + */ + +static int si7006_init(struct device *dev) +{ + struct si7006_data *drv_data = dev->driver_data; + + drv_data->i2c_dev = device_get_binding( + DT_INST_0_SILABS_SI7006_BUS_NAME); + + if (!drv_data->i2c_dev) { + LOG_ERR("i2c master not found."); + return -EINVAL; + } + + LOG_DBG("si7006 init ok"); + + return 0; +} + +static struct si7006_data si_data; + +DEVICE_AND_API_INIT(si7006, DT_INST_0_SILABS_SI7006_LABEL, si7006_init, + &si_data, NULL, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &si7006_api); diff --git a/drivers/sensor/si7006/si7006.h b/drivers/sensor/si7006/si7006.h new file mode 100644 index 00000000000..d583c9265e6 --- /dev/null +++ b/drivers/sensor/si7006/si7006.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019 Electronut Labs + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SI7006_H +#define _SI7006_H + +/* Si7006 register addresses */ +#define SI7006_MEAS_REL_HUMIDITY_MASTER_MODE 0xE5 +#define SI7006_MEAS_REL_HUMIDITY_NO_MASTER_MODE 0xF5 +#define SI7006_MEAS_TEMP_MASTER_MODE 0xE3 +#define SI7006_MEAS_TEMP_NO_MASTER_MODE 0xF3 +#define SI7006_READ_OLD_TEMP 0xE0 +#define SI7006_RESET 0xFE +#define SI7006_WRITE_HUMIDITY_TEMP_CONTR 0xE6 +#define SI7006_READ_HUMIDITY_TEMP_CONTR 0xE7 +#define SI7006_WRITE_HEATER_CONTR 0x51 +#define SI7006_READ_HEATER_CONTR 0x11 +#define SI7006_READ_ID_LOW_0 0xFA +#define SI7006_READ_ID_LOW_1 0x0F +#define SI7006_READ_ID_HIGH_0 0xFC +#define SI7006_READ_ID_HIGH_1 0xC9 +#define SI7006_FIRMWARE_0 0x84 +#define SI7006_FIRMWARE_1 0xB8 + +#endif /* _SI7006_H */ diff --git a/dts/bindings/sensor/silabs,si7006.yaml b/dts/bindings/sensor/silabs,si7006.yaml new file mode 100644 index 00000000000..677975a6889 --- /dev/null +++ b/dts/bindings/sensor/silabs,si7006.yaml @@ -0,0 +1,18 @@ +# +# Copyright (c) 2019, Electronut Labs +# +# SPDX-License-Identifier: Apache-2.0 +# +--- +title: Si7006 Temperature and Humidity sensor +version: 0.1 + +description: > + This is a representation of Si7006 Temperature and Humidity sensor + +inherits: + !include i2c-device.yaml + +properties: + compatible: + constraint: "silabs,si7006" diff --git a/tests/drivers/build_all/dts_fixup.h b/tests/drivers/build_all/dts_fixup.h index 4bc54b76e2e..780bbabb487 100644 --- a/tests/drivers/build_all/dts_fixup.h +++ b/tests/drivers/build_all/dts_fixup.h @@ -166,6 +166,12 @@ #define DT_INST_0_SENSIRION_SHT3XD_BUS_NAME "" #endif +#ifndef DT_INST_0_SILABS_SI7006_LABEL +#define DT_INST_0_SILABS_SI7006_LABEL "" +#define DT_INST_0_SILABS_SI7006_BASE_ADDRESS 0x40 +#define DT_INST_0_SILABS_SI7006_BUS_NAME "" +#endif + #ifndef DT_INST_0_ST_LIS2DS12_LABEL #define DT_INST_0_ST_LIS2DS12_LABEL "" #define DT_INST_0_ST_LIS2DS12_BUS_NAME "" diff --git a/tests/drivers/build_all/sensors_i_z.conf b/tests/drivers/build_all/sensors_i_z.conf index 0750b3961da..581e74641f5 100644 --- a/tests/drivers/build_all/sensors_i_z.conf +++ b/tests/drivers/build_all/sensors_i_z.conf @@ -24,6 +24,7 @@ CONFIG_MAX44009=y CONFIG_MCP9808=y CONFIG_MPU6050=y CONFIG_SHT3XD=y +CONFIG_SI7006=y CONFIG_SX9500=y CONFIG_TEMP_NRF5=y CONFIG_TH02=y