Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
SI7210.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017 AT&T, IIoT Foundry, Plano, TX, USA 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 /** \addtogroup drivers */ 00018 00019 /** Support for Silicon Labs SI7210: Magnetic field and temperature sensor 00020 * 00021 * Example: 00022 * @code 00023 * 00024 * #include "mbed.h" 00025 * #include "SI7210.h" 00026 * 00027 * I2C i2c(I2C_SDA, I2C_SCL); 00028 * SI7210<I2C> si7210(&i2c, SI7210_BASE_ADDR_7BIT); 00029 * 00030 * int main() { 00031 * si7210_measurements_t data; 00032 * bool ok; 00033 * 00034 * ok = si7210.enable() && 00035 * si7210.read(&data) && 00036 * si7210.disable(); 00037 * 00038 * if (ok) { 00039 printf("Mag T: %f\r\n", data.mag_T); 00040 printf("temp C/F: %f/%f\r\n", data.temp_C, data.temp_C * 9 / 5 + 32); 00041 * } else { 00042 * printf("si7210 error!\r\n"); 00043 * } 00044 * } 00045 * @endcode 00046 * @ingroup drivers 00047 */ 00048 00049 #pragma once 00050 00051 #define ARAUTOINC__ARAUTOINC_MASK 0x01 00052 #define OTP_CTRL__OPT_BUSY_MASK 0x01 00053 #define OTP_CTRL__OPT_READ_EN_MASK 0x02 00054 #define POWER_CTRL__SLEEP_MASK 0x01 00055 #define POWER_CTRL__STOP_MASK 0x02 00056 #define POWER_CTRL__ONEBURST_MASK 0x04 00057 #define POWER_CTRL__USESTORE_MASK 0x08 00058 #define POWER_CTRL__MEAS_MASK 0x80 00059 #define DSPSIGSEL__MAG_VAL_SEL 0 00060 #define DSPSIGSEL__TEMP_VAL_SEL 1 00061 00062 /** I2C registers for Si72xx */ 00063 #define SI72XX_OTP_TEMP_OFFSET 0x1D 00064 #define SI72XX_OTP_TEMP_GAIN 0x1E 00065 #define SI72XX_HREVID 0xC0 00066 #define SI72XX_DSPSIGM 0xC1 00067 #define SI72XX_DSPSIGL 0xC2 00068 #define SI72XX_DSPSIGSEL 0xC3 00069 #define SI72XX_POWER_CTRL 0xC4 00070 #define SI72XX_ARAUTOINC 0xC5 00071 #define SI72XX_CTRL1 0xC6 00072 #define SI72XX_CTRL2 0xC7 00073 #define SI72XX_SLTIME 0xC8 00074 #define SI72XX_CTRL3 0xC9 00075 #define SI72XX_A0 0xCA 00076 #define SI72XX_A1 0xCB 00077 #define SI72XX_A2 0xCC 00078 #define SI72XX_CTRL4 0xCD 00079 #define SI72XX_A3 0xCE 00080 #define SI72XX_A4 0xCF 00081 #define SI72XX_A5 0xD0 00082 #define SI72XX_OTP_ADDR 0xE1 00083 #define SI72XX_OTP_DATA 0xE2 00084 #define SI72XX_OTP_CTRL 0xE3 00085 #define SI72XX_TM_FG 0xE4 00086 00087 #define SI7210_BASE_ADDR_7BIT 0x30 00088 00089 typedef struct { 00090 float mag_T; 00091 float temp_C; 00092 } si7210_measurements_t; 00093 00094 template <class T> 00095 class SI7210 { 00096 public: 00097 /** 00098 * Constructor 00099 * 00100 * @param i2c I2C class servicing the strip 00101 */ 00102 SI7210(T * i2c, uint8_t addr_7bit) : _i2c(i2c) { 00103 _isTempOffsetAndGainValid = false; 00104 _enabled = false; 00105 _addr_8bit = ((addr_7bit & 0x3) + SI7210_BASE_ADDR_7BIT) << 1; 00106 } 00107 00108 /** 00109 * Activate the sensor (wake if sleeping). 00110 * 00111 * @returns true (success) or false (failure) 00112 */ 00113 bool enable(void) { 00114 bool ok = _i2c_transfer(_addr_8bit, NULL, 0, 0); 00115 if (ok) 00116 _enabled = true; 00117 return ok; 00118 } 00119 00120 /** 00121 * Deactivate the sensor (puts it to sleep) 00122 * 00123 * @returns true (success) or false (failure) 00124 */ 00125 bool disable(void) { 00126 bool ok = _write_reg(SI72XX_POWER_CTRL, POWER_CTRL__SLEEP_MASK); 00127 if (ok) 00128 _enabled = ok; 00129 return ok; 00130 } 00131 00132 /** 00133 * Read temperature and humidity 00134 * 00135 * @param data points to struct to store measurements in. Stucture is 00136 * valid only when function returns success indication. 00137 * 00138 * @returns true (success) or false (failure) 00139 */ 00140 bool read(si7210_measurements_t * data) { 00141 uint16_t magRaw; 00142 uint16_t tempRaw; 00143 00144 bool ok = _write_reg(SI72XX_ARAUTOINC, ARAUTOINC__ARAUTOINC_MASK) 00145 && _write_reg(SI72XX_DSPSIGSEL, DSPSIGSEL__MAG_VAL_SEL) //capture mag field measurement 00146 && _write_reg(SI72XX_POWER_CTRL, POWER_CTRL__ONEBURST_MASK) 00147 && _read_regs(SI72XX_DSPSIGM, 2, &magRaw) 00148 && _write_reg(SI72XX_DSPSIGSEL, DSPSIGSEL__TEMP_VAL_SEL) //capture temp measurement 00149 && _write_reg(SI72XX_POWER_CTRL, POWER_CTRL__ONEBURST_MASK) 00150 && _read_regs(SI72XX_DSPSIGM, 2, &tempRaw); 00151 00152 if (ok && !_isTempOffsetAndGainValid) { 00153 signed char otpTempOffset; 00154 signed char otpTempGain; 00155 00156 ok = _read_otp(SI72XX_OTP_TEMP_OFFSET, &otpTempOffset) 00157 && _read_otp(SI72XX_OTP_TEMP_GAIN, &otpTempGain); 00158 if (ok) { 00159 _tempOffset = (float)otpTempOffset / 16; 00160 _tempGain = 1 + (float)otpTempGain / 2048; 00161 _isTempOffsetAndGainValid = true; 00162 } 00163 } 00164 00165 if (ok) { 00166 magRaw = ((magRaw >> 8) & 0xff) + ((magRaw & 0xff) << 8); 00167 tempRaw = ((tempRaw >> 8) & 0xff) + ((tempRaw & 0xff) << 8); 00168 ok = (magRaw & 0x8000) && (tempRaw & 0x8000); 00169 data->mag_T = (float)(magRaw - 0xC000) * 0.00125F; 00170 data->temp_C = (float)((tempRaw & ~0x8000) >> 3); 00171 data->temp_C = _tempGain * (-3.83e-6F * data->temp_C * data->temp_C + 0.16094F * data->temp_C - 279.80F - 0.222F * 3.0F) + _tempOffset; 00172 } 00173 00174 return ok; 00175 } 00176 00177 protected: 00178 00179 /** 00180 * I2C read/write helper function 00181 * 00182 * @param address is the register to read/write 00183 * @param buff holds the data to write and recieves the data to read 00184 * @param writeSize is the number of bytes to write to register 00185 * @param readSize is the number of bytes to retrieve from device 00186 * 00187 * @returns true (success) or false (failure) 00188 */ 00189 bool _i2c_transfer(int address, void * buff, size_t writeSize, size_t readSize) { 00190 bool ok; 00191 bool expect_response = (readSize != 0); 00192 00193 ok = !_i2c->write(address, (char*)buff, writeSize, expect_response); 00194 if (ok && expect_response) 00195 ok = !_i2c->read(address, (char*)buff, readSize); 00196 00197 return ok; 00198 } 00199 00200 /** 00201 * Write to an I2C register 00202 * 00203 * @param reg sensor register to write 00204 * @param val value to write 00205 * 00206 * @returns true (success) or false (failure) 00207 */ 00208 bool _write_reg(char reg, char val) { 00209 char out[2] = {reg, val}; 00210 return 0 == _i2c->write(_addr_8bit, out, 2); 00211 } 00212 00213 /** 00214 * Read multiple sensor registers 00215 * 00216 * @param start_reg first sensor register to be read 00217 * @param count number of registers to be read 00218 * @param buff pointer to buffer where to store the register values 00219 * 00220 * @returns true (success) or false (failure) 00221 */ 00222 bool _read_regs(char start_reg, char count, void * buff) { 00223 bool ok; 00224 ok = (0 == _i2c->write(_addr_8bit, &start_reg, 1, true)) 00225 && (0 == _i2c->read(_addr_8bit, (char *)buff, count)); 00226 return ok; 00227 } 00228 00229 /** 00230 * Read sensor OTP 00231 * 00232 * @param otpAddr OTP address to be read 00233 * @param *data where to store the OTP data 00234 * 00235 * @returns true (success) or false (failure) 00236 */ 00237 bool _read_otp(uint8_t otpAddr, void *data) { 00238 uint8_t optCtrl; 00239 00240 bool ok = _read_regs(SI72XX_OTP_CTRL, 1, &optCtrl) 00241 && !(optCtrl & OTP_CTRL__OPT_BUSY_MASK) 00242 && _write_reg(SI72XX_OTP_ADDR, otpAddr) 00243 && _write_reg(SI72XX_OTP_CTRL, OTP_CTRL__OPT_READ_EN_MASK) 00244 && _read_regs(SI72XX_OTP_DATA, 1, data); 00245 00246 return ok; 00247 } 00248 00249 bool _isTempOffsetAndGainValid; 00250 float _tempOffset; 00251 float _tempGain; 00252 bool _enabled; 00253 int _addr_8bit; 00254 T *_i2c; 00255 }; 00256
Generated on Fri Jul 15 2022 09:05:14 by
1.7.2