Library for Sensirion Environmental Sensor Shield for SGP30 & SHTC1

Dependents:   example-sensirion-ublox-c030

Committer:
Haseeb Khalid
Date:
Fri Dec 21 17:24:52 2018 +0500
Revision:
0:3e97001a43f8
Sensirion-ess library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Haseeb Khalid 0:3e97001a43f8 1 /*
Haseeb Khalid 0:3e97001a43f8 2 * Copyright (c) 2017-2018, Sensirion AG
Haseeb Khalid 0:3e97001a43f8 3 * All rights reserved.
Haseeb Khalid 0:3e97001a43f8 4 *
Haseeb Khalid 0:3e97001a43f8 5 * Redistribution and use in source and binary forms, with or without
Haseeb Khalid 0:3e97001a43f8 6 * modification, are permitted provided that the following conditions are met:
Haseeb Khalid 0:3e97001a43f8 7 *
Haseeb Khalid 0:3e97001a43f8 8 * * Redistributions of source code must retain the above copyright notice, this
Haseeb Khalid 0:3e97001a43f8 9 * list of conditions and the following disclaimer.
Haseeb Khalid 0:3e97001a43f8 10 *
Haseeb Khalid 0:3e97001a43f8 11 * * Redistributions in binary form must reproduce the above copyright notice,
Haseeb Khalid 0:3e97001a43f8 12 * this list of conditions and the following disclaimer in the documentation
Haseeb Khalid 0:3e97001a43f8 13 * and/or other materials provided with the distribution.
Haseeb Khalid 0:3e97001a43f8 14 *
Haseeb Khalid 0:3e97001a43f8 15 * * Neither the name of Sensirion AG nor the names of its
Haseeb Khalid 0:3e97001a43f8 16 * contributors may be used to endorse or promote products derived from
Haseeb Khalid 0:3e97001a43f8 17 * this software without specific prior written permission.
Haseeb Khalid 0:3e97001a43f8 18 *
Haseeb Khalid 0:3e97001a43f8 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Haseeb Khalid 0:3e97001a43f8 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Haseeb Khalid 0:3e97001a43f8 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Haseeb Khalid 0:3e97001a43f8 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
Haseeb Khalid 0:3e97001a43f8 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Haseeb Khalid 0:3e97001a43f8 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Haseeb Khalid 0:3e97001a43f8 25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Haseeb Khalid 0:3e97001a43f8 26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Haseeb Khalid 0:3e97001a43f8 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Haseeb Khalid 0:3e97001a43f8 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Haseeb Khalid 0:3e97001a43f8 29 */
Haseeb Khalid 0:3e97001a43f8 30
Haseeb Khalid 0:3e97001a43f8 31 /*
Haseeb Khalid 0:3e97001a43f8 32 * TODO:
Haseeb Khalid 0:3e97001a43f8 33 * - Baseline store/restore
Haseeb Khalid 0:3e97001a43f8 34 * - proper init
Haseeb Khalid 0:3e97001a43f8 35 * - IAQ levels, getIAQLevel()
Haseeb Khalid 0:3e97001a43f8 36 */
Haseeb Khalid 0:3e97001a43f8 37
Haseeb Khalid 0:3e97001a43f8 38
Haseeb Khalid 0:3e97001a43f8 39
Haseeb Khalid 0:3e97001a43f8 40 #include <string.h>
Haseeb Khalid 0:3e97001a43f8 41
Haseeb Khalid 0:3e97001a43f8 42 #include "sensirion_ess.h"
Haseeb Khalid 0:3e97001a43f8 43 DigitalOut led_red(LED_RED);
Haseeb Khalid 0:3e97001a43f8 44 DigitalOut led_yellow(LED_YEL);
Haseeb Khalid 0:3e97001a43f8 45 DigitalOut led_green(LED_GRN);
Haseeb Khalid 0:3e97001a43f8 46
Haseeb Khalid 0:3e97001a43f8 47 SensirionESS::SensirionESS(void *interface)
Haseeb Khalid 0:3e97001a43f8 48 {
Haseeb Khalid 0:3e97001a43f8 49 i2c_connection = (I2C*)(interface);
Haseeb Khalid 0:3e97001a43f8 50 t = new Timer();
Haseeb Khalid 0:3e97001a43f8 51 }
Haseeb Khalid 0:3e97001a43f8 52
Haseeb Khalid 0:3e97001a43f8 53 int SensirionESS::initSensors()
Haseeb Khalid 0:3e97001a43f8 54 {
Haseeb Khalid 0:3e97001a43f8 55
Haseeb Khalid 0:3e97001a43f8 56 if (measureRHTInt() != 0) {
Haseeb Khalid 0:3e97001a43f8 57 setError("Error communicating with SHTC1");
Haseeb Khalid 0:3e97001a43f8 58 return -1;
Haseeb Khalid 0:3e97001a43f8 59 }
Haseeb Khalid 0:3e97001a43f8 60
Haseeb Khalid 0:3e97001a43f8 61 if (initSGP() != 0) {
Haseeb Khalid 0:3e97001a43f8 62 setError("Error communicating with SGPC3");
Haseeb Khalid 0:3e97001a43f8 63 return -2;
Haseeb Khalid 0:3e97001a43f8 64 }
Haseeb Khalid 0:3e97001a43f8 65
Haseeb Khalid 0:3e97001a43f8 66 t->start();
Haseeb Khalid 0:3e97001a43f8 67
Haseeb Khalid 0:3e97001a43f8 68 mInitialized = true;
Haseeb Khalid 0:3e97001a43f8 69 return 0;
Haseeb Khalid 0:3e97001a43f8 70 }
Haseeb Khalid 0:3e97001a43f8 71
Haseeb Khalid 0:3e97001a43f8 72 //////////////////////////////////////////////////////////////////////////////
Haseeb Khalid 0:3e97001a43f8 73 // SHT
Haseeb Khalid 0:3e97001a43f8 74
Haseeb Khalid 0:3e97001a43f8 75 int SensirionESS::measureRHT()
Haseeb Khalid 0:3e97001a43f8 76 {
Haseeb Khalid 0:3e97001a43f8 77 if (!mInitialized) {
Haseeb Khalid 0:3e97001a43f8 78 setError("ESS not initialized");
Haseeb Khalid 0:3e97001a43f8 79 return -1;
Haseeb Khalid 0:3e97001a43f8 80 }
Haseeb Khalid 0:3e97001a43f8 81
Haseeb Khalid 0:3e97001a43f8 82 measureRHTInt();
Haseeb Khalid 0:3e97001a43f8 83 return 0;
Haseeb Khalid 0:3e97001a43f8 84 }
Haseeb Khalid 0:3e97001a43f8 85
Haseeb Khalid 0:3e97001a43f8 86 int SensirionESS::measureRHTInt()
Haseeb Khalid 0:3e97001a43f8 87 {
Haseeb Khalid 0:3e97001a43f8 88 uint8_t cmd[CMD_LENGTH] = { 0x7C, 0xA2 };
Haseeb Khalid 0:3e97001a43f8 89
Haseeb Khalid 0:3e97001a43f8 90 if (i2c_write(SHT_I2C_ADDR, cmd, CMD_LENGTH)) {
Haseeb Khalid 0:3e97001a43f8 91 setError("I2C write error");
Haseeb Khalid 0:3e97001a43f8 92 return -1;
Haseeb Khalid 0:3e97001a43f8 93 }
Haseeb Khalid 0:3e97001a43f8 94
Haseeb Khalid 0:3e97001a43f8 95 wait_ms(SHT_MEASURE_DELAY);
Haseeb Khalid 0:3e97001a43f8 96
Haseeb Khalid 0:3e97001a43f8 97 int ret = i2c_read(SHT_I2C_ADDR, mDataBuf, SHT_DATA_LENGTH);
Haseeb Khalid 0:3e97001a43f8 98 if (ret == -1) {
Haseeb Khalid 0:3e97001a43f8 99 setError("I2C read error");
Haseeb Khalid 0:3e97001a43f8 100 return -2;
Haseeb Khalid 0:3e97001a43f8 101 }
Haseeb Khalid 0:3e97001a43f8 102
Haseeb Khalid 0:3e97001a43f8 103 // check CRC for both RH and T
Haseeb Khalid 0:3e97001a43f8 104 if (crc8(mDataBuf+0, 2) != mDataBuf[2] ||
Haseeb Khalid 0:3e97001a43f8 105 crc8(mDataBuf+3, 2) != mDataBuf[5]) {
Haseeb Khalid 0:3e97001a43f8 106 setError("CRC mismatch");
Haseeb Khalid 0:3e97001a43f8 107 return -3;
Haseeb Khalid 0:3e97001a43f8 108 }
Haseeb Khalid 0:3e97001a43f8 109
Haseeb Khalid 0:3e97001a43f8 110 uint16_t val;
Haseeb Khalid 0:3e97001a43f8 111 val = (mDataBuf[0] << 8) + mDataBuf[1];
Haseeb Khalid 0:3e97001a43f8 112 mTemperature = -45 + 175 * (val / 65535.0);
Haseeb Khalid 0:3e97001a43f8 113 val = (mDataBuf[3] << 8) + mDataBuf[4];
Haseeb Khalid 0:3e97001a43f8 114 mHumidity = 100 * (val / 65535.0);
Haseeb Khalid 0:3e97001a43f8 115
Haseeb Khalid 0:3e97001a43f8 116 return 0;
Haseeb Khalid 0:3e97001a43f8 117 }
Haseeb Khalid 0:3e97001a43f8 118
Haseeb Khalid 0:3e97001a43f8 119 //////////////////////////////////////////////////////////////////////////////
Haseeb Khalid 0:3e97001a43f8 120 // SGP
Haseeb Khalid 0:3e97001a43f8 121
Haseeb Khalid 0:3e97001a43f8 122 int SensirionESS::getProductType() const
Haseeb Khalid 0:3e97001a43f8 123 {
Haseeb Khalid 0:3e97001a43f8 124 return mProductType;
Haseeb Khalid 0:3e97001a43f8 125 }
Haseeb Khalid 0:3e97001a43f8 126
Haseeb Khalid 0:3e97001a43f8 127 int SensirionESS::getFeatureSetVersion() const
Haseeb Khalid 0:3e97001a43f8 128 {
Haseeb Khalid 0:3e97001a43f8 129 return mFeatureSetVersion;
Haseeb Khalid 0:3e97001a43f8 130 }
Haseeb Khalid 0:3e97001a43f8 131
Haseeb Khalid 0:3e97001a43f8 132 int SensirionESS::measureIAQ()
Haseeb Khalid 0:3e97001a43f8 133 {
Haseeb Khalid 0:3e97001a43f8 134 if (!mInitialized) {
Haseeb Khalid 0:3e97001a43f8 135 setError("ESS not initialized");
Haseeb Khalid 0:3e97001a43f8 136 return -1;
Haseeb Khalid 0:3e97001a43f8 137 }
Haseeb Khalid 0:3e97001a43f8 138
Haseeb Khalid 0:3e97001a43f8 139 // keep track of timing
Haseeb Khalid 0:3e97001a43f8 140 mSGPMeasurementTimestamp = t->read_ms();
Haseeb Khalid 0:3e97001a43f8 141
Haseeb Khalid 0:3e97001a43f8 142 uint8_t cmd[CMD_LENGTH] = { 0x20, 0x08 };
Haseeb Khalid 0:3e97001a43f8 143
Haseeb Khalid 0:3e97001a43f8 144 if (i2c_write(SGP_I2C_ADDR, cmd, CMD_LENGTH)) {
Haseeb Khalid 0:3e97001a43f8 145 setError("error in i2c_write");
Haseeb Khalid 0:3e97001a43f8 146 return -1;
Haseeb Khalid 0:3e97001a43f8 147 }
Haseeb Khalid 0:3e97001a43f8 148
Haseeb Khalid 0:3e97001a43f8 149 wait_ms(SGP_MEASURE_DELAY);
Haseeb Khalid 0:3e97001a43f8 150
Haseeb Khalid 0:3e97001a43f8 151 int ret = i2c_read(SGP_I2C_ADDR, mDataBuf, SGP_DATA_LENGTH);
Haseeb Khalid 0:3e97001a43f8 152 if (ret == -1) {
Haseeb Khalid 0:3e97001a43f8 153 setError("error in i2c_read");
Haseeb Khalid 0:3e97001a43f8 154 return -2;
Haseeb Khalid 0:3e97001a43f8 155 }
Haseeb Khalid 0:3e97001a43f8 156
Haseeb Khalid 0:3e97001a43f8 157 if (crc8(mDataBuf, 2) != mDataBuf[2]) {
Haseeb Khalid 0:3e97001a43f8 158 setError("CRC mismatch");
Haseeb Khalid 0:3e97001a43f8 159 return -3;
Haseeb Khalid 0:3e97001a43f8 160 }
Haseeb Khalid 0:3e97001a43f8 161
Haseeb Khalid 0:3e97001a43f8 162 // SGPC3 only has TVOC; SGP30 sends [eco2, tvoc]
Haseeb Khalid 0:3e97001a43f8 163 if (mProductType == PRODUCT_TYPE_SGP30) {
Haseeb Khalid 0:3e97001a43f8 164 mECO2 = (mDataBuf[0] << 8) | mDataBuf[1];
Haseeb Khalid 0:3e97001a43f8 165 if (crc8(mDataBuf+3, 2) != mDataBuf[5]) {
Haseeb Khalid 0:3e97001a43f8 166 setError("CRC mismatch");
Haseeb Khalid 0:3e97001a43f8 167 return -4;
Haseeb Khalid 0:3e97001a43f8 168 }
Haseeb Khalid 0:3e97001a43f8 169 mTVOC = (mDataBuf[3] << 8) | mDataBuf[4];
Haseeb Khalid 0:3e97001a43f8 170 } else {
Haseeb Khalid 0:3e97001a43f8 171 mTVOC = (mDataBuf[0] << 8) | mDataBuf[1];;
Haseeb Khalid 0:3e97001a43f8 172 }
Haseeb Khalid 0:3e97001a43f8 173
Haseeb Khalid 0:3e97001a43f8 174 return 0;
Haseeb Khalid 0:3e97001a43f8 175 }
Haseeb Khalid 0:3e97001a43f8 176
Haseeb Khalid 0:3e97001a43f8 177 int SensirionESS::readFeatureSetInt()
Haseeb Khalid 0:3e97001a43f8 178 {
Haseeb Khalid 0:3e97001a43f8 179 uint8_t cmd[CMD_LENGTH] = { 0x20, 0x2f };
Haseeb Khalid 0:3e97001a43f8 180
Haseeb Khalid 0:3e97001a43f8 181 if (i2c_write(SGP_I2C_ADDR, cmd, CMD_LENGTH)) {
Haseeb Khalid 0:3e97001a43f8 182 setError("error in i2c_write");
Haseeb Khalid 0:3e97001a43f8 183 return -1;
Haseeb Khalid 0:3e97001a43f8 184 }
Haseeb Khalid 0:3e97001a43f8 185
Haseeb Khalid 0:3e97001a43f8 186 wait_ms(2);
Haseeb Khalid 0:3e97001a43f8 187
Haseeb Khalid 0:3e97001a43f8 188 const uint8_t DATA_LEN = 3;
Haseeb Khalid 0:3e97001a43f8 189 uint8_t data[DATA_LEN] = { 0 };
Haseeb Khalid 0:3e97001a43f8 190 int ret = i2c_read(SGP_I2C_ADDR, data, DATA_LEN);
Haseeb Khalid 0:3e97001a43f8 191 if (ret == -1) {
Haseeb Khalid 0:3e97001a43f8 192 setError("I2C read error");
Haseeb Khalid 0:3e97001a43f8 193 return -3;
Haseeb Khalid 0:3e97001a43f8 194 }
Haseeb Khalid 0:3e97001a43f8 195
Haseeb Khalid 0:3e97001a43f8 196 // check CRC
Haseeb Khalid 0:3e97001a43f8 197 if (crc8(data, 2) != data[2]) {
Haseeb Khalid 0:3e97001a43f8 198 setError("CRC mismatch");
Haseeb Khalid 0:3e97001a43f8 199 return -4;
Haseeb Khalid 0:3e97001a43f8 200 }
Haseeb Khalid 0:3e97001a43f8 201
Haseeb Khalid 0:3e97001a43f8 202 // 0 = SGP30, 1 = SGPC3
Haseeb Khalid 0:3e97001a43f8 203 mProductType = (data[0] & 0xF0) >> 4;
Haseeb Khalid 0:3e97001a43f8 204 mFeatureSetVersion = data[1] & 0xFF;
Haseeb Khalid 0:3e97001a43f8 205
Haseeb Khalid 0:3e97001a43f8 206 return 0;
Haseeb Khalid 0:3e97001a43f8 207 }
Haseeb Khalid 0:3e97001a43f8 208
Haseeb Khalid 0:3e97001a43f8 209 int SensirionESS::initSGP()
Haseeb Khalid 0:3e97001a43f8 210 {
Haseeb Khalid 0:3e97001a43f8 211 int ret = readFeatureSetInt();
Haseeb Khalid 0:3e97001a43f8 212 // default: SGP30
Haseeb Khalid 0:3e97001a43f8 213 SGP_INTERMEASURE_DELAY = SGP30_INTERMEASURE_DELAY;
Haseeb Khalid 0:3e97001a43f8 214 SGP_DATA_LENGTH = SGP30_DATA_LENGTH;
Haseeb Khalid 0:3e97001a43f8 215 uint8_t cmd[CMD_LENGTH] = { 0x20, 0x03 };
Haseeb Khalid 0:3e97001a43f8 216
Haseeb Khalid 0:3e97001a43f8 217 if (mProductType == PRODUCT_TYPE_SGPC3) {
Haseeb Khalid 0:3e97001a43f8 218 SGP_INTERMEASURE_DELAY = SGPC3_INTERMEASURE_DELAY;
Haseeb Khalid 0:3e97001a43f8 219 cmd[1] = 0xae;
Haseeb Khalid 0:3e97001a43f8 220 }
Haseeb Khalid 0:3e97001a43f8 221
Haseeb Khalid 0:3e97001a43f8 222 // run init air quality
Haseeb Khalid 0:3e97001a43f8 223 if (i2c_write(SGP_I2C_ADDR, cmd, CMD_LENGTH)) {
Haseeb Khalid 0:3e97001a43f8 224 setError("error in i2c_write");
Haseeb Khalid 0:3e97001a43f8 225 return -1;
Haseeb Khalid 0:3e97001a43f8 226 }
Haseeb Khalid 0:3e97001a43f8 227 wait_ms(10);
Haseeb Khalid 0:3e97001a43f8 228
Haseeb Khalid 0:3e97001a43f8 229 return ret;
Haseeb Khalid 0:3e97001a43f8 230 }
Haseeb Khalid 0:3e97001a43f8 231
Haseeb Khalid 0:3e97001a43f8 232 //////////////////////////////////////////////////////////////////////////////
Haseeb Khalid 0:3e97001a43f8 233 // getter for values read earlier
Haseeb Khalid 0:3e97001a43f8 234 bool SensirionESS::isInitialized()
Haseeb Khalid 0:3e97001a43f8 235 {
Haseeb Khalid 0:3e97001a43f8 236 return mInitialized;
Haseeb Khalid 0:3e97001a43f8 237 }
Haseeb Khalid 0:3e97001a43f8 238
Haseeb Khalid 0:3e97001a43f8 239 float SensirionESS::getTemperature() const
Haseeb Khalid 0:3e97001a43f8 240 {
Haseeb Khalid 0:3e97001a43f8 241 return mTemperature;
Haseeb Khalid 0:3e97001a43f8 242 }
Haseeb Khalid 0:3e97001a43f8 243
Haseeb Khalid 0:3e97001a43f8 244 float SensirionESS::getHumidity() const
Haseeb Khalid 0:3e97001a43f8 245 {
Haseeb Khalid 0:3e97001a43f8 246 return mHumidity;
Haseeb Khalid 0:3e97001a43f8 247 }
Haseeb Khalid 0:3e97001a43f8 248
Haseeb Khalid 0:3e97001a43f8 249 float SensirionESS::getTVOC() const
Haseeb Khalid 0:3e97001a43f8 250 {
Haseeb Khalid 0:3e97001a43f8 251 return mTVOC;
Haseeb Khalid 0:3e97001a43f8 252 }
Haseeb Khalid 0:3e97001a43f8 253
Haseeb Khalid 0:3e97001a43f8 254 float SensirionESS::getECO2() const
Haseeb Khalid 0:3e97001a43f8 255 {
Haseeb Khalid 0:3e97001a43f8 256 return mECO2;
Haseeb Khalid 0:3e97001a43f8 257 }
Haseeb Khalid 0:3e97001a43f8 258
Haseeb Khalid 0:3e97001a43f8 259 void SensirionESS::setLedRYG(int r, int y, int g)
Haseeb Khalid 0:3e97001a43f8 260 {
Haseeb Khalid 0:3e97001a43f8 261 led_red = r;
Haseeb Khalid 0:3e97001a43f8 262 led_yellow = y;
Haseeb Khalid 0:3e97001a43f8 263 led_green = g;
Haseeb Khalid 0:3e97001a43f8 264 }
Haseeb Khalid 0:3e97001a43f8 265
Haseeb Khalid 0:3e97001a43f8 266 //////////////////////////////////////////////////////////////////////////////
Haseeb Khalid 0:3e97001a43f8 267 // error handling
Haseeb Khalid 0:3e97001a43f8 268
Haseeb Khalid 0:3e97001a43f8 269 inline void SensirionESS::setError(const char* error)
Haseeb Khalid 0:3e97001a43f8 270 {
Haseeb Khalid 0:3e97001a43f8 271 strlcpy(mErrorBuf, error, ERROR_BUF_LENGTH);
Haseeb Khalid 0:3e97001a43f8 272 }
Haseeb Khalid 0:3e97001a43f8 273
Haseeb Khalid 0:3e97001a43f8 274 const char* SensirionESS::getError() const
Haseeb Khalid 0:3e97001a43f8 275 {
Haseeb Khalid 0:3e97001a43f8 276 return mErrorBuf;
Haseeb Khalid 0:3e97001a43f8 277 }
Haseeb Khalid 0:3e97001a43f8 278
Haseeb Khalid 0:3e97001a43f8 279 //////////////////////////////////////////////////////////////////////////////
Haseeb Khalid 0:3e97001a43f8 280 // helper
Haseeb Khalid 0:3e97001a43f8 281
Haseeb Khalid 0:3e97001a43f8 282 int SensirionESS::remainingWaitTimeMS()
Haseeb Khalid 0:3e97001a43f8 283 {
Haseeb Khalid 0:3e97001a43f8 284 unsigned long deltaT = t->read_ms() - mSGPMeasurementTimestamp;
Haseeb Khalid 0:3e97001a43f8 285 if (deltaT > SGP_INTERMEASURE_DELAY) {
Haseeb Khalid 0:3e97001a43f8 286 // we're already late, don't wait any longer
Haseeb Khalid 0:3e97001a43f8 287 return 0;
Haseeb Khalid 0:3e97001a43f8 288 }
Haseeb Khalid 0:3e97001a43f8 289 return (SGP_INTERMEASURE_DELAY - deltaT);
Haseeb Khalid 0:3e97001a43f8 290 }
Haseeb Khalid 0:3e97001a43f8 291
Haseeb Khalid 0:3e97001a43f8 292 int8_t SensirionESS::i2c_read(uint8_t address, uint8_t* data, uint16_t count)
Haseeb Khalid 0:3e97001a43f8 293 {
Haseeb Khalid 0:3e97001a43f8 294 if (i2c_connection->read(address << 1, (char *) data, count) != 0)
Haseeb Khalid 0:3e97001a43f8 295 return -1;
Haseeb Khalid 0:3e97001a43f8 296 return 0;
Haseeb Khalid 0:3e97001a43f8 297 }
Haseeb Khalid 0:3e97001a43f8 298
Haseeb Khalid 0:3e97001a43f8 299 int8_t SensirionESS::i2c_write(uint8_t address, const uint8_t* data, uint16_t count)
Haseeb Khalid 0:3e97001a43f8 300 {
Haseeb Khalid 0:3e97001a43f8 301 if (i2c_connection->write(address << 1, (char *) data, count) != 0)
Haseeb Khalid 0:3e97001a43f8 302 return -1;
Haseeb Khalid 0:3e97001a43f8 303 return 0;
Haseeb Khalid 0:3e97001a43f8 304 }
Haseeb Khalid 0:3e97001a43f8 305
Haseeb Khalid 0:3e97001a43f8 306 uint8_t SensirionESS::crc8(const uint8_t* data, uint8_t len)
Haseeb Khalid 0:3e97001a43f8 307 {
Haseeb Khalid 0:3e97001a43f8 308 // adapted from SHT21 sample code from http://www.sensirion.com/en/products/humidity-temperature/download-center/
Haseeb Khalid 0:3e97001a43f8 309
Haseeb Khalid 0:3e97001a43f8 310 uint8_t crc = 0xff;
Haseeb Khalid 0:3e97001a43f8 311 uint8_t byteCtr;
Haseeb Khalid 0:3e97001a43f8 312 for (byteCtr = 0; byteCtr < len; ++byteCtr) {
Haseeb Khalid 0:3e97001a43f8 313 crc ^= (data[byteCtr]);
Haseeb Khalid 0:3e97001a43f8 314 for (uint8_t bit = 8; bit > 0; --bit) {
Haseeb Khalid 0:3e97001a43f8 315 if (crc & 0x80) {
Haseeb Khalid 0:3e97001a43f8 316 crc = (crc << 1) ^ 0x31;
Haseeb Khalid 0:3e97001a43f8 317 } else {
Haseeb Khalid 0:3e97001a43f8 318 crc = (crc << 1);
Haseeb Khalid 0:3e97001a43f8 319 }
Haseeb Khalid 0:3e97001a43f8 320 }
Haseeb Khalid 0:3e97001a43f8 321 }
Haseeb Khalid 0:3e97001a43f8 322 return crc;
Haseeb Khalid 0:3e97001a43f8 323 }