mbed library for MPU9250 (SPI interface)

Dependents:   InvertedPendulum2017

Lib_MPU9250.h

Committer:
bluefish
Date:
2018-05-02
Revision:
2:c142d5a352c5
Parent:
1:5334e111af53

File content as of revision 2:c142d5a352c5:

#ifndef __LIBRARY_MPU9250_SPI_H__
#define __LIBRARY_MPU9250_SPI_H__

#include "mbed.h"

#define MPU9250_FREQ_DEFAULT    (4000000)           // default clock speed
#define MPU9250_ADDR            (0x68)
#define AK8963_ADDR             (0x0C)              // magnetometer address

#define I2C_WRITE_FLAG          (0x00)
#define I2C_READ_FLAG           (0x01)

#define MPU9250A_2G             ((float)0.000061035156f)  // 0.000061035156 g/LSB
#define MPU9250A_4G             ((float)0.000122070312f)  // 0.000122070312 g/LSB
#define MPU9250A_8G             ((float)0.000244140625f)  // 0.000244140625 g/LSB
#define MPU9250A_16G            ((float)0.000488281250f)  // 0.000488281250 g/LSB
 
#define MPU9250G_250DPS         ((float)0.007633587786f)  // 0.007633587786 dps/LSB
#define MPU9250G_500DPS         ((float)0.015267175572f)  // 0.015267175572 dps/LSB
#define MPU9250G_1000DPS        ((float)0.030487804878f)  // 0.030487804878 dps/LSB
#define MPU9250G_2000DPS        ((float)0.060975609756f)  // 0.060975609756 dps/LSB

/*
#define MPU9250G_250DPS_RAD     ((float)0.00013323124f)   // 0.00013323124 rad/LSB
#define MPU9250G_500DPS_RAD     ((float)0.00026646248f)   // 0.00026646248 rad/LSB
#define MPU9250G_1000DPS_RAD    ((float)0.00053211257f)   // 0.00053211257 rad/LSB
#define MPU9250G_2000DPS_RAD    ((float)0.00106422515f)   // 0.00106422515 rad/LSB
*/

#define MPU9250M_4800uT         ((float)0.6f)             // 0.6 uT/LSB
#define MPU9250T_85degC         ((float)0.002995177763f)  // 0.002995177763 degC/LSB

#define MPU9250G_DEG2RAD        ((float)0.01745329251f)   // degree to radian

