1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Driver/shtc1: add saul integration

- add saul integration
- uncrustified
- SAUL/DRIVER tests
This commit is contained in:
steffen 2017-10-26 10:21:12 +02:00 committed by Michel Gerlach
parent 50f5060e90
commit fa05cf0c5d
13 changed files with 613 additions and 0 deletions

View File

@ -533,6 +533,12 @@ ifneq (,$(filter sht3x,$(USEMODULE)))
FEATURES_REQUIRED += periph_i2c
endif
ifneq (,$(filter shtc1,$(USEMODULE)))
FEATURES_REQUIRED += periph_i2c
USEMODULE += xtimer
USEMODULE += checksum
endif
ifneq (,$(filter si114%,$(USEMODULE)))
USEMODULE += xtimer
FEATURES_REQUIRED += periph_i2c

View File

@ -274,6 +274,10 @@ ifneq (,$(filter sht3x,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/sht3x/include
endif
ifneq (,$(filter shtc1,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/shtc1/include
endif
ifneq (,$(filter si114x,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/si114x/include
endif

124
drivers/include/shtc1.h Normal file
View File

@ -0,0 +1,124 @@
/*
* Copyright 2017, RWTH Aachen. All rights reserved.
*
* 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_shtc1 SHTC1 Temperature and humidity sensor
* @ingroup drivers_sensors
* @ingroup drivers_saul
* @brief Driver for the Sensirion SHTC1 sensor.
*
* @file
* @brief Device driver interface for the SHTC1 Temperature and humidity sensor
*
* @author Steffen Robertz <steffen.robertz@rwth-aachen.de>
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
*/
#ifndef SHTC1_H
#define SHTC1_H
#include <stdint.h>
#include "saul.h"
#include "periph/i2c.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief SHTC1 Default Address
*
*/
#ifndef SHTC1_I2C_ADDRESS
#define SHTC1_I2C_ADDRESS (0x70)
#endif
/**
* @brief settings struct with all relevant parameters
* @{
*/
typedef struct {
i2c_t i2c_dev; /**< I2C bus descriptor. */
uint8_t i2c_addr; /**< I2C address of the sensor. */
} shtc1_params_t;
/** @} */
/**
* @brief device descriptor for the SHTC1
* @{
*/
typedef struct {
shtc1_params_t params; /**< Parameters struct with all settings set. */
} shtc1_t;
/** @} */
enum {
SHTC1_OK, /**< Success, no error */
SHTC1_ERROR_BUS, /**< I2C bus error */
SHTC1_ERROR_CRC, /**< CRC error */
SHTC1_ERROR /**< General error */
};
/**
* @brief Initializes the sensor and I2C.
*
* @param[in] dev I2C device descriptor.
* @param[in] params SHTC1 parameters to be used.
*
* @return SHTC1_OK on a working initialization.
* @return SHTC1_ERROR_BUS Reading I2C failed.
* @return SHTC1_ERROR_CRC Wrong ID.
*/
int8_t shtc1_init(shtc1_t* const dev, const shtc1_params_t* params);
/**
* @brief Reads all register values from the device.
* @details The values as raw data will be saved into reveived.
*
* @param[in] dev The I2C device descriptor.
* @param[in] rel_humidity Humidity in centi %.
* @param[in] temperature Temperature in centi °C.
*
* @return SHTC1_OK if a measurement completed.
* @return SHTC1_ERROR_BUS reading I2C failed.
* @return SHTC1_ERROR_CRC on checksum error.
*/
int8_t shtc1_read(const shtc1_t *dev, uint16_t *rel_humidity, int16_t *temperature);
/**
* @brief Reads the ID and saves it in the device descriptor
*
* @details When working correctly ID should equal xxxx'xxxx'xx00'0111 where x is unspecified.
*
* @param[in] dev The I2C device descriptor.
* @param[in] id ID of the device.
*
* @return SHTC1_OK on everything done.
* @return SHTC1_ERROR_BUS on error.
*/
int8_t shtc1_id(const shtc1_t *dev, uint16_t *id);
/**
* @brief Resets sensor
*
* This will reset all internal state machines and reload calibration data from the memory.
*
* @param[in] dev The I2C device descriptor.
*
* @return SHTC1_OK on everything done.
* @return SHTC1_ERROR_BUS on error.
*/
int8_t shtc1_reset(const shtc1_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* SHTC1_H */
/** @} */

3
drivers/shtc1/Makefile Normal file
View File

@ -0,0 +1,3 @@
MODULE = shtc1
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,74 @@
/*
* Copyright 2017, RWTH Aachen. All rights reserved.
*
* 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_shtc1
*
* @{
*
* @file
* @brief Default parameters for the SHTC1 Temperature and humidity sensor
*
* @author Steffen Robertz <steffen.robertz@rwth-aachen.de>
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
*/
#ifndef SHTC1_PARAMS_H
#define SHTC1_PARAMS_H
#include "board.h"
#include "shtc1.h"
#include "shtc1_regs.h"
#include "saul_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Default configuration parameters for SHTC1 sensors
* @{
*/
#ifndef SHTC1_PARAM_I2C_DEV
#define SHTC1_PARAM_I2C_DEV (I2C_DEV(0))
#endif
#ifndef SHTC1_PARAM_I2C_ADDR
#define SHTC1_PARAM_I2C_ADDR SHTC1_I2C_ADDRESS
#endif
#ifndef SHTC1_PARAMS
#define SHTC1_PARAMS { .i2c_dev = SHTC1_PARAM_I2C_DEV, \
.i2c_addr = SHTC1_PARAM_I2C_ADDR }
#endif
#ifndef SHTC1_SAUL_INFO
#define SHTC1_SAUL_INFO { .name = "shtc1 temperature" }, \
{ .name = "shtc1 humidity" }
#endif
/** @} */
/**
* @brief Allocation of SHTC1 configuration
*/
static const shtc1_params_t shtc1_params[] =
{
SHTC1_PARAMS
};
/**
* @brief Configure SAUL registry entries
*/
static const saul_reg_info_t shtc1_saul_info[] =
{
SHTC1_SAUL_INFO
};
#ifdef __cplusplus
}
#endif
#endif /* SHTC1_PARAMS_H */
/** @} */

View File

@ -0,0 +1,49 @@
/*
* Copyright 2017, RWTH Aachen. All rights reserved.
*
* 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_shtc1
*
* @{
* @file
* @brief Register definitions for SHTC1 devices
*
* @author Steffen Robertz <steffen.robertz@rwth-aachen.de>
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
*/
#ifndef SHTC1_REGS_H
#define SHTC1_REGS_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name SHTC1 registers
* @{
*/
#define SHTC1_CRC (0x31) /**< crc polynomial */
#define SHTC1_MEASURE_CLOCK_STRETCHING_TEMP_HIGH (0x7C) /**< Clock stretching enable high*/
#define SHTC1_MEASURE_CLOCK_STRETCHING_TEMP_LOW (0xA2) /**< Clock stretching disable high*/
#define SHTC1_COMMAND_RESET_HIGH (0x80) /**< Reset command high*/
#define SHTC1_COMMAND_RESET_LOW (0x5D) /**< Reset command low*/
#define SHTC1_COMMAND_ID_HIGH (0xEF) /**< Get ID command low*/
#define SHTC1_COMMAND_ID_LOW (0xC8) /**< Get ID command low*/
/** @} */
/**
* @brief SHTC1 default ID
*/
#define SHTC1_ID (0x07) /* ID Mask */
#ifdef __cplusplus
}
#endif
#endif /* SHTC1_REGS_H */
/** @} */

135
drivers/shtc1/shtc1.c Normal file
View File

@ -0,0 +1,135 @@
/*
* Copyright (C) 2017 RWTH-Aachen
*
* 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_shtc1
* @{
*
* @file
* @brief Device driver implementation for the Sensirion SHTC1 temperature
* and humidity sensor.
*
* @author Steffen Robertz <steffen.robertz@rwth-aachen.de>
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
* @}
*/
#include <string.h>
#include <math.h>
#include "log.h"
#include "assert.h"
#include "checksum/crc8.h"
#include "shtc1.h"
#include "shtc1_regs.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
int8_t shtc1_init(shtc1_t *const dev, const shtc1_params_t *params)
{
uint16_t id;
/* check for a valid device descriptor and parameters */
assert(dev && params);
/* copy settings into the device descriptor */
dev->params = *params;
/* Verify the connection by reading the SHTC1's ID and checking its value */
if (shtc1_id(dev, &id) != SHTC1_OK) {
return SHTC1_ERROR_BUS;
}
else if ((id & 0x3F) != SHTC1_ID) {
return SHTC1_ERROR_CRC;
}
else {
return SHTC1_OK;
}
}
int8_t shtc1_read(const shtc1_t *dev, uint16_t *rel_humidity,
int16_t *temperature)
{
uint8_t received[6];
/* Build and issue the measurement command */
uint8_t cmd[] =
{ SHTC1_MEASURE_CLOCK_STRETCHING_TEMP_HIGH,
SHTC1_MEASURE_CLOCK_STRETCHING_TEMP_LOW };
i2c_acquire(dev->params.i2c_dev);
if (i2c_write_bytes(dev->params.i2c_dev, dev->params.i2c_addr, cmd, 2, 0)) {
return SHTC1_ERROR_BUS;
}
/* Receive the measurement */
/* 16 bit Temperature
* 8 bit CRC temp
* 16 Bit Absolute Humidity
* 8 bit CRC Hum
*/
if (i2c_read_bytes(dev->params.i2c_dev, dev->params.i2c_addr, received, 6,
0)) {
return SHTC1_ERROR_BUS;
}
i2c_release(dev->params.i2c_dev);
if (rel_humidity != NULL) {
uint32_t abs_humidity = ((received[3] << 8) | received[4]);
/* 10000 * ( abs_humidity /65536) */
*rel_humidity = (10000 * abs_humidity) >> 16;
}
if (temperature != NULL) {
uint16_t temp_f = ((received[0] << 8) | received[1]);
/* calculate the relative humidity and convert the temperature to centi °C */
/* (175.0 * 100 * temp_f / 65536) - 45 ; */
*temperature = ((17500 * (uint32_t)temp_f) >> 16) - 4500;
}
if (!((crc8(&received[0], 2, SHTC1_CRC, 0xFF) == received[2]) &&
(crc8(&received[3], 2, SHTC1_CRC, 0xFF) == received[5]))) {
/* crc check failed */
DEBUG("CRC Error\n");
return SHTC1_ERROR_CRC;
}
DEBUG("CRC Passed! \n");
return SHTC1_OK;
}
int8_t shtc1_id(const shtc1_t *dev, uint16_t *id)
{
/* Build and send measurement command */
uint8_t data[] = { SHTC1_COMMAND_ID_HIGH, SHTC1_COMMAND_ID_LOW };
i2c_acquire(dev->params.i2c_dev);
if (i2c_write_bytes(dev->params.i2c_dev, dev->params.i2c_addr, data, 2,
0)) {
return SHTC1_ERROR_BUS;
}
/* receive ID and check if the send and receive commands were successful */
if (i2c_read_bytes(dev->params.i2c_dev, dev->params.i2c_addr, data, 2, 0)) {
return SHTC1_ERROR_BUS;
}
i2c_release(dev->params.i2c_dev);
/* Save ID in device descriptor */
*id = (data[0] << 8) | data[1];
return SHTC1_OK;
}
int8_t shtc1_reset(const shtc1_t *const dev)
{
/* Build and issue the reset command */
uint8_t data[] = { SHTC1_COMMAND_RESET_HIGH, SHTC1_COMMAND_RESET_LOW };
i2c_acquire(dev->params.i2c_dev);
if (i2c_write_bytes(dev->params.i2c_dev, dev->params.i2c_addr, data, 2,
0)) {
return SHTC1_ERROR_BUS;
}
i2c_release(dev->params.i2c_dev);
return SHTC1_OK;
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2019 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_shtc1
* @{
*
* @file
* @brief SHTC1 adaption to the RIOT actuator/sensor interface
*
* @author Michel Gerlach <michel.gerlach@haw-hamburg.de>
*
* @}
*/
#include "saul.h"
#include "shtc1.h"
static int read_temperature(const void *dev, phydat_t *res)
{
if (shtc1_read((shtc1_t *)dev, NULL, &res->val[0]) != SHTC1_OK) {
return -ECANCELED;
}
res->unit = UNIT_TEMP_C;
res->scale = -2;
return 1;
}
static int read_relative_humidity(const void *dev, phydat_t *res)
{
if (shtc1_read((shtc1_t *)dev, (uint16_t *)&res->val[0], NULL) != SHTC1_OK) {
return -ECANCELED;
}
res->unit = UNIT_PERCENT;
res->scale = -2;
return 1;
}
const saul_driver_t shtc1_temperature_saul_driver = {
.read = read_temperature,
.write = saul_notsup,
.type = SAUL_SENSE_TEMP,
};
const saul_driver_t shtc1_relative_humidity_saul_driver = {
.read = read_relative_humidity,
.write = saul_notsup,
.type = SAUL_SENSE_HUM,
};

View File

@ -534,6 +534,10 @@ void auto_init(void)
extern void auto_init_sht3x(void);
auto_init_sht3x();
#endif
#ifdef MODULE_SHTC1
extern void auto_init_shtc1(void);
auto_init_shtc1();
#endif
#ifdef MODULE_SDS011
extern void auto_init_sds011(void);
auto_init_sds011();

View File

@ -0,0 +1,85 @@
/*
* Copyright (C) 2019 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 sys_auto_init_saul
* @{
*
* @file
* @brief Auto initialization of shtc1 Digital Humidity Sensor
*
* @author Michel Gerlach <michel.gerlach@haw-hamburg.de>
*
* @}
*/
#ifdef MODULE_SHTC1
#include "assert.h"
#include "log.h"
#include "saul_reg.h"
#include "shtc1.h"
#include "shtc1_params.h"
/**
* @brief Define the number of configured sensors
*/
#define SHTC1_NUM ARRAY_SIZE(shtc1_params)
/**
* @brief Allocate memory for the device descriptors
*/
static shtc1_t shtc1_devs[SHTC1_NUM];
/**
* @brief Memory for the SAUL registry entries
*/
static saul_reg_t saul_entries[SHTC1_NUM * 2];
/**
* @brief Define the number of saul info
*/
#define SHTC1_INFO_NUM ARRAY_SIZE(shtc1_saul_info)
/**
* @brief Reference the driver struct
*/
extern const saul_driver_t shtc1_temperature_saul_driver;
extern const saul_driver_t shtc1_relative_humidity_saul_driver;
void auto_init_shtc1(void)
{
assert(SHTC1_NUM == SHTC1_INFO_NUM);
for (unsigned i = 0; i < SHTC1_NUM; i++) {
LOG_DEBUG("[auto_init_saul] initializing shtc1 #%u\n", i);
if (shtc1_init(&shtc1_devs[i], &shtc1_params[i]) != SHTC1_OK) {
LOG_ERROR("[auto_init_saul] error initializing shtc1 #%u\n", i);
continue;
}
/* temperature */
saul_entries[(i * 2)].dev = &(shtc1_devs[i]);
saul_entries[(i * 2)].name = shtc1_saul_info[i].name;
saul_entries[(i * 2)].driver = &shtc1_temperature_saul_driver;
/* Humidity */
saul_entries[(i * 2)+1].dev = &(shtc1_devs[i]);
saul_entries[(i * 2)+1].name = shtc1_saul_info[i].name;
saul_entries[(i * 2)+1].driver = &shtc1_relative_humidity_saul_driver;
saul_reg_add(&(saul_entries[(i * 2)]));
saul_reg_add(&(saul_entries[(i * 2)+1]));
}
}
#else
typedef int dont_be_pedantic;
#endif /* MODULE_SHTC1 */

View File

@ -0,0 +1,8 @@
include ../Makefile.tests_common
DRIVER ?= shtc1
USEMODULE += fmt
USEMODULE += $(DRIVER)
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,4 @@
#About
Testing application for the SHTC1 temperature and humidity sensor
#Usage
Just build it using the `make BOARD=??? flash` command in the `tests/driver_shtc1` folder. Temperature and humidity values should be printed in the terminal every 2s

61
tests/driver_shtc1/main.c Normal file
View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2017 RWTH Aachen, Steffen Robertz, Josua Arndt
*
* 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 tests
* @{
*
* @file
* @brief Test application for the SHTC1 temperature and humidity sensor
*
* @author Steffen Robertz <steffen.robertz@rwth-aachen.de>
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
* @author Michel Gerlach <michel.gerlach@haw-hamburg.de>
*
* @}
*/
#include <stdio.h>
#include <stdlib.h>
#include "shtc1.h"
#include "shtc1_params.h"
#include "xtimer.h"
#include "fmt.h"
int main(void)
{
shtc1_t dev;
int16_t temp;
uint16_t hum;
char str_temp[8];
char str_hum[8];
size_t len;
puts("SHTC1 test application\n");
if ((shtc1_init(&dev, &shtc1_params[0])) != SHTC1_OK) {
puts("can't initialize the sensor");
return -1;
}
puts("SHTC1 initialized\n");
while (1) {
if (shtc1_read(&dev, &hum, &temp) == SHTC1_OK) {
len = fmt_s16_dfp(str_temp, temp, -2);
str_temp[len] = '\0';
len = fmt_s16_dfp(str_hum, hum, -2);
str_hum[len] = '\0';
}
/* print values to STDIO */
printf("Temperature [°C]: %s\n", str_temp);
printf(" Humidity [%%rH]: %s\n", str_hum);
xtimer_sleep(2);
}
return 0;
}