Silicon Labs Si7210 device driver: I2C Hall Effect Magnetic Position and Temperature Sensor
Revision 2:d85076c18c80, committed 2017-09-14
- Comitter:
- ninensei
- Date:
- Thu Sep 14 00:09:07 2017 +0000
- Parent:
- 1:8cb452601311
- Child:
- 3:beca2e65b1b0
- Commit message:
- Changed filename to match class name.
Changed in this revision
| SI7210.h | Show annotated file Show diff for this revision Revisions of this file |
| si7210.h | Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SI7210.h Thu Sep 14 00:09:07 2017 +0000
@@ -0,0 +1,256 @@
+/* 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 SI7210: Magnetic field and temperature sensor
+ *
+ * Example:
+ * @code
+ *
+ * #include "mbed.h"
+ * #include "SI7210.h"
+ *
+ * I2C i2c(I2C_SDA, I2C_SCL);
+ * SI7210<I2C> si7210(&i2c, SI7210_BASE_ADDR_7BIT);
+ *
+ * int main() {
+ * si7210_measurements_t data;
+ * bool ok;
+ *
+ * ok = si7210.enable() &&
+ * si7210.read(&data) &&
+ * si7210.disable();
+ *
+ * if (ok) {
+ printf("Mag T: %f\r\n", data.mag_T);
+ printf("temp C/F: %f/%f\r\n", data.temp_C, data.temp_C * 9 / 5 + 32);
+ * } else {
+ * printf("si7210 error!\r\n");
+ * }
+ * }
+ * @endcode
+ * @ingroup drivers
+ */
+
+#pragma once
+
+#define ARAUTOINC__ARAUTOINC_MASK 0x01
+#define OTP_CTRL__OPT_BUSY_MASK 0x01
+#define OTP_CTRL__OPT_READ_EN_MASK 0x02
+#define POWER_CTRL__SLEEP_MASK 0x01
+#define POWER_CTRL__STOP_MASK 0x02
+#define POWER_CTRL__ONEBURST_MASK 0x04
+#define POWER_CTRL__USESTORE_MASK 0x08
+#define POWER_CTRL__MEAS_MASK 0x80
+#define DSPSIGSEL__MAG_VAL_SEL 0
+#define DSPSIGSEL__TEMP_VAL_SEL 1
+
+/** I2C registers for Si72xx */
+#define SI72XX_OTP_TEMP_OFFSET 0x1D
+#define SI72XX_OTP_TEMP_GAIN 0x1E
+#define SI72XX_HREVID 0xC0
+#define SI72XX_DSPSIGM 0xC1
+#define SI72XX_DSPSIGL 0xC2
+#define SI72XX_DSPSIGSEL 0xC3
+#define SI72XX_POWER_CTRL 0xC4
+#define SI72XX_ARAUTOINC 0xC5
+#define SI72XX_CTRL1 0xC6
+#define SI72XX_CTRL2 0xC7
+#define SI72XX_SLTIME 0xC8
+#define SI72XX_CTRL3 0xC9
+#define SI72XX_A0 0xCA
+#define SI72XX_A1 0xCB
+#define SI72XX_A2 0xCC
+#define SI72XX_CTRL4 0xCD
+#define SI72XX_A3 0xCE
+#define SI72XX_A4 0xCF
+#define SI72XX_A5 0xD0
+#define SI72XX_OTP_ADDR 0xE1
+#define SI72XX_OTP_DATA 0xE2
+#define SI72XX_OTP_CTRL 0xE3
+#define SI72XX_TM_FG 0xE4
+
+#define SI7210_BASE_ADDR_7BIT 0x30
+
+typedef struct {
+ float mag_T;
+ float temp_C;
+} si7210_measurements_t;
+
+template <class T>
+class SI7210 {
+ public:
+ /**
+ * Constructor
+ *
+ * @param i2c I2C class servicing the strip
+ */
+ SI7210(T * i2c, uint8_t addr_7bit) : _i2c(i2c) {
+ _isTempOffsetAndGainValid = false;
+ _enabled = false;
+ _addr_8bit = ((addr_7bit & 0x3) + SI7210_BASE_ADDR_7BIT) << 1;
+ }
+
+ /**
+ * Activate the sensor (wake if sleeping).
+ *
+ * @returns true (success) or false (failure)
+ */
+ bool enable(void) {
+ bool ok = _i2c_transfer(_addr_8bit, NULL, 0, 0);
+ if (ok)
+ _enabled = true;
+ return ok;
+ }
+
+ /**
+ * Deactivate the sensor (puts it to sleep)
+ *
+ * @returns true (success) or false (failure)
+ */
+ bool disable(void) {
+ bool ok = _write_reg(SI72XX_POWER_CTRL, POWER_CTRL__SLEEP_MASK);
+ if (ok)
+ _enabled = ok;
+ return ok;
+ }
+
+ /**
+ * 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(si7210_measurements_t * data) {
+ uint16_t magRaw;
+ uint16_t tempRaw;
+
+ bool ok = _write_reg(SI72XX_ARAUTOINC, ARAUTOINC__ARAUTOINC_MASK)
+ && _write_reg(SI72XX_DSPSIGSEL, DSPSIGSEL__MAG_VAL_SEL) //capture mag field measurement
+ && _write_reg(SI72XX_POWER_CTRL, POWER_CTRL__ONEBURST_MASK)
+ && _read_regs(SI72XX_DSPSIGM, 2, &magRaw)
+ && _write_reg(SI72XX_DSPSIGSEL, DSPSIGSEL__TEMP_VAL_SEL) //capture temp measurement
+ && _write_reg(SI72XX_POWER_CTRL, POWER_CTRL__ONEBURST_MASK)
+ && _read_regs(SI72XX_DSPSIGM, 2, &tempRaw);
+
+ if (ok && !_isTempOffsetAndGainValid) {
+ char otpTempOffset;
+ char otpTempGain;
+
+ ok = _read_otp(SI72XX_OTP_TEMP_OFFSET, &otpTempOffset)
+ && _read_otp(SI72XX_OTP_TEMP_GAIN, &otpTempGain);
+ if (ok) {
+ _tempOffset = (float)otpTempOffset / 16;
+ _tempGain = 1 + (float)otpTempGain / 2048;
+ _isTempOffsetAndGainValid = true;
+ }
+ }
+
+ if (ok) {
+ magRaw = ((magRaw >> 8) & 0xff) + ((magRaw & 0xff) << 8);
+ tempRaw = ((tempRaw >> 8) & 0xff) + ((tempRaw & 0xff) << 8);
+ ok = (magRaw & 0x8000) && (tempRaw & 0x8000);
+ data->mag_T = (float)(magRaw - 0xC000) * 0.00125F;
+ data->temp_C = (float)((tempRaw & ~0x8000) >> 3);
+ 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;
+ }
+
+ 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;
+ }
+
+ /**
+ * Write to an I2C register
+ *
+ * @param reg sensor register to write
+ * @param val value to write
+ *
+ * @returns true (success) or false (failure)
+ */
+ bool _write_reg(char reg, char val) {
+ char out[2] = {reg, val};
+ return 0 == _i2c->write(_addr_8bit, out, 2);
+ }
+
+ /**
+ * Read multiple sensor registers
+ *
+ * @param start_reg first sensor register to be read
+ * @param count number of registers to be read
+ * @param buff pointer to buffer where to store the register values
+ *
+ * @returns true (success) or false (failure)
+ */
+ bool _read_regs(char start_reg, char count, void * buff) {
+ bool ok;
+ ok = (0 == _i2c->write(_addr_8bit, &start_reg, 1, true))
+ && (0 == _i2c->read(_addr_8bit, (char *)buff, count));
+ return ok;
+ }
+
+ /**
+ * Read sensor OTP
+ *
+ * @param otpAddr OTP address to be read
+ * @param *data where to store the OTP data
+ *
+ * @returns true (success) or false (failure)
+ */
+ bool _read_otp(uint8_t otpAddr, void *data) {
+ uint8_t optCtrl;
+
+ bool ok = _read_regs(SI72XX_OTP_CTRL, 1, &optCtrl)
+ && !(optCtrl & OTP_CTRL__OPT_BUSY_MASK)
+ && _write_reg(SI72XX_OTP_ADDR, otpAddr)
+ && _write_reg(SI72XX_OTP_CTRL, OTP_CTRL__OPT_READ_EN_MASK)
+ && _read_regs(SI72XX_OTP_DATA, 1, data);
+
+ return ok;
+ }
+
+ bool _isTempOffsetAndGainValid;
+ float _tempOffset;
+ float _tempGain;
+ bool _enabled;
+ int _addr_8bit;
+ T *_i2c;
+};
+
--- a/si7210.h Thu Sep 14 00:07:17 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,256 +0,0 @@
-/* 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 SI7210: Magnetic field and temperature sensor
- *
- * Example:
- * @code
- *
- * #include "mbed.h"
- * #include "SI7210.h"
- *
- * I2C i2c(I2C_SDA, I2C_SCL);
- * SI7210<I2C> si7210(&i2c, SI7210_BASE_ADDR_7BIT);
- *
- * int main() {
- * si7210_measurements_t data;
- * bool ok;
- *
- * ok = si7210.enable() &&
- * si7210.read(&data) &&
- * si7210.disable();
- *
- * if (ok) {
- printf("Mag T: %f\r\n", data.mag_T);
- printf("temp C/F: %f/%f\r\n", data.temp_C, data.temp_C * 9 / 5 + 32);
- * } else {
- * printf("si7210 error!\r\n");
- * }
- * }
- * @endcode
- * @ingroup drivers
- */
-
-#pragma once
-
-#define ARAUTOINC__ARAUTOINC_MASK 0x01
-#define OTP_CTRL__OPT_BUSY_MASK 0x01
-#define OTP_CTRL__OPT_READ_EN_MASK 0x02
-#define POWER_CTRL__SLEEP_MASK 0x01
-#define POWER_CTRL__STOP_MASK 0x02
-#define POWER_CTRL__ONEBURST_MASK 0x04
-#define POWER_CTRL__USESTORE_MASK 0x08
-#define POWER_CTRL__MEAS_MASK 0x80
-#define DSPSIGSEL__MAG_VAL_SEL 0
-#define DSPSIGSEL__TEMP_VAL_SEL 1
-
-/** I2C registers for Si72xx */
-#define SI72XX_OTP_TEMP_OFFSET 0x1D
-#define SI72XX_OTP_TEMP_GAIN 0x1E
-#define SI72XX_HREVID 0xC0
-#define SI72XX_DSPSIGM 0xC1
-#define SI72XX_DSPSIGL 0xC2
-#define SI72XX_DSPSIGSEL 0xC3
-#define SI72XX_POWER_CTRL 0xC4
-#define SI72XX_ARAUTOINC 0xC5
-#define SI72XX_CTRL1 0xC6
-#define SI72XX_CTRL2 0xC7
-#define SI72XX_SLTIME 0xC8
-#define SI72XX_CTRL3 0xC9
-#define SI72XX_A0 0xCA
-#define SI72XX_A1 0xCB
-#define SI72XX_A2 0xCC
-#define SI72XX_CTRL4 0xCD
-#define SI72XX_A3 0xCE
-#define SI72XX_A4 0xCF
-#define SI72XX_A5 0xD0
-#define SI72XX_OTP_ADDR 0xE1
-#define SI72XX_OTP_DATA 0xE2
-#define SI72XX_OTP_CTRL 0xE3
-#define SI72XX_TM_FG 0xE4
-
-#define SI7210_BASE_ADDR_7BIT 0x30
-
-typedef struct {
- float mag_T;
- float temp_C;
-} si7210_measurements_t;
-
-template <class T>
-class SI7210 {
- public:
- /**
- * Constructor
- *
- * @param i2c I2C class servicing the strip
- */
- SI7210(T * i2c, uint8_t addr_7bit) : _i2c(i2c) {
- _isTempOffsetAndGainValid = false;
- _enabled = false;
- _addr_8bit = ((addr_7bit & 0x3) + SI7210_BASE_ADDR_7BIT) << 1;
- }
-
- /**
- * Activate the sensor (wake if sleeping).
- *
- * @returns true (success) or false (failure)
- */
- bool enable(void) {
- bool ok = _i2c_transfer(_addr_8bit, NULL, 0, 0);
- if (ok)
- _enabled = true;
- return ok;
- }
-
- /**
- * Deactivate the sensor (puts it to sleep)
- *
- * @returns true (success) or false (failure)
- */
- bool disable(void) {
- bool ok = _write_reg(SI72XX_POWER_CTRL, POWER_CTRL__SLEEP_MASK);
- if (ok)
- _enabled = ok;
- return ok;
- }
-
- /**
- * 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(si7210_measurements_t * data) {
- uint16_t magRaw;
- uint16_t tempRaw;
-
- bool ok = _write_reg(SI72XX_ARAUTOINC, ARAUTOINC__ARAUTOINC_MASK)
- && _write_reg(SI72XX_DSPSIGSEL, DSPSIGSEL__MAG_VAL_SEL) //capture mag field measurement
- && _write_reg(SI72XX_POWER_CTRL, POWER_CTRL__ONEBURST_MASK)
- && _read_regs(SI72XX_DSPSIGM, 2, &magRaw)
- && _write_reg(SI72XX_DSPSIGSEL, DSPSIGSEL__TEMP_VAL_SEL) //capture temp measurement
- && _write_reg(SI72XX_POWER_CTRL, POWER_CTRL__ONEBURST_MASK)
- && _read_regs(SI72XX_DSPSIGM, 2, &tempRaw);
-
- if (ok && !_isTempOffsetAndGainValid) {
- char otpTempOffset;
- char otpTempGain;
-
- ok = _read_otp(SI72XX_OTP_TEMP_OFFSET, &otpTempOffset)
- && _read_otp(SI72XX_OTP_TEMP_GAIN, &otpTempGain);
- if (ok) {
- _tempOffset = (float)otpTempOffset / 16;
- _tempGain = 1 + (float)otpTempGain / 2048;
- _isTempOffsetAndGainValid = true;
- }
- }
-
- if (ok) {
- magRaw = ((magRaw >> 8) & 0xff) + ((magRaw & 0xff) << 8);
- tempRaw = ((tempRaw >> 8) & 0xff) + ((tempRaw & 0xff) << 8);
- ok = (magRaw & 0x8000) && (tempRaw & 0x8000);
- data->mag_T = (float)(magRaw - 0xC000) * 0.00125F;
- data->temp_C = (float)((tempRaw & ~0x8000) >> 3);
- 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;
- }
-
- 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;
- }
-
- /**
- * Write to an I2C register
- *
- * @param reg sensor register to write
- * @param val value to write
- *
- * @returns true (success) or false (failure)
- */
- bool _write_reg(char reg, char val) {
- char out[2] = {reg, val};
- return 0 == _i2c->write(_addr_8bit, out, 2);
- }
-
- /**
- * Read multiple sensor registers
- *
- * @param start_reg first sensor register to be read
- * @param count number of registers to be read
- * @param buff pointer to buffer where to store the register values
- *
- * @returns true (success) or false (failure)
- */
- bool _read_regs(char start_reg, char count, void * buff) {
- bool ok;
- ok = (0 == _i2c->write(_addr_8bit, &start_reg, 1, true))
- && (0 == _i2c->read(_addr_8bit, (char *)buff, count));
- return ok;
- }
-
- /**
- * Read sensor OTP
- *
- * @param otpAddr OTP address to be read
- * @param *data where to store the OTP data
- *
- * @returns true (success) or false (failure)
- */
- bool _read_otp(uint8_t otpAddr, void *data) {
- uint8_t optCtrl;
-
- bool ok = _read_regs(SI72XX_OTP_CTRL, 1, &optCtrl)
- && !(optCtrl & OTP_CTRL__OPT_BUSY_MASK)
- && _write_reg(SI72XX_OTP_ADDR, otpAddr)
- && _write_reg(SI72XX_OTP_CTRL, OTP_CTRL__OPT_READ_EN_MASK)
- && _read_regs(SI72XX_OTP_DATA, 1, data);
-
- return ok;
- }
-
- bool _isTempOffsetAndGainValid;
- float _tempOffset;
- float _tempGain;
- bool _enabled;
- int _addr_8bit;
- T *_i2c;
-};
-