// enum
typedef enum _MPU9250REG{
    // gyro and accel
    SELF_TEST_X_GYRO    =   0x00,
    SELF_TEST_Y_GYRO    =   0x01,
    SELF_TEST_Z_GYRO    =   0x02,
    
    SELF_TEST_X_ACCEL   =   0x0D,
    SELF_TEST_Y_ACCEL   =   0x0E,
    SELF_TEST_Z_ACCEL   =   0x0F,
    
    XG_OFFSET_H         =   0x13,
    XG_OFFSET_L         =   0x14,
    YG_OFFSET_H         =   0x15,
    YG_OFFSET_L         =   0x16,
    ZG_OFFSET_H         =   0x17,
    ZG_OFFSET_L         =   0x18,
    
    SMPLRT_DIV          =   0x19,
    CONFIG              =   0x1A,   
    GYRO_CONFIG         =   0x1B,
    ACCEL_CONFIG        =   0x1C,
    ACCEL_CONFIG2       =   0x1D,
    LP_ACCEL_ODR        =   0x1E,
    WOM_THR             =   0x1F,
    
    FIFO_EN             =   0x23,
    
    I2C_MST_CTRL        =   0x24,
    I2C_SLV0_ADDR       =   0x25,
    I2C_SLV0_REG        =   0x26,
    I2C_SLV0_CTRL       =   0x27,
    I2C_SLV1_ADDR       =   0x28,
    I2C_SLV1_REG        =   0x29,
    I2C_SLV1_CTRL       =   0x2A,
    I2C_SLV2_ADDR       =   0x2B,
    I2C_SLV2_REG        =   0x2C,
    I2C_SLV2_CTRL       =   0x2D,
    I2C_SLV3_ADDR       =   0x2E,
    I2C_SLV3_REG        =   0x2F,
    I2C_SLV3_CTRL       =   0x30,
    I2C_SLV4_ADDR       =   0x31,
    I2C_SLV4_REG        =   0x32,
    I2C_SLV4_DO         =   0x33,
    I2C_SLV4_CTRL       =   0x34,
    I2C_SLV4_DI         =   0x35,
    I2C_MST_STATUS      =   0x36,
    
    INT_PIN_CFG         =   0x37,
    INT_ENABLE          =   0x38,
    INT_STATUS          =   0x3A,
    
    ACCEL_XOUT_H        =   0x3B,
    ACCEL_XOUT_L        =   0x3C,
    ACCEL_YOUT_H        =   0x3D,
    ACCEL_YOUT_L        =   0x3E,
    ACCEL_ZOUT_H        =   0x3F,
    ACCEL_ZOUT_L        =   0x40,
    
    TEMP_OUT_H          =   0x41,
    TEMP_OUT_L          =   0x42,
    
    GYRO_XOUT_H         =   0x43,
    GYRO_XOUT_L         =   0x44,
    GYRO_YOUT_H         =   0x45,
    GYRO_YOUT_L         =   0x46,
    GYRO_ZOUT_H         =   0x47,
    GYRO_ZOUT_L         =   0x48,

    EXT_SENS_DATA_00    =   0x49,
    EXT_SENS_DATA_01    =   0x4A,
    EXT_SENS_DATA_02    =   0x4B,
    EXT_SENS_DATA_03    =   0x4C,
    EXT_SENS_DATA_04    =   0x4D,
    EXT_SENS_DATA_05    =   0x4E,
    EXT_SENS_DATA_06    =   0x4F,
    EXT_SENS_DATA_07    =   0x50,
    EXT_SENS_DATA_08    =   0x51,
    EXT_SENS_DATA_09    =   0x52,
    EXT_SENS_DATA_10    =   0x53,
    EXT_SENS_DATA_11    =   0x54,
    EXT_SENS_DATA_12    =   0x55,
    EXT_SENS_DATA_13    =   0x56,
    EXT_SENS_DATA_14    =   0x57,
    EXT_SENS_DATA_15    =   0x58,
    EXT_SENS_DATA_16    =   0x59,
    EXT_SENS_DATA_17    =   0x5A,
    EXT_SENS_DATA_18    =   0x5B,
    EXT_SENS_DATA_19    =   0x5C,
    EXT_SENS_DATA_20    =   0x5D,
    EXT_SENS_DATA_21    =   0x5E,
    EXT_SENS_DATA_22    =   0x5F,
    EXT_SENS_DATA_23    =   0x60,

    I2C_SLV0_DO         =   0x63,
    I2C_SLV1_DO         =   0x64,
    I2C_SLV2_DO         =   0x65,
    I2C_SLV3_DO         =   0x66,

    I2C_MST_DELAY_CTRL  =   0x67,
    SIGNAL_PATH_RESET   =   0x68,
    MOT_DETECT_CTRL     =   0x69,
    USER_CTRL           =   0x6A,
    PWR_MGMT_1          =   0x6B,
    PWR_MGMT_2          =   0x6C,
    
    FIFO_COUNTH         =   0x72,
    FIFO_COUNTL         =   0x73,
    FIFO_R_W            =   0x74,
    WHO_AM_I            =   0x75,
    
    XA_OFFSET_H         =   0x77,
    XA_OFFSET_L         =   0x78,
    YA_OFFSET_H         =   0x7A,
    YA_OFFSET_L         =   0x7B,
    ZA_OFFSET_H         =   0x7D,
    ZA_OFFSET_L         =   0x7E,
} MPU9250REG;

typedef enum _AK8963REG{    
    // magnetometer
    WIA                 =   0x00,
    INFO                =   0x01,
    ST1                 =   0x02,
    
    HXL                 =   0x03,
    HXH                 =   0x04,
    HYL                 =   0x05,
    HYH                 =   0x06,
    HZL                 =   0x07,
    HZH                 =   0x08,

    ST2                 =   0x09,
    CNTL1               =   0x0A,
    CNTL2               =   0x0B,
    ASTC                =   0x0C,
    TS1                 =   0x0D,
    TS2                 =   0x0E,
    I2CDIS              =   0x0F,

    ASAX                =   0x10,
    ASAY                =   0x11,
    ASAZ                =   0x12,
} AK8963REG;

