mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
drivers: add hts221 temperature and humidity sensor
This commit is contained in:
parent
15f10b088c
commit
55cda8d8ab
@ -115,6 +115,10 @@ ifneq (,$(filter hih6130,$(USEMODULE)))
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter hts221,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_i2c
|
||||
endif
|
||||
|
||||
ifneq (,$(filter io1_xplained,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_gpio
|
||||
USEMODULE += at30tse75x
|
||||
|
@ -148,3 +148,6 @@ endif
|
||||
ifneq (,$(filter apa102,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/apa102/include
|
||||
endif
|
||||
ifneq (,$(filter hts221,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/hts221/include
|
||||
endif
|
||||
|
1
drivers/hts221/Makefile
Normal file
1
drivers/hts221/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
388
drivers/hts221/hts221.c
Normal file
388
drivers/hts221/hts221.c
Normal file
@ -0,0 +1,388 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_hts221
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Driver for the ST HTS221 digital Humidity Sensor
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "hts221.h"
|
||||
#include "periph/i2c.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#define ENABLE_DEBUG (1)
|
||||
#include "debug.h"
|
||||
|
||||
#define I2C_SPEED I2C_SPEED_FAST
|
||||
#define BUS (dev->p.i2c)
|
||||
#define ADDR (dev->p.addr)
|
||||
|
||||
static int _set_power(const hts221_t *dev, const bool active);
|
||||
|
||||
/**
|
||||
* @brief Read calibration parameters for humidity calculation
|
||||
*
|
||||
* @note This function does not acquire or release the I2C bus, must be done
|
||||
* in calling function!
|
||||
*
|
||||
* @param[in|out] dev device descriptor of sensor
|
||||
*
|
||||
* @returns HTS221_OK on success, or error otherwise
|
||||
*/
|
||||
int _humidity_calibration(hts221_t *dev)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
uint8_t reg = HTS221_REGS_H0_RH_X2 | 0x80;
|
||||
/* 1. read h0_rh and h1_rh coefficients */
|
||||
if (i2c_read_regs(BUS, ADDR, reg, &buf[0], 2) != 2) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_regs failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
DEBUG("%s: buf[0]=%u buf[1]=%u\n", DEBUG_FUNC, buf[0], buf[1]);
|
||||
dev->h0_rh = buf[0] >> 1;
|
||||
dev->h1_rh = buf[1] >> 1;
|
||||
DEBUG("%s: h0_rh %" PRIi16 ", h1_rh %" PRIi16 "\n",
|
||||
DEBUG_FUNC, dev->h0_rh, dev->h1_rh);
|
||||
/* 2. read h0_t0_out */
|
||||
reg = HTS221_REGS_H0_T0_OUT_L | 0x80;
|
||||
if (i2c_read_regs(BUS, ADDR, reg, &buf[0], 2) != 2) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_regs failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
DEBUG("%s: buf[0]=%u buf[1]=%u\n", DEBUG_FUNC, buf[0], buf[1]);
|
||||
dev->h0_t0_out = ((uint16_t)buf[1] << 8) | buf[0];
|
||||
/* 3. read h1_t0_out */
|
||||
reg = HTS221_REGS_H1_T0_OUT_L | 0x80;
|
||||
if (i2c_read_regs(BUS, ADDR, reg, &buf[0], 2) != 2) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_regs failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
DEBUG("%s: buf[0]=%u buf[1]=%u\n", DEBUG_FUNC, buf[0], buf[1]);
|
||||
dev->h1_t0_out = ((uint16_t)buf[1] << 8) | buf[0];
|
||||
DEBUG("%s: h0_t0_out %" PRIi16 ", h1_t0_out %" PRIi16 "\n",
|
||||
DEBUG_FUNC, dev->h0_t0_out, dev->h1_t0_out);
|
||||
|
||||
return HTS221_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read calibration parameters for temperature calculation
|
||||
*
|
||||
* @note This function does not acquire or release the I2C bus, must be done
|
||||
* in calling function!
|
||||
*
|
||||
* @param[in|out] dev device descriptor of sensor
|
||||
*
|
||||
* @returns HTS221_OK on success, or error otherwise
|
||||
*/
|
||||
int _temperature_calibration(hts221_t *dev)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
uint8_t tmp;
|
||||
/* 1. read t0_degc and t1_degc coefficients */
|
||||
uint8_t reg = HTS221_REGS_T0_DEGC_X8 | 0x80;
|
||||
if (i2c_read_regs(BUS, ADDR, reg, &buf[0], 2) != 2) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_regs failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
DEBUG("%s: buf[0]=%u buf[1]=%u\n", DEBUG_FUNC, buf[0], buf[1]);
|
||||
/* 2. read t1_t0_msb */
|
||||
if (i2c_read_reg(BUS, ADDR, HTS221_REGS_T1_T0_MSB, &tmp) != 1) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_regs failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
/* 3. calc values */
|
||||
int16_t t0_degc_x8_u16 = (((uint16_t)(tmp & 0x03)) << 8) | buf[0];
|
||||
int16_t t1_degc_x8_u16 = (((uint16_t)(tmp & 0x0C)) << 6) | buf[1];
|
||||
dev->t0_degc = t0_degc_x8_u16 >> 3;
|
||||
dev->t1_degc = t1_degc_x8_u16 >> 3;
|
||||
DEBUG("%s: t0_degc %" PRIi16 ", t1_degc %" PRIi16 "\n",
|
||||
DEBUG_FUNC, dev->t0_degc, dev->t1_degc);
|
||||
/* 4. read t0_out */
|
||||
reg = HTS221_REGS_T0_OUT_L | 0x80;
|
||||
if (i2c_read_regs(BUS, ADDR, reg, &buf[0], 2) != 2) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_regs failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
DEBUG("%s: buf[0]=%u buf[1]=%u\n", DEBUG_FUNC, buf[0], buf[1]);
|
||||
dev->t0_out = ((uint16_t)buf[1] << 8) | buf[0];
|
||||
/* 5. read t1_out */
|
||||
reg = HTS221_REGS_T1_OUT_L | 0x80;
|
||||
if (i2c_read_regs(BUS, ADDR, reg, &buf[0], 2) != 2) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_regs failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
DEBUG("%s: buf[0]=%u buf[1]=%u\n", DEBUG_FUNC, buf[0], buf[1]);
|
||||
dev->t1_out = ((uint16_t)buf[1] << 8) | buf[0];
|
||||
DEBUG("%s: t0_out %" PRIi16 ", t1_out %" PRIi16 "\n",
|
||||
DEBUG_FUNC, dev->t0_out, dev->t1_out);
|
||||
|
||||
return HTS221_OK;
|
||||
}
|
||||
|
||||
int hts221_init(hts221_t *dev, const hts221_params_t *params)
|
||||
{
|
||||
uint8_t reg;
|
||||
|
||||
memcpy(&dev->p, params, sizeof(hts221_params_t));
|
||||
/* initialize the I2C bus */
|
||||
i2c_acquire(BUS);
|
||||
if (i2c_init_master(BUS, I2C_SPEED) < 0) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_init_master failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
|
||||
/* try if we can interact with the device by reading its manufacturer ID */
|
||||
if (i2c_read_reg(BUS, ADDR, HTS221_REGS_WHO_AM_I, ®) != 1) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_regs HTS221_REGS_WHO_AM_I failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
if (reg != HTS221_DEVICE_ID) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: invalid HTS221_DEVICE_ID!\n", DEBUG_FUNC);
|
||||
return -HTS221_NODEV;
|
||||
}
|
||||
i2c_release(BUS);
|
||||
/* reboot device before usage */
|
||||
if (hts221_reboot(dev) != HTS221_OK) {
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
|
||||
i2c_acquire(BUS);
|
||||
if (i2c_write_reg(BUS, ADDR, HTS221_REGS_AV_CONF, dev->p.avgx) != 1) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_write_regs HTS221_REGS_AV_CONF failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
reg = 0;
|
||||
if (i2c_write_reg(BUS, ADDR, HTS221_REGS_CTRL_REG1, reg) != 1) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_write_reg HTS221_REGS_CTRL_REG1 failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
i2c_release(BUS);
|
||||
|
||||
i2c_acquire(BUS);
|
||||
if ((_humidity_calibration(dev) != HTS221_OK) ||
|
||||
(_temperature_calibration(dev) != HTS221_OK)) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: read calibration parameters failed!\n", DEBUG_FUNC);
|
||||
return HTS221_ERROR;
|
||||
}
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: DONE!\n", DEBUG_FUNC);
|
||||
|
||||
return HTS221_OK;
|
||||
}
|
||||
|
||||
int hts221_one_shot(const hts221_t *dev)
|
||||
{
|
||||
uint8_t reg = HTS221_REGS_CTRL_REG1_ODR_ONE_SHOT;
|
||||
|
||||
/* first, disable any continuous measurement, enter one short mode */
|
||||
if (hts221_set_rate(dev, reg) != HTS221_OK) {
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
|
||||
i2c_acquire(BUS);
|
||||
/* second, read current settings */
|
||||
if (i2c_read_reg(BUS, ADDR, HTS221_REGS_CTRL_REG2, ®) != 1) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_regs HTS221_REGS_CTRL_REG1 failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
/* third, enable one-shot */
|
||||
reg |= HTS221_REGS_CTRL_REG2_OS_EN;
|
||||
if (i2c_write_reg(BUS, ADDR, HTS221_REGS_CTRL_REG2, reg) != 1) {
|
||||
i2c_release(BUS);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
i2c_release(BUS);
|
||||
|
||||
return HTS221_OK;
|
||||
}
|
||||
|
||||
int hts221_set_rate(const hts221_t *dev, const uint8_t rate)
|
||||
{
|
||||
uint8_t reg;
|
||||
|
||||
i2c_acquire(BUS);
|
||||
if (i2c_read_reg(BUS, ADDR, HTS221_REGS_CTRL_REG1, ®) != 1) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_reg HTS221_REGS_CTRL_REG1 failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
reg |= rate;
|
||||
DEBUG("hts221_set_rate: %u\n", reg);
|
||||
if (i2c_write_reg(BUS, ADDR, HTS221_REGS_CTRL_REG1, reg) != 1) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_write_reg HTS221_REGS_CTRL_REG1 failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
i2c_release(BUS);
|
||||
|
||||
return HTS221_OK;
|
||||
}
|
||||
|
||||
int hts221_reboot(const hts221_t *dev)
|
||||
{
|
||||
uint8_t reg;
|
||||
|
||||
i2c_acquire(BUS);
|
||||
reg = HTS221_REGS_CTRL_REG2_BOOT;
|
||||
if (i2c_write_reg(BUS, ADDR, HTS221_REGS_CTRL_REG2, reg) != 1) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_write_reg HTS221_REGS_CTRL_REG2 failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
/* loop until HTS221_REGS_CTRL_REG2_BOOT == 0 */
|
||||
do {
|
||||
i2c_read_reg(BUS, ADDR, HTS221_REGS_CTRL_REG2, ®);
|
||||
} while (reg & HTS221_REGS_CTRL_REG2_BOOT);
|
||||
i2c_release(BUS);
|
||||
|
||||
return HTS221_OK;
|
||||
}
|
||||
|
||||
static int _set_power(const hts221_t *dev, const bool active)
|
||||
{
|
||||
uint8_t reg;
|
||||
|
||||
i2c_acquire(BUS);
|
||||
if (i2c_read_reg(BUS, ADDR, HTS221_REGS_CTRL_REG1, ®) != 1) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_reg HTS221_REGS_CTRL_REG1 failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
if (active) {
|
||||
reg |= HTS221_REGS_CTRL_REG1_PD_ACTIVE;
|
||||
}
|
||||
else {
|
||||
reg &= ~HTS221_REGS_CTRL_REG1_PD_ACTIVE;
|
||||
}
|
||||
if (i2c_write_reg(BUS, ADDR, HTS221_REGS_CTRL_REG1, reg) != 1) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_write_reg HTS221_REGS_CTRL_REG1 failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
i2c_release(BUS);
|
||||
|
||||
return HTS221_OK;
|
||||
}
|
||||
|
||||
int hts221_power_on(const hts221_t *dev)
|
||||
{
|
||||
return _set_power(dev, true);
|
||||
}
|
||||
|
||||
int hts221_power_off(const hts221_t *dev)
|
||||
{
|
||||
return _set_power(dev, false);
|
||||
}
|
||||
|
||||
int hts221_get_state(const hts221_t *dev)
|
||||
{
|
||||
uint8_t reg;
|
||||
|
||||
i2c_acquire(BUS);
|
||||
if (i2c_read_reg(BUS, ADDR, HTS221_REGS_STATUS_REG, ®) != 1) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_regs failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
i2c_release(BUS);
|
||||
|
||||
return (int)reg;
|
||||
}
|
||||
|
||||
int hts221_read_humidity(const hts221_t *dev, uint16_t *val)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
|
||||
if (!(hts221_get_state(dev) & HTS221_REGS_STATUS_REG_HDA)) {
|
||||
DEBUG("%s: waiting for data ...\n", DEBUG_FUNC);
|
||||
while (!(hts221_get_state(dev) & HTS221_REGS_STATUS_REG_HDA)) {}
|
||||
}
|
||||
|
||||
/* read raw humidity */
|
||||
i2c_acquire(BUS);
|
||||
uint8_t reg = HTS221_REGS_HUMIDITY_OUT_L | 0x80;
|
||||
if (i2c_read_regs(BUS, ADDR, reg, &buf[0], 2) != 2) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_regs failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: buf[0]=%u buf[1]=%u\n", DEBUG_FUNC, buf[0], buf[1]);
|
||||
int16_t h_t_out = ((uint16_t)buf[1] << 8) | buf[0];
|
||||
DEBUG("%s, h_t_out: %" PRIi16 "\n", DEBUG_FUNC, h_t_out);
|
||||
|
||||
/* compute RH [%] value by linear interpolation */
|
||||
int32_t tmp32 = (h_t_out - dev->h0_t0_out) * (dev->h1_rh - dev->h0_rh) * 10;
|
||||
DEBUG("%s, tmp32: %" PRIi32 "\n", DEBUG_FUNC, tmp32);
|
||||
*val = (tmp32 / (dev->h1_t0_out - dev->h0_t0_out)) + (dev->h0_rh * 10);
|
||||
/* cut of humidty at 100% */
|
||||
if (*val > 1000) {
|
||||
*val = 1000;
|
||||
}
|
||||
DEBUG("%s, val: %" PRIu16 "\n", DEBUG_FUNC, *val);
|
||||
|
||||
return HTS221_OK;
|
||||
}
|
||||
|
||||
int hts221_read_temperature(const hts221_t *dev, int16_t *val)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
|
||||
if (!(hts221_get_state(dev) & HTS221_REGS_STATUS_REG_TDA)) {
|
||||
DEBUG("%s: waiting for data ...\n", DEBUG_FUNC);
|
||||
while (!(hts221_get_state(dev) & HTS221_REGS_STATUS_REG_TDA)) {}
|
||||
}
|
||||
|
||||
/* read raw t_out */
|
||||
i2c_acquire(BUS);
|
||||
uint8_t reg = HTS221_REGS_TEMP_OUT_L | 0x80;
|
||||
if (i2c_read_regs(BUS, ADDR, reg, &buf[0], 2) != 2) {
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: i2c_read_regs failed!\n", DEBUG_FUNC);
|
||||
return -HTS221_NOBUS;
|
||||
}
|
||||
i2c_release(BUS);
|
||||
DEBUG("%s: buf[0]=%u buf[1]=%u\n", DEBUG_FUNC, buf[0], buf[1]);
|
||||
int16_t t_out = ((uint16_t)buf[1] << 8) | buf[0];
|
||||
DEBUG("%s, t_out: %" PRIi16 "\n", DEBUG_FUNC, t_out);
|
||||
|
||||
/* calculate actual temperature */
|
||||
int32_t tmp32 = (t_out - dev->t0_out) * (dev->t1_degc - dev->t0_degc) * 10;
|
||||
DEBUG("%s, tmp32: %" PRIi32 "\n", DEBUG_FUNC, tmp32);
|
||||
*val = (tmp32 / (dev->t1_out - dev->t0_out)) + (dev->t0_degc * 10);
|
||||
DEBUG("%s, val: %" PRIi16 "\n", DEBUG_FUNC, *val);
|
||||
|
||||
return HTS221_OK;
|
||||
}
|
69
drivers/hts221/include/hts221_params.h
Normal file
69
drivers/hts221/include/hts221_params.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_hts221
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Default configuration for ST HTS221 devices
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*/
|
||||
|
||||
#ifndef HTS221_PARAMS_H
|
||||
#define HTS221_PARAMS_H
|
||||
|
||||
#include "board.h"
|
||||
#include "hts221.h"
|
||||
#include "hts221_regs.h"
|
||||
#include "saul_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Set default configuration parameters for the HTS221 driver
|
||||
* @{
|
||||
*/
|
||||
#ifndef HTS221_PARAM_I2C
|
||||
#define HTS221_PARAM_I2C I2C_DEV(0)
|
||||
#endif
|
||||
#ifndef HTS221_PARAM_ADDR
|
||||
#define HTS221_PARAM_ADDR (HTS221_I2C_ADDRESS)
|
||||
#endif
|
||||
#ifndef HTS221_PARAM_AVGX
|
||||
#define HTS221_PARAM_AVGX ((HTS221_REGS_AVGT_16 << HTS221_REGS_AVGT_SHIFT) | \
|
||||
HTS221_REGS_AVGH_32)
|
||||
#endif
|
||||
#ifndef HTS221_PARAM_RATE
|
||||
#define HTS221_PARAM_RATE (HTS221_REGS_CTRL_REG1_ODR_12HZ)
|
||||
#endif
|
||||
#ifndef HTS221_PARAMS
|
||||
#define HTS221_PARAMS { .i2c = HTS221_PARAM_I2C, \
|
||||
.addr = HTS221_PARAM_ADDR, \
|
||||
.avgx = HTS221_PARAM_AVGX, \
|
||||
.rate = HTS221_PARAM_RATE }
|
||||
#endif /* HTS221_PARAMS */
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @brief HTS221 configuration
|
||||
*/
|
||||
static const hts221_params_t hts221_params[] =
|
||||
{
|
||||
HTS221_PARAMS,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HTS221_PARAMS_H */
|
||||
/** @} */
|
153
drivers/hts221/include/hts221_regs.h
Normal file
153
drivers/hts221/include/hts221_regs.h
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_hts221
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Register definitions for ST HTS221 devices
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*/
|
||||
|
||||
#ifndef HTS221_REGS_H
|
||||
#define HTS221_REGS_H
|
||||
|
||||
#include "board.h"
|
||||
#include "hts221.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HTS221_DEVICE_ID (0xBC)
|
||||
/**
|
||||
* @name Register Map
|
||||
* @{
|
||||
*/
|
||||
#define HTS221_REGS_WHO_AM_I (0x0F)
|
||||
#define HTS221_REGS_AV_CONF (0x10)
|
||||
#define HTS221_REGS_CTRL_REG1 (0x20)
|
||||
#define HTS221_REGS_CTRL_REG2 (0x21)
|
||||
#define HTS221_REGS_CTRL_REG3 (0x22) /**< data ready output signal */
|
||||
#define HTS221_REGS_STATUS_REG (0x27)
|
||||
#define HTS221_REGS_HUMIDITY_OUT_L (0x28)
|
||||
#define HTS221_REGS_HUMIDITY_OUT_H (0x29)
|
||||
#define HTS221_REGS_TEMP_OUT_L (0x2A)
|
||||
#define HTS221_REGS_TEMP_OUT_H (0x2B)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Calibration Register Map
|
||||
* @{
|
||||
*/
|
||||
#define HTS221_REGS_H0_RH_X2 (0x30)
|
||||
#define HTS221_REGS_H1_RH_X2 (0x31)
|
||||
#define HTS221_REGS_T0_DEGC_X8 (0x32)
|
||||
#define HTS221_REGS_T1_DEGC_X8 (0x33)
|
||||
#define HTS221_REGS_T1_T0_MSB (0x35)
|
||||
#define HTS221_REGS_H0_T0_OUT_L (0x36)
|
||||
#define HTS221_REGS_H0_T0_OUT_H (0x37)
|
||||
#define HTS221_REGS_H1_T0_OUT_L (0x3A)
|
||||
#define HTS221_REGS_H1_T0_OUT_H (0x3B)
|
||||
#define HTS221_REGS_T0_OUT_L (0x3C)
|
||||
#define HTS221_REGS_T0_OUT_H (0x3D)
|
||||
#define HTS221_REGS_T1_OUT_L (0x3E)
|
||||
#define HTS221_REGS_T1_OUT_H (0x3F)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Shift for AVG oftemperature configuration set in HTS221_REGS_AV_CONF
|
||||
*
|
||||
* Register HTS221_REGS_AV_CONF= [7:6] reserved, [5:3] AVGT2-0, [2:0] AVGH2-0
|
||||
*/
|
||||
#define HTS221_REGS_AVGT_SHIFT (3U)
|
||||
|
||||
/**
|
||||
* @name Humidity average over number of samples 4 to 512
|
||||
* @{
|
||||
*/
|
||||
enum {
|
||||
HTS221_REGS_AVGH_4 = 0,
|
||||
HTS221_REGS_AVGH_8,
|
||||
HTS221_REGS_AVGH_16,
|
||||
HTS221_REGS_AVGH_32,
|
||||
HTS221_REGS_AVGH_64,
|
||||
HTS221_REGS_AVGH_128,
|
||||
HTS221_REGS_AVGH_256,
|
||||
HTS221_REGS_AVGH_512
|
||||
};
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Temperature average over number of samples 2 to 256
|
||||
* @{
|
||||
*/
|
||||
enum {
|
||||
HTS221_REGS_AVGT_2 = 0,
|
||||
HTS221_REGS_AVGT_4,
|
||||
HTS221_REGS_AVGT_8,
|
||||
HTS221_REGS_AVGT_16,
|
||||
HTS221_REGS_AVGT_32,
|
||||
HTS221_REGS_AVGT_64,
|
||||
HTS221_REGS_AVGT_128,
|
||||
HTS221_REGS_AVGT_256
|
||||
};
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Config bits of HTS221_REGS_CTRL_REG1
|
||||
* @{
|
||||
*/
|
||||
#define HTS221_REGS_CTRL_REG1_PD_ACTIVE (1 << 7) /**< power-down control, set active mode */
|
||||
#define HTS221_REGS_CTRL_REG1_BDU (1 << 2) /**< Block data update */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Output data rate settings, HTS221_REGS_CTRL_REG1[1:0]
|
||||
*/
|
||||
enum {
|
||||
HTS221_REGS_CTRL_REG1_ODR_ONE_SHOT = 0,
|
||||
HTS221_REGS_CTRL_REG1_ODR_1HZ,
|
||||
HTS221_REGS_CTRL_REG1_ODR_7HZ,
|
||||
HTS221_REGS_CTRL_REG1_ODR_12HZ
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Config bits of HTS221_REGS_CTRL_REG2
|
||||
* @{
|
||||
*/
|
||||
#define HTS221_REGS_CTRL_REG2_BOOT (1 << 7) /**< Reboot memory content */
|
||||
#define HTS221_REGS_CTRL_REG2_HEATER (1 << 1) /**< Heater ON */
|
||||
#define HTS221_REGS_CTRL_REG2_OS_EN (1 << 2) /**< One-shot enable, start new dataset */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Data ready config bits of HTS221_REGS_CTRL_REG3
|
||||
* @{
|
||||
*/
|
||||
#define HTS221_REGS_CTRL_REG3_DRDY_HL (1 << 7) /**< Data Ready output signal active high, low */
|
||||
#define HTS221_REGS_CTRL_REG3_PP_OD (1 << 6) /**< Push-pull / Open Drain selection on pin 3 */
|
||||
#define HTS221_REGS_CTRL_REG3_DRDY_EN (1 << 2) /**< Data Ready enable */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Status bits to check data availability, HTS221_REGS_STATUS_REG[1:0]
|
||||
* @{
|
||||
*/
|
||||
#define HTS221_REGS_STATUS_REG_TDA (1 << 0) /**< temperature data available */
|
||||
#define HTS221_REGS_STATUS_REG_HDA (1 << 1) /**< humidity data available */
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HTS221_REGS_H */
|
||||
/** @} */
|
168
drivers/include/hts221.h
Normal file
168
drivers/include/hts221.h
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (C) 2017 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup drivers_hts221 ST HTS221 digital Humidity Sensor
|
||||
* @ingroup drivers_sensors
|
||||
* @brief Driver for the ST HTS221 digital Humidity Sensor
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Interface definition for the ST HTS221 driver
|
||||
*
|
||||
* @author Sebastian Meiling <s@mlng.net>
|
||||
*/
|
||||
|
||||
#ifndef HTS221_H
|
||||
#define HTS221_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "periph/i2c.h"
|
||||
#include "hts221_regs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Default I2C bus address (7 Bit) of HTS221 devices
|
||||
*/
|
||||
#ifndef HTS221_I2C_ADDRESS
|
||||
#define HTS221_I2C_ADDRESS (0x5F)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Parameters needed for device initialization
|
||||
*/
|
||||
typedef struct {
|
||||
i2c_t i2c; /**< bus the device is connected to */
|
||||
uint8_t addr; /**< address on that bus */
|
||||
uint8_t avgx; /**< average sampling of humidity and temperature */
|
||||
uint8_t rate; /**< output data rate */
|
||||
} hts221_params_t;
|
||||
|
||||
/**
|
||||
* @brief Return values and error codes
|
||||
*/
|
||||
enum {
|
||||
HTS221_OK = 0,
|
||||
HTS221_ERROR,
|
||||
HTS221_NOBUS,
|
||||
HTS221_NODEV,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for HTS221 sensors
|
||||
*/
|
||||
typedef struct {
|
||||
hts221_params_t p; /**< Configuration parameters */
|
||||
int16_t h0_rh; /**< lower humitidy reference */
|
||||
int16_t h1_rh; /**< upper humitidy reference */
|
||||
int16_t h0_t0_out; /**< lower humitidy to temperature reference */
|
||||
int16_t h1_t0_out; /**< upper humitidy to temperature reference */
|
||||
int16_t t0_degc; /**< lower temperature reference in degC */
|
||||
int16_t t1_degc; /**< upper temperature reference in degC */
|
||||
int16_t t0_out; /**< lower temperature reference raw value */
|
||||
int16_t t1_out; /**< upper temperature reference raw value */
|
||||
} hts221_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize the given HTS221 device
|
||||
*
|
||||
* @param[out] dev device descriptor of sensor to initialize
|
||||
* @param[in] params configuration parameters
|
||||
*
|
||||
* @return HTS221_OK on success
|
||||
* @return HTS221_NOBUS if initialization of I2C bus fails
|
||||
* @return HTS221_NODEV if no HTS221 device found on bus
|
||||
*/
|
||||
int hts221_init(hts221_t *dev, const hts221_params_t *params);
|
||||
|
||||
/**
|
||||
* @brief Reboot device and reload base configuration
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
*
|
||||
* @return 0 on success, or error otherwise
|
||||
*/
|
||||
int hts221_reboot(const hts221_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Set device to continues measurements
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
*
|
||||
* @return 0 on success, or error otherwise
|
||||
*/
|
||||
int hts221_one_shot(const hts221_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Set device to continues measurements
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
* @param[in] rate conversion rate for continues mode
|
||||
*
|
||||
* @return 0 on success, or error otherwise
|
||||
*/
|
||||
int hts221_set_rate(const hts221_t *dev, const uint8_t rate);
|
||||
|
||||
/**
|
||||
* @brief Set device to active
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
*
|
||||
* @return 0 on success, or error otherwise
|
||||
*/
|
||||
int hts221_power_on(const hts221_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Set device to power down
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
*
|
||||
* @return 0 on success, or error otherwise
|
||||
*/
|
||||
int hts221_power_off(const hts221_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Set device to power down
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
*
|
||||
* @return >=0 on success
|
||||
* @return -HTS221_NOBUS on error
|
||||
*/
|
||||
int hts221_get_state(const hts221_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Reading humidity and temperature
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
* @param[out] val humidity [in 10 * percent relative]
|
||||
*
|
||||
* @return 0 on success, or error otherwise
|
||||
*/
|
||||
int hts221_read_humidity(const hts221_t *dev, uint16_t *val);
|
||||
|
||||
/**
|
||||
* @brief Reading humidity and temperature
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
* @param[out] val temperature [in 100 * degree centigrade]
|
||||
*
|
||||
* @return 0 on success, or error otherwise
|
||||
*/
|
||||
int hts221_read_temperature(const hts221_t *dev, int16_t *val);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HTS221_H */
|
||||
/** @} */
|
Loading…
Reference in New Issue
Block a user