MAV'RIC
|
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_ */