From 9781ea99ccf0d94cdaba54d390fb92119b7a1a32 Mon Sep 17 00:00:00 2001
From: Joakim Gebart <joakim.gebart@eistec.se>
Date: Thu, 2 Jul 2015 11:51:08 +0200
Subject: [PATCH] drivers/hih6310: Initial commit of HIH6310 driver

Honeywell HumidIcon Digital Humidity/Temperature Sensors: HIH-6130/6131 Series

Only basic humidity and temperature measurement support is implemented.

Missing:
 - Alarm interrupts
 - Command mode (reconfigure i2c address, alarm levels, alarm polarity, custom ID)
---
 Makefile.dep              |   4 ++
 drivers/hih6130/Makefile  |   3 +
 drivers/hih6130/hih6130.c | 140 ++++++++++++++++++++++++++++++++++++++
 drivers/include/hih6130.h |  70 +++++++++++++++++++
 4 files changed, 217 insertions(+)
 create mode 100644 drivers/hih6130/Makefile
 create mode 100644 drivers/hih6130/hih6130.c
 create mode 100644 drivers/include/hih6130.h

diff --git a/Makefile.dep b/Makefile.dep
index 2a4721a645..cdf9a4744b 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -330,3 +330,7 @@ endif
 ifneq (,$(filter newlib,$(USEMODULE)))
   USEMODULE += uart_stdio
 endif
