JDI_MIP on ThunderBoardSense2(Silicon-Labs)

JDI_MIP (LPM013M126A) Sample on ThunderBoard2(Silicon-Labs)

/media/uploads/STakayama/mip8_tb2_sample0_.jpg LPM013M126A /media/uploads/STakayama/mip8_tb2_sample1.jpg

Links

https://os.mbed.com/teams/JapanDisplayInc/

https://os.mbed.com/teams/JapanDisplayInc/wiki/MIP-reflective-color-display

Committer:
STakayama
Date:
Tue Jan 22 10:23:39 2019 +0000
Revision:
13:9fb661dd4b2a
Parent:
10:525bcf8907fc
BackColor = Cyan

Who changed what in which revision?

UserRevisionLine numberNew contents of line
STakayama 10:525bcf8907fc 1 #include "Si7210.h"
STakayama 10:525bcf8907fc 2
STakayama 10:525bcf8907fc 3 #define OTP_BUSY_MASK 1
STakayama 10:525bcf8907fc 4 #define OTP_READ_EN_MASK 2
STakayama 10:525bcf8907fc 5 #define NUM_HALL_DEVICES 3
STakayama 10:525bcf8907fc 6 #define STOP_MASK 2
STakayama 10:525bcf8907fc 7 #define SLTIMEENA_MASK 1
STakayama 10:525bcf8907fc 8 #define SW_TAMPER_MASK 0xFC
STakayama 10:525bcf8907fc 9 #define SL_FAST_MASK 2
STakayama 10:525bcf8907fc 10 #define SLEEP_MASK 1
STakayama 10:525bcf8907fc 11 #define ONEBURST_MASK 4
STakayama 10:525bcf8907fc 12
STakayama 10:525bcf8907fc 13 namespace silabs {
STakayama 10:525bcf8907fc 14 Si7210::Si7210(PinName sda, PinName scl, uint8_t address)
STakayama 10:525bcf8907fc 15 {
STakayama 10:525bcf8907fc 16 _i2c = new I2C(sda, scl);
STakayama 10:525bcf8907fc 17 _i2c->frequency(400000);
STakayama 10:525bcf8907fc 18 _address = address;
STakayama 10:525bcf8907fc 19 _ownI2C = true;
STakayama 10:525bcf8907fc 20
STakayama 10:525bcf8907fc 21 // Initialize members
STakayama 10:525bcf8907fc 22 _temperatureOffset = 0;
STakayama 10:525bcf8907fc 23 _temperatureGain = 0;
STakayama 10:525bcf8907fc 24 _rawTemperature = 0;
STakayama 10:525bcf8907fc 25 _rawField = 0;
STakayama 10:525bcf8907fc 26 _range = RANGE_20mT;
STakayama 10:525bcf8907fc 27 }
STakayama 10:525bcf8907fc 28
STakayama 10:525bcf8907fc 29 Si7210::Si7210(I2C *i2c_bus, uint8_t address)
STakayama 10:525bcf8907fc 30 {
STakayama 10:525bcf8907fc 31 _i2c = i2c_bus;
STakayama 10:525bcf8907fc 32 _address = address;
STakayama 10:525bcf8907fc 33 _ownI2C = false;
STakayama 10:525bcf8907fc 34
STakayama 10:525bcf8907fc 35 // Initialize members
STakayama 10:525bcf8907fc 36 _temperatureOffset = 0;
STakayama 10:525bcf8907fc 37 _temperatureGain = 0;
STakayama 10:525bcf8907fc 38 _rawTemperature = 0;
STakayama 10:525bcf8907fc 39 _rawField = 0;
STakayama 10:525bcf8907fc 40 _range = RANGE_20mT;
STakayama 10:525bcf8907fc 41 }
STakayama 10:525bcf8907fc 42
STakayama 10:525bcf8907fc 43 Si7210::~Si7210()
STakayama 10:525bcf8907fc 44 {
STakayama 10:525bcf8907fc 45 if (_ownI2C) {
STakayama 10:525bcf8907fc 46 delete _i2c;
STakayama 10:525bcf8907fc 47 }
STakayama 10:525bcf8907fc 48 }
STakayama 10:525bcf8907fc 49
STakayama 10:525bcf8907fc 50 int Si7210::getTemperature()
STakayama 10:525bcf8907fc 51 {
STakayama 10:525bcf8907fc 52 // we operate on 11 fractional bits.
STakayama 10:525bcf8907fc 53 int offset;
STakayama 10:525bcf8907fc 54 int64_t temperature;
STakayama 10:525bcf8907fc 55
STakayama 10:525bcf8907fc 56 if (_temperatureOffset == 0 &&
STakayama 10:525bcf8907fc 57 _temperatureGain == 0) {
STakayama 10:525bcf8907fc 58 /* read out compensation values */
STakayama 10:525bcf8907fc 59 writeRegister(SI72XX_OTP_ADDR, 0x1DU);
STakayama 10:525bcf8907fc 60 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
STakayama 10:525bcf8907fc 61 readRegister(SI72XX_OTP_DATA, (uint8_t*)&_temperatureOffset);
STakayama 10:525bcf8907fc 62
STakayama 10:525bcf8907fc 63 writeRegister(SI72XX_OTP_ADDR, 0x1EU);
STakayama 10:525bcf8907fc 64 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
STakayama 10:525bcf8907fc 65 readRegister(SI72XX_OTP_DATA, (uint8_t*)&_temperatureGain);
STakayama 10:525bcf8907fc 66 }
STakayama 10:525bcf8907fc 67
STakayama 10:525bcf8907fc 68 temperature = ((int64_t)_rawTemperature * (int64_t)_rawTemperature) * (-21) / 10000;
STakayama 10:525bcf8907fc 69 temperature += ((1522 * _rawTemperature) / 10);
STakayama 10:525bcf8907fc 70 temperature -= 273000;
STakayama 10:525bcf8907fc 71
STakayama 10:525bcf8907fc 72
STakayama 10:525bcf8907fc 73 // offset = val@0x1D / 16 = val@0x1D / 2048 * 128
STakayama 10:525bcf8907fc 74 offset = (int32_t)_temperatureOffset * 1000 / 16;
STakayama 10:525bcf8907fc 75 // gain = 1 + val@0x1E
STakayama 10:525bcf8907fc 76 // temperature = raw * gain + offset
STakayama 10:525bcf8907fc 77 temperature = temperature + (temperature * _temperatureGain / 2048) + offset;
STakayama 10:525bcf8907fc 78 // return temperature
STakayama 10:525bcf8907fc 79 return temperature;
STakayama 10:525bcf8907fc 80 }
STakayama 10:525bcf8907fc 81
STakayama 10:525bcf8907fc 82 /*
STakayama 10:525bcf8907fc 83 * Get last measured field strength
STakayama 10:525bcf8907fc 84 * return: int32_t = field strength in micro-Tesla.
STakayama 10:525bcf8907fc 85 */
STakayama 10:525bcf8907fc 86 int Si7210::getFieldStrength()
STakayama 10:525bcf8907fc 87 {
STakayama 10:525bcf8907fc 88 switch(_range) {
STakayama 10:525bcf8907fc 89 case RANGE_20mT:
STakayama 10:525bcf8907fc 90 return (_rawField / 4) + _rawField; // rawField * 1.25
STakayama 10:525bcf8907fc 91 case RANGE_200mT:
STakayama 10:525bcf8907fc 92 return (_rawField * 12) + (_rawField / 2); //rawField * 12.5
STakayama 10:525bcf8907fc 93 default:
STakayama 10:525bcf8907fc 94 return 0;
STakayama 10:525bcf8907fc 95 }
STakayama 10:525bcf8907fc 96 }
STakayama 10:525bcf8907fc 97
STakayama 10:525bcf8907fc 98 /*
STakayama 10:525bcf8907fc 99 * Set measurement range.
STakayama 10:525bcf8907fc 100 * Return true if successful, false if device is not responding.
STakayama 10:525bcf8907fc 101 */
STakayama 10:525bcf8907fc 102 bool Si7210::setFieldStrength(Si7210_range_t range)
STakayama 10:525bcf8907fc 103 {
STakayama 10:525bcf8907fc 104 _range = range;
STakayama 10:525bcf8907fc 105 }
STakayama 10:525bcf8907fc 106
STakayama 10:525bcf8907fc 107 /*
STakayama 10:525bcf8907fc 108 * Perform measurement of magnetic field.
STakayama 10:525bcf8907fc 109 * Return true if new data available
STakayama 10:525bcf8907fc 110 */
STakayama 10:525bcf8907fc 111 bool Si7210::fetchFieldStrength()
STakayama 10:525bcf8907fc 112 {
STakayama 10:525bcf8907fc 113 uint8_t temp = 0x04;
STakayama 10:525bcf8907fc 114 readRegister(SI72XX_DSPSIGM, &temp);
STakayama 10:525bcf8907fc 115 if(temp & 0x80) {
STakayama 10:525bcf8907fc 116 /* Fresh data available */
STakayama 10:525bcf8907fc 117 _rawField = 0;
STakayama 10:525bcf8907fc 118 _rawField += (temp & 0x7FU) * 256;
STakayama 10:525bcf8907fc 119 readRegister(SI72XX_DSPSIGL, &temp);
STakayama 10:525bcf8907fc 120 _rawField += temp;
STakayama 10:525bcf8907fc 121 _rawField -= 16384U;
STakayama 10:525bcf8907fc 122 return true;
STakayama 10:525bcf8907fc 123 }
STakayama 10:525bcf8907fc 124 return false;
STakayama 10:525bcf8907fc 125 }
STakayama 10:525bcf8907fc 126
STakayama 10:525bcf8907fc 127 bool Si7210::measureOnce()
STakayama 10:525bcf8907fc 128 {
STakayama 10:525bcf8907fc 129 uint8_t temp;
STakayama 10:525bcf8907fc 130 wakeup();
STakayama 10:525bcf8907fc 131 readRegister(SI72XX_POWER_CTRL, &temp);
STakayama 10:525bcf8907fc 132 temp = (temp & 0xF0) | 0xA; // Stop control loop
STakayama 10:525bcf8907fc 133 writeRegister(SI72XX_POWER_CTRL, temp);
STakayama 10:525bcf8907fc 134
STakayama 10:525bcf8907fc 135 if (_range == RANGE_200mT) {
STakayama 10:525bcf8907fc 136 writeRegister(SI72XX_OTP_ADDR, 0x27U);
STakayama 10:525bcf8907fc 137 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
STakayama 10:525bcf8907fc 138 readRegister(SI72XX_OTP_DATA, &temp);
STakayama 10:525bcf8907fc 139 writeRegister(SI72XX_A0, temp);
STakayama 10:525bcf8907fc 140 writeRegister(SI72XX_OTP_ADDR, 0x28U);
STakayama 10:525bcf8907fc 141 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
STakayama 10:525bcf8907fc 142 readRegister(SI72XX_OTP_DATA, &temp);
STakayama 10:525bcf8907fc 143 writeRegister(SI72XX_A1, temp);
STakayama 10:525bcf8907fc 144 writeRegister(SI72XX_OTP_ADDR, 0x29U);
STakayama 10:525bcf8907fc 145 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
STakayama 10:525bcf8907fc 146 readRegister(SI72XX_OTP_DATA, &temp);
STakayama 10:525bcf8907fc 147 writeRegister(SI72XX_A2, temp);
STakayama 10:525bcf8907fc 148 writeRegister(SI72XX_OTP_ADDR, 0x2AU);
STakayama 10:525bcf8907fc 149 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
STakayama 10:525bcf8907fc 150 readRegister(SI72XX_OTP_DATA, &temp);
STakayama 10:525bcf8907fc 151 writeRegister(SI72XX_A3, temp);
STakayama 10:525bcf8907fc 152 writeRegister(SI72XX_OTP_ADDR, 0x2BU);
STakayama 10:525bcf8907fc 153 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
STakayama 10:525bcf8907fc 154 readRegister(SI72XX_OTP_DATA, &temp);
STakayama 10:525bcf8907fc 155 writeRegister(SI72XX_A4, temp);
STakayama 10:525bcf8907fc 156 writeRegister(SI72XX_OTP_ADDR, 0x2CU);
STakayama 10:525bcf8907fc 157 writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
STakayama 10:525bcf8907fc 158 readRegister(SI72XX_OTP_DATA, &temp);
STakayama 10:525bcf8907fc 159 writeRegister(SI72XX_A5, temp);
STakayama 10:525bcf8907fc 160 }
STakayama 10:525bcf8907fc 161
STakayama 10:525bcf8907fc 162 writeRegister(SI72XX_CTRL4, 0x44); // Use a burst of 4 samples
STakayama 10:525bcf8907fc 163 temp = 0x4;
STakayama 10:525bcf8907fc 164 writeRegister(SI72XX_DSPSIGSEL, temp); // Select field strength data
STakayama 10:525bcf8907fc 165
STakayama 10:525bcf8907fc 166 readRegister(SI72XX_POWER_CTRL, &temp);
STakayama 10:525bcf8907fc 167 temp = (temp & 0xF0) | 0x0C; // Start measurement
STakayama 10:525bcf8907fc 168 writeRegister(SI72XX_POWER_CTRL, temp);
STakayama 10:525bcf8907fc 169
STakayama 10:525bcf8907fc 170 do {
STakayama 10:525bcf8907fc 171 readRegister(SI72XX_POWER_CTRL, &temp);
STakayama 10:525bcf8907fc 172 } while ( (temp & 0x80) != 0 );
STakayama 10:525bcf8907fc 173
STakayama 10:525bcf8907fc 174 fetchFieldStrength();
STakayama 10:525bcf8907fc 175
STakayama 10:525bcf8907fc 176 writeRegister(SI72XX_CTRL4, 0x0); // Don't burst
STakayama 10:525bcf8907fc 177 temp = 0x1;
STakayama 10:525bcf8907fc 178 writeRegister(SI72XX_DSPSIGSEL, temp); // Select temperature data
STakayama 10:525bcf8907fc 179
STakayama 10:525bcf8907fc 180 readRegister(SI72XX_POWER_CTRL, &temp);
STakayama 10:525bcf8907fc 181 temp = (temp & 0xF0) | 0x0C; // Start measurement
STakayama 10:525bcf8907fc 182 writeRegister(SI72XX_POWER_CTRL, temp);
STakayama 10:525bcf8907fc 183
STakayama 10:525bcf8907fc 184 readRegister(SI72XX_DSPSIGM, &temp);
STakayama 10:525bcf8907fc 185 _rawTemperature = 0;
STakayama 10:525bcf8907fc 186 _rawTemperature += 32 * (temp & 0x7F);
STakayama 10:525bcf8907fc 187 readRegister(SI72XX_DSPSIGL, &temp);
STakayama 10:525bcf8907fc 188 _rawTemperature += (temp >> 3);
STakayama 10:525bcf8907fc 189
STakayama 10:525bcf8907fc 190 sleep();
STakayama 10:525bcf8907fc 191 return true;
STakayama 10:525bcf8907fc 192 }
STakayama 10:525bcf8907fc 193
STakayama 10:525bcf8907fc 194 bool Si7210::check()
STakayama 10:525bcf8907fc 195 {
STakayama 10:525bcf8907fc 196 uint8_t temp;
STakayama 10:525bcf8907fc 197 wakeup();
STakayama 10:525bcf8907fc 198 readRegister(SI72XX_HREVID, &temp);
STakayama 10:525bcf8907fc 199 sleep();
STakayama 10:525bcf8907fc 200
STakayama 10:525bcf8907fc 201 return true;
STakayama 10:525bcf8907fc 202 }
STakayama 10:525bcf8907fc 203
STakayama 10:525bcf8907fc 204 bool Si7210::wakeup()
STakayama 10:525bcf8907fc 205 {
STakayama 10:525bcf8907fc 206 uint8_t temp;
STakayama 10:525bcf8907fc 207 if(_i2c->read(_address, (char*)&temp, 1) == 0) return true;
STakayama 10:525bcf8907fc 208 return false;
STakayama 10:525bcf8907fc 209 }
STakayama 10:525bcf8907fc 210
STakayama 10:525bcf8907fc 211 bool Si7210::sleep()
STakayama 10:525bcf8907fc 212 {
STakayama 10:525bcf8907fc 213 uint8_t temp;
STakayama 10:525bcf8907fc 214 readRegister(SI72XX_CTRL3, &temp);
STakayama 10:525bcf8907fc 215 temp &= 0xFEU; // Clear sltimena
STakayama 10:525bcf8907fc 216 writeRegister(SI72XX_CTRL3, temp);
STakayama 10:525bcf8907fc 217 readRegister(SI72XX_POWER_CTRL, &temp);
STakayama 10:525bcf8907fc 218 temp = (temp & 0xF8U) | 0x01; // clear STOP and set SLEEP
STakayama 10:525bcf8907fc 219 return writeRegister(SI72XX_POWER_CTRL, temp);
STakayama 10:525bcf8907fc 220 }
STakayama 10:525bcf8907fc 221
STakayama 10:525bcf8907fc 222 bool Si7210::readRegister(uint8_t reg, uint8_t *result)
STakayama 10:525bcf8907fc 223 {
STakayama 10:525bcf8907fc 224 _i2c->write(_address, (const char*)&reg, 1, true);
STakayama 10:525bcf8907fc 225 return _i2c->read(_address, (char*)result, 1) == 0;
STakayama 10:525bcf8907fc 226 }
STakayama 10:525bcf8907fc 227
STakayama 10:525bcf8907fc 228 bool Si7210::writeRegister(uint8_t reg, uint8_t data)
STakayama 10:525bcf8907fc 229 {
STakayama 10:525bcf8907fc 230 uint8_t buffer[2] = {reg, data};
STakayama 10:525bcf8907fc 231 return _i2c->write(_address, (const char*)buffer, 2) == 0;
STakayama 10:525bcf8907fc 232 }
STakayama 10:525bcf8907fc 233
STakayama 10:525bcf8907fc 234 } // namespace silabs