library for IMU demo with mag calibration code

Dependencies:   PinDetect mbed

Dependents:   LSM9DS1_Demo_wCal 4180_Lab2_Mike_SD_IMU_I2C_RS232 ECE4180Lab2_bubble Lab2_EverythingIO ... more

Fork of LSM9DS1_Library by Jason Mar

Files at this revision

API Documentation at this revision

Comitter:
4180_1
Date:
Wed Feb 03 18:45:40 2016 +0000
Parent:
1:87d535bf8c53
Commit message:
ver 0.0

Changed in this revision

LSM9DS1.cpp Show annotated file Show diff for this revision Revisions of this file
LSM9DS1.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show diff for this revision Revisions of this file
diff -r 87d535bf8c53 -r 36abf8e18ade LSM9DS1.cpp
--- a/LSM9DS1.cpp	Mon Oct 26 16:14:04 2015 +0000
+++ b/LSM9DS1.cpp	Wed Feb 03 18:45:40 2016 +0000
@@ -99,7 +99,7 @@
     // 2 = 50 Hz    5 = 476 Hz
     // 3 = 119 Hz   6 = 952 Hz
     settings.accel.sampleRate = 6;
-    // Accel cutoff freqeuncy can be any value between -1 - 3. 
+    // Accel cutoff freqeuncy can be any value between -1 - 3.
     // -1 = bandwidth determined by sample rate
     // 0 = 408 Hz   2 = 105 Hz
     // 1 = 211 Hz   3 = 50 Hz
@@ -134,8 +134,7 @@
     settings.mag.operatingMode = 0;
 
     settings.temp.enabled = true;