typedef enum _MPU9250BIT{
    BIT_SLEEP                   =   0x40,
    BIT_H_RESET                 =   0x80,
    BITS_CLKSEL                 =   0x07,
    MPU_CLK_SEL_PLLGYROX        =   0x01,
    MPU_CLK_SEL_PLLGYROZ        =   0x03,
    MPU_EXT_SYNC_GYROX          =   0x02,
    BITS_FS_250DPS              =   0x00,
    BITS_FS_500DPS              =   0x08,
    BITS_FS_1000DPS             =   0x10,
    BITS_FS_2000DPS             =   0x18,
    BITS_FS_2G                  =   0x00,
    BITS_FS_4G                  =   0x08,
    BITS_FS_8G                  =   0x10,
    BITS_FS_16G                 =   0x18,
    BITS_FS_MASK                =   0x18,
    BITS_DLPF_CFG_256HZ_NOLPF2  =   0x00,
    BITS_DLPF_CFG_188HZ         =   0x01,
    BITS_DLPF_CFG_98HZ          =   0x02,
    BITS_DLPF_CFG_42HZ          =   0x03,
    BITS_DLPF_CFG_20HZ          =   0x04,
    BITS_DLPF_CFG_10HZ          =   0x05,
    BITS_DLPF_CFG_5HZ           =   0x06,
    BITS_DLPF_CFG_2100HZ_NOLPF  =   0x07,
    BITS_DLPF_CFG_MASK          =   0x07,
    BIT_INT_ANYRD_2CLEAR        =   0x10,
    BIT_RAW_RDY_EN              =   0x01,
    BIT_I2C_IF_DIS              =   0x10
} MPU9250BIT;

typedef enum _MPU9250IF{
    MPU9250_SPI                 =   0x00,
    MPU9250_I2C                 =   0x10
} MPU9250IF;

class MPU9250{
    public:
        MPU9250( PinName cs, PinName mosi, PinName miso, PinName sck );     // constructor( SPI )
        MPU9250( PinName sda, PinName scl, uint8_t addr = MPU9250_ADDR );   // constructor( I2C )        
        ~MPU9250();                                                         // destructor
        
        void    begin( void );
        void    reset( void );
        
        uint8_t getWhoAmI( void );
        
        void    setAccelRange( MPU9250BIT range );
        void    setGyroRange( MPU9250BIT range );
        void    setDLPF( MPU9250BIT range );

        void    read6AxisRaw( 
            int16_t* ax, int16_t* ay, int16_t* az, 
            int16_t* gx, int16_t* gy, int16_t* gz );
        void    read9AxisRaw( 
            int16_t* ax, int16_t* ay, int16_t* az, 
            int16_t* gx, int16_t* gy, int16_t* gz, 
            int16_t* mx, int16_t* my, int16_t* mz );
        void    readAccelRaw( int16_t* ax, int16_t* ay, int16_t* az );
        void    readGyroRaw(  int16_t* gx, int16_t* gy, int16_t* gz );
        void    readMagRaw(   int16_t* mx, int16_t* my, int16_t* mz );
        int16_t readTempRaw( void );

        void    read6Axis( 
            float* ax, float* ay, float* az, 
            float* gx, float* gy, float* gz );
        void    read9Axis( 
            float* ax, float* ay, float* az, 
            float* gx, float* gy, float* gz, 
            float* mx, float* my, float* mz );
        void    readAccel( float* ax, float* ay, float* az );
        void    readGyro(  float* gx, float* gy, float* gz );
        void    readMag(   float* mx, float* my, float* mz );
        float   readTemp( void );

    private:
        DigitalOut* _cs;
        SPI*        _spi;
        I2C*        _i2c;
        uint8_t     _i2c_addr;
        MPU9250IF   _imu_if;
        
        float       _accscale;
        float       _gyroscale;
//      float       _gyroscalerad;
        
        uint8_t _readRegister(   MPU9250REG addr );
        uint8_t _writeRegister(  MPU9250REG addr, uint8_t data );
        uint8_t _readBuffer(     MPU9250REG addr, uint8_t len, uint8_t* buf );
        uint8_t _writeBuffer(    MPU9250REG addr, uint8_t len, uint8_t* buf );
};

#endif