From a7d9547d5e266fe5683469eca301c82bc5aaee3a Mon Sep 17 00:00:00 2001
From: smlng <s@mlng.net>
Date: Sun, 2 Jul 2017 11:28:15 +0200
Subject: [PATCH] driver, lsm6dsl: fix temperature reading

---
 drivers/include/lsm6dsl.h                  |  6 +++++-
 drivers/lsm6dsl/include/lsm6dsl_internal.h |  5 +++++
 drivers/lsm6dsl/lsm6dsl.c                  | 25 ++++++++++++----------
 3 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/include/lsm6dsl.h b/drivers/include/lsm6dsl.h
index 5feebd88ac..650875b37f 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 7d112db207..e241a86210 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 a641ab7c94..ee3cb5a519 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;
 }
-- 
GitLab