-    for (int i=0; i<3; i++)
-    {
+    for (int i=0; i<3; i++) {
         gBias[i] = 0;
         aBias[i] = 0;
         mBias[i] = 0;
@@ -152,36 +151,36 @@
     //! Todo: don't use _xgAddress or _mAddress, duplicating memory
     _xgAddress = settings.device.agAddress;
     _mAddress = settings.device.mAddress;
-    
+
     constrainScales();
     // Once we have the scale values, we can calculate the resolution
     // of each sensor. That's what these functions are for. One for each sensor
     calcgRes(); // Calculate DPS / ADC tick, stored in gRes variable
     calcmRes(); // Calculate Gs / ADC tick, stored in mRes variable
     calcaRes(); // Calculate g / ADC tick, stored in aRes variable
-    
+
     // Now, initialize our hardware interface.
     if (settings.device.commInterface == IMU_MODE_I2C)  // If we're using I2C
         initI2C();  // Initialize I2C
     else if (settings.device.commInterface == IMU_MODE_SPI)     // else, if we're using SPI
         initSPI();  // Initialize SPI
-        
+
     // To verify communication, we can read from the WHO_AM_I register of
     // each device. Store those in a variable so we can return them.
     uint8_t mTest = mReadByte(WHO_AM_I_M);      // Read the gyro WHO_AM_I
     uint8_t xgTest = xgReadByte(WHO_AM_I_XG);   // Read the accel/mag WHO_AM_I
     pc.printf("%x, %x, %x, %x\n\r", mTest, xgTest, _xgAddress, _mAddress);
     uint16_t whoAmICombined = (xgTest << 8) | mTest;
-    
+
     if (whoAmICombined != ((WHO_AM_I_AG_RSP << 8) | WHO_AM_I_M_RSP))
         return 0;
-    
+
     // Gyro initialization stuff:
     initGyro(); // This will "turn on" the gyro. Setting up interrupts, etc.
-    
+
     // Accelerometer initialization stuff:
     initAccel(); // "Turn on" all axes of the accel. Set up interrupts, etc.
-    
+
     // Magnetometer initialization stuff:
     initMag(); // "Turn on" all axes of the mag. Set up interrupts, etc.
 
@@ -192,50 +191,47 @@
 void LSM9DS1::initGyro()
 {
     uint8_t tempRegValue = 0;
-    
+
     // CTRL_REG1_G (Default value: 0x00)
     // [ODR_G2][ODR_G1][ODR_G0][FS_G1][FS_G0][0][BW_G1][BW_G0]
     // ODR_G[2:0] - Output data rate selection
     // FS_G[1:0] - Gyroscope full-scale selection
     // BW_G[1:0] - Gyroscope bandwidth selection
-    
+
     // To disable gyro, set sample rate bits to 0. We'll only set sample
     // rate if the gyro is enabled.
-    if (settings.gyro.enabled)
-    {
+    if (settings.gyro.enabled) {
         tempRegValue = (settings.gyro.sampleRate & 0x07) << 5;
     }
-    switch (settings.gyro.scale)
-    {
+    switch (settings.gyro.scale) {
         case 500:
             tempRegValue |= (0x1 << 3);
             break;
         case 2000:
             tempRegValue |= (0x3 << 3);
             break;
-        // Otherwise we'll set it to 245 dps (0x0 << 4)
+            // Otherwise we'll set it to 245 dps (0x0 << 4)
     }
     tempRegValue |= (settings.gyro.bandwidth & 0x3);
     xgWriteByte(CTRL_REG1_G, tempRegValue);
-    
+
     // CTRL_REG2_G (Default value: 0x00)
     // [0][0][0][0][INT_SEL1][INT_SEL0][OUT_SEL1][OUT_SEL0]
     // INT_SEL[1:0] - INT selection configuration
     // OUT_SEL[1:0] - Out selection configuration
-    xgWriteByte(CTRL_REG2_G, 0x00); 
-    
+    xgWriteByte(CTRL_REG2_G, 0x00);
+
     // CTRL_REG3_G (Default value: 0x00)
     // [LP_mode][HP_EN][0][0][HPCF3_G][HPCF2_G][HPCF1_G][HPCF0_G]
     // LP_mode - Low-power mode enable (0: disabled, 1: enabled)
     // HP_EN - HPF enable (0:disabled, 1: enabled)
     // HPCF_G[3:0] - HPF cutoff frequency
     tempRegValue = settings.gyro.lowPowerEnable ? (1<<7) : 0;
-    if (settings.gyro.HPFEnable)
-    {
+    if (settings.gyro.HPFEnable) {
         tempRegValue |= (1<<6) | (settings.gyro.HPFCutoff & 0x0F);
     }
     xgWriteByte(CTRL_REG3_G, tempRegValue);
-    
+
     // CTRL_REG4 (Default value: 0x38)
     // [0][0][Zen_G][Yen_G][Xen_G][0][LIR_XL1][4D_XL1]
     // Zen_G - Z-axis output enable (0:disable, 1:enable)
@@ -249,7 +245,7 @@
     if (settings.gyro.enableX) tempRegValue |= (1<<3);
     if (settings.gyro.latchInterrupt) tempRegValue |= (1<<1);
     xgWriteByte(CTRL_REG4, tempRegValue);
-    
+
     // ORIENT_CFG_G (Default value: 0x00)
     // [0][0][SignX_G][SignY_G][SignZ_G][Orient_2][Orient_1][Orient_0]
     // SignX_G - Pitch axis (X) angular rate sign (0: positive, 1: negative)
@@ -264,7 +260,7 @@
 void LSM9DS1::initAccel()
 {
     uint8_t tempRegValue = 0;
-    
+
     //  CTRL_REG5_XL (0x1F) (Default value: 0x38)
     //  [DEC_1][DEC_0][Zen_XL][Yen_XL][Zen_XL][0][0][0]
     //  DEC[0:1] - Decimation of accel data on OUT REG and FIFO.
@@ -275,9 +271,9 @@
     if (settings.accel.enableZ) tempRegValue |= (1<<5);
     if (settings.accel.enableY) tempRegValue |= (1<<4);
     if (settings.accel.enableX) tempRegValue |= (1<<3);
-    
+
     xgWriteByte(CTRL_REG5_XL, tempRegValue);
-    
+
     // CTRL_REG6_XL (0x20) (Default value: 0x00)
     // [ODR_XL2][ODR_XL1][ODR_XL0][FS1_XL][FS0_XL][BW_SCAL_ODR][BW_XL1][BW_XL0]
     // ODR_XL[2:0] - Output data rate & power mode selection
@@ -286,12 +282,10 @@
     // BW_XL[1:0] - Anti-aliasing filter bandwidth selection
     tempRegValue = 0;
     // To disable the accel, set the sampleRate bits to 0.
-    if (settings.accel.enabled)
-    {
+    if (settings.accel.enabled) {
         tempRegValue |= (settings.accel.sampleRate & 0x07) << 5;
     }
-    switch (settings.accel.scale)
-    {
+    switch (settings.accel.scale) {
         case 4:
             tempRegValue |= (0x2 << 3);
             break;
@@ -301,15 +295,14 @@
         case 16:
             tempRegValue |= (0x1 << 3);
             break;
-        // Otherwise it'll be set to 2g (0x0 << 3)
+            // Otherwise it'll be set to 2g (0x0 << 3)
     }
-    if (settings.accel.bandwidth >= 0)
-    {
+    if (settings.accel.bandwidth >= 0) {
         tempRegValue |= (1<<2); // Set BW_SCAL_ODR
         tempRegValue |= (settings.accel.bandwidth & 0x03);
     }
     xgWriteByte(CTRL_REG6_XL, tempRegValue);
-    
+
     // CTRL_REG7_XL (0x21) (Default value: 0x00)
     // [HR][DCF1][DCF0][0][0][FDS][0][HPIS1]
     // HR - High resolution mode (0: disable, 1: enable)
@@ -317,8 +310,7 @@
     // FDS - Filtered data selection
     // HPIS1 - HPF enabled for interrupt function
     tempRegValue = 0;
-    if (settings.accel.highResEnable)
-    {
+    if (settings.accel.highResEnable) {
         tempRegValue |= (1<<7); // Set HR bit
         tempRegValue |= (settings.accel.highResBandwidth & 0x3) << 5;
     }
@@ -333,22 +325,22 @@
 // remove errors due to imprecise or varying initial placement. Calibration of sensor data in this manner
 // is good practice.
 void LSM9DS1::calibrate(bool autoCalc)
-{  
+{
     uint8_t data[6] = {0, 0, 0, 0, 0, 0};
     uint8_t samples = 0;
     int ii;
     int32_t aBiasRawTemp[3] = {0, 0, 0};
     int32_t gBiasRawTemp[3] = {0, 0, 0};
-    
+    pc.printf("\n\rPlace IMU on level surface and do not move it for gyro and accel calibration.\n\r");
+    wait(1);
     // Turn on FIFO and set threshold to 32 samples
     enableFIFO(true);
     setFIFO(FIFO_THS, 0x1F);
-    while (samples < 0x1F)
-    {
+    while (samples < 0x1F) {
         samples = (xgReadByte(FIFO_SRC) & 0x3F); // Read number of stored samples
     }
-    for(ii = 0; ii < samples ; ii++) 
-    {   // Read the gyro data stored in the FIFO
+    for(ii = 0; ii < samples ; ii++) {
+        // Read the gyro data stored in the FIFO
         readGyro();
         gBiasRawTemp[0] += gx;
         gBiasRawTemp[1] += gy;
@@ -357,18 +349,17 @@
         aBiasRawTemp[0] += ax;
         aBiasRawTemp[1] += ay;
         aBiasRawTemp[2] += az - (int16_t)(1./aRes); // Assumes sensor facing up!
-    }  
-    for (ii = 0; ii < 3; ii++)
-    {
+    }
+    for (ii = 0; ii < 3; ii++) {
         gBiasRaw[ii] = gBiasRawTemp[ii] / samples;
         gBias[ii] = calcGyro(gBiasRaw[ii]);
         aBiasRaw[ii] = aBiasRawTemp[ii] / samples;
         aBias[ii] = calcAccel(aBiasRaw[ii]);
     }
-    
+
     enableFIFO(false);
     setFIFO(FIFO_OFF, 0x00);
-    
+
     if (autoCalc) _autoCalc = true;
 }
 
@@ -377,30 +368,28 @@
     int i, j;
     int16_t magMin[3] = {0, 0, 0};
     int16_t magMax[3] = {0, 0, 0}; // The road warrior
-    
-    for (i=0; i<128; i++)
-    {
-        while (!magAvailable())
-            ;
+    pc.printf("\n\n\r Rotate IMU device at least 360 in horizontal plane for magnetometer calibration\n\r");
+    wait(0.5);
+    for (i=0; i<1000; i++) {
+        while (!magAvailable(ALL_AXIS));
         readMag();
         int16_t magTemp[3] = {0, 0, 0};
-        magTemp[0] = mx;        
+        magTemp[0] = mx;
         magTemp[1] = my;
         magTemp[2] = mz;
-        for (j = 0; j < 3; j++)
-        {
+        for (j = 0; j < 3; j++) {
             if (magTemp[j] > magMax[j]) magMax[j] = magTemp[j];
             if (magTemp[j] < magMin[j]) magMin[j] = magTemp[j];
         }
     }
-    for (j = 0; j < 3; j++)
-    {
+    for (j = 0; j < 3; j++) {
         mBiasRaw[j] = (magMax[j] + magMin[j]) / 2;
         mBias[j] = calcMag(mBiasRaw[j]);
+        pc.printf("%f  ",mBias[j]);
         if (loadIn)
             magOffset(j, mBiasRaw[j]);
     }
-    
+    pc.printf("\n\rMAG calibration done\n\r");
 }
 void LSM9DS1::magOffset(uint8_t axis, int16_t offset)
 {
@@ -416,7 +405,7 @@
 void LSM9DS1::initMag()
 {
     uint8_t tempRegValue = 0;
-    
+
     // CTRL_REG1_M (Default value: 0x10)
     // [TEMP_COMP][OM1][OM0][DO2][DO1][DO0][0][ST]
     // TEMP_COMP - Temperature compensation
@@ -429,28 +418,27 @@
     tempRegValue |= (settings.mag.XYPerformance & 0x3) << 5;
     tempRegValue |= (settings.mag.sampleRate & 0x7) << 2;
     mWriteByte(CTRL_REG1_M, tempRegValue);
-    
+
     // CTRL_REG2_M (Default value 0x00)
     // [0][FS1][FS0][0][REBOOT][SOFT_RST][0][0]
     // FS[1:0] - Full-scale configuration
     // REBOOT - Reboot memory content (0:normal, 1:reboot)
     // SOFT_RST - Reset config and user registers (0:default, 1:reset)
     tempRegValue = 0;
-    switch (settings.mag.scale)
-    {
-    case 8:
-        tempRegValue |= (0x1 << 5);
-        break;
-    case 12:
-        tempRegValue |= (0x2 << 5);
-        break;
-    case 16:
-        tempRegValue |= (0x3 << 5);
-        break;
-    // Otherwise we'll default to 4 gauss (00)
+    switch (settings.mag.scale) {
+        case 8:
+            tempRegValue |= (0x1 << 5);
+            break;
+        case 12:
+            tempRegValue |= (0x2 << 5);
+            break;
+        case 16:
+            tempRegValue |= (0x3 << 5);
+            break;
+            // Otherwise we'll default to 4 gauss (00)
     }
     mWriteByte(CTRL_REG2_M, tempRegValue); // +/-4Gauss
-    
+
     // CTRL_REG3_M (Default value: 0x03)
     // [I2C_DISABLE][0][LP][0][0][SIM][MD1][MD0]
     // I2C_DISABLE - Disable I2C interace (0:enable, 1:disable)
@@ -463,7 +451,7 @@
     if (settings.mag.lowPowerEnable) tempRegValue |= (1<<5);
     tempRegValue |= (settings.mag.operatingMode & 0x3);
     mWriteByte(CTRL_REG3_M, tempRegValue); // Continuous conversion mode
-    
+
     // CTRL_REG4_M (Default value: 0x00)
     // [0][0][0][0][OMZ1][OMZ0][BLE][0]
     // OMZ[1:0] - Z-axis operative mode selection
@@ -473,7 +461,7 @@
     tempRegValue = 0;
     tempRegValue = (settings.mag.ZPerformance & 0x3) << 2;
     mWriteByte(CTRL_REG4_M, tempRegValue);
-    
+
     // CTRL_REG5_M (Default value: 0x00)
     // [0][BDU][0][0][0][0][0][0]
     // BDU - Block data update for magnetic data
@@ -485,21 +473,21 @@
 uint8_t LSM9DS1::accelAvailable()
 {
     uint8_t status = xgReadByte(STATUS_REG_1);
-    
+
     return (status & (1<<0));
 }
 
 uint8_t LSM9DS1::gyroAvailable()
 {
     uint8_t status = xgReadByte(STATUS_REG_1);
-    
+
     return ((status & (1<<1)) >> 1);
 }
 
 uint8_t LSM9DS1::tempAvailable()
 {
     uint8_t status = xgReadByte(STATUS_REG_1);
-    
+
     return ((status & (1<<2)) >> 2);
 }
 
@@ -507,19 +495,18 @@
 {
     uint8_t status;
     status = mReadByte(STATUS_REG_M);
-    
+
     return ((status & (1<<axis)) >> axis);
 }
 
 void LSM9DS1::readAccel()
 {
-    uint8_t temp[6]; // We'll read six bytes from the accelerometer into temp   
+    uint8_t temp[6]; // We'll read six bytes from the accelerometer into temp
     xgReadBytes(OUT_X_L_XL, temp, 6); // Read 6 bytes, beginning at OUT_X_L_XL
     ax = (temp[1] << 8) | temp[0]; // Store x-axis values into ax
     ay = (temp[3] << 8) | temp[2]; // Store y-axis values into ay
     az = (temp[5] << 8) | temp[4]; // Store z-axis values into az
-    if (_autoCalc)
-    {
+    if (_autoCalc) {
         ax -= aBiasRaw[X_AXIS];
         ay -= aBiasRaw[Y_AXIS];
         az -= aBiasRaw[Z_AXIS];
@@ -532,20 +519,23 @@
     int16_t value;
     xgReadBytes(OUT_X_L_XL + (2 * axis), temp, 2);
     value = (temp[1] << 8) | temp[0];
-    
+
     if (_autoCalc)
         value -= aBiasRaw[axis];
-    
+
     return value;
 }
 
 void LSM9DS1::readMag()
 {
-    uint8_t temp[6]; // We'll read six bytes from the mag into temp 
+    uint8_t temp[6]; // We'll read six bytes from the mag into temp
     mReadBytes(OUT_X_L_M, temp, 6); // Read 6 bytes, beginning at OUT_X_L_M
     mx = (temp[1] << 8) | temp[0]; // Store x-axis values into mx
     my = (temp[3] << 8) | temp[2]; // Store y-axis values into my
     mz = (temp[5] << 8) | temp[4]; // Store z-axis values into mz
+    mx = mx - mBiasRaw[0];
+    my = my - mBiasRaw[1];
+    mz = mz - mBiasRaw[2];
 }
 
 int16_t LSM9DS1::readMag(lsm9ds1_axis axis)
@@ -557,9 +547,9 @@
 
 void LSM9DS1::readTemp()
 {
-    uint8_t temp[2]; // We'll read two bytes from the temperature sensor into temp  
+    uint8_t temp[2]; // We'll read two bytes from the temperature sensor into temp
     xgReadBytes(OUT_TEMP_L, temp, 2); // Read 2 bytes, beginning at OUT_TEMP_L
-    temperature = ((int16_t)temp[1] << 8) | temp[0];
+    temperature = (int16_t)((temp[1] << 8) | temp[0]);
 }
 
 void LSM9DS1::readGyro()
@@ -569,8 +559,7 @@
     gx = (temp[1] << 8) | temp[0]; // Store x-axis values into gx
     gy = (temp[3] << 8) | temp[2]; // Store y-axis values into gy
     gz = (temp[5] << 8) | temp[4]; // Store z-axis values into gz
-    if (_autoCalc)
-    {
+    if (_autoCalc) {
         gx -= gBiasRaw[X_AXIS];
         gy -= gBiasRaw[Y_AXIS];
         gz -= gBiasRaw[Z_AXIS];
@@ -581,21 +570,21 @@
 {
     uint8_t temp[2];
     int16_t value;
-    
+
     xgReadBytes(OUT_X_L_G + (2 * axis), temp, 2);
-    
+
     value = (temp[1] << 8) | temp[0];
-    
+
     if (_autoCalc)
         value -= gBiasRaw[axis];
-    
+
     return value;
 }
 
 float LSM9DS1::calcGyro(int16_t gyro)
 {
     // Return the gyro raw reading times our pre-calculated DPS / (ADC tick):
-    return gRes * gyro; 
+    return gRes * gyro;
 }
 
 float LSM9DS1::calcAccel(int16_t accel)
@@ -616,8 +605,7 @@
     uint8_t ctrl1RegValue = xgReadByte(CTRL_REG1_G);
     // Mask out scale bits (3 & 4):
     ctrl1RegValue &= 0xE7;
-    switch (gScl)
-    {
+    switch (gScl) {
         case 500:
             ctrl1RegValue |= (0x1 << 3);
             settings.gyro.scale = 500;
@@ -631,8 +619,8 @@
             break;
     }
     xgWriteByte(CTRL_REG1_G, ctrl1RegValue);
-    
-    calcgRes(); 
+
+    calcgRes();
 }
 
 void LSM9DS1::setAccelScale(uint8_t aScl)
@@ -641,9 +629,8 @@
     uint8_t tempRegValue = xgReadByte(CTRL_REG6_XL);
     // Mask out accel scale bits:
     tempRegValue &= 0xE7;
-    
-    switch (aScl)
-    {
+
+    switch (aScl) {
         case 4:
             tempRegValue |= (0x2 << 3);
             settings.accel.scale = 4;
@@ -661,7 +648,7 @@
             break;
     }
     xgWriteByte(CTRL_REG6_XL, tempRegValue);
-    
+
     // Then calculate a new aRes, which relies on aScale being set correctly:
     calcaRes();
 }
@@ -672,29 +659,28 @@
     uint8_t temp = mReadByte(CTRL_REG2_M);
     // Then mask out the mag scale bits:
     temp &= 0xFF^(0x3 << 5);
-    
-    switch (mScl)
-    {
-    case 8:
-        temp |= (0x1 << 5);
-        settings.mag.scale = 8;
-        break;
-    case 12:
-        temp |= (0x2 << 5);
-        settings.mag.scale = 12;
-        break;
-    case 16:
-        temp |= (0x3 << 5);
-        settings.mag.scale = 16;
-        break;
-    default: // Otherwise we'll default to 4 gauss (00)
-        settings.mag.scale = 4;
-        break;
-    }   
-    
+
+    switch (mScl) {
+        case 8:
+            temp |= (0x1 << 5);
+            settings.mag.scale = 8;
+            break;
+        case 12:
+            temp |= (0x2 << 5);
+            settings.mag.scale = 12;
+            break;
+        case 16:
+            temp |= (0x3 << 5);
+            settings.mag.scale = 16;
+            break;
+        default: // Otherwise we'll default to 4 gauss (00)
+            settings.mag.scale = 4;
+            break;
+    }
+
     // And write the new register value back into CTRL_REG6_XM:
     mWriteByte(CTRL_REG2_M, temp);
-    
+
     // We've updated the sensor, but we also need to update our class variables
     // First update mScale:
     //mScale = mScl;
@@ -705,8 +691,7 @@
 void LSM9DS1::setGyroODR(uint8_t gRate)
 {
     // Only do this if gRate is not 0 (which would disable the gyro)
-    if ((gRate & 0x07) != 0)
-    {
+    if ((gRate & 0x07) != 0) {
         // We need to preserve the other bytes in CTRL_REG1_G. So, first read it:
         uint8_t temp = xgReadByte(CTRL_REG1_G);
         // Then mask out the gyro ODR bits:
@@ -722,8 +707,7 @@
 void LSM9DS1::setAccelODR(uint8_t aRate)
 {
     // Only do this if aRate is not 0 (which would disable the accel)
-    if ((aRate & 0x07) != 0)
-    {
+    if ((aRate & 0x07) != 0) {
         // We need to preserve the other bytes in CTRL_REG1_XM. So, first read it:
         uint8_t temp = xgReadByte(CTRL_REG6_XL);
         // Then mask out the accel ODR bits:
@@ -762,53 +746,52 @@
 void LSM9DS1::calcmRes()
 {
     //mRes = ((float) settings.mag.scale) / 32768.0;
-    switch (settings.mag.scale)
-    {
-    case 4:
-        mRes = magSensitivity[0];
-        break;
-    case 8:
-        mRes = magSensitivity[1];
-        break;
-    case 12:
-        mRes = magSensitivity[2];
-        break;
-    case 16:
-        mRes = magSensitivity[3];
-        break;
+    switch (settings.mag.scale) {
+        case 4:
+            mRes = magSensitivity[0];
+            break;
+        case 8:
+            mRes = magSensitivity[1];
+            break;
+        case 12:
+            mRes = magSensitivity[2];
+            break;
+        case 16:
+            mRes = magSensitivity[3];
+            break;
     }
-    
+
 }
 
 void LSM9DS1::configInt(interrupt_select interrupt, uint8_t generator,
-                         h_lactive activeLow, pp_od pushPull)
+                        h_lactive activeLow, pp_od pushPull)
 {
     // Write to INT1_CTRL or INT2_CTRL. [interupt] should already be one of
     // those two values.
     // [generator] should be an OR'd list of values from the interrupt_generators enum
     xgWriteByte(interrupt, generator);
-    
+
     // Configure CTRL_REG8
     uint8_t temp;
     temp = xgReadByte(CTRL_REG8);
-    
+
     if (activeLow) temp |= (1<<5);
     else temp &= ~(1<<5);
-    
+
     if (pushPull) temp &= ~(1<<4);
     else temp |= (1<<4);
-    
+
     xgWriteByte(CTRL_REG8, temp);
 }
 
 void LSM9DS1::configInactivity(uint8_t duration, uint8_t threshold, bool sleepOn)
 {
     uint8_t temp = 0;
-    
+
     temp = threshold & 0x7F;
     if (sleepOn) temp |= (1<<7);
     xgWriteByte(ACT_THS, temp);
-    
+
     xgWriteByte(ACT_DUR, duration);
 }
 
@@ -833,7 +816,7 @@
     // Write threshold value to INT_GEN_THS_?_XL.
     // axis will be 0, 1, or 2 (x, y, z respectively)
     xgWriteByte(INT_GEN_THS_X_XL + axis, threshold);
-    
+
     // Write duration and wait to INT_GEN_DUR_XL
     uint8_t temp;
     temp = (duration & 0x7F);
@@ -844,13 +827,12 @@
 uint8_t LSM9DS1::getAccelIntSrc()
 {
     uint8_t intSrc = xgReadByte(INT_GEN_SRC_XL);
-    
+
     // Check if the IA_XL (interrupt active) bit is set
-    if (intSrc & (1<<6))
-    {
+    if (intSrc & (1<<6)) {
         return (intSrc & 0x3F);
     }
-    
+
     return 0;
 }
 
@@ -873,7 +855,7 @@
     // axis will be 0, 1, or 2 (x, y, z respectively)
     xgWriteByte(INT_GEN_THS_XH_G + (axis * 2), buffer[0]);
     xgWriteByte(INT_GEN_THS_XH_G + 1 + (axis * 2), buffer[1]);
-    
+
     // Write duration and wait to INT_GEN_DUR_XL
     uint8_t temp;
     temp = (duration & 0x7F);
@@ -884,27 +866,26 @@
 uint8_t LSM9DS1::getGyroIntSrc()
 {
     uint8_t intSrc = xgReadByte(INT_GEN_SRC_G);
-    
+
     // Check if the IA_G (interrupt active) bit is set
-    if (intSrc & (1<<6))
-    {
+    if (intSrc & (1<<6)) {
         return (intSrc & 0x3F);
     }
-    
+
     return 0;
 }
 
 void LSM9DS1::configMagInt(uint8_t generator, h_lactive activeLow, bool latch)
 {
     // Mask out non-generator bits (0-4)
-    uint8_t config = (generator & 0xE0);    
+    uint8_t config = (generator & 0xE0);
     // IEA bit is 0 for active-low, 1 for active-high.
     if (activeLow == INT_ACTIVE_HIGH) config |= (1<<2);
     // IEL bit is 0 for latched, 1 for not-latched
     if (!latch) config |= (1<<1);
     // As long as we have at least 1 generator, enable the interrupt
     if (generator != 0) config |= (1<<0);
-    
+
     mWriteByte(INT_CFG_M, config);
 }
 
@@ -919,13 +900,12 @@
 uint8_t LSM9DS1::getMagIntSrc()
 {
     uint8_t intSrc = mReadByte(INT_SRC_M);
-    
+
     // Check if the INT (interrupt active) bit is set
-    if (intSrc & (1<<0))
-    {
+    if (intSrc & (1<<0)) {
         return (intSrc & 0xFE);
     }
-    
+
     return 0;
 }
 
@@ -960,21 +940,18 @@
 
 void LSM9DS1::constrainScales()
 {
-    if ((settings.gyro.scale != 245) && (settings.gyro.scale != 500) && 
-        (settings.gyro.scale != 2000))
-    {
+    if ((settings.gyro.scale != 245) && (settings.gyro.scale != 500) &&
+            (settings.gyro.scale != 2000)) {
         settings.gyro.scale = 245;
     }
-        
+
     if ((settings.accel.scale != 2) && (settings.accel.scale != 4) &&
-        (settings.accel.scale != 8) && (settings.accel.scale != 16))
-    {
+            (settings.accel.scale != 8) && (settings.accel.scale != 16)) {
         settings.accel.scale = 2;
     }
-        
+
     if ((settings.mag.scale != 4) && (settings.mag.scale != 8) &&
-        (settings.mag.scale != 12) && (settings.mag.scale != 16))
-    {
+            (settings.mag.scale != 12) && (settings.mag.scale != 16)) {
         settings.mag.scale = 4;
     }
 }
@@ -984,7 +961,7 @@
     // Whether we're using I2C or SPI, write a byte using the
     // gyro-specific I2C address or SPI CS pin.
     if (settings.device.commInterface == IMU_MODE_I2C) {
-        printf("yo");
+        pc.printf("yo");
         I2CwriteByte(_xgAddress, subAddress, data);
     } else if (settings.device.commInterface == IMU_MODE_SPI) {
         SPIwriteByte(_xgAddress, subAddress, data);
@@ -995,9 +972,10 @@
 {
     // Whether we're using I2C or SPI, write a byte using the
     // accelerometer-specific I2C address or SPI CS pin.
-    if (settings.device.commInterface == IMU_MODE_I2C)
+    if (settings.device.commInterface == IMU_MODE_I2C) {
+        pc.printf("mo");
         return I2CwriteByte(_mAddress, subAddress, data);
-    else if (settings.device.commInterface == IMU_MODE_SPI)
+    } else if (settings.device.commInterface == IMU_MODE_SPI)
         return SPIwriteByte(_mAddress, subAddress, data);
 }
 
@@ -1044,12 +1022,12 @@
 
 void LSM9DS1::initSPI()
 {
-    /* 
+    /*
     pinMode(_xgAddress, OUTPUT);
     digitalWrite(_xgAddress, HIGH);
     pinMode(_mAddress, OUTPUT);
     digitalWrite(_mAddress, HIGH);
-    
+
     SPI.begin();
     // Maximum SPI frequency is 10MHz, could divide by 2 here:
     SPI.setClockDivider(SPI_CLOCK_DIV2);
@@ -1065,12 +1043,12 @@
 {
     /*
     digitalWrite(csPin, LOW); // Initiate communication
-    
+
     // If write, bit 0 (MSB) should be 0
     // If single write, bit 1 should be 0
     SPI.transfer(subAddress & 0x3F); // Send Address
     SPI.transfer(data); // Send data
-    
+
     digitalWrite(csPin, HIGH); // Close communication
     */
 }
@@ -1078,23 +1056,23 @@
 uint8_t LSM9DS1::SPIreadByte(uint8_t csPin, uint8_t subAddress)
 {
     uint8_t temp;
-    // Use the multiple read function to read 1 byte. 
+    // Use the multiple read function to read 1 byte.
     // Value is returned to `temp`.
     SPIreadBytes(csPin, subAddress, &temp, 1);
     return temp;
 }
 
 void LSM9DS1::SPIreadBytes(uint8_t csPin, uint8_t subAddress,
-                            uint8_t * dest, uint8_t count)
+                           uint8_t * dest, uint8_t count)
 {
     // To indicate a read, set bit 0 (msb) of first byte to 1
     uint8_t rAddress = 0x80 | (subAddress & 0x3F);
-    // Mag SPI port is different. If we're reading multiple bytes, 
+    // Mag SPI port is different. If we're reading multiple bytes,
     // set bit 1 to 1. The remaining six bytes are the address to be read
     if ((csPin == _mAddress) && count > 1)
         rAddress |= 0x40;
-    
-    /* 
+
+    /*
     digitalWrite(csPin, LOW); // Initiate communication
     SPI.transfer(rAddress);
     for (int i=0; i<count; i++)
@@ -1107,17 +1085,17 @@
 
 void LSM9DS1::initI2C()
 {
-    /* 
+    /*
     Wire.begin();   // Initialize I2C library
     */
-    
+
     //already initialized in constructor!
 }
 
 // Wire.h read and write protocols
 void LSM9DS1::I2CwriteByte(uint8_t address, uint8_t subAddress, uint8_t data)
 {
-    /* 
+    /*
     Wire.beginTransmission(address);  // Initialize the Tx buffer
     Wire.write(subAddress);           // Put slave register address in Tx buffer
     Wire.write(data);                 // Put data in Tx buffer
@@ -1129,26 +1107,26 @@
 
 uint8_t LSM9DS1::I2CreadByte(uint8_t address, uint8_t subAddress)
 {
-    /* 
+    /*
     int timeout = LSM9DS1_COMMUNICATION_TIMEOUT;
-    uint8_t data; // `data` will store the register data    
-    
+    uint8_t data; // `data` will store the register data
+
     Wire.beginTransmission(address);         // Initialize the Tx buffer
     Wire.write(subAddress);                  // Put slave register address in Tx buffer
     Wire.endTransmission(true);             // Send the Tx buffer, but send a restart to keep connection alive
-    Wire.requestFrom(address, (uint8_t) 1);  // Read one byte from slave register address 
+    Wire.requestFrom(address, (uint8_t) 1);  // Read one byte from slave register address
     while ((Wire.available() < 1) && (timeout-- > 0))
         delay(1);
-    
+
     if (timeout <= 0)
         return 255; //! Bad! 255 will be misinterpreted as a good value.
-    
+
     data = Wire.read();                      // Fill Rx buffer with result
     return data;                             // Return data read from slave register
     */
     char data;
-    char temp[1] = {subAddress};
-    
+    char temp[2] = {subAddress};
+
     i2c.write(address, temp, 1);
     //i2c.write(address & 0xFE);
     temp[1] = 0x00;
@@ -1159,8 +1137,8 @@
 }
 
 uint8_t LSM9DS1::I2CreadBytes(uint8_t address, uint8_t subAddress, uint8_t * dest, uint8_t count)
-{  
-    /* 
+{
+    /*
     int timeout = LSM9DS1_COMMUNICATION_TIMEOUT;
     Wire.beginTransmission(address);   // Initialize the Tx buffer
     // Next send the register to be read. OR with 0x80 to indicate multi-read.
@@ -1168,12 +1146,12 @@
 
     Wire.endTransmission(true);             // Send the Tx buffer, but send a restart to keep connection alive
     uint8_t i = 0;
-    Wire.requestFrom(address, count);  // Read bytes from slave register address 
+    Wire.requestFrom(address, count);  // Read bytes from slave register address
     while ((Wire.available() < count) && (timeout-- > 0))
         delay(1);
     if (timeout <= 0)
         return -1;
-    
+
     for (int i=0; i<count;)
     {
         if (Wire.available())
@@ -1188,10 +1166,10 @@
     char temp[1] = {subAddress};
     i2c.write(address, temp, 1);
     i2c.read(address, temp_dest, count);
-    
+
     //i2c doesn't take uint8_ts, but rather chars so do this nasty af conversion
     for (i=0; i < count; i++) {
-        dest[i] = temp_dest[i];    
+        dest[i] = temp_dest[i];
     }
     return count;
 }
diff -r 87d535bf8c53 -r 36abf8e18ade LSM9DS1.h
--- a/LSM9DS1.h	Mon Oct 26 16:14:04 2015 +0000
+++ b/LSM9DS1.h	Wed Feb 03 18:45:40 2016 +0000
@@ -312,7 +312,8 @@
     *    Any OR'd combination of ZIEN, YIEN, XIEN
     *  - activeLow = Interrupt active configuration
     *    Can be either INT_ACTIVE_HIGH or INT_ACTIVE_LOW
-    */  - latch: latch gyroscope interrupt request.
+    *  - latch: latch gyroscope interrupt request.
+    */
     void configMagInt(uint8_t generator, h_lactive activeLow, bool latch = true);
     
     /** configMagThs() -- Configure the threshold of a gyroscope axis
diff -r 87d535bf8c53 -r 36abf8e18ade main.cpp
--- a/main.cpp	Mon Oct 26 16:14:04 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#include "LSM9DS1.h"
-
-DigitalOut myled(LED1);
-Serial pc(USBTX, USBRX);
-
-int main() {
-    //LSM9DS1 lol(p9, p10, 0x6B, 0x1E);
-    LSM9DS1 lol(p9, p10, 0xD6, 0x3C);
-    lol.begin();
-    if (!lol.begin()) {
-        pc.printf("Failed to communicate with LSM9DS1.\n");
-    }
-    lol.calibrate();
-    while(1) {
-        lol.readTemp();
-        lol.readMag();
-        lol.readGyro();
-        
-        //pc.printf("%d %d %d %d %d %d %d %d %d\n\r", lol.calcGyro(lol.gx), lol.calcGyro(lol.gy), lol.calcGyro(lol.gz), lol.ax, lol.ay, lol.az, lol.mx, lol.my, lol.mz);
-        //pc.printf("%d %d %d\n\r", lol.calcGyro(lol.gx), lol.calcGyro(lol.gy), lol.calcGyro(lol.gz));
-        pc.printf("gyro: %d %d %d\n\r", lol.gx, lol.gy, lol.gz);
-        pc.printf("accel: %d %d %d\n\r", lol.ax, lol.ay, lol.az);
-        pc.printf("mag: %d %d %d\n\n\r", lol.mx, lol.my, lol.mz);
-        myled = 1;
-        wait(2);
-        myled = 0;
-        wait(2);
-    }
-}