Shinichi Takayama
/
MIP8f_ThunderBoard2
JDI_MIP on ThunderBoardSense2(Silicon-Labs)
Embed:
(wiki syntax)
Show/hide line numbers
Si7210.cpp
00001 #include "Si7210.h" 00002 00003 #define OTP_BUSY_MASK 1 00004 #define OTP_READ_EN_MASK 2 00005 #define NUM_HALL_DEVICES 3 00006 #define STOP_MASK 2 00007 #define SLTIMEENA_MASK 1 00008 #define SW_TAMPER_MASK 0xFC 00009 #define SL_FAST_MASK 2 00010 #define SLEEP_MASK 1 00011 #define ONEBURST_MASK 4 00012 00013 namespace silabs { 00014 Si7210::Si7210(PinName sda, PinName scl, uint8_t address) 00015 { 00016 _i2c = new I2C(sda, scl); 00017 _i2c->frequency(400000); 00018 _address = address; 00019 _ownI2C = true; 00020 00021 // Initialize members 00022 _temperatureOffset = 0; 00023 _temperatureGain = 0; 00024 _rawTemperature = 0; 00025 _rawField = 0; 00026 _range = RANGE_20mT; 00027 } 00028 00029 Si7210::Si7210(I2C *i2c_bus, uint8_t address) 00030 { 00031 _i2c = i2c_bus; 00032 _address = address; 00033 _ownI2C = false; 00034 00035 // Initialize members 00036 _temperatureOffset = 0; 00037 _temperatureGain = 0; 00038 _rawTemperature = 0; 00039 _rawField = 0; 00040 _range = RANGE_20mT; 00041 } 00042 00043 Si7210::~Si7210() 00044 { 00045 if (_ownI2C) { 00046 delete _i2c; 00047 } 00048 } 00049 00050 int Si7210::getTemperature() 00051 { 00052 // we operate on 11 fractional bits. 00053 int offset; 00054 int64_t temperature; 00055 00056 if (_temperatureOffset == 0 && 00057 _temperatureGain == 0) { 00058 /* read out compensation values */ 00059 writeRegister(SI72XX_OTP_ADDR, 0x1DU); 00060 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK); 00061 readRegister(SI72XX_OTP_DATA, (uint8_t*)&_temperatureOffset); 00062 00063 writeRegister(SI72XX_OTP_ADDR, 0x1EU); 00064 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK); 00065 readRegister(SI72XX_OTP_DATA, (uint8_t*)&_temperatureGain); 00066 } 00067 00068 temperature = ((int64_t)_rawTemperature * (int64_t)_rawTemperature) * (-21) / 10000; 00069 temperature += ((1522 * _rawTemperature) / 10); 00070 temperature -= 273000; 00071 00072 00073 // offset = val@0x1D / 16 = val@0x1D / 2048 * 128 00074 offset = (int32_t)_temperatureOffset * 1000 / 16; 00075 // gain = 1 + val@0x1E 00076 // temperature = raw * gain + offset 00077 temperature = temperature + (temperature * _temperatureGain / 2048) + offset; 00078 // return temperature 00079 return temperature; 00080 } 00081 00082 /* 00083 * Get last measured field strength 00084 * return: int32_t = field strength in micro-Tesla. 00085 */ 00086 int Si7210::getFieldStrength() 00087 { 00088 switch(_range) { 00089 case RANGE_20mT: 00090 return (_rawField / 4) + _rawField; // rawField * 1.25 00091 case RANGE_200mT: 00092 return (_rawField * 12) + (_rawField / 2); //rawField * 12.5 00093 default: 00094 return 0; 00095 } 00096 } 00097 00098 /* 00099 * Set measurement range. 00100 * Return true if successful, false if device is not responding. 00101 */ 00102 bool Si7210::setFieldStrength(Si7210_range_t range) 00103 { 00104 _range = range; 00105 } 00106 00107 /* 00108 * Perform measurement of magnetic field. 00109 * Return true if new data available 00110 */ 00111 bool Si7210::fetchFieldStrength() 00112 { 00113 uint8_t temp = 0x04; 00114 readRegister(SI72XX_DSPSIGM, &temp); 00115 if(temp & 0x80) { 00116 /* Fresh data available */ 00117 _rawField = 0; 00118 _rawField += (temp & 0x7FU) * 256; 00119 readRegister(SI72XX_DSPSIGL, &temp); 00120 _rawField += temp; 00121 _rawField -= 16384U; 00122 return true; 00123 } 00124 return false; 00125 } 00126 00127 bool Si7210::measureOnce() 00128 { 00129 uint8_t temp; 00130 wakeup(); 00131 readRegister(SI72XX_POWER_CTRL, &temp); 00132 temp = (temp & 0xF0) | 0xA; // Stop control loop 00133 writeRegister(SI72XX_POWER_CTRL, temp); 00134 00135 if (_range == RANGE_200mT) { 00136 writeRegister(SI72XX_OTP_ADDR, 0x27U); 00137 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK); 00138 readRegister(SI72XX_OTP_DATA, &temp); 00139 writeRegister(SI72XX_A0, temp); 00140 writeRegister(SI72XX_OTP_ADDR, 0x28U); 00141 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK); 00142 readRegister(SI72XX_OTP_DATA, &temp); 00143 writeRegister(SI72XX_A1, temp); 00144 writeRegister(SI72XX_OTP_ADDR, 0x29U); 00145 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK); 00146 readRegister(SI72XX_OTP_DATA, &temp); 00147 writeRegister(SI72XX_A2, temp); 00148 writeRegister(SI72XX_OTP_ADDR, 0x2AU); 00149 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK); 00150 readRegister(SI72XX_OTP_DATA, &temp); 00151 writeRegister(SI72XX_A3, temp); 00152 writeRegister(SI72XX_OTP_ADDR, 0x2BU); 00153 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK); 00154 readRegister(SI72XX_OTP_DATA, &temp); 00155 writeRegister(SI72XX_A4, temp); 00156 writeRegister(SI72XX_OTP_ADDR, 0x2CU); 00157 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK); 00158 readRegister(SI72XX_OTP_DATA, &temp); 00159 writeRegister(SI72XX_A5, temp); 00160 } 00161 00162 writeRegister(SI72XX_CTRL4, 0x44); // Use a burst of 4 samples 00163 temp = 0x4; 00164 writeRegister(SI72XX_DSPSIGSEL, temp); // Select field strength data 00165 00166 readRegister(SI72XX_POWER_CTRL, &temp); 00167 temp = (temp & 0xF0) | 0x0C; // Start measurement 00168 writeRegister(SI72XX_POWER_CTRL, temp); 00169 00170 do { 00171 readRegister(SI72XX_POWER_CTRL, &temp); 00172 } while ( (temp & 0x80) != 0 ); 00173 00174 fetchFieldStrength(); 00175 00176 writeRegister(SI72XX_CTRL4, 0x0); // Don't burst 00177 temp = 0x1; 00178 writeRegister(SI72XX_DSPSIGSEL, temp); // Select temperature data 00179 00180 readRegister(SI72XX_POWER_CTRL, &temp); 00181 temp = (temp & 0xF0) | 0x0C; // Start measurement 00182 writeRegister(SI72XX_POWER_CTRL, temp); 00183 00184 readRegister(SI72XX_DSPSIGM, &temp); 00185 _rawTemperature = 0; 00186 _rawTemperature += 32 * (temp & 0x7F); 00187 readRegister(SI72XX_DSPSIGL, &temp); 00188 _rawTemperature += (temp >> 3); 00189 00190 sleep(); 00191 return true; 00192 } 00193 00194 bool Si7210::check() 00195 { 00196 uint8_t temp; 00197 wakeup(); 00198 readRegister(SI72XX_HREVID, &temp); 00199 sleep(); 00200 00201 return true; 00202 } 00203 00204 bool Si7210::wakeup() 00205 { 00206 uint8_t temp; 00207 if(_i2c->read(_address, (char*)&temp, 1) == 0) return true; 00208 return false; 00209 } 00210 00211 bool Si7210::sleep() 00212 { 00213 uint8_t temp; 00214 readRegister(SI72XX_CTRL3, &temp); 00215 temp &= 0xFEU; // Clear sltimena 00216 writeRegister(SI72XX_CTRL3, temp); 00217 readRegister(SI72XX_POWER_CTRL, &temp); 00218 temp = (temp & 0xF8U) | 0x01; // clear STOP and set SLEEP 00219 return writeRegister(SI72XX_POWER_CTRL, temp); 00220 } 00221 00222 bool Si7210::readRegister(uint8_t reg, uint8_t *result) 00223 { 00224 _i2c->write(_address, (const char*)®, 1, true); 00225 return _i2c->read(_address, (char*)result, 1) == 0; 00226 } 00227 00228 bool Si7210::writeRegister(uint8_t reg, uint8_t data) 00229 { 00230 uint8_t buffer[2] = {reg, data}; 00231 return _i2c->write(_address, (const char*)buffer, 2) == 0; 00232 } 00233 00234 } // namespace silabs
Generated on Sat Jul 16 2022 02:12:35 by 1.7.2