From 392bacd9c7936aa0abade168595d14b1e960495b Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 22 Apr 2021 21:26:20 +0200 Subject: [PATCH] drivers/lis2dh12: add support for temperature sensor --- drivers/include/lis2dh12.h | 18 ++++++++++ drivers/lis2dh12/include/lis2dh12_registers.h | 8 +++++ drivers/lis2dh12/lis2dh12.c | 33 +++++++++++++++++++ drivers/lis2dh12/lis2dh12_saul.c | 19 ++++++++++- drivers/saul/init_devs/auto_init_lis2dh12.c | 16 +++++---- 5 files changed, 87 insertions(+), 7 deletions(-) diff --git a/drivers/include/lis2dh12.h b/drivers/include/lis2dh12.h index f70ae77e57..b7bb106f91 100644 --- a/drivers/include/lis2dh12.h +++ b/drivers/include/lis2dh12.h @@ -244,8 +244,11 @@ typedef struct { /** * @brief Export the SAUL interface for this driver + * @{ */ extern const saul_driver_t lis2dh12_saul_driver; +extern const saul_driver_t lis2dh12_saul_temp_driver; +/** @} */ #if MODULE_LIS2DH12_INT || DOXYGEN /** @@ -370,6 +373,21 @@ int lis2dh12_init(lis2dh12_t *dev, const lis2dh12_params_t *params); */ int lis2dh12_read(const lis2dh12_t *dev, lis2dh12_fifo_data_t *data); +/** + * @brief Read temperature data from the given device + * + * @note The temperature sensor is not calibrated. + * Temperature values are only relative to a device specific + * reference. + * + * @param[in] dev device descriptor + * @param[out] temp temperature data in centi-°C + * + * @return LIS2DH12_OK on success + * @return LIS2DH12_NOBUS on bus error + */ +int lis2dh12_read_temperature(const lis2dh12_t *dev, int16_t *temp); + /** * @brief Clear the LIS2DH12 memory, clears all sampled data * diff --git a/drivers/lis2dh12/include/lis2dh12_registers.h b/drivers/lis2dh12/include/lis2dh12_registers.h index b956245125..530434f285 100644 --- a/drivers/lis2dh12/include/lis2dh12_registers.h +++ b/drivers/lis2dh12/include/lis2dh12_registers.h @@ -33,6 +33,14 @@ enum { LIS2DH12_STATUS_REG_AUX_TOR = 0x40, /**< Temperature data overrun */ }; +/** + * @brief STATUS_REG_TEMP definitions + */ +enum { + LIS2DH12_TEMP_CFG_REG_DISABLE = 0x00, /**< Temperature sensor disable */ + LIS2DH12_TEMP_CFG_REG_ENABLE = 0xC0, /**< Temperature sensor enable */ +}; + /** * @brief STATUS_REG definitions */ diff --git a/drivers/lis2dh12/lis2dh12.c b/drivers/lis2dh12/lis2dh12.c index 76c0713b98..963eb9be4c 100644 --- a/drivers/lis2dh12/lis2dh12.c +++ b/drivers/lis2dh12/lis2dh12.c @@ -23,6 +23,7 @@ #include "byteorder.h" #include "mutex.h" #include "timex.h" +#include "xtimer.h" #include "lis2dh12.h" #include "lis2dh12_internal.h" @@ -188,6 +189,9 @@ int lis2dh12_init(lis2dh12_t *dev, const lis2dh12_params_t *params) _write(dev, REG_CTRL_REG1, reg1.reg); + /* enable block data update */ + _write(dev, REG_CTRL_REG4, 0x80); + _release(dev); DEBUG("[lis2dh12] initialization successful\n"); @@ -579,6 +583,30 @@ int lis2dh12_clear_data(const lis2dh12_t *dev) return LIS2DH12_OK; } +int lis2dh12_read_temperature(const lis2dh12_t *dev, int16_t *temp) +{ + uint8_t bytes[2]; + + _acquire(dev); + + /* enable temperature sensor */ + if (!_read(dev, REG_TEMP_CFG_REG)) { + uint8_t odr = _read(dev, REG_CTRL_REG1) >> 4; + _write(dev, REG_TEMP_CFG_REG, LIS2DH12_TEMP_CFG_REG_ENABLE); + if (IS_USED(MODULE_XTIMER)) { + xtimer_msleep(MS_PER_SEC / hz_per_dr[odr]); + } + } + + _read_burst(dev, REG_OUT_TEMP_L, bytes, sizeof(bytes)); + _release(dev); + + *temp = 100 * (int8_t)bytes[1]; + *temp += (100 * bytes[0]) >> 8; + + return 0; +} + int lis2dh12_set_reference(const lis2dh12_t *dev, uint8_t reference) { @@ -777,5 +805,10 @@ int lis2dh12_poweroff(const lis2dh12_t *dev) /* set datarate to zero */ lis2dh12_set_datarate(dev, 0); + /* disable temperature sensor */ + _acquire(dev); + _write(dev, REG_TEMP_CFG_REG, LIS2DH12_TEMP_CFG_REG_DISABLE); + _release(dev); + return LIS2DH12_OK; } diff --git a/drivers/lis2dh12/lis2dh12_saul.c b/drivers/lis2dh12/lis2dh12_saul.c index b6df866556..25b87b2cf8 100644 --- a/drivers/lis2dh12/lis2dh12_saul.c +++ b/drivers/lis2dh12/lis2dh12_saul.c @@ -31,8 +31,25 @@ static int read_accelerometer(const void *dev, phydat_t *res) return 3; } +static int read_temperature(const void *dev, phydat_t *res) +{ + if (lis2dh12_read_temperature(dev, &res->val[0])) { + return -ECANCELED; + } + res->unit = UNIT_TEMP_C; + res->scale = -2; + + return 1; +} + const saul_driver_t lis2dh12_saul_driver = { .read = read_accelerometer, .write = saul_notsup, - .type = SAUL_SENSE_ACCEL + .type = SAUL_SENSE_ACCEL, +}; + +const saul_driver_t lis2dh12_saul_temp_driver = { + .read = read_temperature, + .write = saul_notsup, + .type = SAUL_SENSE_TEMP, }; diff --git a/drivers/saul/init_devs/auto_init_lis2dh12.c b/drivers/saul/init_devs/auto_init_lis2dh12.c index 4f89ee230c..05b9a1724e 100644 --- a/drivers/saul/init_devs/auto_init_lis2dh12.c +++ b/drivers/saul/init_devs/auto_init_lis2dh12.c @@ -30,7 +30,6 @@ */ #define LIS2DH12_NUM ARRAY_SIZE(lis2dh12_params) - /** * @brief Number of defined SAUL registry info entries */ @@ -45,7 +44,7 @@ static lis2dh12_t lis2dh12_devs[LIS2DH12_NUM]; /** * @brief Memory for the SAUL registry entries */ -static saul_reg_t saul_entries[LIS2DH12_NUM]; +static saul_reg_t saul_entries[LIS2DH12_NUM * 2]; void auto_init_lis2dh12(void) { @@ -62,9 +61,14 @@ void auto_init_lis2dh12(void) continue; } - saul_entries[i].dev = &(lis2dh12_devs[i]); - saul_entries[i].name = lis2dh12_saul_info[i].name; - saul_entries[i].driver = &lis2dh12_saul_driver; - saul_reg_add(&(saul_entries[i])); + saul_entries[2 * i].dev = &lis2dh12_devs[i]; + saul_entries[2 * i].name = lis2dh12_saul_info[i].name; + saul_entries[2 * i].driver = &lis2dh12_saul_driver; + saul_reg_add(&saul_entries[2 * i]); + + saul_entries[2 * i + 1].dev = &lis2dh12_devs[i]; + saul_entries[2 * i + 1].name = lis2dh12_saul_info[i].name; + saul_entries[2 * i + 1].driver = &lis2dh12_saul_temp_driver; + saul_reg_add(&saul_entries[2 * i + 1]); } }