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 #pragma once 25 26 #include <string> 27 #include <mraa/common.hpp> 28 #include <mraa/i2c.hpp> 29 30 #include <mraa/gpio.hpp> 31 32 #if defined(SWIGJAVA) || defined(JAVACALLBACK) 33 #include "../IsrCallback.h" 34 #endif 35 36 #define LSM9DS0_I2C_BUS 1 37 #define LSM9DS0_DEFAULT_XM_ADDR 0x1d 38 #define LSM9DS0_DEFAULT_GYRO_ADDR 0x6b 39 40 namespace upm { 41 42 /** 43 * @brief LSM9DS0 accelerometer library 44 * @defgroup lsm9ds0 libupm-lsm9ds0 45 * @ingroup i2c gpio accelerometer compass 46 */ 47 48 /** 49 * @library lsm9ds0 50 * @sensor lsm9ds0 51 * @comname LSM9DS0 3-axis Gyroscope, Accelerometer, and Magnetometer 52 * @type accelerometer compass 53 * @man sparkfun 54 * @con i2c gpio 55 * @web https://www.sparkfun.com/products/13033 56 * 57 * @brief API for the LSM9DS0 3-axis Gyroscope, Accelerometer, 58 * and Magnetometer 59 * 60 * The LSM9DS0 is a system-in-package featuring a 3D digital linear 61 * acceleration sensor, a 3D digital angular rate sensor, and a 3D 62 * digital magnetic sensor. 63 * 64 * The LSM9DS0 has a linear acceleration full scale of 65 * 2g/4g/6g/8g/16g, a magnetic field full scale of 2/4/8/12 66 * gauss and an angular rate of 245/500/2000 dps. 67 * 68 * While not all of the functionality of this device is supported 69 * initially, methods and register definitions are provided that 70 * should allow an end user to implement whatever features are 71 * required. 72 * 73 * This driver was developed on a Sparkfun 9DOF edison block. 74 * 75 * @snippet lsm9ds0.cxx Interesting 76 */ 77 78 class LSM9DS0 { 79 public: 80 81 // NOTE: reserved registers must not be written into or permanent 82 // damage to the device can result. Reserved bitfields must 83 // always be 0. 84 85 // There are two sub-devices within this device - the 86 // Accelerometer and Magnetometer (XM) and the Gyroscope (G), each 87 // with their own I2C address. 88 89 /** 90 * LSM9DS0 Gyroscope (G) registers 91 */ 92 typedef enum { 93 // 0x00-0x0e reserved 94 95 REG_WHO_AM_I_G = 0x0f, // should be 0xd4 96 97 // 0x10-0x1f reserved 98 99 REG_CTRL_REG1_G = 0x20, 100 REG_CTRL_REG2_G = 0x21, 101 REG_CTRL_REG3_G = 0x22, 102 REG_CTRL_REG4_G = 0x23, 103 REG_CTRL_REG5_G = 0x24, 104 105 REG_REFERENCE_G = 0x25, 106 107 // 0x26 reserved 108 109 REG_STATUS_REG_G = 0x27, 110 111 REG_OUT_X_L_G = 0x28, // gyro output, X axis, LSB 112 REG_OUT_X_H_G = 0x29, // gyro output, X axis, MSB 113 REG_OUT_Y_L_G = 0x2a, 114 REG_OUT_Y_H_G = 0x2b, 115 REG_OUT_Z_L_G = 0x2c, 116 REG_OUT_Z_H_G = 0x2d, 117 118 REG_FIFO_CTRL_REG_G = 0x2e, 119 REG_FIFO_SRC_REG_G = 0x2f, 120 121 REG_INT1_CFG_G = 0x30, 122 REG_INT1_SRC_G = 0x31, 123 124 REG_INT1_TSH_XH_G = 0x32, // interrupt threshold registers 125 REG_INT1_TSH_XL_G = 0x33, 126 REG_INT1_TSH_YH_G = 0x34, 127 REG_INT1_TSH_YL_G = 0x35, 128 REG_INT1_TSH_ZH_G = 0x36, 129 REG_INT1_TSH_ZL_G = 0x37, 130 131 // See fig 19 & 20 and preceeding description in the datasheet 132 // on how to use this register 133 REG_INT1_DURATION_G = 0x38 134 } REG_G_T; 135 136 /** 137 * Gyro CTRL_REG1_G bits 138 */ 139 typedef enum { 140 CTRL_REG1_G_YEN = 0x01, // Y enable, odd ordering... 141 CTRL_REG1_G_XEN = 0x02, 142 CTRL_REG1_G_ZEN = 0x04, 143 CTRL_REG1_G_PD = 0x08, // power down (0) 144 145 CTRL_REG1_G_BW0 = 0x10, // bandwidth 146 CTRL_REG1_G_BW1 = 0x20, 147 _CTRL_REG1_G_BW_MASK = 3, 148 _CTRL_REG1_G_BW_SHIFT = 4, 149 150 CTRL_REG1_G_DR0 = 0x40, // data rate 151 CTRL_REG1_G_DR1 = 0x80, 152 _CTRL_REG1_G_DR_MASK = 3, 153 _CTRL_REG1_G_DR_SHIFT = 6, 154 155 // The following are synthetic register and shift/mask 156 // definitions. Together both BW and DR setup the device for a 157 // specific output data rate (ODR) and cutoff frequency. These 158 // definitions allow us to use a more informative configuration 159 // for these 4 bits, rather than having the user go to the 160 // datasheet to figure out what to put for those values in order 161 // to get the desired ODR/cutoff. These are the values we will 162 // use in this driver. 163 164 CTRL_REG1_G_ODR0 = 0x10, // BW0 165 CTRL_REG1_G_ODR1 = 0x20, // BW1 166 CTRL_REG1_G_ODR2 = 0x40, // DR0 167 CTRL_REG1_G_ODR3 = 0x80, // DR1 168 _CTRL_REG1_G_ODR_MASK = 15, 169 _CTRL_REG1_G_ODR_SHIFT = 4 170 } CTRL_REG1_G_BITS_T; 171 172 /** 173 * CRTL_REG1_G_ODR values 174 */ 175 typedef enum { 176 G_ODR_95_12_5 = 0, // ODR = 95Hz, cutoff = 12.5 177 G_ODR_95_25 = 1, // ODR = 95Hz, cutoff = 25 178 // Other two (2 and 3) are the same (95_25) 179 180 G_ODR_190_12_5 = 4, 181 G_ODR_190_25 = 5, 182 G_ODR_190_50 = 6, 183 G_ODR_190_70 = 7, 184 185 G_ODR_380_20 = 8, 186 G_ODR_380_25 = 9, 187 G_ODR_380_50 = 10, 188 G_ODR_380_100 = 11, 189 190 G_ODR_760_30 = 12, 191 G_ODR_760_35 = 13, 192 G_ODR_760_50 = 14, 193 G_ODR_760_100 = 15 194 } G_ODR_T; 195 196 /** 197 * Gyro CTRL_REG2_G bits 198 */ 199 typedef enum { 200 CTRL_REG2_G_HPCF0 = 0x01, // high-pass cutoff freq 201 CTRL_REG2_G_HPCF1 = 0x02, 202 CTRL_REG2_G_HPCF2 = 0x04, 203 CTRL_REG2_G_HPCF3 = 0x08, 204 _CTRL_REG2_G_HPCF_MASK = 15, 205 _CTRL_REG2_G_HPCF_SHIFT = 0, 206 207 CTRL_REG2_G_HPM0 = 0x10, // high-pass filter mode 208 CTRL_REG2_G_HPM1 = 0x20, 209 _CTRL_REG2_G_HPM_MASK = 3, 210 _CTRL_REG2_G_HPM_SHIFT = 4, 211 212 // 0x40, 0x80 reserved 213 } CTRL_REG2_G_BITS_T; 214 215 /** 216 * CRTL_REG2_G_HPCF values 217 * 218 * See table 26 in the datasheet, as these depend on your data 219 * rate (ODR). We will label these according to the 95Hz column, 220 * but of course the actual cutoff frequency depends on ODR. 221 */ 222 typedef enum { 223 G_HPCF_7_2 = 0, // 7.2 Hz (if ODR is 95Hz) 224 G_HPCF_3_5 = 1, 225 G_HPCF_1_8 = 2, 226 G_HPCF_0_9 = 3, // 0.9Hz 227 G_HPCF_0_45 = 4, 228 G_HPCF_0_18 = 5, 229 G_HPCF_0_09 = 6, 230 G_HPCF_0_045 = 7, 231 G_HPCF_0_018 = 8, 232 G_HPCF_0_009 = 9 233 234 // 10-15 unused 235 } G_HPCF_T; 236 237 /** 238 * CRTL_REG2_G_HPM values 239 * 240 */ 241 typedef enum { 242 G_HPM_NORMAL_RESET_HPF = 0, // reset reading (HP_RESET_FILTER) 243 G_HPM_REFERENCE = 1, // REF signal for filtering 244 G_HPM_NORMAL = 2, // normal mode 245 G_HPM_AUTORESET_ON_INTR = 3 // autoreset in interrupt event 246 } G_HPM_T; 247 248 /** 249 * Gyro CTRL_REG3_G bits (interrupt G config) 250 */ 251 typedef enum { 252 CTRL_REG3_G_I2_EMPTY = 0x01, // FIFO empty on DRDY_G 253 CTRL_REG3_G_I2_ORUN = 0x02, // FIFO Overrun intr 254 CTRL_REG3_G_I2_WTM = 0x04, // FIFO watermark intr 255 CTRL_REG3_G_I2_DRDY = 0x08, // data ready on DRDY_G 256 CTRL_REG3_G_PP_OD = 0x10, // push-pull/open drain 257 CTRL_REG3_G_H_LACTIVE = 0x20, 258 CTRL_REG3_G_I1_BOOT = 0x40, 259 CTRL_REG3_G_I1_INT1 = 0x80, // intr enable on INT_G pin 260 } CTRL_REG3_G_BITS_T; 261 262 /** 263 * Gyro CTRL_REG4_G bits 264 */ 265 typedef enum { 266 CTRL_REG4_G_SIM = 0x01, // SPI mode selection 267 268 CTRL_REG4_G_ST0 = 0x02, // self test enables 269 CTRL_REG4_G_ST1 = 0x04, 270 _CTRL_REG4_G_ST_MASK = 3, 271 _CTRL_REG4_G_ST_SHIFT = 1, 272 273 // 0x08 reserved 274 275 CTRL_REG4_G_FS0 = 0x10, // full scale selection 276 CTRL_REG4_G_FS1 = 0x20, 277 _CTRL_REG4_G_FS_MASK = 3, 278 _CTRL_REG4_G_FS_SHIFT = 4, 279 280 CTRL_REG4_G_BLE = 0x40, // big/little endian data selection 281 CTRL_REG4_G_BDU = 0x80 // block data updates 282 } CTRL_REG4_G_BITS_T; 283 284 /** 285 * CRTL_REG4_G_ST values 286 * 287 */ 288 typedef enum { 289 G_ST_NORMAL = 0, // normal mode 290 G_ST_SELFTEST0 = 1, // x+, y-, z- 291 292 // 2, reserved 293 294 G_ST_SELFTEST1 = 3 // x-, y+, z+ 295 } G_ST_T; 296 297 /** 298 * CRTL_REG4_G_FS values 299 * 300 */ 301 typedef enum { 302 G_FS_245 = 0, // 245 deg/sec 303 G_FS_500 = 1, 304 G_FS_2000 = 2 305 // 3 is also 2000 306 } G_FS_T; 307 308 /** 309 * Gyro CTRL_REG5_G bits 310 */ 311 typedef enum { 312 CTRL_REG5_G_OUTSEL0 = 0x01, // see fig. 18 in the datasheet 313 CTRL_REG5_G_OUTSEL1 = 0x02, 314 _CTRL_REG5_G_OUTSEL_MASK = 3, 315 _CTRL_REG5_G_OUTSEL_SHIFT = 0, 316 317 CTRL_REG5_G_INT1SEL0 = 0x04, // see fig. 18 in the datasheet 318 CTRL_REG5_G_INT1SEL1 = 0x08, 319 _CTRL_REG5_G_INT1SEL_MASK = 3, 320 _CTRL_REG5_G_INT1SEL_SHIFT = 2, 321 322 CTRL_REG5_G_HPEN = 0x10, // HPF enable 323 324 // 0x20 reserved 325 326 CTRL_REG5_G_FIFO_EN = 0x40, 327 CTRL_REG5_G_BOOT = 0x80 // reboot memory content 328 } CTRL_REG5_G_BITS_T; 329 330 331 /** 332 * CRTL_REG5_G_OUTSEL and INT1SEL values. See Figure 18 in the 333 * datasheet. 334 */ 335 typedef enum { 336 G_INT1OUTSEL_0 = 0, 337 G_INT1OUTSEL_1 = 1, 338 G_INT1OUTSEL_2 = 2, 339 G_INT1OUTSEL_3 = 3 340 } G_INT1OUTSEL_T; 341 342 /** 343 * Gyro STATUS_REG_G bits 344 */ 345 typedef enum { 346 STATUS_REG_G_XDA = 0x01, // X axis data available 347 STATUS_REG_G_YDA = 0x02, 348 STATUS_REG_G_ZDA = 0x04, 349 STATUS_REG_G_ZYXDA = 0x08, // X, Y, and Z data available 350 351 STATUS_REG_G_XOR = 0x10, // X data overrun 352 STATUS_REG_G_YOR = 0x20, 353 STATUS_REG_G_ZOR = 0x40, 354 STATUS_REG_G_ZYXOR = 0x80 355 } STATUS_REG_G_BITS_T; 356 357 /** 358 * Gyro FIFO_CTRL_REG_G bits 359 */ 360 typedef enum { 361 FIFO_CTRL_REG_G_WTM0 = 0x01, // FIFO watermark 362 FIFO_CTRL_REG_G_WTM1 = 0x02, 363 FIFO_CTRL_REG_G_WTM2 = 0x04, 364 FIFO_CTRL_REG_G_WTM3 = 0x08, 365 FIFO_CTRL_REG_G_WTM4 = 0x10, 366 _FIFO_CTRL_REG_G_WTM_MASK = 31, 367 _FIFO_CTRL_REG_G_WTM_SHIFT = 0, 368 369 FIFO_CTRL_REG_G_FM0 = 0x20, // FIFO mode config 370 FIFO_CTRL_REG_G_FM1 = 0x40, 371 FIFO_CTRL_REG_G_FM2 = 0x80, 372 _FIFO_CTRL_REG_G_FM_MASK = 7, 373 _FIFO_CTRL_REG_G_FM_SHIFT = 5, 374 } FIFO_CTRL_REG_G_T; 375 376 // FIFO_CTRL_REG_G_WTM (FIFO watermark) is just a numeric value 377 // between 0-31, so we won't enumerate those values. 378 379 /** 380 * FIFO_CTRL_REG_G_FM values (FIFO Modes) 381 * 382 */ 383 typedef enum { 384 G_FM_BYPASS = 0, 385 G_FM_FIFO = 1, 386 G_FM_STREAM = 2, 387 G_FM_STREAM2FIFO = 3, 388 G_FM_BYPASS2STREAM = 4 389 390 // 5-7 unused 391 } G_FM_T; 392 393 /** 394 * FIFO_SRC_REG_G bits 395 * 396 */ 397 typedef enum { 398 FIFO_CTRL_REG_G_FSS0 = 0x01, // FIFO stored data level 399 FIFO_CTRL_REG_G_FSS1 = 0x02, 400 FIFO_CTRL_REG_G_FSS2 = 0x04, 401 FIFO_CTRL_REG_G_FSS3 = 0x08, 402 FIFO_CTRL_REG_G_FSS4 = 0x10, 403 _FIFO_CTRL_REG_G_FSS_MASK = 31, 404 _FIFO_CTRL_REG_G_FSS_SHIFT = 0, 405 406 FIFO_CTRL_REG_G_EMPTY = 0x20, // FIFO empty 407 FIFO_CTRL_REG_G_OVRN = 0x40, // FIFO overrun 408 FIFO_CTRL_REG_G_WTM = 0x80 // watermark status 409 } FIFO_SRC_REG_G_BITS_T; 410 411 /** 412 * INT1_CFG_G bits 413 * 414 */ 415 typedef enum { 416 INT1_CFG_G_XLIE = 0x01, // X Low event interrupt enable 417 INT1_CFG_G_XHIE = 0x02, // X High event interrupt enable 418 INT1_CFG_G_YLIE = 0x04, 419 INT1_CFG_G_YHIE = 0x08, 420 INT1_CFG_G_ZLIE = 0x10, 421 INT1_CFG_G_ZHIE = 0x20, 422 423 INT1_CFG_G_LIR = 0x40, // latch interrupt request 424 INT1_CFG_G_ANDOR = 0x80 // OR or AND interrupt events 425 } INT1_CFG_G_BITS_T; 426 427 /** 428 * INT1_SRC_G bits 429 * 430 */ 431 typedef enum { 432 INT1_SRC_G_XL = 0x01, // X low interrupt 433 INT1_SRC_G_XH = 0x02, // X high interrupt 434 INT1_SRC_G_YL = 0x04, 435 INT1_SRC_G_YH = 0x08, 436 INT1_SRC_G_ZL = 0x10, 437 INT1_SRC_G_ZH = 0x20, 438 439 INT1_SRC_G_IA = 0x40 // interrupt active 440 441 // 0x80 reserved 442 } INT1_SRC_G_BITS_T; 443 444 // The following registers are for the Accelerometer (A/X), 445 // Magnetometer (M), and Temperature device. 446 447 /** 448 * LSM9DS0 Accelerometer (X) and Magnetometer (M) registers 449 */ 450 typedef enum { 451 // 0x00-0x04 reserved 452 453 REG_OUT_TEMP_L_XM = 0x05, // temperature 454 REG_OUT_TEMP_H_XM = 0x06, 455 456 REG_STATUS_REG_M = 0x07, 457 458 REG_OUT_X_L_M = 0x08, // magnetometer outputs 459 REG_OUT_X_H_M = 0x09, 460 REG_OUT_Y_L_M = 0x0a, 461 REG_OUT_Y_H_M = 0x0b, 462 REG_OUT_Z_L_M = 0x0c, 463 REG_OUT_Z_H_M = 0x0d, 464 465 // 0x0e reserved 466 467 REG_WHO_AM_I_XM = 0x0f, 468 469 // 0x10, 0x11 reserved 470 471 REG_INT_CTRL_REG_M = 0x12, 472 REG_INT_SRC_REG_M = 0x13, 473 474 REG_INT_THS_L_M = 0x14, // magnetometer threshold 475 REG_INT_THS_H_M = 0x15, 476 477 REG_OFFSET_X_L_M = 0x16, 478 REG_OFFSET_X_H_M = 0x17, 479 REG_OFFSET_Y_L_M = 0x18, 480 REG_OFFSET_Y_H_M = 0x19, 481 REG_OFFSET_Z_L_M = 0x1a, 482 REG_OFFSET_Z_H_M = 0x1b, 483 484 REG_REFERENCE_X = 0x1c, 485 REG_REFERENCE_Y = 0x1d, 486 REG_REFERENCE_Z = 0x1e, 487 488 REG_CTRL_REG0_XM = 0x1f, 489 REG_CTRL_REG1_XM = 0x20, 490 REG_CTRL_REG2_XM = 0x21, 491 REG_CTRL_REG3_XM = 0x22, 492 REG_CTRL_REG4_XM = 0x23, 493 REG_CTRL_REG5_XM = 0x24, 494 REG_CTRL_REG6_XM = 0x25, 495 REG_CTRL_REG7_XM = 0x26, 496 497 REG_STATUS_REG_A = 0x27, 498 499 REG_OUT_X_L_A = 0x28, // accelerometer outputs 500 REG_OUT_X_H_A = 0x29, 501 REG_OUT_Y_L_A = 0x2a, 502 REG_OUT_Y_H_A = 0x2b, 503 REG_OUT_Z_L_A = 0x2c, 504 REG_OUT_Z_H_A = 0x2d, 505 506 REG_FIFO_CTRL_REG = 0x2e, 507 REG_FIFO_SRC_REG = 0x2f, 508 509 REG_INT_GEN_1_REG = 0x30, 510 REG_INT_GEN_1_SRC = 0x31, 511 REG_INT_GEN_1_THS = 0x32, 512 REG_INT_GEN_1_DURATION = 0x33, 513 514 REG_INT_GEN_2_REG = 0x34, 515 REG_INT_GEN_2_SRC = 0x35, 516 REG_INT_GEN_2_THS = 0x36, 517 REG_INT_GEN_2_DURATION = 0x37, 518 519 REG_CLICK_CFG = 0x38, 520 REG_CLICK_SRC = 0x39, 521 REG_CLICK_THS = 0x3a, 522 523 REG_TIME_LIMIT = 0x3b, 524 REG_TIME_LATENCY = 0x3c, 525 REG_TIME_WINDOW = 0x3d, 526 527 REG_ACT_THS = 0x3e, 528 REG_ACT_DUR = 0x3f 529 } REG_XM_T; 530 531 /** 532 * XM STATUS_REG_M bits 533 */ 534 typedef enum { 535 STATUS_REG_M_XMDA = 0x01, // X mag axis data available 536 STATUS_REG_M_YMDA = 0x02, 537 STATUS_REG_M_ZMDA = 0x04, 538 STATUS_REG_M_ZYXMDA = 0x08, // X, Y, and Z mag data available 539 540 STATUS_REG_M_XMOR = 0x10, // X mag data overrun 541 STATUS_REG_M_YMOR = 0x20, 542 STATUS_REG_M_ZMOR = 0x40, 543 STATUS_REG_M_ZYXMOR = 0x80 544 } STATUS_REG_M_BITS_T; 545 546 /** 547 * INT_CTRL_REG_M bits 548 */ 549 typedef enum { 550 INT_CTRL_REG_M_MIEN = 0x01, // mag interrupt enable 551 INT_CTRL_REG_M_4D = 0x02, 552 INT_CTRL_REG_M_IEL = 0x04, // latch intr request 553 INT_CTRL_REG_M_IEA = 0x08, 554 INT_CTRL_REG_M_PP_OD = 0x10, // push-pull/open drian 555 INT_CTRL_REG_M_ZMIEN = 0x20, // Z mag axis interrupt recognition 556 INT_CTRL_REG_M_YMIEN = 0x40, 557 INT_CTRL_REG_M_XMIEN = 0x80 558 } INT_CTRL_REG_M_BITS_T; 559 560 /** 561 * INT_SRC_REG_M bits 562 */ 563 typedef enum { 564 INT_SRC_REG_M_MINT = 0x01, 565 INT_SRC_REG_M_MROI = 0x02, 566 INT_SRC_REG_M_NTH_Z = 0x04, 567 INT_SRC_REG_M_NTH_Y = 0x08, 568 INT_SRC_REG_M_NTH_X = 0x10, 569 INT_SRC_REG_M_PTH_Z = 0x20, 570 INT_SRC_REG_M_PTH_Y = 0x40, 571 INT_SRC_REG_M_PTH_X = 0x80 572 } INT_SRC_REG_M_BITS_T; 573 574 575 /** 576 * CTRL_REG0_XM bits 577 */ 578 typedef enum { 579 CTRL_REG0_XM_HPIS2 = 0x01, // HPF enable for int generator 2 580 CTRL_REG0_XM_HPIS1 = 0x02, 581 582 CTRL_REG0_XM_HP_CLICK = 0x04, // HPF enable for click 583 584 // 0x08,0x10 reserved 585 586 CTRL_REG0_XM_WTM_LEN = 0x20, // watermark enable 587 CTRL_REG0_XM_FIFO_EN = 0x40, // FIFO enable 588 CTRL_REG0_XM_BOOT = 0x80 // reboot memory content 589 } CTRL_REG0_XM_BITS_T; 590 591 /** 592 * CTRL_REG1_XM bits 593 */ 594 typedef enum { 595 CTRL_REG1_XM_AXEN = 0x01, // accelerometer x axis enable 596 CTRL_REG1_XM_AYEN = 0x02, 597 CTRL_REG1_XM_AZEN = 0x03, 598 599 CTRL_REG1_XM_BDU = 0x04, // block data update 600 601 CTRL_REG1_XM_AODR0 = 0x10, // accelerometer output data rate 602 CTRL_REG1_XM_AODR1 = 0x20, 603 CTRL_REG1_XM_AODR2 = 0x40, 604 CTRL_REG1_XM_AODR3 = 0x80, 605 _CTRL_REG1_XM_AODR_MASK = 15, 606 _CTRL_REG1_XM_AODR_SHIFT = 4 607 } CTRL_REG1_XM_BITS_T; 608 609 /** 610 * CTRL_REG1_XM_AODR values 611 */ 612 typedef enum { 613 XM_AODR_PWRDWN = 0, // power down mode 614 XM_AODR_3_125 = 1, // 3.125 Hz 615 XM_AODR_6_25 = 2, 616 XM_AODR_12_5 = 3, 617 XM_AODR_25 = 4, // 25Hz 618 XM_AODR_50 = 5, 619 XM_AODR_100 = 6, 620 XM_AODR_200 = 7, 621 XM_AODR_400 = 8, 622 XM_AODR_800 = 9, 623 XM_AODR_1000 = 10 624 // 11-15 unused 625 } XM_AODR_T; 626 627 /** 628 * CTRL_REG2_XM bits 629 */ 630 typedef enum { 631 CTRL_REG2_XM_SIM = 0x01, 632 633 CTRL_REG2_XM_AST0 = 0x02, // accel self-test enable 634 CTRL_REG2_XM_AST1 = 0x04, 635 _CTRL_REG2_XM_AST_MASK = 3, 636 _CTRL_REG2_XM_AST_SHIFT = 1, 637 638 CTRL_REG2_XM_AFS0 = 0x08, // accel full scale 639 CTRL_REG2_XM_AFS1 = 0x10, 640 CTRL_REG2_XM_AFS2 = 0x20, 641 _CTRL_REG2_XM_AFS_MASK = 7, 642 _CTRL_REG2_XM_AFS_SHIFT = 3, 643 644 CTRL_REG2_XM_ABW0 = 0x40, // accel anti-alias filter bandwidth 645 CTRL_REG2_XM_ABW1 = 0x80, 646 _CTRL_REG2_XM_ABW_MASK = 3, 647 _CTRL_REG2_XM_ABW_SHIFT = 6 648 } CTRL_REG2_XM_BITS_T; 649 650 /** 651 * CTRL_REG2_XM_AST values 652 */ 653 typedef enum { 654 XM_AST_NORMAL = 0, 655 XM_AST_POS_SIGN = 1, 656 XM_AST_NEG_SIGN = 2 657 // 3 not allowed 658 } XM_AST_T; 659 660 /** 661 * CTRL_REG2_XM_AFS (accel full scale) values 662 */ 663 typedef enum { 664 XM_AFS_2 = 0, // 2g 665 XM_AFS_4 = 1, 666 XM_AFS_6 = 2, 667 XM_AFS_8 = 3, 668 XM_AFS_16 = 4 669 670 // 5-7 not used 671 } XM_AFS_T; 672 673 /** 674 * CTRL_REG2_XM_ABW (accel anti-alias filter bandwidth) values 675 */ 676 typedef enum { 677 XM_ABW_773 = 0, // 773Hz 678 XM_ABW_194 = 1, // these two might be inverted (typo in ds) 679 XM_ABW_362 = 2, 680 XM_ABW_50 = 3 681 } XM_ABW_T; 682 683 /** 684 * CTRL_REG3_XM bits 685 */ 686 typedef enum { 687 CTRL_REG3_XM_P1_EMPTY = 0x01, // INT1_XM pin enables 688 CTRL_REG3_XM_P1_DRDYM = 0x02, 689 CTRL_REG3_XM_P1_DRDYA = 0x04, 690 CTRL_REG3_XM_P1_INTM = 0x08, 691 CTRL_REG3_XM_P1_INT2 = 0x10, 692 CTRL_REG3_XM_P1_INT1 = 0x20, 693 CTRL_REG3_XM_P1_TAP = 0x40, 694 CTRL_REG3_XM_P1_BOOT = 0x80 695 } CTRL_REG3_XM_BITS_T; 696 697 /** 698 * CTRL_REG4_XM bits 699 */ 700 typedef enum { 701 CTRL_REG4_XM_P2_WTM = 0x01, // INT2_XM pin enables 702 CTRL_REG4_XM_P2_OVERRUN = 0x02, 703 CTRL_REG4_XM_P2_DRDYM = 0x04, 704 CTRL_REG4_XM_P2_DRDYA = 0x08, 705 CTRL_REG4_XM_P2_INTM = 0x10, 706 CTRL_REG4_XM_P2_INT2 = 0x20, 707 CTRL_REG4_XM_P2_INT1 = 0x40, 708 CTRL_REG4_XM_P2_TAP = 0x80 709 } CTRL_REG4_XM_BITS_T; 710 711 /** 712 * CTRL_REG5_XM bits 713 */ 714 typedef enum { 715 CTRL_REG5_XM_LIR1 = 0x01, // latch intr 1 716 CTRL_REG5_XM_LIR2 = 0x02, // latch intr 2 717 718 CTRL_REG5_XM_ODR0 = 0x04, // mag output data rate 719 CTRL_REG5_XM_ODR1 = 0x08, 720 CTRL_REG5_XM_ODR2 = 0x10, 721 _CTRL_REG5_XM_ODR_MASK = 7, 722 _CTRL_REG5_XM_ODR_SHIFT = 2, 723 724 CTRL_REG5_XM_RES0 = 0x20, // mag resolution 725 CTRL_REG5_XM_RES1 = 0x40, 726 _CTRL_REG5_XM_RES_MASK = 3, 727 _CTRL_REG5_XM_RES_SHIFT = 5, 728 729 CTRL_REG5_XM_TEMP_EN = 0x80 // temp sensor enable 730 } CTRL_REG5_XM_BITS_T; 731 732 /** 733 * CTRL_REG5_XM_ODR (magnetometer output data rate) values 734 */ 735 typedef enum { 736 XM_ODR_3_125 = 0, // 3.125Hz 737 XM_ODR_6_25 = 1, 738 XM_ODR_12_5 = 2, 739 XM_ODR_25 = 3, 740 XM_ODR_50 = 4, 741 XM_ODR_100 = 5 742 743 // 6, 7 reserved 744 } XM_ODR_T; 745 746 /** 747 * CTRL_REG5_XM_RES (magnetometer resolution) values 748 */ 749 typedef enum { 750 XM_RES_LOW = 0, // low resolution 751 752 // 1, 2 reserved 753 754 XM_RES_HIGH = 3, 755 } XM_RES_T; 756 757 /** 758 * CTRL_REG6_XM bits 759 */ 760 typedef enum { 761 // 0x01-0x10 reserved 762 763 CTRL_REG6_XM_MFS0 = 0x20, 764 CTRL_REG6_XM_MFS1 = 0x40, 765 _CTRL_REG6_XM_MFS_MASK = 3, 766 _CTRL_REG6_XM_MFS_SHIFT = 5 767 768 // 0x80 reserved 769 } CTRL_REG6_XM_BITS_T; 770 771 /** 772 * CTRL_REG6_XM_MFS (magnetometer full scale) values 773 */ 774 typedef enum { 775 XM_MFS_2 = 0, // +/- 2 gauss 776 XM_MFS_4 = 1, 777 XM_MFS_8 = 2, 778 XM_MFS_12 = 3 779 } XM_MFS_T; 780 781 /** 782 * CTRL_REG7_XM bits 783 */ 784 typedef enum { 785 CTRL_REG7_XM_MD0 = 0x01, // mag sensor mode 786 CTRL_REG7_XM_MD1 = 0x02, 787 _CTRL_REG7_XM_MD_MASK = 3, 788 _CTRL_REG7_XM_MD_SHIFT = 0, 789 790 CTRL_REG7_XM_MLP = 0x04, // mag low power mode 791 792 // 0x08, 0x10 reserved 793 794 CTRL_REG7_XM_AFDS = 0x20, // filtered acceleration data 795 796 CTRL_REG7_XM_AHPM0 = 0x40, // accel HPF selection 797 CTRL_REG7_XM_AHPM1 = 0x80, 798 _CTRL_REG7_XM_AHPM_MASK = 3, 799 _CTRL_REG7_XM_AHPM_SHIFT = 6 800 } CTRL_REG7_XM_BITS_T; 801 802 /** 803 * CTRL_REG7_XM_MD (magnetometer sensor mode) values 804 */ 805 typedef enum { 806 XM_MD_CONTINUOUS = 0, // continuous conversion 807 XM_MD_SINGLE = 1, // single conversion 808 XM_MD_POWERDOWN = 2 // power down mode 809 // 3 is also power down mode, for some odd reason 810 } XM_MD_T; 811 812 /** 813 * CTRL_REG7_AHPM_MD (accel high-pass filter mode) values 814 */ 815 typedef enum { 816 // XM_AHPM_NORMAL_REF: Normal mode (resets x, y and z-axis 817 // reading REFERENCE_X (1Ch), REFERENCE_Y (1Dh) and REFERENCE_Y 818 // (1Dh) registers respectively) 819 820 XM_AHPM_NORMAL_REF = 0, 821 XM_AHPM_REFERENCE = 1, 822 XM_AHPM_NORMAL = 2, 823 XM_AHPM_AUTORESET = 3 // autoreset on interrupt 824 } XM_AHPM_T; 825 826 /** 827 * XM STATUS_REG_A bits 828 */ 829 typedef enum { 830 STATUS_REG_A_XADA = 0x01, // X accel axis data available 831 STATUS_REG_A_YADA = 0x02, 832 STATUS_REG_A_ZADA = 0x04, 833 STATUS_REG_A_ZYXADA = 0x08, // X, Y, and Z accel data available 834 835 STATUS_REG_A_XAOR = 0x10, // X accel data overrun 836 STATUS_REG_A_YAOR = 0x20, 837 STATUS_REG_A_ZAOR = 0x40, 838 STATUS_REG_A_ZYXAOR = 0x80 839 } STATUS_REG_A_BITS_T; 840 841 /** 842 * XM FIFO_CTRL_REG bits 843 */ 844 typedef enum { 845 FIFO_CTRL_REG_FTH0 = 0x01, // FIFO watermark/threshold 846 FIFO_CTRL_REG_FTH1 = 0x02, 847 FIFO_CTRL_REG_FTH2 = 0x04, 848 FIFO_CTRL_REG_FTH3 = 0x08, 849 FIFO_CTRL_REG_FTH4 = 0x10, 850 _FIFO_CTRL_REG_FTH_MASK = 31, 851 _FIFO_CTRL_REG_FTH_SHIFT = 0, 852 853 FIFO_CTRL_REG_FM0 = 0x20, // FIFO mode config 854 FIFO_CTRL_REG_FM1 = 0x40, 855 FIFO_CTRL_REG_FM2 = 0x80, 856 _FIFO_CTRL_REG_FM_MASK = 7, 857 _FIFO_CTRL_REG_FM_SHIFT = 5, 858 } FIFO_CTRL_REG_T; 859 860 // FIFO_CTRL_REG_FTH (FIFO watermark/threshold) is just a numeric 861 // value between 0-31, so we won't enumerate those values. 862 863 /** 864 * XM FIFO_CTRL_REG_FM values (FIFO Modes) 865 * 866 */ 867 typedef enum { 868 FM_BYPASS = 0, 869 FM_FIFO = 1, 870 FM_STREAM = 2, 871 FM_STREAM2FIFO = 3, 872 FM_BYPASS2STREAM = 4 873 874 // 5-7 unused 875 } FM_T; 876 877 /** 878 * FIFO_SRC_REG bits 879 * 880 */ 881 typedef enum { 882 FIFO_CTRL_REG_FSS0 = 0x01, // FIFO stored data level 883 FIFO_CTRL_REG_FSS1 = 0x02, 884 FIFO_CTRL_REG_FSS2 = 0x04, 885 FIFO_CTRL_REG_FSS3 = 0x08, 886 FIFO_CTRL_REG_FSS4 = 0x10, 887 _FIFO_CTRL_REG_FSS_MASK = 31, 888 _FIFO_CTRL_REG_FSS_SHIFT = 0, 889 890 FIFO_CTRL_REG_EMPTY = 0x20, // FIFO empty 891 FIFO_CTRL_REG_OVRN = 0x40, // FIFO overrun 892 FIFO_CTRL_REG_WTM = 0x80 // watermark status 893 } FIFO_SRC_REG_BITS_T; 894 895 /** 896 * INT_GEN_1_REG and INT_GEN_2_REG (GEN_X) bits 897 * 898 */ 899 typedef enum { 900 INT_GEN_X_REG_XLIE_XDOWNE = 0x01, // enable intr on X low or dir recog 901 INT_GEN_X_REG_XHIE_XUPE = 0x02, 902 INT_GEN_X_REG_YLIE_YDOWNE = 0x04, 903 INT_GEN_X_REG_YHIE_YUPE = 0x08, 904 INT_GEN_X_REG_ZLIE_ZDOWNE = 0x10, 905 INT_GEN_X_REG_ZHIE_ZUPE = 0x20, 906 INT_GEN_X_REG_6D = 0x40, // enable 6D direction function 907 INT_GEN_X_REG_AOI = 0x80 // AND/OR combination of intrs 908 } INT_GEN_X_REG_BITS_T; 909 910 /** 911 * INT_GEN_1_SRC and INT_GEN_2_SRC (GEN_X) bits 912 * 913 */ 914 typedef enum { 915 INT_GEN_X_SRC_XL = 0x01, 916 INT_GEN_X_SRC_XH = 0x02, 917 INT_GEN_X_SRC_YL = 0x04, 918 INT_GEN_X_SRC_YH = 0x08, 919 INT_GEN_X_SRC_ZL = 0x10, 920 INT_GEN_X_SRC_ZH = 0x20, 921 INT_GEN_X_SRC_IA = 0x40 922 // 0x80 reserved 923 } INT_GEN_X_SRC_BITS_T; 924 925 /** 926 * INT_GEN_1_THS and INT_GEN_2_THS (GEN_X) bits 927 * 928 */ 929 typedef enum { 930 INT_GEN_X_THS0 = 0x01, // interrupt threshold 931 INT_GEN_X_THS1 = 0x02, 932 INT_GEN_X_THS2 = 0x04, 933 INT_GEN_X_THS3 = 0x08, 934 INT_GEN_X_THS4 = 0x10, 935 INT_GEN_X_THS5 = 0x20, 936 INT_GEN_X_THS6 = 0x40, 937 _INT_GEN_X_THS_MASK = 127, 938 _INT_GEN_X_THS_SHIFT = 0 939 // 0x80 reserved 940 } INT_GEN_X_THS_BITS_T; 941 942 /** 943 * INT_GEN_1_DUR and INT_GEN_2_DUR (GEN_X) bits 944 * 945 */ 946 typedef enum { 947 INT_GEN_X_DUR0 = 0x01, // interrupt duration 948 INT_GEN_X_DUR1 = 0x02, 949 INT_GEN_X_DUR2 = 0x04, 950 INT_GEN_X_DUR3 = 0x08, 951 INT_GEN_X_DUR4 = 0x10, 952 INT_GEN_X_DUR5 = 0x20, 953 INT_GEN_X_DUR6 = 0x40, 954 _INT_GEN_X_DUR_MASK = 127, 955 _INT_GEN_X_DUR_SHIFT = 0 956 // 0x80 reserved 957 } INT_GEN_X_DUR_BITS_T; 958 959 /** 960 * CLICK_CONFIG bits 961 * 962 */ 963 typedef enum { 964 CLICK_CONFIG_XS = 0x01, // enable intr single click x 965 CLICK_CONFIG_XD = 0x02, // enable intr double click x 966 CLICK_CONFIG_YS = 0x04, 967 CLICK_CONFIG_YD = 0x08, 968 CLICK_CONFIG_ZS = 0x10, 969 CLICK_CONFIG_ZD = 0x20 970 // 0x40, 0x80 reserved 971 } CLICK_CONFIG_BITS_T; 972 973 /** 974 * CLICK_SRC bits 975 * 976 */ 977 typedef enum { 978 CLICK_SRC_X = 0x01, 979 CLICK_SRC_Y = 0x02, 980 CLICK_SRC_Z = 0x04, 981 CLICK_SRC_SIGN = 0x08, 982 CLICK_SRC_SCLICK = 0x10, 983 CLICK_SRC_DCLICK = 0x20, 984 CLICK_SRC_IA = 0x40 985 // 0x80 reserved 986 } CLICK_SRC_BITS_T; 987 988 /** 989 * CLICK_THS bits 990 * 991 */ 992 typedef enum { 993 CLICK_THS_THS0 = 0x01, // click threshold 994 CLICK_THS_THS1 = 0x02, 995 CLICK_THS_THS2 = 0x04, 996 CLICK_THS_THS3 = 0x08, 997 CLICK_THS_THS4 = 0x10, 998 CLICK_THS_THS5 = 0x20, 999 CLICK_THS_THS6 = 0x40, 1000 _CLICK_THS_THS_MASK = 127, 1001 _CLICK_THS_THS_SHIFT = 0 1002 // 0x80 reserved 1003 } CLICK_THS_BITS_T; 1004 1005 /** 1006 * CLICK_TIME_LIMIT bits 1007 * 1008 */ 1009 typedef enum { 1010 CLICK_TIME_LIMIT_TLI0 = 0x01, 1011 CLICK_TIME_LIMIT_TLI1 = 0x02, 1012 CLICK_TIME_LIMIT_TLI2 = 0x04, 1013 CLICK_TIME_LIMIT_TLI3 = 0x08, 1014 CLICK_TIME_LIMIT_TLI4 = 0x10, 1015 CLICK_TIME_LIMIT_TLI5 = 0x20, 1016 CLICK_TIME_LIMIT_TLI6 = 0x40, 1017 _CLICK_TIME_LIMIT_TLI_MASK = 127, 1018 _CLICK_TIME_LIMIT_TLI_SHIFT = 0 1019 // 0x80 reserved 1020 } CLICK_TIME_LIMIT_BITS_T; 1021 1022 /** 1023 * ACT_THS (sleep-to-wake/return-to-sleep activation threshold) bits 1024 * 1025 */ 1026 typedef enum { 1027 ACT_THS_ACTH0 = 0x01, // 1 LSb = 16mg (?) 1028 ACT_THS_ACTH1 = 0x02, 1029 ACT_THS_ACTH2 = 0x04, 1030 ACT_THS_ACTH3 = 0x08, 1031 ACT_THS_ACTH4 = 0x10, 1032 ACT_THS_ACTH5 = 0x20, 1033 ACT_THS_ACTH6 = 0x40, 1034 _ACT_THS_ACTH_MASK = 127, 1035 _ACT_THS_ACTH_SHIFT = 0 1036 // 0x80 reserved 1037 } ACT_THS_BITS_T; 1038 1039 // Driver specific enumerations 1040 1041 // device enums for read/write regs 1042 typedef enum { 1043 DEV_GYRO, 1044 DEV_XM 1045 } DEVICE_T; 1046 1047 // interrupt selection for installISR() and uninstallISR() 1048 typedef enum { 1049 INTERRUPT_G_INT, // gyroscope interrupt 1050 INTERRUPT_G_DRDY, // gyroscope data ready interrupt 1051 INTERRUPT_XM_GEN1, // XM interrupt generator 1 1052 INTERRUPT_XM_GEN2 // XM interrupt generator 2 1053 } INTERRUPT_PINS_T; 1054 1055 1056 /** 1057 * lsm9ds0 constructor 1058 * 1059 * @param bus i2c bus to use 1060 * @param address the address for this device 1061 */ 1062 LSM9DS0(int bus=LSM9DS0_I2C_BUS, 1063 uint8_t gAddress=LSM9DS0_DEFAULT_GYRO_ADDR, 1064 uint8_t xmAddress=LSM9DS0_DEFAULT_XM_ADDR); 1065 1066 /** 1067 * LSM9DS0 Destructor 1068 */ 1069 ~LSM9DS0(); 1070 1071 /** 1072 * set up initial values and start operation 1073 * 1074 * @return true if successful 1075 */ 1076 bool init(); 1077 1078 /** 1079 * update the accelerometer, gyroscope, magnetometer and 1080 * termperature values. 1081 */ 1082 void update(); 1083 1084 /** 1085 * update the gyroscope values only 1086 */ 1087 void updateGyroscope(); 1088 1089 /** 1090 * update the accelerometer values only 1091 */ 1092 void updateAccelerometer(); 1093 1094 /** 1095 * update the magnetometer values only 1096 */ 1097 void updateMagnetometer(); 1098 1099 /** 1100 * update the temperature value only 1101 */ 1102 void updateTemperature(); 1103 1104 /** 1105 * read a register 1106 * 1107 * @param dev the device to access (XM or G) 1108 * @param reg the register to read 1109 * @return the value of the register 1110 */ 1111 uint8_t readReg(DEVICE_T dev, uint8_t reg); 1112 1113 /** 1114 * read contiguous register into a buffer 1115 * 1116 * @param dev the device to access (XM or G) 1117 * @param reg the register to start reading at 1118 * @param buf the buffer to store the results 1119 * @param len the number of registers to read 1120 * @return the value of the register 1121 */ 1122 void readRegs(DEVICE_T dev, uint8_t reg, uint8_t *buffer, int len); 1123 1124 /** 1125 * write to a register 1126 * 1127 * @param dev the device to access (XM or G) 1128 * @param reg the register to write to 1129 * @param val the value to write 1130 * @return true if successful, false otherwise 1131 */ 1132 bool writeReg(DEVICE_T dev, uint8_t reg, uint8_t val); 1133 1134 /** 1135 * enable or disable the gyro power down mode 1136 * 1137 * @param enable true to put device to sleep, false to wake up 1138 * @return true if successful, false otherwise 1139 */ 1140 bool setGyroscopePowerDown(bool enable); 1141 1142 /** 1143 * enable or disable gyroscope axes. If all axis are disabled, 1144 * and powerdown mode is not set, then the gyro goes into sleep 1145 * mode. 1146 * 1147 * @param axes bit mask of valid axes, (CTRL_REG1_G_YEN, ...) 1148 * @return true if successful, false otherwise 1149 */ 1150 bool setGyroscopeEnableAxes(uint8_t axes); 1151 1152 /** 1153 * set the gyroscope Output Data Rate (ODR) 1154 * 1155 * @param odr one of the G_ODR_T values 1156 * @return true if successful, false otherwise 1157 */ 1158 bool setGyroscopeODR(G_ODR_T odr); 1159 1160 /** 1161 * set the scaling mode of the gyroscope 1162 * 1163 * @param scale one of the G_FS_T values 1164 * @return true if successful, false otherwise 1165 */ 1166 bool setGyroscopeScale(G_FS_T scale); 1167 1168 /** 1169 * enable or disable accelerometer axes. 1170 * 1171 * @param axes bit mask of valid axes, (CTRL_REG1_XM_AXEN, ...) 1172 * @return true if successful, false otherwise 1173 */ 1174 bool setAccelerometerEnableAxes(uint8_t axes); 1175 1176 /** 1177 * set the accelerometer Output Data Rate (ODR) 1178 * 1179 * @param odr one of the XM_AODR_T values 1180 * @return true if successful, false otherwise 1181 */ 1182 bool setAccelerometerODR(XM_AODR_T odr); 1183 1184 /** 1185 * set the scaling mode of the accelerometer 1186 * 1187 * @param scale one of the XM_AFS_T values 1188 * @return true if successful, false otherwise 1189 */ 1190 bool setAccelerometerScale(XM_AFS_T scale); 1191 1192 /** 1193 * set the magnetometer resolution 1194 * 1195 * @param res one of the XM_RES_T values 1196 * @return true if successful, false otherwise 1197 */ 1198 bool setMagnetometerResolution(XM_RES_T res); 1199 1200 /** 1201 * set the magnetometer Output Data Rate (ODR) 1202 * 1203 * @param odr one of the XM_ODR_T values 1204 * @return true if successful, false otherwise 1205 */ 1206 bool setMagnetometerODR(XM_ODR_T odr); 1207 1208 /** 1209 * set the magnetometer sensor mode 1210 * 1211 * @param mode one of the XM_MD_T values 1212 * @return true if successful, false otherwise 1213 */ 1214 bool setMagnetometerMode(XM_MD_T mode); 1215 1216 /** 1217 * enable or disable magnetometer low power mode (LPM). When in 1218 * low power mode, the magnetometer updates at 3.125Hz, regardless 1219 * of it's ODR setting. 1220 * 1221 * @param enable true to enable LPM, false otherwise 1222 * @return true if successful, false otherwise 1223 */ 1224 bool setMagnetometerLPM(bool enable); 1225 1226 /** 1227 * set the scaling mode of the magnetometer 1228 * 1229 * @param scale one of the XM_MFS_T values 1230 * @return true if successful, false otherwise 1231 */ 1232 bool setMagnetometerScale(XM_MFS_T scale); 1233 1234 /** 1235 * get the accelerometer values in gravities 1236 * 1237 * @param x the returned x value, if arg is non-NULL 1238 * @param y the returned y value, if arg is non-NULL 1239 * @param z the returned z value, if arg is non-NULL 1240 * @return true if successful, false otherwise 1241 */ 1242 void getAccelerometer(float *x, float *y, float *z); 1243 1244 /** 1245 * get the gyroscope values in degrees per second 1246 * 1247 * @param x the returned x value, if arg is non-NULL 1248 * @param y the returned y value, if arg is non-NULL 1249 * @param z the returned z value, if arg is non-NULL 1250 * @return true if successful, false otherwise 1251 */ 1252 void getGyroscope(float *x, float *y, float *z); 1253 1254 /** 1255 * get the magnetometer values in gauss 1256 * 1257 * @param x the returned x value, if arg is non-NULL 1258 * @param y the returned y value, if arg is non-NULL 1259 * @param z the returned z value, if arg is non-NULL 1260 * @return true if successful, false otherwise 1261 */ 1262 void getMagnetometer(float *x, float *y, float *z); 1263 1264 #if defined(SWIGJAVA) || defined(JAVACALLBACK) 1265 /** 1266 * get the accelerometer values in gravities 1267 * 1268 * @return Array containing X, Y, Z acceleration values 1269 */ 1270 float *getAccelerometer(); 1271 1272 /** 1273 * get the gyroscope values in degrees per second 1274 * 1275 * @return Array containing X, Y, Z gyroscope values 1276 */ 1277 float *getGyroscope(); 1278 1279 /** 1280 * get the magnetometer values in gauss 1281 * 1282 * @return Array containing X, Y, Z magnetometer values 1283 */ 1284 float *getMagnetometer(); 1285 #endif 1286 1287 /** 1288 * get the temperature value. Unfortunately the datasheet does 1289 * not provide a mechanism to convert the temperature value into 1290 * the correct value, so I made a 'guess'. If it's wrong, and you 1291 * figure it out, send a patch! 1292 * 1293 * @return the temperature value in degrees Celcius 1294 */ 1295 float getTemperature(); 1296 1297 /** 1298 * enable onboard temperature measurement sensor 1299 * 1300 * @param enable true to enable temperature sensor, false to disable 1301 * @return true if successful, false otherwise 1302 */ 1303 bool enableTemperatureSensor(bool enable); 1304 1305 /** 1306 * return the gyroscope status register 1307 * 1308 * @return bitmask of STATUS_REG_G_BITS_T bits 1309 */ 1310 uint8_t getGyroscopeStatus(); 1311 1312 /** 1313 * return the magnetometer status register 1314 * 1315 * @return bitmask of STATUS_REG_M_BITS_T bits 1316 */ 1317 uint8_t getMagnetometerStatus(); 1318 1319 /** 1320 * return the accelerometer status register 1321 * 1322 * @return bitmask of STATUS_REG_A_BITS_T bits 1323 */ 1324 uint8_t getAccelerometerStatus(); 1325 1326 /** 1327 * return the gyroscope interrupt config register 1328 * 1329 * @return bitmask of INT1_CFG_G_BITS_T bits 1330 */ 1331 uint8_t getGyroscopeInterruptConfig(); 1332 1333 /** 1334 * set the gyroscope interrupt config register 1335 * 1336 * @param enables bitmask of INT1_CFG_G_BITS_T values 1337 * @return true if successful 1338 */ 1339 bool setGyroscopeInterruptConfig(uint8_t enables); 1340 1341 /** 1342 * return the gyroscope interrupt src register 1343 * 1344 * @return bitmask of INT1_SRC_G_BITS_T bits 1345 */ 1346 uint8_t getGyroscopeInterruptSrc(); 1347 1348 /** 1349 * return the magnetometer interrupt control register 1350 * 1351 * @return bitmask of INT_CTRL_REG_M_BITS_T bits 1352 */ 1353 uint8_t getMagnetometerInterruptControl(); 1354 1355 /** 1356 * set the magnetometer interrupt control register 1357 * 1358 * @param enables bitmask of INT_CTRL_REG_M_BITS_T values 1359 * @return true if successful 1360 */ 1361 bool setMagnetometerInterruptControl(uint8_t enables); 1362 1363 /** 1364 * return the magnetometer interrupt src register 1365 * 1366 * @return bitmask of INT_SRC_REG_M_BITS_T bits 1367 */ 1368 uint8_t getMagnetometerInterruptSrc(); 1369 1370 /** 1371 * return the inertial interrupt generator 1 register 1372 * 1373 * @return bitmask of INT_GEN_X_REG_BITS_T bits 1374 */ 1375 uint8_t getInterruptGen1(); 1376 1377 /** 1378 * set the inertial interrupt generator 1 register 1379 * 1380 * @param enables bitmask of INT_GEN_X_REG_BITS_T values 1381 * @return true if successful 1382 */ 1383 bool setInterruptGen1(uint8_t enables); 1384 1385 /** 1386 * return the inertial interrupt generator 1 src register 1387 * 1388 * @return bitmask of INT_GEN_X_SRC_BITS_T bits 1389 */ 1390 uint8_t getInterruptGen1Src(); 1391 1392 /** 1393 * return the inertial interrupt generator 2 register 1394 * 1395 * @return bitmask of INT_GEN_X_REG_BITS_T bits 1396 */ 1397 uint8_t getInterruptGen2(); 1398 1399 /** 1400 * set the inertial interrupt generator 2 register 1401 * 1402 * @param enables bitmask of INT_GEN_X_REG_BITS_T values 1403 * @return true if successful 1404 */ 1405 bool setInterruptGen2(uint8_t enables); 1406 1407 /** 1408 * return the inertial interrupt generator 2 src register 1409 * 1410 * @return bitmask of INT_GEN_X_SRC_BITS_T bits 1411 */ 1412 uint8_t getInterruptGen2Src(); 1413 1414 #if defined(SWIGJAVA) || defined(JAVACALLBACK) 1415 void installISR(INTERRUPT_PINS_T intr, int gpio, mraa::Edge level, 1416 IsrCallback *cb); 1417 #else 1418 /** 1419 * install an interrupt handler. 1420 * 1421 * @param intr one of the INTERRUPT_PINS_T values specifying which 1422 * interrupt pin out of 4 you are installing 1423 * @param gpio gpio pin to use as interrupt pin 1424 * @param level the interrupt trigger level (one of mraa::Edge 1425 * values). Make sure that you have configured the interrupt pin 1426 * properly for whatever level you choose. 1427 * @param isr the interrupt handler, accepting a void * argument 1428 * @param arg the argument to pass the the interrupt handler 1429 */ 1430 void installISR(INTERRUPT_PINS_T intr, int gpio, mraa::Edge level, 1431 void (*isr)(void *), void *arg); 1432 #endif 1433 /** 1434 * uninstall a previously installed interrupt handler 1435 * 1436 * @param intr one of the INTERRUPT_PINS_T values specifying which 1437 * interrupt pin out of 4 you are uninstalling 1438 */ 1439 void uninstallISR(INTERRUPT_PINS_T intr); 1440 1441 protected: 1442 // uncompensated accelerometer and gyroscope values 1443 float m_accelX; 1444 float m_accelY; 1445 float m_accelZ; 1446 1447 float m_gyroX; 1448 float m_gyroY; 1449 float m_gyroZ; 1450 1451 float m_magX; 1452 float m_magY; 1453 float m_magZ; 1454 1455 // uncompensated temperature value 1456 float m_temp; 1457 1458 // accelerometer and gyro scaling factors, depending on their Full 1459 // Scale settings. 1460 float m_accelScale; 1461 float m_gyroScale; 1462 float m_magScale; 1463 1464 private: 1465 // OR'd with a register, this enables register autoincrement mode, 1466 // which we need. 1467 #if defined(SWIGJAVA) || defined(JAVACALLBACK) 1468 void installISR(INTERRUPT_PINS_T intr, int gpio, mraa::Edge level, 1469 void (*isr)(void *), void *arg); 1470 #endif 1471 1472 static const uint8_t m_autoIncrementMode = 0x80; 1473 1474 mraa::I2c m_i2cG; 1475 mraa::I2c m_i2cXM; 1476 uint8_t m_gAddr; 1477 uint8_t m_xmAddr; 1478 1479 // return a reference to a gpio pin pointer depending on intr 1480 mraa::Gpio*& getPin(INTERRUPT_PINS_T intr); 1481 1482 // possible interrupt pins 1483 mraa::Gpio *m_gpioG_INT; 1484 mraa::Gpio *m_gpioG_DRDY; 1485 mraa::Gpio *m_gpioXM_GEN1; 1486 mraa::Gpio *m_gpioXM_GEN2; 1487 }; 1488 } 1489 1490 1491