+
+ifneq (,$(filter hih6130,$(USEMODULE)))
+  USEMODULE += vtimer
+endif
diff --git a/drivers/hih6130/Makefile b/drivers/hih6130/Makefile
new file mode 100644
index 0000000000..85e928e184
--- /dev/null
+++ b/drivers/hih6130/Makefile
@@ -0,0 +1,3 @@
+MODULE = hih6130
+
+include $(RIOTBASE)/Makefile.base
diff --git a/drivers/hih6130/hih6130.c b/drivers/hih6130/hih6130.c
new file mode 100644
index 0000000000..8050e74305
--- /dev/null
+++ b/drivers/hih6130/hih6130.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2015 Eistec AB
+ *
+ * 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     driver_hih6130
+ * @{
+ *
+ * @file
+ * @brief       Device driver implementation for Honeywell HumidIcon Digital
+ *              Humidity/Temperature Sensors: HIH-6130/6131 Series
+ *
+ * @author      Joakim Gebart <joakim.gebart@eistec.se>
+ *
+ * @}
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "hih6130.h"
+#include "periph/i2c.h"
+#include "timex.h"
+#include "vtimer.h"
+
+#define ENABLE_DEBUG    (0)
+#include "debug.h"
+
+/* Humidity is stored in the first 2 bytes of data */
+#define HIH6130_HUMIDITY_DATA_LENGTH (2)
+/* Humidity + temperature data is 4 bytes long */
+#define HIH6130_FULL_DATA_LENGTH (4)
+/* Bit mask for the status bits in the first byte transferred */
+#define HIH6130_STATUS_MASK      (0xc0)
+/* Bit mask for the humidity data */
+#define HIH6130_HUMIDITY_MASK    (0x3fff)
+/* Temperature data is left adjusted within the word */
+#define HIH6130_TEMPERATURE_SHIFT (2)
+
+enum {
+    HIH6130_STATUS_OK           = 0x00,
+    /**
+     * stale data: data that has already been fetched since the last measurement
+     * cycle, or data fetched before the first measurement has been completed.
+     */
+    HIH6130_STATUS_STALE_DATA   = 0x40,
+    HIH6130_STATUS_COMMAND_MODE = 0x80,
+    HIH6130_STATUS_DIAGNOSTIC   = 0xc0,
+};
+
+/** @brief Delay between requesting a measurement and data becoming ready */
+static const timex_t measurement_delay = {
+        .seconds = 0, .microseconds = 50 * MS_IN_USEC, };
+
+/** @brief Trigger a new measurement on the sensor */
+static inline int hih6130_measurement_request(hih6130_t *dev)
+{
+    i2c_acquire(dev->i2c);
+
+    /* An empty write request triggers a new measurement */
+    if (i2c_write_bytes(dev->i2c, dev->addr, (char *)NULL, 0) < 0) {
+        i2c_release(dev->i2c);
+        return -1;
+    }
+
+    i2c_release(dev->i2c);
+
+    return 0;
+}
+
+void hih6130_init(hih6130_t *dev, i2c_t i2c, uint8_t address)
+{
+    /* write device descriptor */
+    dev->i2c = i2c;
+    dev->addr = address;
+}
+
+static inline int hih6130_get_humidity_temperature_raw(hih6130_t *dev, uint16_t *humidity_raw, uint16_t *temperature_raw)
+{
+    int status;
+    uint8_t buf[HIH6130_FULL_DATA_LENGTH];
+
+    i2c_acquire(dev->i2c);
+
+    if (i2c_read_bytes(dev->i2c, dev->addr, (char*)&buf[0], sizeof(buf)) != sizeof(buf)) {
+        i2c_release(dev->i2c);
+        return -1;
+    }
+
+    i2c_release(dev->i2c);
+
+    /* data is in big-endian format, with status bits in the first byte. */
+    switch (buf[0] & HIH6130_STATUS_MASK) {
+        case HIH6130_STATUS_OK:
+            status = 0;
+            break;
+        case HIH6130_STATUS_STALE_DATA:
+            status = 1;
+            break;
+        default:
+            return -2;
+    }
+
+    *humidity_raw    = ((buf[0] << 8) | buf[1]) & HIH6130_HUMIDITY_MASK;
+    *temperature_raw = (((buf[2] << 8) | buf[3]) >> HIH6130_TEMPERATURE_SHIFT);
+
+    return status;
+}
+
+int hih6130_get_humidity_temperature_float(hih6130_t *dev,
+    float *relative_humidity_percent, float *temperature_celsius)
+{
+    uint16_t hum_raw, temp_raw;
+    int status;
+
+    if (hih6130_measurement_request(dev) != 0) {
+        return -1;
+    }
+
+    vtimer_sleep(measurement_delay);
+
+    status = hih6130_get_humidity_temperature_raw(dev, &hum_raw, &temp_raw);
+
+    if (status < 0) {
+        return -1;
+    }
+
+    if (relative_humidity_percent != NULL) {
+        *relative_humidity_percent = hum_raw * (100.f / 16383.f);
+    }
+    if (temperature_celsius != NULL) {
+        *temperature_celsius = temp_raw * (165.f / 16383.f) - 40.f;
+    }
+
+    return status;
+}
diff --git a/drivers/include/hih6130.h b/drivers/include/hih6130.h
new file mode 100644
index 0000000000..92c7780f03
--- /dev/null
+++ b/drivers/include/hih6130.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2015 Eistec AB
+ *
+ * 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    driver_hih6130 HIH6130 humidity and temperature sensor
+ * @ingroup     drivers
+ * @brief       Device driver for Honeywell HumidIcon Digital
+ *              Humidity/Temperature Sensors: HIH-6130/6131 Series
+ * @{
+ *
+ * @file
+ * @brief       Device driver for Honeywell HumidIcon Digital
+ *              Humidity/Temperature Sensors: HIH-6130/6131 Series
+ *
+ * @author      Joakim Gebart <joakim.gebart@eistec.se>
+ */
+
+#ifndef HIH6130_H_
+#define HIH6130_H_
+
+#include <stdint.h>
+
+#include "periph/i2c.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Device descriptor for HIH6130/HIH6131 sensors
+ */
+typedef struct {
+    i2c_t i2c;              /**< I2C device the sensor is connected to */
+    uint8_t addr;           /**< the slave address of the sensor on the I2C bus */
+} hih6130_t;
+
+/**
+ * @brief Initialize a sensor
+ *
+ * @param[out] dev          device descriptor of sensor to initialize
+ * @param[in]  i2c          I2C bus the sensor is connected to
+ * @param[in]  address      I2C slave address of the sensor
+ */
+void hih6130_init(hih6130_t *dev, i2c_t i2c, uint8_t address);
+
+/**
+ * @brief Read humidity and temperature from sensor and convert to floating-point
+ *
+ * @param[in]  dev                       Sensor device descriptor
+ * @param[out] relative_humidity_percent Measured relative humidity in percent
+ * @param[out] temperature_celsius       Measured temperature in degrees Celsius
+ *
+ * @return 0 on success
+ * @return -1 on error
+ * @return 1 if data is stale
+ */
+int hih6130_get_humidity_temperature_float(hih6130_t *dev,
+    float *relative_humidity_percent, float *temperature_celsius);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HIH6130_H_ */
+/** @} */
-- 
GitLab