JDI_MIP on ThunderBoardSense2(Silicon-Labs)
JDI_MIP (LPM013M126A) Sample on ThunderBoard2(Silicon-Labs)
LPM013M126A
Links
https://os.mbed.com/teams/JapanDisplayInc/
https://os.mbed.com/teams/JapanDisplayInc/wiki/MIP-reflective-color-display
Si7210/Si7210.cpp@13:9fb661dd4b2a, 2019-01-22 (annotated)
- 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?
User | Revision | Line number | New 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*)®, 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 |