MAV'RIC
/home/travis/build/lis-epfl/MAVRIC_Library/drivers/mpu_9250.hpp
00001 /*******************************************************************************
00002  * Copyright (c) 2009-2016, MAV'RIC Development Team
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright notice,
00009  * this list of conditions and the following disclaimer.
00010  *
00011  * 2. Redistributions in binary form must reproduce the above copyright notice,
00012  * this list of conditions and the following disclaimer in the documentation
00013  * and/or other materials provided with the distribution.
00014  *
00015  * 3. Neither the name of the copyright holder nor the names of its contributors
00016  * may be used to endorse or promote products derived from this software without
00017  * specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00023  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029  * POSSIBILITY OF SUCH DAMAGE.
00030  ******************************************************************************/
00031 
00032 /*******************************************************************************
00033  * \file mpu_9250.hpp
00034  *
00035  * \author MAV'RIC Team
00036  * \author Jean-François Burnier
00037  *
00038  * \brief This file is the driver for the integrated 3axis gyroscope,
00039  *        accelerometer and magnetometer: MPU 9250
00040  *
00041  ******************************************************************************/
00042 
00043 
00044 #ifndef MPU_9250_HPP_
00045 #define MPU_9250_HPP_
00046 
00047 #include <cstdint>
00048 #include <array>
00049 
00050 #include "drivers/accelerometer.hpp"
00051 #include "drivers/gyroscope.hpp"
00052 #include "drivers/magnetometer.hpp"
00053 
00054 #include "hal/common/gpio.hpp"
00055 #include "hal/common/spi.hpp"
00056 
00062 class Mpu_9250_acc: public Accelerometer
00063 {
00064 public:
00065     virtual bool update_acc(void) = 0;
00066 
00067     bool update(void)
00068     {
00069         return update_acc();
00070     }
00071 };
00072 
00073 
00079 class Mpu_9250_gyr: public Gyroscope
00080 {
00081 public:
00082     virtual bool update_gyr(void) = 0;
00083 
00084     bool update(void)
00085     {
00086         return update_gyr();
00087     }
00088 };
00089 
00095  class Mpu_9250_mag: public Magnetometer
00096 {
00097 public:
00098     virtual bool update_mag(void) = 0;
00099 
00100     bool update(void)
00101     {
00102         return update_mag();
00103     }
00104 };
00105 
00106 
00115 class Mpu_9250: public Mpu_9250_acc, public Mpu_9250_gyr, public Mpu_9250_mag
00116 {
00117 public:
00118     /*
00119      * \brief   Enum for defining lowpass filter frequency
00120      *          for accelerometer
00121      */
00122     typedef enum
00123     {
00124         ACC_LOWPASS_460_HZ = 0x00,
00125         ACC_LOWPASS_184_HZ = 0x01,
00126         ACC_LOWPASS_92_HZ  = 0x02,
00127         ACC_LOWPASS_41_HZ  = 0x03,
00128         ACC_LOWPASS_20_HZ  = 0x04,
00129         ACC_LOWPASS_10_HZ  = 0x05,
00130         ACC_LOWPASS_5_HZ   = 0x06,
00131     } acc_filter_t;
00132 
00133     /*
00134      * \brief   Enum for defining range for accelerometer
00135      */
00136     typedef enum
00137     {
00138         ACC_2G    = 0x00,
00139         ACC_4G    = 0x08,
00140         ACC_8G    = 0x10,
00141         ACC_16G   = 0x18,
00142     } acc_range_t ;
00143 
00144     /*
00145      * \brief   Enum for defining lowpass filter frequency
00146      *          for gyroscope
00147      */
00148     typedef enum
00149     {
00150         GYRO_LOWPASS_250_HZ = 0x00,
00151         GYRO_LOWPASS_184_HZ = 0x01,
00152         GYRO_LOWPASS_92_HZ  = 0x02,
00153         GYRO_LOWPASS_41_HZ  = 0x03,
00154         GYRO_LOWPASS_20_HZ  = 0x04,
00155         GYRO_LOWPASS_10_HZ  = 0x05,
00156         GYRO_LOWPASS_5_HZ   = 0x06,
00157     } gyro_filter_t;
00158 
00159     /*
00160      * \brief   Enum for defining range for gyroscope
00161      */
00162     typedef enum
00163     {
00164         GYRO_250_DEG  = 0x00,
00165         GYRO_500_DEG  = 0x08,
00166         GYRO_1000_DEG = 0x10,
00167         GYRO_2000_DEG = 0x18,
00168     } gyro_range_t ;
00169 
00173     typedef struct
00174     {
00175         acc_filter_t       acc_filter;         
00176         acc_range_t        acc_range;          
00177         gyro_filter_t      gyro_filter;        
00178         gyro_range_t       gyro_range;         
00179         uint16_t           default_sample_rate;
00180 
00181     } conf_t;
00182 
00188     static inline conf_t mpu_9250_default_config()
00189     {
00190         conf_t conf                 = {};
00191 
00192         conf.acc_filter             = ACC_LOWPASS_184_HZ;
00193         conf.acc_range              = ACC_2G;
00194         conf.gyro_filter            = GYRO_LOWPASS_184_HZ;
00195         conf.gyro_range             = GYRO_500_DEG;
00196         // conf.gyro_range             = GYRO_1000_DEG;
00197         // conf.gyro_range             = GYRO_250_DEG;
00198         conf.default_sample_rate    = 500; // in Hz
00199 
00200         return conf;
00201     };
00202 
00210     Mpu_9250(Spi& spi, Gpio& nss_gpio, const conf_t config = mpu_9250_default_config());
00211 
00212 
00221     bool init(void);
00222 
00223 
00231     bool update_acc(void);
00232     bool update_gyr(void);
00233     bool update_mag(void);
00234 
00235 
00241     const float& last_update_us(void) const;
00242 
00243 
00253     const std::array<float, 3>& gyro(void) const;
00254 
00255 
00256 
00266     const float& gyro_X(void) const;
00267 
00268 
00278     const float& gyro_Y(void) const;
00279 
00280 
00290     const float& gyro_Z(void) const;
00291 
00292 
00302     const std::array<float, 3>& acc(void) const;
00303 
00304 
00314     const float& acc_X(void) const;
00315 
00316 
00326     const float& acc_Y(void) const;
00327 
00328 
00338     const float& acc_Z(void) const;
00339 
00349     const std::array<float, 3>& mag(void) const;
00350 
00351 
00361     const float& mag_X(void) const;
00362 
00363 
00373     const float& mag_Y(void) const;
00374 
00375 
00385     const float& mag_Z(void) const;
00386 
00392     const float& temperature(void) const;
00393 
00399     bool mpu_reset(void);
00400 
00406     bool mag_reset(void);
00407 
00416     bool mag_read_reg(uint8_t reg, uint8_t* in_data);
00417 
00426     bool mag_write_reg(uint8_t reg, uint8_t* out_data);
00427 
00441     bool write_reg(uint8_t reg, uint8_t* out_data, uint32_t nbytes = 1);
00442 
00456     bool read_reg(uint8_t reg, uint8_t* in_data, uint32_t nbytes = 1);
00457 
00458     // AK8963 register addresses
00459     static const uint8_t AK8963_WHOAMI_REG     = 0x00;
00460     static const uint8_t AK8963_ST1_REG        = 0x02;
00461     static const uint8_t AK8963_HXL            = 0x03;
00462     static const uint8_t AK8963_ST2_REG        = 0x09;
00463 
00464     // AK8963 register bits
00465     static const uint8_t AK8963_CNTL1_CONT_8HZ     = 0x02;
00466     static const uint8_t AK8963_CNTL1_CONT_100HZ   = 0x06;
00467     static const uint8_t AK8963_CNTL1_16BITS       = 0x10;
00468     static const uint8_t AK8963_CNTL1_REG          = 0x0A;
00469     static const uint8_t AK8963_CNTL2_REG          = 0x0B;
00470     static const uint8_t AK8963_CNTL2_SRST         = 0x01;
00471     static const uint8_t AK8963_WHOAMI_ID          = 0x48;
00472 
00473     // MPU9250 register adresses
00474     static const uint8_t AK8963_ADDR           = 0x0C;
00475     static const uint8_t SMPLRT_DIV_REG        = 0x19;
00476     static const uint8_t DLPF_CFG_REG          = 0x1A;
00477     static const uint8_t GYRO_CFG_REG          = 0x1B;
00478     static const uint8_t ACCEL_CFG_REG         = 0x1C;
00479     static const uint8_t ACCEL_CFG2_REG        = 0x1D;
00480     static const uint8_t SLV0_ADDR_REG         = 0x25;
00481     static const uint8_t SLV0_REG_REG          = 0x26;
00482     static const uint8_t SLV0_CTRL_REG         = 0x27;
00483     static const uint8_t SLV4_ADDR_REG         = 0x31;
00484     static const uint8_t SLV4_REG_REG          = 0x32;
00485     static const uint8_t SLV4_DO_REG           = 0x33;
00486     static const uint8_t SLV4_CTRL_REG         = 0x34;
00487     static const uint8_t SLV4_DI_REG           = 0x35;
00488     static const uint8_t I2C_MST_STATUS_REG    = 0x36;
00489     static const uint8_t ACCEL_X_OUT_MSB       = 0x3B;
00490     static const uint8_t ACCEL_X_OUT_LSB       = 0x3C;
00491     static const uint8_t ACCEL_Y_OUT_MSB       = 0x3D;
00492     static const uint8_t ACCEL_Y_OUT_LSB       = 0x3E;
00493     static const uint8_t ACCEL_Z_OUT_MSB       = 0x3F;
00494     static const uint8_t ACCEL_Z_OUT_LSB       = 0x40;
00495     static const uint8_t GYRO_X_OUT_MSB        = 0x43;
00496     static const uint8_t GYRO_X_OUT_LSB        = 0x44;
00497     static const uint8_t GYRO_Y_OUT_MSB        = 0x45;
00498     static const uint8_t GYRO_Y_OUT_LSB        = 0x46;
00499     static const uint8_t GYRO_Z_OUT_MSB        = 0x47;
00500     static const uint8_t GYRO_Z_OUT_LSB        = 0x48;
00501     static const uint8_t EXT_SENS_DATA_00      = 0x49;
00502     static const uint8_t USER_CTRL_REG         = 0x6A;
00503     static const uint8_t PWR_MGMT_REG          = 0x6B;
00504     static const uint8_t WHOAMI_REG            = 0x75;
00505 
00506     // MPU9250 register bits
00507     static const uint8_t READ_FLAG     = 0x80;
00508     static const uint8_t WRITE_FLAG    = 0x7f;
00509     static const uint8_t WHOAMI_ID     = 0x71;
00510 
00511     // I2C master status register bits
00512     static const uint8_t I2C_MST_SLV4_NACK = 0x10;
00513     static const uint8_t I2C_MST_SLV4_DONE = 0x40;
00514 
00515     // I2C SLV register bits
00516     static const uint8_t I2CSLV_EN     = 0x80;
00517 
00518     // Power management and clock selection
00519     static const uint8_t PWRMGMT_IMU_RST   = 0x80;
00520     static const uint8_t PWRMGMT_PLL_X_CLK = 0x01;
00521 
00522     // User control registers
00523     static const uint8_t USERCTL_DIS_I2C       = 0x10;
00524     static const uint8_t USERCTL_I2C_MST_EN    = 0x20;
00525     static const uint8_t USERCTL_GYRO_RST      = 0x01;
00526 
00527 private:
00528     Spi&                    spi_;              
00529     Gpio&                   nss_;              
00530     std::array<float, 3>    acc_data_;         
00531     std::array<float, 3>    gyro_data_;        
00532     std::array<float, 3>    mag_data_;         
00533     float                   temperature_;      
00534     float                   last_update_us_;   
00535     conf_t                  config_;           
00536     float                   acc_scale_;        
00537     float                   gyro_scale_;       
00538 
00544     bool set_acc_lpf(void);
00545 
00551     bool set_gyro_lpf(void);
00552 
00558     bool set_mpu_sample_rate(void);
00559 
00569     bool set_mag_mode(void);
00570 
00576     bool set_acc_range(void);
00577 
00583     bool set_gyro_range(void);
00584 
00588     void select_slave(void);
00589 
00593     void unselect_slave(void);
00594 
00595 };
00596 
00597 #endif /* MPU_9250_HPP_ */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines