1 /*
2 * Author: Jon Trulson <jtrulson@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
LSM9DS0(int bus,uint8_t gAddress,uint8_t xmAddress)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
~LSM9DS0()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
init()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
update()205 void LSM9DS0::update()
206 {
207 updateGyroscope();
208 updateAccelerometer();
209 updateMagnetometer();
210 updateTemperature();
211 }
212
updateGyroscope()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
updateAccelerometer()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
updateMagnetometer()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
updateTemperature()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
readReg(DEVICE_T dev,uint8_t reg)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
readRegs(DEVICE_T dev,uint8_t reg,uint8_t * buffer,int len)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
writeReg(DEVICE_T dev,uint8_t reg,uint8_t val)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
setGyroscopePowerDown(bool enable)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
setGyroscopeEnableAxes(uint8_t axes)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
setGyroscopeODR(G_ODR_T odr)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
setGyroscopeScale(G_FS_T scale)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
setAccelerometerEnableAxes(uint8_t axes)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
setAccelerometerODR(XM_AODR_T odr)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
setAccelerometerScale(XM_AFS_T scale)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
setMagnetometerResolution(XM_RES_T res)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
setMagnetometerODR(XM_ODR_T odr)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
setMagnetometerMode(XM_MD_T mode)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
setMagnetometerLPM(bool enable)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
setMagnetometerScale(XM_MFS_T scale)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
getAccelerometer(float * x,float * y,float * z)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
getGyroscope(float * x,float * y,float * z)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
getMagnetometer(float * x,float * y,float * z)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
getAccelerometer()625 float *LSM9DS0::getAccelerometer()
626 {
627 float *v = new float[3];
628 getAccelerometer(&v[0], &v[1], &v[2]);
629 return v;
630 }
631
getGyroscope()632 float *LSM9DS0::getGyroscope()
633 {
634 float *v = new float[3];
635 getGyroscope(&v[0], &v[1], &v[2]);
636 return v;
637 }
638
getMagnetometer()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
getTemperature()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
enableTemperatureSensor(bool enable)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
getGyroscopeStatus()669 uint8_t LSM9DS0::getGyroscopeStatus()
670 {
671 return readReg(DEV_GYRO, REG_STATUS_REG_G);
672 }
673
getMagnetometerStatus()674 uint8_t LSM9DS0::getMagnetometerStatus()
675 {
676 return readReg(DEV_XM, REG_STATUS_REG_M);
677 }
678
getAccelerometerStatus()679 uint8_t LSM9DS0::getAccelerometerStatus()
680 {
681 return readReg(DEV_XM, REG_STATUS_REG_A);
682 }
683
getGyroscopeInterruptConfig()684 uint8_t LSM9DS0::getGyroscopeInterruptConfig()
685 {
686 return readReg(DEV_GYRO, REG_INT1_CFG_G);
687 }
688
setGyroscopeInterruptConfig(uint8_t enables)689 bool LSM9DS0::setGyroscopeInterruptConfig(uint8_t enables)
690 {
691 return writeReg(DEV_GYRO, REG_INT1_CFG_G, enables);
692 }
693
getGyroscopeInterruptSrc()694 uint8_t LSM9DS0::getGyroscopeInterruptSrc()
695 {
696 return readReg(DEV_GYRO, REG_INT1_SRC_G);
697 }
698
getMagnetometerInterruptControl()699 uint8_t LSM9DS0::getMagnetometerInterruptControl()
700 {
701 return readReg(DEV_XM, REG_INT_CTRL_REG_M);
702 }
703
setMagnetometerInterruptControl(uint8_t enables)704 bool LSM9DS0::setMagnetometerInterruptControl(uint8_t enables)
705 {
706 return writeReg(DEV_XM, REG_INT_CTRL_REG_M, enables);
707 }
708
getMagnetometerInterruptSrc()709 uint8_t LSM9DS0::getMagnetometerInterruptSrc()
710 {
711 return readReg(DEV_XM, REG_INT_SRC_REG_M);
712 }
713
getInterruptGen1()714 uint8_t LSM9DS0::getInterruptGen1()
715 {
716 return readReg(DEV_XM, REG_INT_GEN_1_REG);
717 }
718
setInterruptGen1(uint8_t enables)719 bool LSM9DS0::setInterruptGen1(uint8_t enables)
720 {
721 return writeReg(DEV_XM, REG_INT_GEN_1_REG, enables);
722 }
723
getInterruptGen1Src()724 uint8_t LSM9DS0::getInterruptGen1Src()
725 {
726 return readReg(DEV_XM, REG_INT_GEN_1_SRC);
727 }
728
getInterruptGen2()729 uint8_t LSM9DS0::getInterruptGen2()
730 {
731 return readReg(DEV_XM, REG_INT_GEN_2_REG);
732 }
733
setInterruptGen2(uint8_t enables)734 bool LSM9DS0::setInterruptGen2(uint8_t enables)
735 {
736 return writeReg(DEV_XM, REG_INT_GEN_2_REG, enables);
737 }
738
getInterruptGen2Src()739 uint8_t LSM9DS0::getInterruptGen2Src()
740 {
741 return readReg(DEV_XM, REG_INT_GEN_2_SRC);
742 }
743
744 #ifdef SWIGJAVA
installISR(INTERRUPT_PINS_T intr,int gpio,mraa::Edge level,IsrCallback * cb)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
installISR(INTERRUPT_PINS_T intr,int gpio,mraa::Edge level,void (* isr)(void *),void * arg)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
uninstallISR(INTERRUPT_PINS_T intr)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
getPin(INTERRUPT_PINS_T intr)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