Revision:
1:344923bddd4f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SI7021.h	Thu Sep 14 00:16:02 2017 +0000
@@ -0,0 +1,143 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2017 AT&T, IIoT Foundry, Plano, TX, USA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** \addtogroup drivers */
+
+/** Support for Silicon Labs SI7021 temperature and humidity sensor
+ *
+ * Example:
+ * @code
+ *
+ * #include "mbed.h"
+ * #include "SI7021.h"
+ *
+ * I2C          i2c(I2C_SDA, I2C_SCL);
+ * SI7021<I2C>  si7021(&i2c);
+ *
+ * int main() {
+ *     si7021_measurements_t  data;
+ *     bool                   ok;
+ *
+ *     ok = si7021->read(&data);
+ *           
+ *     if (ok) {
+ *         printf("%%RelHum: %f\r\n", data.humidity_PR);
+ *         printf("temp C/F: %f/%f\r\n", data.temp_C, data.temp_C * 9 / 5 + 32);
+ *     } else {
+ *         printf("si7021 error!\r\n");
+ *     }
+ * }
+ * @endcode
+ * @ingroup drivers
+ */
+
+#pragma once
+
+#define SI7021A20_I2C_ADDR              0x80
+
+#define SI7021A20_CMD_MEAS_RH_HMM       0xE5
+#define SI7021A20_CMD_MEAS_RH_NHMM      0xF5
+#define SI7021A20_CMD_MEAS_TEMP_HMM     0xE3
+#define SI7021A20_CMD_MEAS_TEMP_NHMM    0xF3
+#define SI7021A20_CMD_READ_TEMP         0xE0
+#define SI7021A20_CMD_RESET             0xFE
+#define SI7021A20_CMD_WRITE_USER1       0xE6
+#define SI7021A20_CMD_WRITE_USER2       0xE7
+#define SI7021A20_CMD_WRITE_HEAT_CTRL   0x51
+#define SI7021A20_CMD_READ_HEAT_CTRL    0x11
+#define SI7021A20_CMD_READ_ID1          0xFA0F
+#define SI7021A20_CMD_READ_ID2          0xFCC9
+#define SI7021A20_REGF_ID2_DEV_ID               0x15
+#define SI7021A20_CMD_READ_FW_REV       0x84B8
+
+typedef struct {
+    float       temp_C;
+    float       humidity_PR;
+} si7021_measurements_t;
+
+template <class T>
+class SI7021 {
+ public:
+    /**
+    * Constructor
+    *
+    * @param i2c I2C class servicing the strip
+    */
+    SI7021(T * i2c) : _i2c(i2c) {}
+
+    /**
+    * Read temperature and humidity
+    *
+    * @param data points to struct to store measurements in.  Stucture is
+    *      valid only when function returns success indication.
+    *
+    * @returns true (success) or false (failure)
+    */
+    bool read(si7021_measurements_t * data) {
+        bool    ok;
+        union {
+            char    cmd;
+            struct {
+                uint8_t  meas_msb;
+                uint8_t  meas_lsb;
+            };
+        } buff;
+        
+        buff.cmd = SI7021A20_CMD_MEAS_RH_HMM;
+        ok = (_i2c_transfer(SI7021A20_I2C_ADDR, &buff, 1, 2));
+        if (ok) {
+            // Humidity% = measurement * 125/65536 - 6
+            int meas_raw        = ((int)buff.meas_msb << 8) + buff.meas_lsb;
+            data->humidity_PR   = (float)meas_raw * (125.0F/65536.0F) - 6.0F;
+        
+            buff.cmd = SI7021A20_CMD_READ_TEMP;
+            ok = _i2c_transfer(SI7021A20_I2C_ADDR, &buff, 1, 2);
+        }
+        if (ok) {
+            // TempC = measurement * 175.72/65536 - 46.85
+            int meas_raw    = ((int)buff.meas_msb << 8) + buff.meas_lsb;
+            data->temp_C    = meas_raw * (175.72/65536.0) - 46.85;
+         }
+        return ok;
+    }    
+
+ protected:
+
+    /**
+    * I2C read/write helper function
+    *
+    * @param address is the register to read/write
+    * @param buff holds the data to write and recieves the data to read
+    * @param writeSize is the number of bytes to write to register
+    * @param readSize is the number of bytes to retrieve from device
+    *
+    * @returns true (success) or false (failure)
+    */
+    bool _i2c_transfer(int address, void * buff, size_t writeSize, size_t readSize) {
+        bool ok;
+        bool expect_response = (readSize != 0);
+    
+        ok = !_i2c->write(address, (char*)buff, writeSize, expect_response);
+        if (ok && expect_response)
+            ok = !_i2c->read(address, (char*)buff, readSize);
+    
+        return ok;
+    }
+    
+
+    T  *_i2c;
+};
+