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 MPU60X0_I2C_BUS 0 37 #define MPU60X0_DEFAULT_I2C_ADDR 0x68 38 39 namespace upm { 40 41 /** 42 * @library mpu9150 43 * @sensor mpu60x0 44 * @comname MPU60X0 3-axis Gyroscope and 3-axis Accelerometer 45 * @type accelerometer compass 46 * @man seeed 47 * @con i2c gpio 48 * 49 * @brief API for the MPU60X0 3-axis Gyroscope and 3-axis Accelerometer 50 * 51 * The MPU60X0 devices provide the world’s first integrated 6-axis 52 * motion processor solution that eliminates the package-level 53 * gyroscope and accelerometer cross-axis misalignment associated 54 * with discrete solutions. The devices combine a 3-axis gyroscope 55 * and a 3-axis accelerometer on the same silicon die. 56 * 57 * While not all of the functionality of this device is supported 58 * initially, methods and register definitions are provided that 59 * should allow an end user to implement whatever features are 60 * required. 61 * 62 * @snippet mpu60x0.cxx Interesting 63 */ 64 class MPU60X0 { 65 public: 66 67 // NOTE: These enums were composed from both the mpu6050 and 68 // mpu9150 register maps, since this driver was written using an 69 // mpu9150, but we'd like this module to be usable with a 70 // standalone mpu60x0. 71 // 72 // Registers and bitfields marked with an '*' in their 73 // comment indicate registers or bit fields present in the mpu9150 74 // register map, but not in the original mpu6050 register map. If 75 // using this module on a standalone mpu6050, you should avoid 76 // using those registers or bitfields marked with an *. 77 78 /** 79 * MPU60X0 registers 80 */ 81 typedef enum { 82 REG_SELF_TEST_X = 0x0d, 83 REG_SELF_TEST_Y = 0x0e, 84 REG_SELF_TEST_Z = 0x0f, 85 REG_SELF_TEST_A = 0x10, 86 87 REG_SMPLRT_DIV = 0x19, // sample rate divider 88 89 REG_CONFIG = 0x1a, 90 REG_GYRO_CONFIG = 0x1b, 91 REG_ACCEL_CONFIG = 0x1c, 92 93 REG_FF_THR = 0x1d, // *freefall threshold 94 REG_FF_DUR = 0x1e, // *freefall duration 95 96 REG_MOT_THR = 0x1f, // motion threshold 97 REG_MOT_DUR = 0x20, // *motion duration 98 99 REG_ZRMOT_THR = 0x21, // *zero motion threshhold 100 REG_ZRMOT_DUR = 0x22, // *zero motion duration 101 102 REG_FIFO_EN = 0x23, 103 104 REG_I2C_MST_CTRL = 0x24, // I2C master control 105 106 REG_I2C_SLV0_ADDR = 0x25, // I2C slave 0 107 REG_I2C_SLV0_REG = 0x26, 108 REG_I2C_SLV0_CTRL = 0x27, 109 110 REG_I2C_SLV1_ADDR = 0x28, // I2C slave 1 111 REG_I2C_SLV1_REG = 0x29, 112 REG_I2C_SLV1_CTRL = 0x2a, 113 114 REG_I2C_SLV2_ADDR = 0x2b, // I2C slave 2 115 REG_I2C_SLV2_REG = 0x2c, 116 REG_I2C_SLV2_CTRL = 0x2d, 117 118 REG_I2C_SLV3_ADDR = 0x2e, // I2C slave 3 119 REG_I2C_SLV3_REG = 0x2f, 120 REG_I2C_SLV3_CTRL = 0x30, 121 122 REG_I2C_SLV4_ADDR = 0x31, // I2C slave 4 123 REG_I2C_SLV4_REG = 0x32, 124 REG_I2C_SLV4_DO = 0x33, 125 REG_I2C_SLV4_CTRL = 0x34, 126 REG_I2C_SLV4_DI = 0x35, 127 128 REG_I2C_MST_STATUS = 0x36, // I2C master status 129 130 REG_INT_PIN_CFG = 0x37, // interrupt pin config/i2c bypass 131 REG_INT_ENABLE = 0x38, 132 133 // 0x39 reserved 134 135 REG_INT_STATUS = 0x3a, // interrupt status 136 137 REG_ACCEL_XOUT_H = 0x3b, // accelerometer outputs 138 REG_ACCEL_XOUT_L = 0x3c, 139 140 REG_ACCEL_YOUT_H = 0x3d, 141 REG_ACCEL_YOUT_L = 0x3e, 142 143 REG_ACCEL_ZOUT_H = 0x3f, 144 REG_ACCEL_ZOUT_L = 0x40, 145 146 REG_TEMP_OUT_H = 0x41, // temperature output 147 REG_TEMP_OUT_L = 0x42, 148 149 REG_GYRO_XOUT_H = 0x43, // gyro outputs 150 REG_GYRO_XOUT_L = 0x44, 151 152 REG_GYRO_YOUT_H = 0x45, 153 REG_GYRO_YOUT_L = 0x46, 154 155 REG_GYRO_ZOUT_H = 0x47, 156 REG_GYRO_ZOUT_L = 0x48, 157 158 REG_EXT_SENS_DATA_00 = 0x49, // external sensor data 159 REG_EXT_SENS_DATA_01 = 0x4a, 160 REG_EXT_SENS_DATA_02 = 0x4b, 161 REG_EXT_SENS_DATA_03 = 0x4c, 162 REG_EXT_SENS_DATA_04 = 0x4d, 163 REG_EXT_SENS_DATA_05 = 0x4e, 164 REG_EXT_SENS_DATA_06 = 0x4f, 165 REG_EXT_SENS_DATA_07 = 0x50, 166 REG_EXT_SENS_DATA_08 = 0x51, 167 REG_EXT_SENS_DATA_09 = 0x52, 168 REG_EXT_SENS_DATA_10 = 0x53, 169 REG_EXT_SENS_DATA_11 = 0x54, 170 REG_EXT_SENS_DATA_12 = 0x55, 171 REG_EXT_SENS_DATA_13 = 0x56, 172 REG_EXT_SENS_DATA_14 = 0x57, 173 REG_EXT_SENS_DATA_15 = 0x58, 174 REG_EXT_SENS_DATA_16 = 0x59, 175 REG_EXT_SENS_DATA_17 = 0x5a, 176 REG_EXT_SENS_DATA_18 = 0x5b, 177 REG_EXT_SENS_DATA_19 = 0x5c, 178 REG_EXT_SENS_DATA_20 = 0x5d, 179 REG_EXT_SENS_DATA_21 = 0x5e, 180 REG_EXT_SENS_DATA_22 = 0x5f, 181 REG_EXT_SENS_DATA_23 = 0x60, 182 183 REG_MOT_DETECT_STATUS = 0x61, // * 184 185 // 0x62 reserved 186 187 REG_I2C_SLV0_DO = 0x63, // I2C slave data outs 188 REG_I2C_SLV1_DO = 0x64, 189 REG_I2C_SLV2_DO = 0x65, 190 REG_I2C_SLV3_DO = 0x66, 191 192 REG_I2C_MST_DELAY_CTRL = 0x67, 193 194 REG_SIGNAL_PATH_RESET = 0x68, // signal path resets 195 196 REG_MOT_DETECT_CTRL = 0x69, 197 198 REG_USER_CTRL = 0x6a, 199 200 REG_PWR_MGMT_1 = 0x6b, // power management 201 REG_PWR_MGMT_2 = 0x6c, 202 203 // 0x6d-0x71 reserved 204 205 REG_FIFO_COUNTH = 0x72, 206 REG_FIFO_COUNTL = 0x73, 207 208 REG_FIFO_R_W = 0x74, 209 210 REG_WHO_AM_I = 0x75 211 } MPU60X0_REG_T; 212 213 /** 214 * CONFIG bits 215 */ 216 typedef enum { 217 CONFIG_DLPF_CFG0 = 0x01, // digital low-pass filter config 218 CONFIG_DLPF_CFG1 = 0x02, 219 CONFIG_DLPF_CFG2 = 0x04, 220 _CONFIG_DLPF_SHIFT = 0, 221 _CONFIG_DLPF_MASK = 7, 222 223 CONFIG_EXT_SYNC_SET0 = 0x08, // FSYNC pin config 224 CONFIG_EXT_SYNC_SET1 = 0x10, 225 CONFIG_EXT_SYNC_SET2 = 0x20, 226 _CONFIG_EXT_SYNC_SET_SHIFT = 3, 227 _CONFIG_EXT_SYNC_SET_MASK = 7 228 } CONFIG_BITS_T; 229 230 /** 231 * CONFIG DLPF_CFG values 232 */ 233 typedef enum { 234 DLPF_260_256 = 0, // accel/gyro bandwidth (Hz) 235 DLPF_184_188 = 1, 236 DLPF_94_98 = 2, 237 DLPF_44_42 = 3, 238 DLPF_21_20 = 4, 239 DLPF_10_10 = 5, 240 DLPF_5_5 = 6, 241 DLPF_RESERVED = 7 242 } DLPF_CFG_T; 243 244 /** 245 * CONFIG EXT_SYNC_SET values 246 */ 247 typedef enum { 248 EXT_SYNC_DISABLED = 0, 249 EXT_SYNC_TEMP_OUT = 1, 250 EXT_SYNC_GYRO_XOUT = 2, 251 EXT_SYNC_GYRO_YOUT = 3, 252 EXT_SYNC_GYRO_ZOUT = 4, 253 EXT_SYNC_ACCEL_XOUT = 5, 254 EXT_SYNC_ACCEL_YOUT = 6, 255 EXT_SYNC_ACCEL_ZOUT = 7 256 } EXT_SYNC_SET_T; 257 258 /** 259 * GYRO_CONFIG bits 260 */ 261 typedef enum { 262 // 0x01-0x04 reserved 263 FS_SEL0 = 0x08, // gyro full scale range 264 FS_SEL1 = 0x10, 265 _FS_SEL_SHIFT = 3, 266 _FS_SEL_MASK = 3, 267 268 ZG_ST = 0x20, // gyro self test bits 269 YG_ST = 0x40, 270 XG_ST = 0x80 271 } GRYO_CONFIG_BITS_T; 272 273 /** 274 * GYRO FS_SEL values 275 */ 276 typedef enum { 277 FS_250 = 0, // 250 deg/s, 131 LSB deg/s 278 FS_500 = 1, // 500 deg/s, 65.5 LSB deg/s 279 FS_1000 = 2, // 1000 deg/s, 32.8 LSB deg/s 280 FS_2000 = 3 // 2000 deg/s, 16.4 LSB deg/s 281 } FS_SEL_T; 282 283 /** 284 * ACCEL_CONFIG bits 285 */ 286 typedef enum { 287 // 0x01-0x04 reserved 288 AFS_SEL0 = 0x08, // accel full scale range 289 AFS_SEL1 = 0x10, 290 _AFS_SEL_SHIFT = 3, 291 _AFS_SEL_MASK = 3, 292 293 ZA_ST = 0x20, // gyro self test bits 294 YA_ST = 0x40, 295 XA_ST = 0x80 296 } ACCEL_CONFIG_BITS_T; 297 298 /** 299 * ACCEL AFS_SEL (full scaling) values 300 */ 301 typedef enum { 302 AFS_2 = 0, // 2g, 16384 LSB/g 303 AFS_4 = 1, // 4g, 8192 LSB/g 304 AFS_8 = 2, // 8g, 4096 LSB/g 305 AFS_16 = 3 // 16g, 2048 LSB/g 306 } AFS_SEL_T; 307 308 /** 309 * REG_FIFO_EN bits 310 */ 311 typedef enum { 312 SLV0_FIFO_EN = 0x01, 313 SLV1_FIFO_EN = 0x02, 314 SLV2_FIFO_EN = 0x04, 315 316 ACCEL_FIFO_EN = 0x08, 317 318 ZG_FIFO_EN = 0x10, 319 YG_FIFO_EN = 0x20, 320 XG_FIFO_EN = 0x40, 321 322 TEMP_FIFO_EN = 0x80 323 } FIFO_EN_BITS_T; 324 325 /** 326 * REG_I2C_MST_CTRL bits 327 */ 328 typedef enum { 329 I2C_MST_CLK0 = 0x01, 330 I2C_MST_CLK1 = 0x02, 331 I2C_MST_CLK2 = 0x04, 332 I2C_MST_CLK3 = 0x08, 333 _I2C_MST_CLK_SHIFT = 0, 334 _I2C_MST_CLK_MASK = 15, 335 336 I2C_MST_P_NSR = 0x10, 337 338 SLV_3_FIFO_EN = 0x20, 339 340 WAIT_FOR_ES = 0x40, 341 342 MULT_MST_EN = 0x80 343 } I2C_MST_CTRL_BITS_T; 344 345 /** 346 * I2C_MST_CLK values 347 */ 348 typedef enum { 349 MST_CLK_348 = 0, // 348Khz 350 MST_CLK_333 = 1, 351 MST_CLK_320 = 2, 352 MST_CLK_308 = 3, 353 MST_CLK_296 = 4, 354 MST_CLK_286 = 5, 355 MST_CLK_276 = 6, 356 MST_CLK_267 = 7, 357 MST_CLK_258 = 8, 358 MST_CLK_500 = 9, 359 MST_CLK_471 = 10, 360 MST_CLK_444 = 11, 361 MST_CLK_421 = 12, 362 MST_CLK_400 = 13, 363 MST_CLK_381 = 14, 364 MST_CLK_364 = 15 365 } I2C_MST_CLK_T; 366 367 /** 368 * REG_I2C SLV0-SLV4 _ADDR bits 369 */ 370 typedef enum { 371 I2C_SLV_ADDR0 = 0x01, 372 I2C_SLV_ADDR1 = 0x02, 373 I2C_SLV_ADDR2 = 0x04, 374 I2C_SLV_ADDR3 = 0x08, 375 I2C_SLV_ADDR4 = 0x10, 376 I2C_SLV_ADDR5 = 0x20, 377 I2C_SLV_ADDR6 = 0x40, 378 _I2C_SLV_ADDR_SHIFT = 0, 379 _I2C_SLV_ADDR_MASK = 127, 380 381 I2C_SLV_RW = 0x80 382 } I2C_SLV_ADDR_BITS_T; 383 384 /** 385 * REG_I2C SLV0-SLV3 _CTRL bits 386 */ 387 typedef enum { 388 I2C_SLV_LEN0 = 0x01, 389 I2C_SLV_LEN1 = 0x02, 390 I2C_SLV_LEN2 = 0x04, 391 I2C_SLV_LEN3 = 0x08, 392 _I2C_SLV_LEN_SHIFT = 0, 393 _I2C_SLV_LEN_MASK = 15, 394 395 I2C_SLV_GRP = 0x10, 396 I2C_SLV_REG_DIS = 0x20, 397 I2C_SLV_BYTE_SW = 0x40, 398 I2C_SLV_EN = 0x80 399 } I2C_SLV_CTRL_BITS_T; 400 401 /** 402 * REG_I2C_SLV4_CTRL bits, these are different from the SLV0-SLV3 403 * CRTL bits. 404 * 405 * MST_DLY is not enumerated in the register map. It configures 406 * the reduced access rate of i2c slaves relative to the sample 407 * rate. When a slave’s access rate is decreased relative to the 408 * Sample Rate, the slave is accessed every 409 * 1 / (1 + I2C_MST_DLY) samples 410 */ 411 typedef enum { 412 I2C_MST_DLY0 = 0x01, 413 I2C_MST_DLY1 = 0x02, 414 I2C_MST_DLY2 = 0x04, 415 I2C_MST_DLY3 = 0x08, 416 I2C_MST_DLY4 = 0x10, 417 _I2C_MST_DLY_SHIFT = 0, 418 _I2C_MST_DLY_MASK = 31, 419 420 I2C_SLV4_REG_DIS = 0x20, 421 I2C_SLV4_INT_EN = 0x40, 422 I2C_SLV4_EN = 0x80 423 } I2C_SLV4_CTRL_BITS_T; 424 425 /** 426 * REG_I2C_MST_STATUS bits 427 */ 428 typedef enum { 429 I2C_SLV0_NACK = 0x01, 430 I2C_SLV1_NACK = 0x02, 431 I2C_SLV2_NACK = 0x04, 432 I2C_SLV3_NACK = 0x08, 433 I2C_SLV4_NACK = 0x10, 434 435 I2C_LOST_ARB = 0x20, 436 I2C_SLV4_DONE = 0x40, 437 PASS_THROUGH = 0x80 438 } I2C_MST_STATUS_BITS_T; 439 440 /** 441 * REG_INT_PIN_CFG bits 442 */ 443 typedef enum { 444 CLKOUT_EN = 0x01, // * 445 446 I2C_BYPASS_ENABLE = 0x02, 447 448 FSYNC_INT_EN = 0x04, 449 FSYNC_INT_LEVEL = 0x08, 450 451 INT_RD_CLEAR = 0x10, 452 453 LATCH_INT_EN = 0x20, 454 455 INT_OPEN = 0x40, 456 INT_LEVEL = 0x80 457 } INT_PIN_CFG_BITS_T; 458 459 /** 460 * REG_INT_ENABLE bits 461 */ 462 typedef enum { 463 DATA_RDY_EN = 0x01, // * 464 465 // 0x02, 0x04 reserved 466 467 I2C_MST_INT_EN = 0x08, 468 469 FIFO_OFLOW_EN = 0x10, 470 471 ZMOT_EN = 0x20, // *zero motion 472 MOT_EN = 0x40, 473 FF_EN = 0x80 // *freefall 474 } INT_ENABLE_BITS_T; 475 476 /** 477 * REG_INT_STATUS bits 478 */ 479 typedef enum { 480 DATA_RDY_INT = 0x01, 481 482 // 0x02, 0x04 reserved 483 484 I2C_MST_INT = 0x08, 485 486 FIFO_OFLOW_INT = 0x10, 487 488 ZMOT_INT = 0x20, // *zero motion 489 MOT_INT = 0x40, 490 FF_INT = 0x80 // *freefall 491 } INT_STATUS_BITS_T; 492 493 /** 494 * REG_MOT_DETECT_STATUS bits (mpu9150 only) 495 */ 496 typedef enum { 497 MOT_ZRMOT = 0x01, // * 498 499 // 0x02 reserved 500 501 MOT_ZPOS = 0x04, // * 502 MOT_ZNEG = 0x08, // * 503 504 MOT_YPOS = 0x10, // * 505 MOT_YNEG = 0x20, // * 506 507 MOT_XPOS = 0x40, // * 508 MOT_XNEG = 0x80, // * 509 } MOT_DETECT_STATUS_BITS_T; 510 511 /** 512 * REG_MST_DELAY_CTRL bits 513 */ 514 typedef enum { 515 I2C_SLV0_DLY_EN = 0x01, 516 I2C_SLV1_DLY_EN = 0x02, 517 I2C_SLV2_DLY_EN = 0x04, 518 I2C_SLV3_DLY_EN = 0x08, 519 I2C_SLV4_DLY_EN = 0x10, 520 521 // 0x20, 0x40, reserved 522 523 DELAY_ES_SHADOW = 0x80 524 } MST_DELAY_CTRL_BITS_T; 525 526 /** 527 * REG_SIGNAL_PATH_RESET bits 528 */ 529 typedef enum { 530 TEMP_RESET = 0x01, 531 ACCEL_RESET = 0x02, 532 GYRO_RESET = 0x04 533 534 // 0x08-0x80 reserved 535 } SIGNAL_PATH_RESET_BITS_T; 536 537 /** 538 * REG_MOT_DETECT_CTRL bits 539 */ 540 typedef enum { 541 MOT_COUNT0 = 0x01, // * 542 MOT_COUNT1 = 0x02, // * 543 _MOT_COUNT_SHIFT = 0, 544 _MOT_COUNT_MASK = 3, 545 546 FF_COUNT0 = 0x04, // * 547 FF_COUNT1 = 0x08, // * 548 _FF_COUNT_SHIFT = 2, 549 _FF_COUNT_MASK = 3, 550 551 ACCEL_ON_DELAY0 = 0x10, 552 ACCEL_ON_DELAY1 = 0x20, 553 _ACCEL_ON_DELAY_SHIFT = 4, 554 _ACCEL_ON_DELAY_MASK = 3 555 // 0x40,0x80 reserved 556 } MOT_DETECT_CTRL_BITS_T; 557 558 /** 559 * MOT_COUNT or FF_COUNT values (mpu9150 only) 560 */ 561 typedef enum { 562 COUNT_0 = 0, // Reset 563 COUNT_1 = 1, // counter decrement 1 564 COUNT_2 = 2, // counter decrement 2 565 COUNT_4 = 3 // counter decrement 4 566 } MOT_FF_COUNT_T; 567 568 /** 569 * ACCEL_ON_DELAY values 570 */ 571 typedef enum { 572 ON_DELAY_0 = 0, // no delay 573 ON_DELAY_1 = 1, // add 1ms 574 ON_DELAY_2 = 2, // add 2ms 575 ON_DELAY_3 = 3 // add 3ms 576 } ACCEL_ON_DELAY_T; 577 578 /** 579 * REG_USER_CTRL bits 580 */ 581 typedef enum { 582 SIG_COND_RESET = 0x01, 583 I2C_MST_RESET = 0x02, 584 FIFO_RESET = 0x04, 585 586 // 0x08 reserved 587 588 I2C_IF_DIS = 0x10, 589 I2C_MST_EN = 0x20, 590 FIFO_EN = 0x40 591 592 /// 0x80 reserved 593 } USER_CTRL_BITS_T; 594 595 /** 596 * REG_PWR_MGMT_1 bits 597 */ 598 typedef enum { 599 CLKSEL0 = 0x01, 600 CLKSEL1 = 0x02, 601 CLKSEL2 = 0x04, 602 _CLKSEL_SHIFT = 0, 603 _CLKSEL_MASK = 7, 604 605 TEMP_DIS = 0x08, 606 607 // 0x10 reserved 608 609 PWR_CYCLE = 0x20, 610 PWR_SLEEP = 0x40, 611 DEVICE_RESET = 0x80 612 } PWR_MGMT_1_BITS_T; 613 614 /** 615 * CLKSEL values 616 */ 617 typedef enum { 618 INT_8MHZ = 0, // internal 8Mhz osc 619 PLL_XG = 1, // PLL X axis gyro 620 PLL_YG = 2, // PLL Y axis gyro 621 PLL_ZG = 3, // PLL Z axis gyro 622 PLL_EXT_32KHZ = 4, // PLL with external 32.768Khz ref 623 PLL_EXT_19MHZ = 5, // PLL with external 19.2Mhz ref 624 // 6 - reserved 625 CLK_STOP = 7 // stops clk 626 } CLKSEL_T; 627 628 /** 629 * REG_PWR_MGMT_2 bits 630 */ 631 typedef enum { 632 STBY_ZG = 0x01, 633 STBY_YG = 0x02, 634 STBY_XG = 0x04, 635 STBY_ZA = 0x08, 636 STBY_YA = 0x10, 637 STBY_XA = 0x20, 638 639 LP_WAKE_CTRL0 = 0x40, 640 LP_WAKE_CTRL1 = 0x80, 641 _LP_WAKE_CTRL_SHIFT = 6, 642 _LP_WAKE_CTRL_MASK = 3 643 } PWR_MGMT_2_BITS_T; 644 645 /** 646 * LP_WAKE_CTRL values 647 */ 648 typedef enum { 649 LP_WAKE_1_25 = 0, // wakeup feq: 1.25hz 650 LP_WAKE_5 = 1, // 5hz 651 LP_WAKE_20 = 2, // 20hz 652 LP_WAKE_40 = 3, // 40hz 653 } LP_WAKE_CRTL_T; 654 655 656 /** 657 * mpu60x0 constructor 658 * 659 * @param bus i2c bus to use 660 * @param address the address for this device 661 */ 662 MPU60X0(int bus=MPU60X0_I2C_BUS, uint8_t address=MPU60X0_DEFAULT_I2C_ADDR); 663 664 /** 665 * MPU60X0 Destructor 666 */ 667 ~MPU60X0(); 668 669 /** 670 * set up initial values and start operation 671 * 672 * @return true if successful 673 */ 674 bool init(); 675 676 /** 677 * take a measurement and store the current sensor values 678 * internally. Note, these user facing registers are only updated 679 * from the internal device sensor values when the i2c serial 680 * traffic is 'idle'. So, if you are reading the values too fast, 681 * the bus may never be idle, and you will just end up reading 682 * the same values over and over. 683 * 684 * Unfortunately, it is is not clear how long 'idle' actually 685 * means, so if you see this behavior, reduce the rate at which 686 * you are calling update(). 687 * 688 */ 689 void update(); 690 691 /** 692 * read a register 693 * 694 * @param reg the register to read 695 * @return the value of the register 696 */ 697 uint8_t readReg(uint8_t reg); 698 699 /** 700 * read contiguous refister into a buffer 701 * 702 * @param reg the register to start reading at 703 * @param buffer the buffer to store the results 704 * @param len the number of registers to read 705 * @return the value of the register 706 */ 707 void readRegs(uint8_t reg, uint8_t *buffer, int len); 708 709 /** 710 * write to a register 711 * 712 * @param reg the register to write to 713 * @param val the value to write 714 * @return true if successful, false otherwise 715 */ 716 bool writeReg(uint8_t reg, uint8_t val); 717 718 /** 719 * enable or disable device sleep 720 * 721 * @param enable true to put device to sleep, false to wake up 722 * @return true if successful, false otherwise 723 */ 724 bool setSleep(bool enable); 725 726 /** 727 * specify the clock source for the device to use 728 * 729 * @param clk one of the CLKSEL_T values 730 * @return true if successful, false otherwise 731 */ 732 bool setClockSource(CLKSEL_T clk); 733 734 /** 735 * set the scaling mode of the gyroscope 736 * 737 * @param scale one of the FS_SEL_T values 738 * @return true if successful, false otherwise 739 */ 740 bool setGyroscopeScale(FS_SEL_T scale); 741 742 /** 743 * set the scaling mode of the accelerometer 744 * 745 * @param scale one of the AFS_SEL_T values 746 * @return true if successful, false otherwise 747 */ 748 bool setAccelerometerScale(AFS_SEL_T scale); 749 750 /** 751 * set the Low Pass Digital filter. This enables filtering (if 752 * non-0) of the accelerometer and gyro outputs. 753 * 754 * @param scale one of the DLPF_CFG_T values 755 * @return true if successful, false otherwise 756 */ 757 bool setDigitalLowPassFilter(DLPF_CFG_T dlp); 758 759 /** 760 * set the sample rate divider. This register specifies the 761 * divider from the gyro output rate used to generate the Sample 762 * Rate. The sensor registor output, FIFO output, DMP sampling 763 * and motion detection are all based on the Sample Rate. 764 * 765 * The Sample Rate is generated by dividing the gyro output rate 766 * by this register: 767 * 768 * Sample Rate = Gyro output rate / (1 + sample rate divider). 769 * 770 * The Gyro output rate is 8Khz when the Digital Low Pass Filter 771 * (DLPF) is 0 or 7 (DLPF_260_256 or DLPF_RESERVED), and 1Khz 772 * otherwise. 773 * 774 * @param scale one of the DLPF_CFG_T values 775 * @return true if successful, false otherwise 776 */ 777 bool setSampleRateDivider(uint8_t div); 778 779 /** 780 * get the current Sample Rate divider 781 * 782 * @return the current sample rate divider 783 */ 784 uint8_t getSampleRateDivider(); 785 786 /** 787 * get the accelerometer values 788 * 789 * @param x the returned x value, if arg is non-NULL 790 * @param y the returned y value, if arg is non-NULL 791 * @param z the returned z value, if arg is non-NULL 792 * @return true if successful, false otherwise 793 */ 794 void getAccelerometer(float *x, float *y, float *z); 795 796 /** 797 * get the gyroscope values 798 * 799 * @param x the returned x value, if arg is non-NULL 800 * @param y the returned y value, if arg is non-NULL 801 * @param z the returned z value, if arg is non-NULL 802 * @return true if successful, false otherwise 803 */ 804 void getGyroscope(float *x, float *y, float *z); 805 806 #if defined(SWIGJAVA) || defined(JAVACALLBACK) 807 /** 808 * get the accelerometer values 809 * 810 * @return Array containing X, Y, Z accelerometer values 811 */ 812 float *getAccelerometer(); 813 814 /** 815 * get the gyroscope values 816 * 817 * @return Array containing X, Y, Z gyroscope values 818 */ 819 float *getGyroscope(); 820 #endif 821 822 823 /** 824 * get the temperature value 825 * 826 * @return the temperature value in degrees Celcius 827 */ 828 virtual float getTemperature(); 829 830 /** 831 * enable onboard temperature measurement sensor 832 * 833 * @param enable true to enable temperature sensor, false to disable 834 * @return true if successful, false otherwise 835 */ 836 bool enableTemperatureSensor(bool enable); 837 838 /** 839 * configure external sync. An external signal connected to the 840 * FSYNC pin can be sampled by configuring EXT_SYNC_SET. Signal 841 * changes to the FSYNC pin are latched so that short strobes may 842 * be captured. The latched FSYNC signal will be sampled at the 843 * Sampling Rate, as defined in register 25. After sampling, the 844 * latch will reset to the current FSYNC signal state. 845 * 846 * The sampled value will be reported in place of the least 847 * significant bit in a sensor data register determined by the 848 * value of EXT_SYNC_SET 849 * 850 * @param val one of the EXT_SYNC_SET_T values 851 * @return true if successful, false otherwise 852 */ 853 bool setExternalSync(EXT_SYNC_SET_T val); 854 855 /** 856 * enable I2C Bypass. Enabling this feature allows devices on the 857 * MPU60X0 auxillary I2C bus to be visible on the MCU's I2C bus. 858 * 859 * @param enable true to I2C bypass 860 * @return true if successful, false otherwise 861 */ 862 bool enableI2CBypass(bool enable); 863 864 /** 865 * set the motion detection threshold for interrupt generation. 866 * Motion is detected when the absolute value of any of the 867 * accelerometer measurements exceeds this Motion detection 868 * threshold. 869 * 870 * @param thr threshold 871 * @return true if successful, false otherwise 872 */ 873 bool setMotionDetectionThreshold(uint8_t thr); 874 875 /** 876 * return the interrupt status register. 877 * 878 * @return the interrupt status word (see INT_STATUS_BITS_T) 879 */ 880 uint8_t getInterruptStatus(); 881 882 /** 883 * set the interrupt enables 884 * 885 * @param enables bitmask of INT_ENABLE_BITS_T values to enable 886 * @return true if successful, false otherwise 887 */ 888 bool setInterruptEnables(uint8_t enables); 889 890 /** 891 * get the current interrupt enables register 892 * 893 * @return bitmask of INT_ENABLE_BITS_T values 894 */ 895 uint8_t getInterruptEnables(); 896 897 /** 898 * set the interrupt pin configuration 899 * 900 * @param cfg bitmask of INT_PIN_CFG_BITS_T values 901 * @return true if successful, false otherwise 902 */ 903 bool setInterruptPinConfig(uint8_t cfg); 904 905 /** 906 * get the current interrupt pin configuration 907 * 908 * @return bitmask of INT_PIN_CFG_BITS_T values 909 */ 910 uint8_t getInterruptPinConfig(); 911 912 /** 913 * install an interrupt handler. 914 * 915 * @param gpio gpio pin to use as interrupt pin 916 * @param level the interrupt trigger level (one of mraa::Edge 917 * values). Make sure that you have configured the interrupt pin 918 * (setInterruptPinConfig()) properly for whatever level you 919 * choose. 920 * @param isr the interrupt handler, accepting a void * argument 921 * @param arg the argument to pass the the interrupt handler 922 */ 923 #if defined(SWIGJAVA) || defined(JAVACALLBACK) 924 void installISR(int gpio, mraa::Edge level, IsrCallback *cb); 925 #else 926 void installISR(int gpio, mraa::Edge level, void (*isr)(void *), void *arg); 927 #endif 928 929 /** 930 * uninstall a previously installed interrupt handler 931 * 932 */ 933 void uninstallISR(); 934 935 protected: 936 // uncompensated accelerometer and gyroscope values 937 float m_accelX; 938 float m_accelY; 939 float m_accelZ; 940 941 float m_gyroX; 942 float m_gyroY; 943 float m_gyroZ; 944 945 // uncompensated temperature value 946 float m_temp; 947 948 // accelerometer and gyro scaling factors, depending on their Full 949 // Scale settings. 950 float m_accelScale; 951 float m_gyroScale; 952 953 private: 954 #if defined(SWIGJAVA) || defined(JAVACALLBACK) 955 void installISR(int gpio, mraa::Edge level, void (*isr)(void *), void *arg); 956 #endif 957 958 mraa::I2c m_i2c; 959 uint8_t m_addr; 960 961 mraa::Gpio *m_gpioIRQ; 962 }; 963 } 964 965 966