Home | History | Annotate | Download | only in mpu9150
      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 #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 worlds 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 slaves 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