Home | History | Annotate | Download | only in lsm9ds0
      1 /*
      2  * Author: Jon Trulson <jtrulson (at) ics.com>
      3  * Copyright (c) 2015 Intel Corporation.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sublicense, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be
     14  * included in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 #include <unistd.h>
     26 #include <iostream>
     27 #include <stdexcept>
     28 #include <string.h>
     29 
     30 #include "lsm9ds0.h"
     31 
     32 using namespace upm;
     33 using namespace std;
     34 
     35 
     36 LSM9DS0::LSM9DS0(int bus, uint8_t gAddress, uint8_t xmAddress) :
     37   m_i2cG(bus), m_i2cXM(bus), m_gpioG_INT(0), m_gpioG_DRDY(0),
     38   m_gpioXM_GEN1(0), m_gpioXM_GEN2(0)
     39 {
     40   m_gAddr = gAddress;
     41   m_xmAddr = xmAddress;
     42 
     43   m_accelX = 0.0;
     44   m_accelY = 0.0;
     45   m_accelZ = 0.0;
     46 
     47   m_gyroX = 0.0;
     48   m_gyroY = 0.0;
     49   m_gyroZ = 0.0;
     50 
     51   m_magX = 0.0;
     52   m_magY = 0.0;
     53   m_magZ = 0.0;
     54 
     55   m_temp = 0.0;
     56 
     57   m_accelScale = 0.0;
     58   m_gyroScale = 0.0;
     59   m_magScale = 0.0;
     60 
     61   mraa::Result rv;
     62   if ( (rv = m_i2cG.address(m_gAddr)) != mraa::SUCCESS)
     63     {
     64       throw std::runtime_error(string(__FUNCTION__) +
     65                                ": Could not initialize Gyro i2c address");
     66       return;
     67     }
     68 
     69   if ( (rv = m_i2cXM.address(m_xmAddr)) != mraa::SUCCESS)
     70     {
     71       throw std::runtime_error(string(__FUNCTION__) +
     72                                ": Could not initialize XM i2c address");
     73       return;
     74     }
     75 }
     76 
     77 LSM9DS0::~LSM9DS0()
     78 {
     79   uninstallISR(INTERRUPT_G_INT);
     80   uninstallISR(INTERRUPT_G_DRDY);
     81   uninstallISR(INTERRUPT_XM_GEN1);
     82   uninstallISR(INTERRUPT_XM_GEN2);
     83 }
     84 
     85 bool LSM9DS0::init()
     86 {
     87   // Init the gyroscope
     88 
     89   // power up
     90   if (!setGyroscopePowerDown(false))
     91     {
     92       throw std::runtime_error(string(__FUNCTION__) +
     93                                ": Unable to wake up gyro");
     94       return false;
     95     }
     96 
     97   // enable all axes
     98   if (!setGyroscopeEnableAxes(CTRL_REG1_G_YEN |CTRL_REG1_G_XEN |
     99                               CTRL_REG1_G_ZEN))
    100     {
    101       throw std::runtime_error(string(__FUNCTION__) +
    102                                ": Unable to enable gyro axes");
    103       return false;
    104     }
    105 
    106   // set gyro ODR
    107   if (!setGyroscopeODR(G_ODR_95_25))
    108     {
    109       throw std::runtime_error(string(__FUNCTION__) +
    110                                ": Unable to set gyro ODR");
    111       return false;
    112     }
    113 
    114   // set gyro scale
    115   if (!setGyroscopeScale(G_FS_245))
    116     {
    117       throw std::runtime_error(string(__FUNCTION__) +
    118                                ": Unable to set gyro scale");
    119       return false;
    120     }
    121 
    122   // Init the accelerometer
    123 
    124   // power up and set ODR
    125   if (!setAccelerometerODR(XM_AODR_100))
    126     {
    127       throw std::runtime_error(string(__FUNCTION__) +
    128                                ": Unable to set accel ODR");
    129       return false;
    130     }
    131 
    132   // enable all axes
    133   if (!setAccelerometerEnableAxes(CTRL_REG1_XM_AXEN |CTRL_REG1_XM_AYEN |
    134                                   CTRL_REG1_XM_AZEN))
    135     {
    136       throw std::runtime_error(string(__FUNCTION__) +
    137                                ": Unable to enable accel axes");
    138       return false;
    139     }
    140 
    141   // set scaling rate
    142   if (!setAccelerometerScale(XM_AFS_2))
    143     {
    144       throw std::runtime_error(string(__FUNCTION__) +
    145                                ": Unable to set accel scale");
    146       return false;
    147     }
    148 
    149   // temperature sensor
    150 
    151   // enable the temperature sensor
    152   if (!enableTemperatureSensor(true))
    153     {
    154       throw std::runtime_error(string(__FUNCTION__) +
    155                                ": Unable to enable temp sensor");
    156       return false;
    157     }
    158 
    159   // Init the magnetometer
    160 
    161   // set mode (this also powers it up if not XM_MD_POWERDOWN)
    162   if (!setMagnetometerMode(XM_MD_CONTINUOUS))
    163     {
    164       throw std::runtime_error(string(__FUNCTION__) +
    165                                ": Unable to set mag scale");
    166       return false;
    167     }
    168 
    169   // turn LPM off
    170   if (!setMagnetometerLPM(false))
    171     {
    172       throw std::runtime_error(string(__FUNCTION__) +
    173                                ": Unable to disable mag LPM");
    174       return false;
    175     }
    176 
    177   // set resolution
    178   if (!setMagnetometerResolution(XM_RES_LOW))
    179     {
    180       throw std::runtime_error(string(__FUNCTION__) +
    181                                ": Unable to set mag res");
    182       return false;
    183     }
    184 
    185   // set ODR
    186   if (!setMagnetometerODR(XM_ODR_12_5))
    187     {
    188       throw std::runtime_error(string(__FUNCTION__) +
    189                                ": Unable to set mag ODR");
    190       return false;
    191     }
    192 
    193   // set scale
    194   if (!setMagnetometerScale(XM_MFS_2))
    195     {
    196       throw std::runtime_error(string(__FUNCTION__) +
    197                                ": Unable to set mag scale");
    198       return false;
    199     }
    200 
    201   return true;
    202 }
    203 
    204 
    205 void LSM9DS0::update()
    206 {
    207   updateGyroscope();
    208   updateAccelerometer();
    209   updateMagnetometer();
    210   updateTemperature();
    211 }
    212 
    213 void LSM9DS0::updateGyroscope()
    214 {
    215   uint8_t buffer[6];
    216 
    217   memset(buffer, 0, 6);
    218   readRegs(DEV_GYRO, REG_OUT_X_L_G, buffer, 6);
    219 
    220   int16_t x, y, z;
    221 
    222   x =  ( (buffer[1] << 8) | buffer[0] );
    223   y =  ( (buffer[3] << 8) | buffer[2] );
    224   z =  ( (buffer[5] << 8) | buffer[4] );
    225 
    226   m_gyroX = float(x);
    227   m_gyroY = float(y);
    228   m_gyroZ = float(z);
    229 }
    230 
    231 void LSM9DS0::updateAccelerometer()
    232 {
    233   uint8_t buffer[6];
    234 
    235   memset(buffer, 0, 6);
    236   readRegs(DEV_XM, REG_OUT_X_L_A, buffer, 6);
    237 
    238   int16_t x, y, z;
    239 
    240   x =  ( (buffer[1] << 8) | buffer[0] );
    241   y =  ( (buffer[3] << 8) | buffer[2] );
    242   z =  ( (buffer[5] << 8) | buffer[4] );
    243 
    244   m_accelX = float(x);
    245   m_accelY = float(y);
    246   m_accelZ = float(z);
    247 }
    248 
    249 void LSM9DS0::updateMagnetometer()
    250 {
    251   uint8_t buffer[6];
    252 
    253   memset(buffer, 0, 6);
    254   readRegs(DEV_XM, REG_OUT_X_L_M, buffer, 6);
    255 
    256   int16_t x, y, z;
    257 
    258   x =  ( (buffer[1] << 8) | buffer[0] );
    259   y =  ( (buffer[3] << 8) | buffer[2] );
    260   z =  ( (buffer[5] << 8) | buffer[4] );
    261 
    262   m_magX = float(x);
    263   m_magY = float(y);
    264   m_magZ = float(z);
    265 }
    266 
    267 void LSM9DS0::updateTemperature()
    268 {
    269   uint8_t buffer[2];
    270 
    271   memset(buffer, 0, 2);
    272   readRegs(DEV_XM, REG_OUT_TEMP_L_XM, buffer, 2);
    273 
    274   //  cerr << "HIGH: " << int(buffer[1]) << " LOW: " << int(buffer[0]) << endl;
    275 
    276   // 12b signed
    277   int16_t temp = ( (buffer[1] << 8) | (buffer[0] ) );
    278   if (temp & 0x0800)
    279     {
    280       temp &= ~0x0800;
    281       temp *= -1;
    282     }
    283 
    284   m_temp = float(temp);
    285 }
    286 
    287 uint8_t LSM9DS0::readReg(DEVICE_T dev, uint8_t reg)
    288 {
    289   mraa::I2c *device;
    290 
    291   switch(dev)
    292     {
    293     case DEV_GYRO: device = &m_i2cG; break;
    294     case DEV_XM:   device = &m_i2cXM; break;
    295     default:
    296       throw std::logic_error(string(__FUNCTION__) +
    297                              ": Internal error, invalid device specified");
    298       return 0;
    299     }
    300 
    301   return device->readReg(reg);
    302 }
    303 
    304 void LSM9DS0::readRegs(DEVICE_T dev, uint8_t reg, uint8_t *buffer, int len)
    305 {
    306   mraa::I2c *device;
    307 
    308   switch(dev)
    309     {
    310     case DEV_GYRO: device = &m_i2cG; break;
    311     case DEV_XM:   device = &m_i2cXM; break;
    312     default:
    313       throw std::logic_error(string(__FUNCTION__) +
    314                              ": Internal error, invalid device specified");
    315       return;
    316     }
    317 
    318   // We need to set the high bit of the register to enable
    319   // auto-increment mode for reading multiple registers in one go.
    320   device->readBytesReg(reg | m_autoIncrementMode, buffer, len);
    321 }
    322 
    323 bool LSM9DS0::writeReg(DEVICE_T dev, uint8_t reg, uint8_t val)
    324 {
    325   mraa::I2c *device;
    326 
    327   switch(dev)
    328     {
    329     case DEV_GYRO: device = &m_i2cG; break;
    330     case DEV_XM:   device = &m_i2cXM; break;
    331     default:
    332       throw std::logic_error(string(__FUNCTION__) +
    333                              ": Internal error, invalid device specified");
    334       return false;
    335     }
    336 
    337   mraa::Result rv;
    338   if ((rv = device->writeReg(reg, val)) != mraa::SUCCESS)
    339     {
    340       throw std::runtime_error(std::string(__FUNCTION__) +
    341                                ": I2c.writeReg() failed");
    342       return false;
    343     }
    344 
    345   return true;
    346 }
    347 
    348 bool LSM9DS0::setGyroscopePowerDown(bool enable)
    349 {
    350   uint8_t reg = readReg(DEV_GYRO, REG_CTRL_REG1_G);
    351 
    352   if (enable)
    353     reg &= ~CTRL_REG1_G_PD;
    354   else
    355     reg |= CTRL_REG1_G_PD;
    356 
    357   return writeReg(DEV_GYRO, REG_CTRL_REG1_G, reg);
    358 }
    359 
    360 bool LSM9DS0::setGyroscopeEnableAxes(uint8_t axes)
    361 {
    362   uint8_t reg = readReg(DEV_GYRO, REG_CTRL_REG1_G);
    363 
    364   // filter out any non-axis related data from arg
    365   axes &= (CTRL_REG1_G_YEN | CTRL_REG1_G_XEN |  CTRL_REG1_G_ZEN);
    366 
    367   // clear them in the register
    368   reg &= ~(CTRL_REG1_G_YEN | CTRL_REG1_G_XEN |  CTRL_REG1_G_ZEN);
    369 
    370   // now add them
    371   reg |= axes;
    372 
    373   return writeReg(DEV_GYRO, REG_CTRL_REG1_G, reg);
    374 }
    375 
    376 bool LSM9DS0::setGyroscopeODR(G_ODR_T odr)
    377 {
    378   uint8_t reg = readReg(DEV_GYRO, REG_CTRL_REG1_G);
    379 
    380   reg &= ~(_CTRL_REG1_G_ODR_MASK << _CTRL_REG1_G_ODR_SHIFT);
    381 
    382   reg |= (odr << _CTRL_REG1_G_ODR_SHIFT);
    383 
    384   return writeReg(DEV_GYRO, REG_CTRL_REG1_G, reg);
    385 }
    386 
    387 bool LSM9DS0::setGyroscopeScale(G_FS_T scale)
    388 {
    389   uint8_t reg = readReg(DEV_GYRO, REG_CTRL_REG4_G);
    390 
    391   reg &= ~(_CTRL_REG4_G_FS_MASK << _CTRL_REG4_G_FS_SHIFT);
    392 
    393   reg |= (scale << _CTRL_REG4_G_FS_SHIFT);
    394 
    395   if (!writeReg(DEV_GYRO, REG_CTRL_REG4_G, reg))
    396     {
    397       return false;
    398     }
    399 
    400   // store scaling factor (mDeg/s/LSB)
    401 
    402   switch (scale)
    403     {
    404     case G_FS_245:
    405       m_gyroScale = 8.75;
    406       break;
    407 
    408     case G_FS_500:
    409       m_gyroScale = 17.5;
    410       break;
    411 
    412     case G_FS_2000:
    413       m_gyroScale = 70.0;
    414       break;
    415 
    416     default: // should never occur, but...
    417       m_gyroScale = 0.0;        // set a safe, though incorrect value
    418       throw std::logic_error(string(__FUNCTION__) +
    419                              ": internal error, unsupported scale");
    420       break;
    421     }
    422 
    423   return true;
    424 }
    425 
    426 bool LSM9DS0::setAccelerometerEnableAxes(uint8_t axes)
    427 {
    428   uint8_t reg = readReg(DEV_XM, REG_CTRL_REG1_XM);
    429 
    430   // filter out any non-axis related data from arg
    431   axes &= (CTRL_REG1_XM_AXEN | CTRL_REG1_XM_AYEN | CTRL_REG1_XM_AZEN);
    432 
    433   // clear them in the register
    434   reg &= ~(CTRL_REG1_XM_AXEN | CTRL_REG1_XM_AYEN | CTRL_REG1_XM_AZEN);
    435 
    436   // now add them
    437   reg |= axes;
    438 
    439   return writeReg(DEV_XM, REG_CTRL_REG1_XM, reg);
    440 }
    441 
    442 bool LSM9DS0::setAccelerometerODR(XM_AODR_T odr)
    443 {
    444   uint8_t reg = readReg(DEV_XM, REG_CTRL_REG1_XM);
    445 
    446   reg &= ~(_CTRL_REG1_XM_AODR_MASK << _CTRL_REG1_XM_AODR_SHIFT);
    447 
    448   reg |= (odr << _CTRL_REG1_XM_AODR_SHIFT);
    449 
    450   return writeReg(DEV_XM, REG_CTRL_REG1_XM, reg);
    451 }
    452 
    453 bool LSM9DS0::setAccelerometerScale(XM_AFS_T scale)
    454 {
    455   uint8_t reg = readReg(DEV_XM, REG_CTRL_REG2_XM);
    456 
    457   reg &= ~(_CTRL_REG2_XM_AFS_MASK << _CTRL_REG2_XM_AFS_SHIFT);
    458 
    459   reg |= (scale << _CTRL_REG2_XM_AFS_SHIFT);
    460 
    461   if (!writeReg(DEV_XM, REG_CTRL_REG2_XM, reg))
    462     {
    463       return false;
    464     }
    465 
    466   // store scaling factor
    467 
    468   switch (scale)
    469     {
    470     case XM_AFS_2:
    471       m_accelScale = 0.061;
    472       break;
    473 
    474     case XM_AFS_4:
    475       m_accelScale = 0.122 ;
    476       break;
    477 
    478     case XM_AFS_6:
    479       m_accelScale = 0.183 ;
    480       break;
    481 
    482     case XM_AFS_8:
    483       m_accelScale = 0.244 ;
    484       break;
    485 
    486     case XM_AFS_16:
    487       m_accelScale = 0.732 ;
    488       break;
    489 
    490     default: // should never occur, but...
    491       m_accelScale = 0.0;        // set a safe, though incorrect value
    492       throw std::logic_error(string(__FUNCTION__) +
    493                              ": internal error, unsupported scale");
    494       break;
    495     }
    496 
    497   return true;
    498 }
    499 
    500 bool LSM9DS0::setMagnetometerResolution(XM_RES_T res)
    501 {
    502   uint8_t reg = readReg(DEV_XM, REG_CTRL_REG5_XM);
    503 
    504   reg &= ~(_CTRL_REG5_XM_RES_MASK << _CTRL_REG5_XM_RES_SHIFT);
    505 
    506   reg |= (res << _CTRL_REG5_XM_RES_SHIFT);
    507 
    508   return writeReg(DEV_XM, REG_CTRL_REG5_XM, reg);
    509 }
    510 
    511 bool LSM9DS0::setMagnetometerODR(XM_ODR_T odr)
    512 {
    513   uint8_t reg = readReg(DEV_XM, REG_CTRL_REG5_XM);
    514 
    515   reg &= ~(_CTRL_REG5_XM_ODR_MASK << _CTRL_REG5_XM_ODR_SHIFT);
    516 
    517   reg |= (odr << _CTRL_REG5_XM_ODR_SHIFT);
    518 
    519   return writeReg(DEV_XM, REG_CTRL_REG5_XM, reg);
    520 }
    521 
    522 bool LSM9DS0::setMagnetometerMode(XM_MD_T mode)
    523 {
    524   uint8_t reg = readReg(DEV_XM, REG_CTRL_REG7_XM);
    525 
    526   reg &= ~(_CTRL_REG7_XM_MD_MASK << _CTRL_REG7_XM_MD_SHIFT);
    527 
    528   reg |= (mode << _CTRL_REG7_XM_MD_SHIFT);
    529 
    530   return writeReg(DEV_XM, REG_CTRL_REG7_XM, reg);
    531 }
    532 
    533 bool LSM9DS0::setMagnetometerLPM(bool enable)
    534 {
    535   uint8_t reg = readReg(DEV_XM, REG_CTRL_REG7_XM);
    536 
    537   if (enable)
    538     reg |= CTRL_REG7_XM_MLP;
    539   else
    540     reg &= ~CTRL_REG7_XM_MLP;
    541 
    542   return writeReg(DEV_XM, REG_CTRL_REG7_XM, reg);
    543 }
    544 
    545 bool LSM9DS0::setMagnetometerScale(XM_MFS_T scale)
    546 {
    547   uint8_t reg = readReg(DEV_XM, REG_CTRL_REG6_XM);
    548 
    549   reg &= ~(_CTRL_REG6_XM_MFS_MASK << _CTRL_REG6_XM_MFS_SHIFT);
    550 
    551   reg |= (scale << _CTRL_REG6_XM_MFS_SHIFT);
    552 
    553   if (!writeReg(DEV_XM, REG_CTRL_REG6_XM, reg))
    554     {
    555       return false;
    556     }
    557 
    558   // store scaling factor
    559 
    560   switch (scale)
    561     {
    562     case XM_MFS_2:
    563       m_magScale = 0.08;
    564       break;
    565 
    566     case XM_MFS_4:
    567       m_magScale = 0.16;
    568       break;
    569 
    570     case XM_MFS_8:
    571       m_magScale = 0.32;
    572       break;
    573 
    574     case XM_MFS_12:
    575       m_magScale = 0.48;
    576       break;
    577 
    578     default: // should never occur, but...
    579       m_magScale = 0.0;        // set a safe, though incorrect value
    580       throw std::logic_error(string(__FUNCTION__) +
    581                              ": internal error, unsupported scale");
    582       break;
    583     }
    584 
    585   return true;
    586 }
    587 
    588 void LSM9DS0::getAccelerometer(float *x, float *y, float *z)
    589 {
    590   if (x)
    591     *x = (m_accelX * m_accelScale) / 1000.0;
    592 
    593   if (y)
    594     *y = (m_accelY * m_accelScale) / 1000.0;
    595 
    596   if (z)
    597     *z = (m_accelZ * m_accelScale) / 1000.0;
    598 }
    599 
    600 void LSM9DS0::getGyroscope(float *x, float *y, float *z)
    601 {
    602   if (x)
    603     *x = (m_gyroX * m_gyroScale) / 1000.0;
    604 
    605   if (y)
    606     *y = (m_gyroY * m_gyroScale) / 1000.0;
    607 
    608   if (z)
    609     *z = (m_gyroZ * m_gyroScale) / 1000.0;
    610 }
    611 
    612 void LSM9DS0::getMagnetometer(float *x, float *y, float *z)
    613 {
    614   if (x)
    615     *x = (m_magX * m_magScale) / 1000.0;
    616 
    617   if (y)
    618     *y = (m_magY * m_magScale) / 1000.0;
    619 
    620   if (z)
    621     *z = (m_magZ * m_magScale) / 1000.0;
    622 }
    623 
    624 #ifdef JAVACALLBACK
    625 float *LSM9DS0::getAccelerometer()
    626 {
    627   float *v = new float[3];
    628   getAccelerometer(&v[0], &v[1], &v[2]);
    629   return v;
    630 }
    631 
    632 float *LSM9DS0::getGyroscope()
    633 {
    634   float *v = new float[3];
    635   getGyroscope(&v[0], &v[1], &v[2]);
    636   return v;
    637 }
    638 
    639 float *LSM9DS0::getMagnetometer()
    640 {
    641   float *v = new float[3];
    642   getMagnetometer(&v[0], &v[1], &v[2]);
    643   return v;
    644 }
    645 #endif
    646 
    647 float LSM9DS0::getTemperature()
    648 {
    649   // This might be wrong... The datasheet does not provide enough info
    650   // to calculate the temperature given a specific sensor reading.  So
    651   // - with 12b resolution, signed, and 8 degrees/per LSB, we come up
    652   // with the following.  Then scale up and we get a number that seems
    653   // pretty close.
    654   return (((m_temp / 2048.0) * 8.0) * 100.0);
    655 }
    656 
    657 bool LSM9DS0::enableTemperatureSensor(bool enable)
    658 {
    659   uint8_t reg = readReg(DEV_XM, REG_CTRL_REG5_XM);
    660 
    661   if (enable)
    662     reg |= CTRL_REG5_XM_TEMP_EN;
    663   else
    664     reg &= ~CTRL_REG5_XM_TEMP_EN;
    665 
    666   return writeReg(DEV_XM, REG_CTRL_REG5_XM, reg);
    667 }
    668 
    669 uint8_t LSM9DS0::getGyroscopeStatus()
    670 {
    671   return readReg(DEV_GYRO, REG_STATUS_REG_G);
    672 }
    673 
    674 uint8_t LSM9DS0::getMagnetometerStatus()
    675 {
    676   return readReg(DEV_XM, REG_STATUS_REG_M);
    677 }
    678 
    679 uint8_t LSM9DS0::getAccelerometerStatus()
    680 {
    681   return readReg(DEV_XM, REG_STATUS_REG_A);
    682 }
    683 
    684 uint8_t LSM9DS0::getGyroscopeInterruptConfig()
    685 {
    686   return readReg(DEV_GYRO, REG_INT1_CFG_G);
    687 }
    688 
    689 bool LSM9DS0::setGyroscopeInterruptConfig(uint8_t enables)
    690 {
    691   return writeReg(DEV_GYRO, REG_INT1_CFG_G, enables);
    692 }
    693 
    694 uint8_t LSM9DS0::getGyroscopeInterruptSrc()
    695 {
    696   return readReg(DEV_GYRO, REG_INT1_SRC_G);
    697 }
    698 
    699 uint8_t LSM9DS0::getMagnetometerInterruptControl()
    700 {
    701   return readReg(DEV_XM, REG_INT_CTRL_REG_M);
    702 }
    703 
    704 bool LSM9DS0::setMagnetometerInterruptControl(uint8_t enables)
    705 {
    706   return writeReg(DEV_XM, REG_INT_CTRL_REG_M, enables);
    707 }
    708 
    709 uint8_t LSM9DS0::getMagnetometerInterruptSrc()
    710 {
    711   return readReg(DEV_XM, REG_INT_SRC_REG_M);
    712 }
    713 
    714 uint8_t LSM9DS0::getInterruptGen1()
    715 {
    716   return readReg(DEV_XM, REG_INT_GEN_1_REG);
    717 }
    718 
    719 bool LSM9DS0::setInterruptGen1(uint8_t enables)
    720 {
    721   return writeReg(DEV_XM, REG_INT_GEN_1_REG, enables);
    722 }
    723 
    724 uint8_t LSM9DS0::getInterruptGen1Src()
    725 {
    726   return readReg(DEV_XM, REG_INT_GEN_1_SRC);
    727 }
    728 
    729 uint8_t LSM9DS0::getInterruptGen2()
    730 {
    731   return readReg(DEV_XM, REG_INT_GEN_2_REG);
    732 }
    733 
    734 bool LSM9DS0::setInterruptGen2(uint8_t enables)
    735 {
    736   return writeReg(DEV_XM, REG_INT_GEN_2_REG, enables);
    737 }
    738 
    739 uint8_t LSM9DS0::getInterruptGen2Src()
    740 {
    741   return readReg(DEV_XM, REG_INT_GEN_2_SRC);
    742 }
    743 
    744 #ifdef SWIGJAVA
    745 void LSM9DS0::installISR(INTERRUPT_PINS_T intr, int gpio, mraa::Edge level,
    746 			 IsrCallback *cb)
    747 {
    748         installISR(intr, gpio, level, generic_callback_isr, cb);
    749 }
    750 #endif
    751 
    752 void LSM9DS0::installISR(INTERRUPT_PINS_T intr, int gpio, mraa::Edge level,
    753                          void (*isr)(void *), void *arg)
    754 {
    755   // delete any existing ISR and GPIO context
    756   uninstallISR(intr);
    757 
    758   // greate gpio context
    759   getPin(intr) = new mraa::Gpio(gpio);
    760 
    761   getPin(intr)->dir(mraa::DIR_IN);
    762   getPin(intr)->isr(level, isr, arg);
    763 }
    764 
    765 void LSM9DS0::uninstallISR(INTERRUPT_PINS_T intr)
    766 {
    767   if (getPin(intr))
    768     {
    769       getPin(intr)->isrExit();
    770       delete getPin(intr);
    771 
    772       getPin(intr) = 0;
    773     }
    774 }
    775 
    776 mraa::Gpio*& LSM9DS0::getPin(INTERRUPT_PINS_T intr)
    777 {
    778   switch(intr)
    779     {
    780     case INTERRUPT_G_INT:
    781       return m_gpioG_INT;
    782       break;
    783     case INTERRUPT_G_DRDY:
    784       return m_gpioG_DRDY;
    785       break;
    786     case INTERRUPT_XM_GEN1:
    787       return m_gpioXM_GEN1;
    788       break;
    789     case INTERRUPT_XM_GEN2:
    790       return m_gpioXM_GEN2;
    791       break;
    792     default:
    793       throw std::out_of_range(string(__FUNCTION__) +
    794                               ": Invalid interrupt enum passed");
    795     }
    796 }
    797