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