diff --git a/drivers/include/lsm6dsl.h b/drivers/include/lsm6dsl.h index 5feebd88acdeffcf3f562807c7f15b4fe4c07150..650875b37f0eafb5c09c1d15a3f58b9ac7adec22 100644 --- a/drivers/include/lsm6dsl.h +++ b/drivers/include/lsm6dsl.h @@ -132,8 +132,12 @@ int lsm6dsl_read_gyro(const lsm6dsl_t *dev, lsm6dsl_3d_data_t *data); /** * @brief Read temperature data * + * @note To avoid floating point data types but still provide high resolution + * for temperature readings, resulting values are scale by factor 100. + * + * * @param[in] dev device to read - * @param[out] data temperature value + * @param[out] data temperature value, in °C x 100 * * @return 0 on success * @return < 0 on error diff --git a/drivers/lsm6dsl/include/lsm6dsl_internal.h b/drivers/lsm6dsl/include/lsm6dsl_internal.h index 7d112db207c307a7c94083b7d32dee5ac8d3fe32..e241a862104e63334dbdf6fa1b369cfd86cd8c17 100644 --- a/drivers/lsm6dsl/include/lsm6dsl_internal.h +++ b/drivers/lsm6dsl/include/lsm6dsl_internal.h @@ -149,6 +149,11 @@ extern "C" { #define LSM6DSL_FIFO_CTRL3_GYRO_DEC_SHIFT (3) /** @} */ +/** + * @brief Offset for temperature calculation + */ +#define LSM6DSL_TEMP_OFFSET (0x1900) + #ifdef __cplusplus } #endif diff --git a/drivers/lsm6dsl/lsm6dsl.c b/drivers/lsm6dsl/lsm6dsl.c index a641ab7c94ead8801d357f4e22b6bfd7f6f915f7..ee3cb5a5191e70d85cf73da58dbcd2aa032a2be3 100644 --- a/drivers/lsm6dsl/lsm6dsl.c +++ b/drivers/lsm6dsl/lsm6dsl.c @@ -198,21 +198,24 @@ int lsm6dsl_read_gyro(const lsm6dsl_t *dev, lsm6dsl_3d_data_t *data) int lsm6dsl_read_temp(const lsm6dsl_t *dev, int16_t *data) { - int res; uint8_t tmp; - + uint16_t traw; + /* read raw temperature */ i2c_acquire(dev->params.i2c); - res = i2c_read_reg(dev->params.i2c, dev->params.addr, LSM6DSL_REG_OUT_TEMP_L, &tmp); - *data = tmp; - - res += i2c_read_reg(dev->params.i2c, dev->params.addr, LSM6DSL_REG_OUT_TEMP_H, &tmp); - *data |= tmp << 8; - - i2c_release(dev->params.i2c); - - if (res < 2) { + if (i2c_read_reg(dev->params.i2c, dev->params.addr, LSM6DSL_REG_OUT_TEMP_L, &tmp) != 1) { + i2c_release(dev->params.i2c); return -1; } + traw = tmp; + if (i2c_read_reg(dev->params.i2c, dev->params.addr, LSM6DSL_REG_OUT_TEMP_H, &tmp) != 1) { + i2c_release(dev->params.i2c); + return -1; + } + traw |= (uint16_t)tmp << 8; + i2c_release(dev->params.i2c); + /* convert temperature */ + traw += LSM6DSL_TEMP_OFFSET; + *data = (int16_t)(((int32_t)traw * 100) / 256); return 0; }