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

Revision:
10:525bcf8907fc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Si7210/Si7210.cpp	Wed Jan 09 07:39:41 2019 +0000
@@ -0,0 +1,234 @@
+#include "Si7210.h"
+
+#define OTP_BUSY_MASK         1
+#define OTP_READ_EN_MASK      2
+#define NUM_HALL_DEVICES      3
+#define STOP_MASK             2
+#define SLTIMEENA_MASK        1
+#define SW_TAMPER_MASK        0xFC
+#define SL_FAST_MASK          2
+#define SLEEP_MASK            1
+#define ONEBURST_MASK         4
+
+namespace silabs {
+Si7210::Si7210(PinName sda, PinName scl, uint8_t address)
+{
+    _i2c = new I2C(sda, scl);
+    _i2c->frequency(400000);
+    _address = address;
+    _ownI2C = true;
+    
+    // Initialize members
+    _temperatureOffset = 0;
+    _temperatureGain = 0;
+    _rawTemperature = 0;
+    _rawField = 0;
+    _range = RANGE_20mT;
+}
+
+Si7210::Si7210(I2C *i2c_bus, uint8_t address)
+{
+    _i2c = i2c_bus;
+    _address = address;
+    _ownI2C = false;
+    
+    // Initialize members
+    _temperatureOffset = 0;
+    _temperatureGain = 0;
+    _rawTemperature = 0;
+    _rawField = 0;
+    _range = RANGE_20mT;
+}
+
+Si7210::~Si7210()
+{
+    if (_ownI2C) {
+        delete _i2c;
+    }
+}
+
+int Si7210::getTemperature()
+{
+    // we operate on 11 fractional bits.
+    int offset;
+    int64_t temperature;
+    
+    if (_temperatureOffset == 0 &&
+        _temperatureGain == 0) {
+        /* read out compensation values */
+        writeRegister(SI72XX_OTP_ADDR, 0x1DU);
+        writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
+        readRegister(SI72XX_OTP_DATA, (uint8_t*)&_temperatureOffset);
+        
+        writeRegister(SI72XX_OTP_ADDR, 0x1EU);
+        writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
+        readRegister(SI72XX_OTP_DATA, (uint8_t*)&_temperatureGain);
+    }
+    
+    temperature = ((int64_t)_rawTemperature * (int64_t)_rawTemperature) * (-21) / 10000;
+    temperature += ((1522 * _rawTemperature) / 10);
+    temperature -= 273000;
+    
+    
+    // offset = val@0x1D / 16 = val@0x1D / 2048 * 128
+    offset = (int32_t)_temperatureOffset * 1000 / 16;
+    // gain = 1 + val@0x1E
+    // temperature = raw * gain + offset
+    temperature = temperature + (temperature * _temperatureGain / 2048) + offset;
+    // return temperature
+    return temperature;
+}
+
+/*
+ * Get last measured field strength
+ * return: int32_t = field strength in micro-Tesla.
+ */
+int Si7210::getFieldStrength()
+{   
+    switch(_range) {
+        case RANGE_20mT:
+            return (_rawField / 4) + _rawField; // rawField * 1.25
+        case RANGE_200mT:
+            return (_rawField * 12) + (_rawField / 2); //rawField * 12.5
+        default:
+            return 0;
+    }
+}
+
+/*
+ * Set measurement range.
+ * Return true if successful, false if device is not responding.
+ */
+bool Si7210::setFieldStrength(Si7210_range_t range)
+{
+    _range = range;
+}
+
+/*
+ * Perform measurement of magnetic field.
+ * Return true if new data available
+ */
+bool Si7210::fetchFieldStrength()
+{
+    uint8_t temp = 0x04;
+    readRegister(SI72XX_DSPSIGM, &temp);
+    if(temp & 0x80) {
+        /* Fresh data available */
+        _rawField = 0;
+        _rawField += (temp & 0x7FU) * 256;
+        readRegister(SI72XX_DSPSIGL, &temp);
+        _rawField += temp;
+        _rawField -= 16384U;
+        return true;
+    }
+    return false;
+}
+
+bool Si7210::measureOnce()
+{
+    uint8_t temp;
+    wakeup();
+    readRegister(SI72XX_POWER_CTRL, &temp);
+    temp = (temp & 0xF0) | 0xA; // Stop control loop
+    writeRegister(SI72XX_POWER_CTRL, temp);
+    
+    if (_range == RANGE_200mT) {
+        writeRegister(SI72XX_OTP_ADDR, 0x27U);
+        writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
+        readRegister(SI72XX_OTP_DATA, &temp);
+        writeRegister(SI72XX_A0, temp);
+        writeRegister(SI72XX_OTP_ADDR, 0x28U);
+        writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
+        readRegister(SI72XX_OTP_DATA, &temp);
+        writeRegister(SI72XX_A1, temp);
+        writeRegister(SI72XX_OTP_ADDR, 0x29U);
+        writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
+        readRegister(SI72XX_OTP_DATA, &temp);
+        writeRegister(SI72XX_A2, temp);
+        writeRegister(SI72XX_OTP_ADDR, 0x2AU);
+        writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
+        readRegister(SI72XX_OTP_DATA, &temp);
+        writeRegister(SI72XX_A3, temp);
+        writeRegister(SI72XX_OTP_ADDR, 0x2BU);
+        writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
+        readRegister(SI72XX_OTP_DATA, &temp);
+        writeRegister(SI72XX_A4, temp);
+        writeRegister(SI72XX_OTP_ADDR, 0x2CU);
+        writeRegister(SI72XX_OTP_CTRL, OTP_READ_EN_MASK);
+        readRegister(SI72XX_OTP_DATA, &temp);
+        writeRegister(SI72XX_A5, temp);
+    }
+    
+    writeRegister(SI72XX_CTRL4, 0x44); // Use a burst of 4 samples
+    temp = 0x4;
+    writeRegister(SI72XX_DSPSIGSEL, temp); // Select field strength data
+    
+    readRegister(SI72XX_POWER_CTRL, &temp);
+    temp = (temp & 0xF0) | 0x0C; // Start measurement
+    writeRegister(SI72XX_POWER_CTRL, temp);
+    
+    do {
+        readRegister(SI72XX_POWER_CTRL, &temp);
+    } while ( (temp & 0x80) != 0 );
+    
+    fetchFieldStrength();
+    
+    writeRegister(SI72XX_CTRL4, 0x0); // Don't burst
+    temp = 0x1;
+    writeRegister(SI72XX_DSPSIGSEL, temp); // Select temperature data
+    
+    readRegister(SI72XX_POWER_CTRL, &temp);
+    temp = (temp & 0xF0) | 0x0C; // Start measurement
+    writeRegister(SI72XX_POWER_CTRL, temp);
+    
+    readRegister(SI72XX_DSPSIGM, &temp);
+    _rawTemperature = 0;
+    _rawTemperature += 32 * (temp & 0x7F);
+    readRegister(SI72XX_DSPSIGL, &temp);
+    _rawTemperature += (temp >> 3);
+    
+    sleep();
+    return true;
+}
+
+bool Si7210::check()
+{
+    uint8_t temp;
+    wakeup();
+    readRegister(SI72XX_HREVID, &temp);
+    sleep();
+    
+    return true;
+}
+
+bool Si7210::wakeup()
+{
+    uint8_t temp;
+    if(_i2c->read(_address, (char*)&temp, 1) == 0) return true;
+    return false;
+}
+
+bool Si7210::sleep()
+{
+    uint8_t temp;
+    readRegister(SI72XX_CTRL3, &temp);
+    temp &= 0xFEU; // Clear sltimena
+    writeRegister(SI72XX_CTRL3, temp);
+    readRegister(SI72XX_POWER_CTRL, &temp);
+    temp = (temp & 0xF8U) | 0x01; // clear STOP and set SLEEP
+    return writeRegister(SI72XX_POWER_CTRL, temp);
+}
+
+bool Si7210::readRegister(uint8_t reg, uint8_t *result)
+{
+    _i2c->write(_address, (const char*)&reg, 1, true);
+    return _i2c->read(_address, (char*)result, 1) == 0;
+}
+
+bool Si7210::writeRegister(uint8_t reg, uint8_t data)
+{
+    uint8_t buffer[2] = {reg, data};
+    return _i2c->write(_address, (const char*)buffer, 2) == 0;
+}
+
+} // namespace silabs
\ No newline at end of file