inv_mpu.c D:/gitt/MicrochipFor32/bsp_MPU6050/inv_mpu.c 浏览该文件的文档.00001 /* 00002 $License: 00003 Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. 00004 See included License.txt for License information. 00005 $ 00006 */ 00020 #include <stdio.h> 00021 #include <stdlib.h> 00022 #include <string.h> 00023 #include <math.h> 00024 #include "inv_mpu.h" 00025 #include "inv_mpu_dmp_motion_driver.h" 00026 #include "mpu6050.h" 00027 #include "usart.h" 00028 #include "varint.h" 00029 00030 #define MPU6050 //定义我们使用的传感器为MPU6050 00031 #define MOTION_DRIVER_TARGET_MSP430 //定义驱动部分,采用MSP430的驱动(移植到STM32F1) 00032 00033 /* The following functions must be defined for this platform: 00034 * i2c_write(unsigned char slave_addr, unsigned char reg_addr, 00035 * unsigned char length, unsigned char const *data) 00036 * i2c_read(unsigned char slave_addr, unsigned char reg_addr, 00037 * unsigned char length, unsigned char *data) 00038 * delay_ms(unsigned long num_ms) 00039 * get_ms(unsigned long *count) 00040 * reg_int_cb(void (*cb)(void), unsigned char port, unsigned char pin) 00041 * labs(long x) 00042 * fabsf(float x) 00043 * min(int a, int b) 00044 */ 00045 #if defined MOTION_DRIVER_TARGET_MSP430 00046 00047 #define i2c_write MPU_Write_Len 00048 #define i2c_read MPU_Read_Len 00049 #define delay_ms HAL_Delay 00050 #define get_ms mget_ms 00051 //static inline int reg_int_cb(struct int_param_s *int_param) 00052 //{ 00053 // return msp430_reg_int_cb(int_param->cb, int_param->pin, int_param->lp_exit, 00054 // int_param->active_low); 00055 //} 00056 void log_none(char *fmt,...){;} 00057 #define log_i log_none //打印信息 00058 #define log_e log_none //打印信息 00059 /* labs is already defined by TI's toolchain. */ 00060 /* fabs is for doubles. fabsf is for floats. */ 00061 #define fabs fabsf 00062 #define min(a,b) ((a<b)?a:b) 00063 #elif defined EMPL_TARGET_MSP430 00064 #include "msp430.h" 00065 #include "msp430_i2c.h" 00066 #include "msp430_clock.h" 00067 #include "msp430_interrupt.h" 00068 #include "log.h" 00069 #define i2c_write msp430_i2c_write 00070 #define i2c_read msp430_i2c_read 00071 #define delay_ms msp430_delay_ms 00072 #define get_ms msp430_get_clock_ms 00073 static inline int reg_int_cb(struct int_param_s *int_param) 00074 { 00075 return msp430_reg_int_cb(int_param->cb, int_param->pin, int_param->lp_exit, 00076 int_param->active_low); 00077 } 00078 #define log_i MPL_LOGI 00079 #define log_e MPL_LOGE 00080 /* labs is already defined by TI's toolchain. */ 00081 /* fabs is for doubles. fabsf is for floats. */ 00082 #define fabs fabsf 00083 #define min(a,b) ((a<b)?a:b) 00084 #elif defined EMPL_TARGET_UC3L0 00085 /* Instead of using the standard TWI driver from the ASF library, we're using 00086 * a TWI driver that follows the slave address + register address convention. 00087 */ 00088 #include "twi.h" 00089 #include "delay.h" 00090 #include "sysclk.h" 00091 #include "log.h" 00092 #include "sensors_xplained.h" 00093 #include "uc3l0_clock.h" 00094 #define i2c_write(a, b, c, d) twi_write(a, b, d, c) 00095 #define i2c_read(a, b, c, d) twi_read(a, b, d, c) 00096 /* delay_ms is a function already defined in ASF. */ 00097 #define get_ms uc3l0_get_clock_ms 00098 static inline int reg_int_cb(struct int_param_s *int_param) 00099 { 00100 sensor_board_irq_connect(int_param->pin, int_param->cb, int_param->arg); 00101 return 0; 00102 } 00103 #define log_i MPL_LOGI 00104 #define log_e MPL_LOGE 00105 /* UC3 is a 32-bit processor, so abs and labs are equivalent. */ 00106 #define labs abs 00107 #define fabs(x) (((x)>0)?(x):-(x)) 00108 #else 00109 #error Gyro driver is missing the system layer implementations. 00110 #endif 00111 00112 #if !defined MPU6050 && !defined MPU9150 && !defined MPU6500 && !defined MPU9250 00113 #error Which gyro are you using? Define MPUxxxx in your compiler options. 00114 #endif 00115 00116 /* Time for some messy macro work. =] 00117 * #define MPU9150 00118 * is equivalent to.. 00119 * #define MPU6050 00120 * #define AK8975_SECONDARY 00121 * 00122 * #define MPU9250 00123 * is equivalent to.. 00124 * #define MPU6500 00125 * #define AK8963_SECONDARY 00126 */ 00127 #if defined MPU9150 00128 #ifndef MPU6050 00129 #define MPU6050 00130 #endif /* #ifndef MPU6050 */ 00131 #if defined AK8963_SECONDARY 00132 #error "MPU9150 and AK8963_SECONDARY cannot both be defined." 00133 #elif !defined AK8975_SECONDARY /* #if defined AK8963_SECONDARY */ 00134 #define AK8975_SECONDARY 00135 #endif /* #if defined AK8963_SECONDARY */ 00136 #elif defined MPU9250 /* #if defined MPU9150 */ 00137 #ifndef MPU6500 00138 #define MPU6500 00139 #endif /* #ifndef MPU6500 */ 00140 #if defined AK8975_SECONDARY 00141 #error "MPU9250 and AK8975_SECONDARY cannot both be defined." 00142 #elif !defined AK8963_SECONDARY /* #if defined AK8975_SECONDARY */ 00143 #define AK8963_SECONDARY 00144 #endif /* #if defined AK8975_SECONDARY */ 00145 #endif /* #if defined MPU9150 */ 00146 00147 #if defined AK8975_SECONDARY || defined AK8963_SECONDARY 00148 #define AK89xx_SECONDARY 00149 #else 00150 /* #warning "No compass = less profit for Invensense. Lame." */ 00151 #endif 00152 00153 static int set_int_enable(unsigned char enable); 00154 00155 /* Hardware registers needed by driver. */ 00156 struct gyro_reg_s { 00157 unsigned char who_am_i; 00158 unsigned char rate_div; 00159 unsigned char lpf; 00160 unsigned char prod_id; 00161 unsigned char user_ctrl; 00162 unsigned char fifo_en; 00163 unsigned char gyro_cfg; 00164 unsigned char accel_cfg; 00165 // unsigned char accel_cfg2; 00166 // unsigned char lp_accel_odr; 00167 unsigned char motion_thr; 00168 unsigned char motion_dur; 00169 unsigned char fifo_count_h; 00170 unsigned char fifo_r_w; 00171 unsigned char raw_gyro; 00172 unsigned char raw_accel; 00173 unsigned char temp; 00174 unsigned char int_enable; 00175 unsigned char dmp_int_status; 00176 unsigned char int_status; 00177 // unsigned char accel_intel; 00178 unsigned char pwr_mgmt_1; 00179 unsigned char pwr_mgmt_2; 00180 unsigned char int_pin_cfg; 00181 unsigned char mem_r_w; 00182 unsigned char accel_offs; 00183 unsigned char i2c_mst; 00184 unsigned char bank_sel; 00185 unsigned char mem_start_addr; 00186 unsigned char prgm_start_h; 00187 #if defined AK89xx_SECONDARY 00188 unsigned char s0_addr; 00189 unsigned char s0_reg; 00190 unsigned char s0_ctrl; 00191 unsigned char s1_addr; 00192 unsigned char s1_reg; 00193 unsigned char s1_ctrl; 00194 unsigned char s4_ctrl; 00195 unsigned char s0_do; 00196 unsigned char s1_do; 00197 unsigned char i2c_delay_ctrl; 00198 unsigned char raw_compass; 00199 /* The I2C_MST_VDDIO bit is in this register. */ 00200 unsigned char yg_offs_tc; 00201 #endif 00202 }; 00203 00204 /* Information specific to a particular device. */ 00205 struct hw_s { 00206 unsigned char addr; 00207 unsigned short max_fifo; 00208 unsigned char num_reg; 00209 unsigned short temp_sens; 00210 short temp_offset; 00211 unsigned short bank_size; 00212 #if defined AK89xx_SECONDARY 00213 unsigned short compass_fsr; 00214 #endif 00215 }; 00216 00217 /* When entering motion interrupt mode, the driver keeps track of the 00218 * previous state so that it can be restored at a later time. 00219 * TODO: This is tacky. Fix it. 00220 */ 00221 struct motion_int_cache_s { 00222 unsigned short gyro_fsr; 00223 unsigned char accel_fsr; 00224 unsigned short lpf; 00225 unsigned short sample_rate; 00226 unsigned char sensors_on; 00227 unsigned char fifo_sensors; 00228 unsigned char dmp_on; 00229 }; 00230 00231 /* Cached chip configuration data. 00232 * TODO: A lot of these can be handled with a bitmask. 00233 */ 00234 struct chip_cfg_s { 00235 /* Matches gyro_cfg >> 3 & 0x03 */ 00236 unsigned char gyro_fsr; 00237 /* Matches accel_cfg >> 3 & 0x03 */ 00238 unsigned char accel_fsr; 00239 /* Enabled sensors. Uses same masks as fifo_en, NOT pwr_mgmt_2. */ 00240 unsigned char sensors; 00241 /* Matches config register. */ 00242 unsigned char lpf; 00243 unsigned char clk_src; 00244 /* Sample rate, NOT rate divider. */ 00245 unsigned short sample_rate; 00246 /* Matches fifo_en register. */ 00247 unsigned char fifo_enable; 00248 /* Matches int enable register. */ 00249 unsigned char int_enable; 00250 /* 1 if devices on auxiliary I2C bus appear on the primary. */ 00251 unsigned char bypass_mode; 00252 /* 1 if half-sensitivity. 00253 * NOTE: This doesn't belong here, but everything else in hw_s is const, 00254 * and this allows us to save some precious RAM. 00255 */ 00256 unsigned char accel_half; 00257 /* 1 if device in low-power accel-only mode. */ 00258 unsigned char lp_accel_mode; 00259 /* 1 if interrupts are only triggered on motion events. */ 00260 unsigned char int_motion_only; 00261 struct motion_int_cache_s cache; 00262 /* 1 for active low interrupts. */ 00263 unsigned char active_low_int; 00264 /* 1 for latched interrupts. */ 00265 unsigned char latched_int; 00266 /* 1 if DMP is enabled. */ 00267 unsigned char dmp_on; 00268 /* Ensures that DMP will only be loaded once. */ 00269 unsigned char dmp_loaded; 00270 /* Sampling rate used when DMP is enabled. */ 00271 unsigned short dmp_sample_rate; 00272 #ifdef AK89xx_SECONDARY 00273 /* Compass sample rate. */ 00274 unsigned short compass_sample_rate; 00275 unsigned char compass_addr; 00276 short mag_sens_adj[3]; 00277 #endif 00278 }; 00279 00280 /* Information for self-test. */ 00281 struct test_s { 00282 unsigned long gyro_sens; 00283 unsigned long accel_sens; 00284 unsigned char reg_rate_div; 00285 unsigned char reg_lpf; 00286 unsigned char reg_gyro_fsr; 00287 unsigned char reg_accel_fsr; 00288 unsigned short wait_ms; 00289 unsigned char packet_thresh; 00290 float min_dps; 00291 float max_dps; 00292 float max_gyro_var; 00293 float min_g; 00294 float max_g; 00295 float max_accel_var; 00296 }; 00297 00298 /* Gyro driver state variables. */ 00299 struct gyro_state_s { 00300 const struct gyro_reg_s *reg; 00301 const struct hw_s *hw; 00302 struct chip_cfg_s chip_cfg; 00303 const struct test_s *test; 00304 }; 00305 00306 /* Filter configurations. */ 00307 enum lpf_e { 00308 INV_FILTER_256HZ_NOLPF2 = 0, 00309 INV_FILTER_188HZ, 00310 INV_FILTER_98HZ, 00311 INV_FILTER_42HZ, 00312 INV_FILTER_20HZ, 00313 INV_FILTER_10HZ, 00314 INV_FILTER_5HZ, 00315 INV_FILTER_2100HZ_NOLPF, 00316 NUM_FILTER 00317 }; 00318 00319 /* Full scale ranges. */ 00320 enum gyro_fsr_e { 00321 INV_FSR_250DPS = 0, 00322 INV_FSR_500DPS, 00323 INV_FSR_1000DPS, 00324 INV_FSR_2000DPS, 00325 NUM_GYRO_FSR 00326 }; 00327 00328 /* Full scale ranges. */ 00329 enum accel_fsr_e { 00330 INV_FSR_2G = 0, 00331 INV_FSR_4G, 00332 INV_FSR_8G, 00333 INV_FSR_16G, 00334 NUM_ACCEL_FSR 00335 }; 00336 00337 /* Clock sources. */ 00338 enum clock_sel_e { 00339 INV_CLK_INTERNAL = 0, 00340 INV_CLK_PLL, 00341 NUM_CLK 00342 }; 00343 00344 /* Low-power accel wakeup rates. */ 00345 enum lp_accel_rate_e { 00346 #if defined MPU6050 00347 INV_LPA_1_25HZ, 00348 INV_LPA_5HZ, 00349 INV_LPA_20HZ, 00350 INV_LPA_40HZ 00351 #elif defined MPU6500 00352 INV_LPA_0_3125HZ, 00353 INV_LPA_0_625HZ, 00354 INV_LPA_1_25HZ, 00355 INV_LPA_2_5HZ, 00356 INV_LPA_5HZ, 00357 INV_LPA_10HZ, 00358 INV_LPA_20HZ, 00359 INV_LPA_40HZ, 00360 INV_LPA_80HZ, 00361 INV_LPA_160HZ, 00362 INV_LPA_320HZ, 00363 INV_LPA_640HZ 00364 #endif 00365 }; 00366 00367 #define BIT_I2C_MST_VDDIO (0x80) 00368 #define BIT_FIFO_EN (0x40) 00369 #define BIT_DMP_EN (0x80) 00370 #define BIT_FIFO_RST (0x04) 00371 #define BIT_DMP_RST (0x08) 00372 #define BIT_FIFO_OVERFLOW (0x10) 00373 #define BIT_DATA_RDY_EN (0x01) 00374 #define BIT_DMP_INT_EN (0x02) 00375 #define BIT_MOT_INT_EN (0x40) 00376 #define BITS_FSR (0x18) 00377 #define BITS_LPF (0x07) 00378 #define BITS_HPF (0x07) 00379 #define BITS_CLK (0x07) 00380 #define BIT_FIFO_SIZE_1024 (0x40) 00381 #define BIT_FIFO_SIZE_2048 (0x80) 00382 #define BIT_FIFO_SIZE_4096 (0xC0) 00383 #define BIT_RESET (0x80) 00384 #define BIT_SLEEP (0x40) 00385 #define BIT_S0_DELAY_EN (0x01) 00386 #define BIT_S2_DELAY_EN (0x04) 00387 #define BITS_SLAVE_LENGTH (0x0F) 00388 #define BIT_SLAVE_BYTE_SW (0x40) 00389 #define BIT_SLAVE_GROUP (0x10) 00390 #define BIT_SLAVE_EN (0x80) 00391 #define BIT_I2C_READ (0x80) 00392 #define BITS_I2C_MASTER_DLY (0x1F) 00393 #define BIT_AUX_IF_EN (0x20) 00394 #define BIT_ACTL (0x80) 00395 #define BIT_LATCH_EN (0x20) 00396 #define BIT_ANY_RD_CLR (0x10) 00397 #define BIT_BYPASS_EN (0x02) 00398 #define BITS_WOM_EN (0xC0) 00399 #define BIT_LPA_CYCLE (0x20) 00400 #define BIT_STBY_XA (0x20) 00401 #define BIT_STBY_YA (0x10) 00402 #define BIT_STBY_ZA (0x08) 00403 #define BIT_STBY_XG (0x04) 00404 #define BIT_STBY_YG (0x02) 00405 #define BIT_STBY_ZG (0x01) 00406 #define BIT_STBY_XYZA (BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA) 00407 #define BIT_STBY_XYZG (BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG) 00408 00409 #if defined AK8975_SECONDARY 00410 #define SUPPORTS_AK89xx_HIGH_SENS (0x00) 00411 #define AK89xx_FSR (9830) 00412 #elif defined AK8963_SECONDARY 00413 #define SUPPORTS_AK89xx_HIGH_SENS (0x10) 00414 #define AK89xx_FSR (4915) 00415 #endif 00416 00417 #ifdef AK89xx_SECONDARY 00418 #define AKM_REG_WHOAMI (0x00) 00419 00420 #define AKM_REG_ST1 (0x02) 00421 #define AKM_REG_HXL (0x03) 00422 #define AKM_REG_ST2 (0x09) 00423 00424 #define AKM_REG_CNTL (0x0A) 00425 #define AKM_REG_ASTC (0x0C) 00426 #define AKM_REG_ASAX (0x10) 00427 #define AKM_REG_ASAY (0x11) 00428 #define AKM_REG_ASAZ (0x12) 00429 00430 #define AKM_DATA_READY (0x01) 00431 #define AKM_DATA_OVERRUN (0x02) 00432 #define AKM_OVERFLOW (0x80) 00433 #define AKM_DATA_ERROR (0x40) 00434 00435 #define AKM_BIT_SELF_TEST (0x40) 00436 00437 #define AKM_POWER_DOWN (0x00 | SUPPORTS_AK89xx_HIGH_SENS) 00438 #define AKM_SINGLE_MEASUREMENT (0x01 | SUPPORTS_AK89xx_HIGH_SENS) 00439 #define AKM_FUSE_ROM_ACCESS (0x0F | SUPPORTS_AK89xx_HIGH_SENS) 00440 #define AKM_MODE_SELF_TEST (0x08 | SUPPORTS_AK89xx_HIGH_SENS) 00441 00442 #define AKM_WHOAMI (0x48) 00443 #endif 00444 00445 #if defined MPU6050 00446 //const struct gyro_reg_s reg = { 00447 // .who_am_i = 0x75, 00448 // .rate_div = 0x19, 00449 // .lpf = 0x1A, 00450 // .prod_id = 0x0C, 00451 // .user_ctrl = 0x6A, 00452 // .fifo_en = 0x23, 00453 // .gyro_cfg = 0x1B, 00454 // .accel_cfg = 0x1C, 00455 // .motion_thr = 0x1F, 00456 // .motion_dur = 0x20, 00457 // .fifo_count_h = 0x72, 00458 // .fifo_r_w = 0x74, 00459 // .raw_gyro = 0x43, 00460 // .raw_accel = 0x3B, 00461 // .temp = 0x41, 00462 // .int_enable = 0x38, 00463 // .dmp_int_status = 0x39, 00464 // .int_status = 0x3A, 00465 // .pwr_mgmt_1 = 0x6B, 00466 // .pwr_mgmt_2 = 0x6C, 00467 // .int_pin_cfg = 0x37, 00468 // .mem_r_w = 0x6F, 00469 // .accel_offs = 0x06, 00470 // .i2c_mst = 0x24, 00471 // .bank_sel = 0x6D, 00472 // .mem_start_addr = 0x6E, 00473 // .prgm_start_h = 0x70 00474 //#ifdef AK89xx_SECONDARY 00475 // ,.raw_compass = 0x49, 00476 // .yg_offs_tc = 0x01, 00477 // .s0_addr = 0x25, 00478 // .s0_reg = 0x26, 00479 // .s0_ctrl = 0x27, 00480 // .s1_addr = 0x28, 00481 // .s1_reg = 0x29, 00482 // .s1_ctrl = 0x2A, 00483 // .s4_ctrl = 0x34, 00484 // .s0_do = 0x63, 00485 // .s1_do = 0x64, 00486 // .i2c_delay_ctrl = 0x67 00487 //#endif 00488 //}; 00489 const struct gyro_reg_s reg = { 00490 0x75, //who_am_i 00491 0x19, //rate_div 00492 0x1A, //lpf 00493 0x0C, //prod_id 00494 0x6A, //user_ctrl 00495 0x23, //fifo_en 00496 0x1B, //gyro_cfg 00497 0x1C, //accel_cfg 00498 0x1F, // motion_thr 00499 0x20, // motion_dur 00500 0x72, // fifo_count_h 00501 0x74, // fifo_r_w 00502 0x43, // raw_gyro 00503 0x3B, // raw_accel 00504 0x41, // temp 00505 0x38, // int_enable 00506 0x39, // dmp_int_status 00507 0x3A, // int_status 00508 0x6B, // pwr_mgmt_1 00509 0x6C, // pwr_mgmt_2 00510 0x37, // int_pin_cfg 00511 0x6F, // mem_r_w 00512 0x06, // accel_offs 00513 0x24, // i2c_mst 00514 0x6D, // bank_sel 00515 0x6E, // mem_start_addr 00516 0x70 // prgm_start_h 00517 }; 00518 00519 //const struct hw_s hw = { 00520 // .addr = 0x68, 00521 // .max_fifo = 1024, 00522 // .num_reg = 118, 00523 // .temp_sens = 340, 00524 // .temp_offset = -521, 00525 // .bank_size = 256 00526 //#if defined AK89xx_SECONDARY 00527 // ,.compass_fsr = AK89xx_FSR 00528 //#endif 00529 //}; 00530 const struct hw_s hw={ 00531 0x68, //addr 00532 1024, //max_fifo 00533 118, //num_reg 00534 340, //temp_sens 00535 -521, //temp_offset 00536 256 //bank_size 00537 }; 00538 00539 //const struct test_s test = { 00540 // .gyro_sens = 32768/250, 00541 // .accel_sens = 32768/16, 00542 // .reg_rate_div = 0, /* 1kHz. */ 00543 // .reg_lpf = 1, /* 188Hz. */ 00544 // .reg_gyro_fsr = 0, /* 250dps. */ 00545 // .reg_accel_fsr = 0x18, /* 16g. */ 00546 // .wait_ms = 50, 00547 // .packet_thresh = 5, /* 5% */ 00548 // .min_dps = 10.f, 00549 // .max_dps = 105.f, 00550 // .max_gyro_var = 0.14f, 00551 // .min_g = 0.3f, 00552 // .max_g = 0.95f, 00553 // .max_accel_var = 0.14f 00554 //}; 00555 const struct test_s test={ 00556 32768/250, //gyro_sens 00557 32768/16, // accel_sens 00558 0, // reg_rate_div 00559 1, // reg_lpf 00560 0, // reg_gyro_fsr 00561 0x18, // reg_accel_fsr 00562 50, // wait_ms 00563 5, // packet_thresh 00564 10.0f, // min_dps 00565 105.0f, // max_dps 00566 0.14f, // max_gyro_var 00567 0.3f, // min_g 00568 0.95f, // max_g 00569 0.14f // max_accel_var 00570 }; 00571 00572 //static struct gyro_state_s st = { 00573 // .reg = &reg, 00574 // .hw = &hw, 00575 // .test = &test 00576 //}; 00577 static struct gyro_state_s st={ 00578 &reg, 00579 &hw, 00580 {0}, 00581 &test 00582 }; 00583 00584 00585 #elif defined MPU6500 00586 const struct gyro_reg_s reg = { 00587 .who_am_i = 0x75, 00588 .rate_div = 0x19, 00589 .lpf = 0x1A, 00590 .prod_id = 0x0C, 00591 .user_ctrl = 0x6A, 00592 .fifo_en = 0x23, 00593 .gyro_cfg = 0x1B, 00594 .accel_cfg = 0x1C, 00595 .accel_cfg2 = 0x1D, 00596 .lp_accel_odr = 0x1E, 00597 .motion_thr = 0x1F, 00598 .motion_dur = 0x20, 00599 .fifo_count_h = 0x72, 00600 .fifo_r_w = 0x74, 00601 .raw_gyro = 0x43, 00602 .raw_accel = 0x3B, 00603 .temp = 0x41, 00604 .int_enable = 0x38, 00605 .dmp_int_status = 0x39, 00606 .int_status = 0x3A, 00607 .accel_intel = 0x69, 00608 .pwr_mgmt_1 = 0x6B, 00609 .pwr_mgmt_2 = 0x6C, 00610 .int_pin_cfg = 0x37, 00611 .mem_r_w = 0x6F, 00612 .accel_offs = 0x77, 00613 .i2c_mst = 0x24, 00614 .bank_sel = 0x6D, 00615 .mem_start_addr = 0x6E, 00616 .prgm_start_h = 0x70 00617 #ifdef AK89xx_SECONDARY 00618 ,.raw_compass = 0x49, 00619 .s0_addr = 0x25, 00620 .s0_reg = 0x26, 00621 .s0_ctrl = 0x27, 00622 .s1_addr = 0x28, 00623 .s1_reg = 0x29, 00624 .s1_ctrl = 0x2A, 00625 .s4_ctrl = 0x34, 00626 .s0_do = 0x63, 00627 .s1_do = 0x64, 00628 .i2c_delay_ctrl = 0x67 00629 #endif 00630 }; 00631 const struct hw_s hw = { 00632 .addr = 0x68, 00633 .max_fifo = 1024, 00634 .num_reg = 128, 00635 .temp_sens = 321, 00636 .temp_offset = 0, 00637 .bank_size = 256 00638 #if defined AK89xx_SECONDARY 00639 ,.compass_fsr = AK89xx_FSR 00640 #endif 00641 }; 00642 00643 const struct test_s test = { 00644 .gyro_sens = 32768/250, 00645 .accel_sens = 32768/16, 00646 .reg_rate_div = 0, /* 1kHz. */ 00647 .reg_lpf = 1, /* 188Hz. */ 00648 .reg_gyro_fsr = 0, /* 250dps. */ 00649 .reg_accel_fsr = 0x18, /* 16g. */ 00650 .wait_ms = 50, 00651 .packet_thresh = 5, /* 5% */ 00652 .min_dps = 10.f, 00653 .max_dps = 105.f, 00654 .max_gyro_var = 0.14f, 00655 .min_g = 0.3f, 00656 .max_g = 0.95f, 00657 .max_accel_var = 0.14f 00658 }; 00659 00660 static struct gyro_state_s st = { 00661 .reg = &reg, 00662 .hw = &hw, 00663 .test = &test 00664 }; 00665 #endif 00666 00667 #define MAX_PACKET_LENGTH (12) 00668 00669 #ifdef AK89xx_SECONDARY 00670 static int setup_compass(void); 00671 #define MAX_COMPASS_SAMPLE_RATE (100) 00672 #endif 00673 00681 static int set_int_enable(unsigned char enable) 00682 { 00683 unsigned char tmp; 00684 00685 if (st.chip_cfg.dmp_on) { 00686 if (enable) 00687 tmp = BIT_DMP_INT_EN; 00688 else 00689 tmp = 0x00; 00690 if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &tmp)) 00691 return -1; 00692 st.chip_cfg.int_enable = tmp; 00693 } else { 00694 if (!st.chip_cfg.sensors) 00695 return -1; 00696 if (enable && st.chip_cfg.int_enable) 00697 return 0; 00698 if (enable) 00699 tmp = BIT_DATA_RDY_EN; 00700 else 00701 tmp = 0x00; 00702 if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &tmp)) 00703 return -1; 00704 st.chip_cfg.int_enable = tmp; 00705 } 00706 return 0; 00707 } 00708 00713 int mpu_reg_dump(void) 00714 { 00715 unsigned char ii; 00716 unsigned char data; 00717 00718 for (ii = 0; ii < st.hw->num_reg; ii++) { 00719 if (ii == st.reg->fifo_r_w || ii == st.reg->mem_r_w) 00720 continue; 00721 if (i2c_read(st.hw->addr, ii, 1, &data)) 00722 return -1; 00723 log_i("%#5x: %#5x\r\n", ii, data); 00724 } 00725 return 0; 00726 } 00727 00735 int mpu_read_reg(unsigned char reg, unsigned char *data) 00736 { 00737 if (reg == st.reg->fifo_r_w || reg == st.reg->mem_r_w) 00738 return -1; 00739 if (reg >= st.hw->num_reg) 00740 return -1; 00741 return i2c_read(st.hw->addr, reg, 1, data); 00742 } 00743 00757 int mpu_init(void) 00758 { 00759 unsigned char data[6], rev; 00760 00761 /* Reset device. */ 00762 data[0] = BIT_RESET; 00763 if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) 00764 return -1; 00765 delay_ms(100); 00766 00767 /* Wake up chip. */ 00768 data[0] = 0x00; 00769 if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) 00770 return -1; 00771 00772 #if defined MPU6050 00773 /* Check product revision. */ 00774 if (i2c_read(st.hw->addr, st.reg->accel_offs, 6, data)) 00775 return -1; 00776 rev = ((data[5] & 0x01) << 2) | ((data[3] & 0x01) << 1) | 00777 (data[1] & 0x01); 00778 00779 if (rev) { 00780 /* Congrats, these parts are better. */ 00781 if (rev == 1) 00782 st.chip_cfg.accel_half = 1; 00783 else if (rev == 2) 00784 st.chip_cfg.accel_half = 0; 00785 else { 00786 log_e("Unsupported software product rev %d.\n", rev); 00787 return -1; 00788 } 00789 } else { 00790 if (i2c_read(st.hw->addr, st.reg->prod_id, 1, data)) 00791 return -1; 00792 rev = data[0] & 0x0F; 00793 if (!rev) { 00794 log_e("Product ID read as 0 indicates device is either " 00795 "incompatible or an MPU3050.\n"); 00796 return -1; 00797 } else if (rev == 4) { 00798 log_i("Half sensitivity part found.\n"); 00799 st.chip_cfg.accel_half = 1; 00800 } else 00801 st.chip_cfg.accel_half = 0; 00802 } 00803 #elif defined MPU6500 00804 #define MPU6500_MEM_REV_ADDR (0x17) 00805 if (mpu_read_mem(MPU6500_MEM_REV_ADDR, 1, &rev)) 00806 return -1; 00807 if (rev == 0x1) 00808 st.chip_cfg.accel_half = 0; 00809 else { 00810 log_e("Unsupported software product rev %d.\n", rev); 00811 return -1; 00812 } 00813 00814 /* MPU6500 shares 4kB of memory between the DMP and the FIFO. Since the 00815 * first 3kB are needed by the DMP, we'll use the last 1kB for the FIFO. 00816 */ 00817 data[0] = BIT_FIFO_SIZE_1024 | 0x8; 00818 if (i2c_write(st.hw->addr, st.reg->accel_cfg2, 1, data)) 00819 return -1; 00820 #endif 00821 00822 /* Set to invalid values to ensure no I2C writes are skipped. */ 00823 st.chip_cfg.sensors = 0xFF; 00824 st.chip_cfg.gyro_fsr = 0xFF; 00825 st.chip_cfg.accel_fsr = 0xFF; 00826 st.chip_cfg.lpf = 0xFF; 00827 st.chip_cfg.sample_rate = 0xFFFF; 00828 st.chip_cfg.fifo_enable = 0xFF; 00829 st.chip_cfg.bypass_mode = 0xFF; 00830 #ifdef AK89xx_SECONDARY 00831 st.chip_cfg.compass_sample_rate = 0xFFFF; 00832 #endif 00833 /* mpu_set_sensors always preserves this setting. */ 00834 st.chip_cfg.clk_src = INV_CLK_PLL; 00835 /* Handled in next call to mpu_set_bypass. */ 00836 st.chip_cfg.active_low_int = 1; 00837 st.chip_cfg.latched_int = 0; 00838 st.chip_cfg.int_motion_only = 0; 00839 st.chip_cfg.lp_accel_mode = 0; 00840 memset(&st.chip_cfg.cache, 0, sizeof(st.chip_cfg.cache)); 00841 st.chip_cfg.dmp_on = 0; 00842 st.chip_cfg.dmp_loaded = 0; 00843 st.chip_cfg.dmp_sample_rate = 0; 00844 00845 if (mpu_set_gyro_fsr(2000)) 00846 return -1; 00847 if (mpu_set_accel_fsr(2)) 00848 return -1; 00849 if (mpu_set_lpf(42)) 00850 return -1; 00851 if (mpu_set_sample_rate(50)) 00852 return -1; 00853 if (mpu_configure_fifo(0)) 00854 return -1; 00855 00856 // if (int_param) 00857 // reg_int_cb(int_param); 00858 00859 #ifdef AK89xx_SECONDARY 00860 setup_compass(); 00861 if (mpu_set_compass_sample_rate(10)) 00862 return -1; 00863 #else 00864 /* Already disabled by setup_compass. */ 00865 if (mpu_set_bypass(0)) 00866 return -1; 00867 #endif 00868 00869 mpu_set_sensors(0); 00870 return 0; 00871 } 00872 00888 int mpu_lp_accel_mode(unsigned char rate) 00889 { 00890 unsigned char tmp[2]; 00891 00892 if (rate > 40) 00893 return -1; 00894 00895 if (!rate) { 00896 mpu_set_int_latched(0); 00897 tmp[0] = 0; 00898 tmp[1] = BIT_STBY_XYZG; 00899 if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, tmp)) 00900 return -1; 00901 st.chip_cfg.lp_accel_mode = 0; 00902 return 0; 00903 } 00904 /* For LP accel, we automatically configure the hardware to produce latched 00905 * interrupts. In LP accel mode, the hardware cycles into sleep mode before 00906 * it gets a chance to deassert the interrupt pin; therefore, we shift this 00907 * responsibility over to the MCU. 00908 * 00909 * Any register read will clear the interrupt. 00910 */ 00911 mpu_set_int_latched(1); 00912 #if defined MPU6050 00913 tmp[0] = BIT_LPA_CYCLE; 00914 if (rate == 1) { 00915 tmp[1] = INV_LPA_1_25HZ; 00916 mpu_set_lpf(5); 00917 } else if (rate <= 5) { 00918 tmp[1] = INV_LPA_5HZ; 00919 mpu_set_lpf(5); 00920 } else if (rate <= 20) { 00921 tmp[1] = INV_LPA_20HZ; 00922 mpu_set_lpf(10); 00923 } else { 00924 tmp[1] = INV_LPA_40HZ; 00925 mpu_set_lpf(20); 00926 } 00927 tmp[1] = (tmp[1] << 6) | BIT_STBY_XYZG; 00928 if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, tmp)) 00929 return -1; 00930 #elif defined MPU6500 00931 /* Set wake frequency. */ 00932 if (rate == 1) 00933 tmp[0] = INV_LPA_1_25HZ; 00934 else if (rate == 2) 00935 tmp[0] = INV_LPA_2_5HZ; 00936 else if (rate <= 5) 00937 tmp[0] = INV_LPA_5HZ; 00938 else if (rate <= 10) 00939 tmp[0] = INV_LPA_10HZ; 00940 else if (rate <= 20) 00941 tmp[0] = INV_LPA_20HZ; 00942 else if (rate <= 40) 00943 tmp[0] = INV_LPA_40HZ; 00944 else if (rate <= 80) 00945 tmp[0] = INV_LPA_80HZ; 00946 else if (rate <= 160) 00947 tmp[0] = INV_LPA_160HZ; 00948 else if (rate <= 320) 00949 tmp[0] = INV_LPA_320HZ; 00950 else 00951 tmp[0] = INV_LPA_640HZ; 00952 if (i2c_write(st.hw->addr, st.reg->lp_accel_odr, 1, tmp)) 00953 return -1; 00954 tmp[0] = BIT_LPA_CYCLE; 00955 if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, tmp)) 00956 return -1; 00957 #endif 00958 st.chip_cfg.sensors = INV_XYZ_ACCEL; 00959 st.chip_cfg.clk_src = 0; 00960 st.chip_cfg.lp_accel_mode = 1; 00961 mpu_configure_fifo(0); 00962 00963 return 0; 00964 } 00965 00972 int mpu_get_gyro_reg(short *data, unsigned long *timestamp) 00973 { 00974 unsigned char tmp[6]; 00975 00976 if (!(st.chip_cfg.sensors & INV_XYZ_GYRO)) 00977 return -1; 00978 00979 if (i2c_read(st.hw->addr, st.reg->raw_gyro, 6, tmp)) 00980 return -1; 00981 data[0] = (tmp[0] << 8) | tmp[1]; 00982 data[1] = (tmp[2] << 8) | tmp[3]; 00983 data[2] = (tmp[4] << 8) | tmp[5]; 00984 if (timestamp) 00985 get_ms(timestamp); 00986 return 0; 00987 } 00988 00995 int mpu_get_accel_reg(short *data, unsigned long *timestamp) 00996 { 00997 unsigned char tmp[6]; 00998 00999 if (!(st.chip_cfg.sensors & INV_XYZ_ACCEL)) 01000 return -1; 01001 01002 if (i2c_read(st.hw->addr, st.reg->raw_accel, 6, tmp)) 01003 return -1; 01004 data[0] = (tmp[0] << 8) | tmp[1]; 01005 data[1] = (tmp[2] << 8) | tmp[3]; 01006 data[2] = (tmp[4] << 8) | tmp[5]; 01007 if (timestamp) 01008 get_ms(timestamp); 01009 return 0; 01010 } 01011 01018 int mpu_get_temperature(long *data, unsigned long *timestamp) 01019 { 01020 unsigned char tmp[2]; 01021 short raw; 01022 01023 if (!(st.chip_cfg.sensors)) 01024 return -1; 01025 01026 if (i2c_read(st.hw->addr, st.reg->temp, 2, tmp)) 01027 return -1; 01028 raw = (tmp[0] << 8) | tmp[1]; 01029 if (timestamp) 01030 get_ms(timestamp); 01031 01032 data[0] = (long)((35 + ((raw - (float)st.hw->temp_offset) / st.hw->temp_sens)) * 65536L); 01033 return 0; 01034 } 01035 01043 int mpu_set_accel_bias(const long *accel_bias) 01044 { 01045 unsigned char data[6]; 01046 short accel_hw[3]; 01047 short got_accel[3]; 01048 short fg[3]; 01049 01050 if (!accel_bias) 01051 return -1; 01052 if (!accel_bias[0] && !accel_bias[1] && !accel_bias[2]) 01053 return 0; 01054 01055 if (i2c_read(st.hw->addr, 3, 3, data)) 01056 return -1; 01057 fg[0] = ((data[0] >> 4) + 8) & 0xf; 01058 fg[1] = ((data[1] >> 4) + 8) & 0xf; 01059 fg[2] = ((data[2] >> 4) + 8) & 0xf; 01060 01061 accel_hw[0] = (short)(accel_bias[0] * 2 / (64 + fg[0])); 01062 accel_hw[1] = (short)(accel_bias[1] * 2 / (64 + fg[1])); 01063 accel_hw[2] = (short)(accel_bias[2] * 2 / (64 + fg[2])); 01064 01065 if (i2c_read(st.hw->addr, 0x06, 6, data)) 01066 return -1; 01067 01068 got_accel[0] = ((short)data[0] << 8) | data[1]; 01069 got_accel[1] = ((short)data[2] << 8) | data[3]; 01070 got_accel[2] = ((short)data[4] << 8) | data[5]; 01071 01072 accel_hw[0] += got_accel[0]; 01073 accel_hw[1] += got_accel[1]; 01074 accel_hw[2] += got_accel[2]; 01075 01076 data[0] = (accel_hw[0] >> 8) & 0xff; 01077 data[1] = (accel_hw[0]) & 0xff; 01078 data[2] = (accel_hw[1] >> 8) & 0xff; 01079 data[3] = (accel_hw[1]) & 0xff; 01080 data[4] = (accel_hw[2] >> 8) & 0xff; 01081 data[5] = (accel_hw[2]) & 0xff; 01082 01083 if (i2c_write(st.hw->addr, 0x06, 6, data)) 01084 return -1; 01085 return 0; 01086 } 01087 01092 int mpu_reset_fifo(void) 01093 { 01094 unsigned char data; 01095 01096 if (!(st.chip_cfg.sensors)) 01097 return -1; 01098 01099 data = 0; 01100 if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data)) 01101 return -1; 01102 if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &data)) 01103 return -1; 01104 if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) 01105 return -1; 01106 01107 if (st.chip_cfg.dmp_on) { 01108 data = BIT_FIFO_RST | BIT_DMP_RST; 01109 if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) 01110 return -1; 01111 delay_ms(50); 01112 data = BIT_DMP_EN | BIT_FIFO_EN; 01113 if (st.chip_cfg.sensors & INV_XYZ_COMPASS) 01114 data |= BIT_AUX_IF_EN; 01115 if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) 01116 return -1; 01117 if (st.chip_cfg.int_enable) 01118 data = BIT_DMP_INT_EN; 01119 else 01120 data = 0; 01121 if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data)) 01122 return -1; 01123 data = 0; 01124 if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &data)) 01125 return -1; 01126 } else { 01127 data = BIT_FIFO_RST; 01128 if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) 01129 return -1; 01130 if (st.chip_cfg.bypass_mode || !(st.chip_cfg.sensors & INV_XYZ_COMPASS)) 01131 data = BIT_FIFO_EN; 01132 else 01133 data = BIT_FIFO_EN | BIT_AUX_IF_EN; 01134 if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) 01135 return -1; 01136 delay_ms(50); 01137 if (st.chip_cfg.int_enable) 01138 data = BIT_DATA_RDY_EN; 01139 else 01140 data = 0; 01141 if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data)) 01142 return -1; 01143 if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &st.chip_cfg.fifo_enable)) 01144 return -1; 01145 } 01146 return 0; 01147 } 01148 01154 int mpu_get_gyro_fsr(unsigned short *fsr) 01155 { 01156 switch (st.chip_cfg.gyro_fsr) { 01157 case INV_FSR_250DPS: 01158 fsr[0] = 250; 01159 break; 01160 case INV_FSR_500DPS: 01161 fsr[0] = 500; 01162 break; 01163 case INV_FSR_1000DPS: 01164 fsr[0] = 1000; 01165 break; 01166 case INV_FSR_2000DPS: 01167 fsr[0] = 2000; 01168 break; 01169 default: 01170 fsr[0] = 0; 01171 break; 01172 } 01173 return 0; 01174 } 01175 01181 int mpu_set_gyro_fsr(unsigned short fsr) 01182 { 01183 unsigned char data; 01184 01185 if (!(st.chip_cfg.sensors)) 01186 return -1; 01187 01188 switch (fsr) { 01189 case 250: 01190 data = INV_FSR_250DPS << 3; 01191 break; 01192 case 500: 01193 data = INV_FSR_500DPS << 3; 01194 break; 01195 case 1000: 01196 data = INV_FSR_1000DPS << 3; 01197 break; 01198 case 2000: 01199 data = INV_FSR_2000DPS << 3; 01200 break; 01201 default: 01202 return -1; 01203 } 01204 01205 if (st.chip_cfg.gyro_fsr == (data >> 3)) 01206 return 0; 01207 if (i2c_write(st.hw->addr, st.reg->gyro_cfg, 1, &data)) 01208 return -1; 01209 st.chip_cfg.gyro_fsr = data >> 3; 01210 return 0; 01211 } 01212 01218 int mpu_get_accel_fsr(unsigned char *fsr) 01219 { 01220 switch (st.chip_cfg.accel_fsr) { 01221 case INV_FSR_2G: 01222 fsr[0] = 2; 01223 break; 01224 case INV_FSR_4G: 01225 fsr[0] = 4; 01226 break; 01227 case INV_FSR_8G: 01228 fsr[0] = 8; 01229 break; 01230 case INV_FSR_16G: 01231 fsr[0] = 16; 01232 break; 01233 default: 01234 return -1; 01235 } 01236 if (st.chip_cfg.accel_half) 01237 fsr[0] <<= 1; 01238 return 0; 01239 } 01240 01246 int mpu_set_accel_fsr(unsigned char fsr) 01247 { 01248 unsigned char data; 01249 01250 if (!(st.chip_cfg.sensors)) 01251 return -1; 01252 01253 switch (fsr) { 01254 case 2: 01255 data = INV_FSR_2G << 3; 01256 break; 01257 case 4: 01258 data = INV_FSR_4G << 3; 01259 break; 01260 case 8: 01261 data = INV_FSR_8G << 3; 01262 break; 01263 case 16: 01264 data = INV_FSR_16G << 3; 01265 break; 01266 default: 01267 return -1; 01268 } 01269 01270 if (st.chip_cfg.accel_fsr == (data >> 3)) 01271 return 0; 01272 if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, &data)) 01273 return -1; 01274 st.chip_cfg.accel_fsr = data >> 3; 01275 return 0; 01276 } 01277 01283 int mpu_get_lpf(unsigned short *lpf) 01284 { 01285 switch (st.chip_cfg.lpf) { 01286 case INV_FILTER_188HZ: 01287 lpf[0] = 188; 01288 break; 01289 case INV_FILTER_98HZ: 01290 lpf[0] = 98; 01291 break; 01292 case INV_FILTER_42HZ: 01293 lpf[0] = 42; 01294 break; 01295 case INV_FILTER_20HZ: 01296 lpf[0] = 20; 01297 break; 01298 case INV_FILTER_10HZ: 01299 lpf[0] = 10; 01300 break; 01301 case INV_FILTER_5HZ: 01302 lpf[0] = 5; 01303 break; 01304 case INV_FILTER_256HZ_NOLPF2: 01305 case INV_FILTER_2100HZ_NOLPF: 01306 default: 01307 lpf[0] = 0; 01308 break; 01309 } 01310 return 0; 01311 } 01312 01319 int mpu_set_lpf(unsigned short lpf) 01320 { 01321 unsigned char data; 01322 01323 if (!(st.chip_cfg.sensors)) 01324 return -1; 01325 01326 if (lpf >= 188) 01327 data = INV_FILTER_188HZ; 01328 else if (lpf >= 98) 01329 data = INV_FILTER_98HZ; 01330 else if (lpf >= 42) 01331 data = INV_FILTER_42HZ; 01332 else if (lpf >= 20) 01333 data = INV_FILTER_20HZ; 01334 else if (lpf >= 10) 01335 data = INV_FILTER_10HZ; 01336 else 01337 data = INV_FILTER_5HZ; 01338 01339 if (st.chip_cfg.lpf == data) 01340 return 0; 01341 if (i2c_write(st.hw->addr, st.reg->lpf, 1, &data)) 01342 return -1; 01343 st.chip_cfg.lpf = data; 01344 return 0; 01345 } 01346 01352 int mpu_get_sample_rate(unsigned short *rate) 01353 { 01354 if (st.chip_cfg.dmp_on) 01355 return -1; 01356 else 01357 rate[0] = st.chip_cfg.sample_rate; 01358 return 0; 01359 } 01360 01367 int mpu_set_sample_rate(unsigned short rate) 01368 { 01369 unsigned char data; 01370 01371 if (!(st.chip_cfg.sensors)) 01372 return -1; 01373 01374 if (st.chip_cfg.dmp_on) 01375 return -1; 01376 else { 01377 if (st.chip_cfg.lp_accel_mode) { 01378 if (rate && (rate <= 40)) { 01379 /* Just stay in low-power accel mode. */ 01380 mpu_lp_accel_mode(rate); 01381 return 0; 01382 } 01383 /* Requested rate exceeds the allowed frequencies in LP accel mode, 01384 * switch back to full-power mode. 01385 */ 01386 mpu_lp_accel_mode(0); 01387 } 01388 if (rate < 4) 01389 rate = 4; 01390 else if (rate > 1000) 01391 rate = 1000; 01392 01393 data = 1000 / rate - 1; 01394 if (i2c_write(st.hw->addr, st.reg->rate_div, 1, &data)) 01395 return -1; 01396 01397 st.chip_cfg.sample_rate = 1000 / (1 + data); 01398 01399 #ifdef AK89xx_SECONDARY 01400 mpu_set_compass_sample_rate(min(st.chip_cfg.compass_sample_rate, MAX_COMPASS_SAMPLE_RATE)); 01401 #endif 01402 01403 /* Automatically set LPF to 1/2 sampling rate. */ 01404 mpu_set_lpf(st.chip_cfg.sample_rate >> 1); 01405 return 0; 01406 } 01407 } 01408 01414 int mpu_get_compass_sample_rate(unsigned short *rate) 01415 { 01416 #ifdef AK89xx_SECONDARY 01417 rate[0] = st.chip_cfg.compass_sample_rate; 01418 return 0; 01419 #else 01420 rate[0] = 0; 01421 return -1; 01422 #endif 01423 } 01424 01436 int mpu_set_compass_sample_rate(unsigned short rate) 01437 { 01438 #ifdef AK89xx_SECONDARY 01439 unsigned char div; 01440 if (!rate || rate > st.chip_cfg.sample_rate || rate > MAX_COMPASS_SAMPLE_RATE) 01441 return -1; 01442 01443 div = st.chip_cfg.sample_rate / rate - 1; 01444 if (i2c_write(st.hw->addr, st.reg->s4_ctrl, 1, &div)) 01445 return -1; 01446 st.chip_cfg.compass_sample_rate = st.chip_cfg.sample_rate / (div + 1); 01447 return 0; 01448 #else 01449 return -1; 01450 #endif 01451 } 01452 01458 int mpu_get_gyro_sens(float *sens) 01459 { 01460 switch (st.chip_cfg.gyro_fsr) { 01461 case INV_FSR_250DPS: 01462 sens[0] = 131.f; 01463 break; 01464 case INV_FSR_500DPS: 01465 sens[0] = 65.5f; 01466 break; 01467 case INV_FSR_1000DPS: 01468 sens[0] = 32.8f; 01469 break; 01470 case INV_FSR_2000DPS: 01471 sens[0] = 16.4f; 01472 break; 01473 default: 01474 return -1; 01475 } 01476 return 0; 01477 } 01478 01484 int mpu_get_accel_sens(unsigned short *sens) 01485 { 01486 switch (st.chip_cfg.accel_fsr) { 01487 case INV_FSR_2G: 01488 sens[0] = 16384; 01489 break; 01490 case INV_FSR_4G: 01491 sens[0] = 8092; 01492 break; 01493 case INV_FSR_8G: 01494 sens[0] = 4096; 01495 break; 01496 case INV_FSR_16G: 01497 sens[0] = 2048; 01498 break; 01499 default: 01500 return -1; 01501 } 01502 if (st.chip_cfg.accel_half) 01503 sens[0] >>= 1; 01504 return 0; 01505 } 01506 01516 int mpu_get_fifo_config(unsigned char *sensors) 01517 { 01518 sensors[0] = st.chip_cfg.fifo_enable; 01519 return 0; 01520 } 01521 01531 int mpu_configure_fifo(unsigned char sensors) 01532 { 01533 unsigned char prev; 01534 int result = 0; 01535 01536 /* Compass data isn't going into the FIFO. Stop trying. */ 01537 sensors &= ~INV_XYZ_COMPASS; 01538 01539 if (st.chip_cfg.dmp_on) 01540 return 0; 01541 else { 01542 if (!(st.chip_cfg.sensors)) 01543 return -1; 01544 prev = st.chip_cfg.fifo_enable; 01545 st.chip_cfg.fifo_enable = sensors & st.chip_cfg.sensors; 01546 if (st.chip_cfg.fifo_enable != sensors) 01547 /* You're not getting what you asked for. Some sensors are 01548 * asleep. 01549 */ 01550 result = -1; 01551 else 01552 result = 0; 01553 if (sensors || st.chip_cfg.lp_accel_mode) 01554 set_int_enable(1); 01555 else 01556 set_int_enable(0); 01557 if (sensors) { 01558 if (mpu_reset_fifo()) { 01559 st.chip_cfg.fifo_enable = prev; 01560 return -1; 01561 } 01562 } 01563 } 01564 01565 return result; 01566 } 01567 01573 int mpu_get_power_state(unsigned char *power_on) 01574 { 01575 if (st.chip_cfg.sensors) 01576 power_on[0] = 1; 01577 else 01578 power_on[0] = 0; 01579 return 0; 01580 } 01581 01592 int mpu_set_sensors(unsigned char sensors) 01593 { 01594 unsigned char data; 01595 #ifdef AK89xx_SECONDARY 01596 unsigned char user_ctrl; 01597 #endif 01598 01599 if (sensors & INV_XYZ_GYRO) 01600 data = INV_CLK_PLL; 01601 else if (sensors) 01602 data = 0; 01603 else 01604 data = BIT_SLEEP; 01605 if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, &data)) { 01606 st.chip_cfg.sensors = 0; 01607 return -1; 01608 } 01609 st.chip_cfg.clk_src = data & ~BIT_SLEEP; 01610 01611 data = 0; 01612 if (!(sensors & INV_X_GYRO)) 01613 data |= BIT_STBY_XG; 01614 if (!(sensors & INV_Y_GYRO)) 01615 data |= BIT_STBY_YG; 01616 if (!(sensors & INV_Z_GYRO)) 01617 data |= BIT_STBY_ZG; 01618 if (!(sensors & INV_XYZ_ACCEL)) 01619 data |= BIT_STBY_XYZA; 01620 if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_2, 1, &data)) { 01621 st.chip_cfg.sensors = 0; 01622 return -1; 01623 } 01624 01625 if (sensors && (sensors != INV_XYZ_ACCEL)) 01626 /* Latched interrupts only used in LP accel mode. */ 01627 mpu_set_int_latched(0); 01628 01629 #ifdef AK89xx_SECONDARY 01630 #ifdef AK89xx_BYPASS 01631 if (sensors & INV_XYZ_COMPASS) 01632 mpu_set_bypass(1); 01633 else 01634 mpu_set_bypass(0); 01635 #else 01636 if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &user_ctrl)) 01637 return -1; 01638 /* Handle AKM power management. */ 01639 if (sensors & INV_XYZ_COMPASS) { 01640 data = AKM_SINGLE_MEASUREMENT; 01641 user_ctrl |= BIT_AUX_IF_EN; 01642 } else { 01643 data = AKM_POWER_DOWN; 01644 user_ctrl &= ~BIT_AUX_IF_EN; 01645 } 01646 if (st.chip_cfg.dmp_on) 01647 user_ctrl |= BIT_DMP_EN; 01648 else 01649 user_ctrl &= ~BIT_DMP_EN; 01650 if (i2c_write(st.hw->addr, st.reg->s1_do, 1, &data)) 01651 return -1; 01652 /* Enable/disable I2C master mode. */ 01653 if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &user_ctrl)) 01654 return -1; 01655 #endif 01656 #endif 01657 01658 st.chip_cfg.sensors = sensors; 01659 st.chip_cfg.lp_accel_mode = 0; 01660 delay_ms(50); 01661 return 0; 01662 } 01663 01669 int mpu_get_int_status(short *status) 01670 { 01671 unsigned char tmp[2]; 01672 if (!st.chip_cfg.sensors) 01673 return -1; 01674 if (i2c_read(st.hw->addr, st.reg->dmp_int_status, 2, tmp)) 01675 return -1; 01676 status[0] = (tmp[0] << 8) | tmp[1]; 01677 return 0; 01678 } 01679 01698 int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp, 01699 unsigned char *sensors, unsigned char *more) 01700 { 01701 /* Assumes maximum packet size is gyro (6) + accel (6). */ 01702 unsigned char data[MAX_PACKET_LENGTH]; 01703 unsigned char packet_size = 0; 01704 unsigned short fifo_count, index = 0; 01705 01706 if (st.chip_cfg.dmp_on) 01707 return -1; 01708 01709 sensors[0] = 0; 01710 if (!st.chip_cfg.sensors) 01711 return -1; 01712 if (!st.chip_cfg.fifo_enable) 01713 return -1; 01714 01715 if (st.chip_cfg.fifo_enable & INV_X_GYRO) 01716 packet_size += 2; 01717 if (st.chip_cfg.fifo_enable & INV_Y_GYRO) 01718 packet_size += 2; 01719 if (st.chip_cfg.fifo_enable & INV_Z_GYRO) 01720 packet_size += 2; 01721 if (st.chip_cfg.fifo_enable & INV_XYZ_ACCEL) 01722 packet_size += 6; 01723 01724 if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, data)) 01725 return -1; 01726 fifo_count = (data[0] << 8) | data[1]; 01727 if (fifo_count < packet_size) 01728 return 0; 01729 // log_i("FIFO count: %hd\n", fifo_count); 01730 if (fifo_count > (st.hw->max_fifo >> 1)) { 01731 /* FIFO is 50% full, better check overflow bit. */ 01732 if (i2c_read(st.hw->addr, st.reg->int_status, 1, data)) 01733 return -1; 01734 if (data[0] & BIT_FIFO_OVERFLOW) { 01735 mpu_reset_fifo(); 01736 return -2; 01737 } 01738 } 01739 get_ms((unsigned long*)timestamp); 01740 01741 if (i2c_read(st.hw->addr, st.reg->fifo_r_w, packet_size, data)) 01742 return -1; 01743 more[0] = fifo_count / packet_size - 1; 01744 sensors[0] = 0; 01745 01746 if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_XYZ_ACCEL) { 01747 accel[0] = (data[index+0] << 8) | data[index+1]; 01748 accel[1] = (data[index+2] << 8) | data[index+3]; 01749 accel[2] = (data[index+4] << 8) | data[index+5]; 01750 sensors[0] |= INV_XYZ_ACCEL; 01751 index += 6; 01752 } 01753 if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_X_GYRO) { 01754 gyro[0] = (data[index+0] << 8) | data[index+1]; 01755 sensors[0] |= INV_X_GYRO; 01756 index += 2; 01757 } 01758 if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_Y_GYRO) { 01759 gyro[1] = (data[index+0] << 8) | data[index+1]; 01760 sensors[0] |= INV_Y_GYRO; 01761 index += 2; 01762 } 01763 if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_Z_GYRO) { 01764 gyro[2] = (data[index+0] << 8) | data[index+1]; 01765 sensors[0] |= INV_Z_GYRO; 01766 index += 2; 01767 } 01768 01769 return 0; 01770 } 01771 01779 int mpu_read_fifo_stream(unsigned short length, unsigned char *data, 01780 unsigned char *more) 01781 { 01782 unsigned char tmp[2]; 01783 unsigned short fifo_count; 01784 if (!st.chip_cfg.dmp_on) 01785 return -1; 01786 if (!st.chip_cfg.sensors) 01787 return -1; 01788 01789 if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, tmp)) 01790 return -1; 01791 fifo_count = (tmp[0] << 8) | tmp[1]; 01792 if (fifo_count < length) { 01793 more[0] = 0; 01794 return -1; 01795 } 01796 if (fifo_count > (st.hw->max_fifo >> 1)) { 01797 /* FIFO is 50% full, better check overflow bit. */ 01798 if (i2c_read(st.hw->addr, st.reg->int_status, 1, tmp)) 01799 return -1; 01800 if (tmp[0] & BIT_FIFO_OVERFLOW) { 01801 mpu_reset_fifo(); 01802 return -2; 01803 } 01804 } 01805 01806 if (i2c_read(st.hw->addr, st.reg->fifo_r_w, length, data)) 01807 return -1; 01808 more[0] = fifo_count / length - 1; 01809 return 0; 01810 } 01811 01817 int mpu_set_bypass(unsigned char bypass_on) 01818 { 01819 unsigned char tmp; 01820 01821 if (st.chip_cfg.bypass_mode == bypass_on) 01822 return 0; 01823 01824 if (bypass_on) { 01825 if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) 01826 return -1; 01827 tmp &= ~BIT_AUX_IF_EN; 01828 if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) 01829 return -1; 01830 delay_ms(3); 01831 tmp = BIT_BYPASS_EN; 01832 if (st.chip_cfg.active_low_int) 01833 tmp |= BIT_ACTL; 01834 if (st.chip_cfg.latched_int) 01835 tmp |= BIT_LATCH_EN | BIT_ANY_RD_CLR; 01836 if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) 01837 return -1; 01838 } else { 01839 /* Enable I2C master mode if compass is being used. */ 01840 if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) 01841 return -1; 01842 if (st.chip_cfg.sensors & INV_XYZ_COMPASS) 01843 tmp |= BIT_AUX_IF_EN; 01844 else 01845 tmp &= ~BIT_AUX_IF_EN; 01846 if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) 01847 return -1; 01848 delay_ms(3); 01849 if (st.chip_cfg.active_low_int) 01850 tmp = BIT_ACTL; 01851 else 01852 tmp = 0; 01853 if (st.chip_cfg.latched_int) 01854 tmp |= BIT_LATCH_EN | BIT_ANY_RD_CLR; 01855 if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) 01856 return -1; 01857 } 01858 st.chip_cfg.bypass_mode = bypass_on; 01859 return 0; 01860 } 01861 01867 int mpu_set_int_level(unsigned char active_low) 01868 { 01869 st.chip_cfg.active_low_int = active_low; 01870 return 0; 01871 } 01872 01879 int mpu_set_int_latched(unsigned char enable) 01880 { 01881 unsigned char tmp; 01882 if (st.chip_cfg.latched_int == enable) 01883 return 0; 01884 01885 if (enable) 01886 tmp = BIT_LATCH_EN | BIT_ANY_RD_CLR; 01887 else 01888 tmp = 0; 01889 if (st.chip_cfg.bypass_mode) 01890 tmp |= BIT_BYPASS_EN; 01891 if (st.chip_cfg.active_low_int) 01892 tmp |= BIT_ACTL; 01893 if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) 01894 return -1; 01895 st.chip_cfg.latched_int = enable; 01896 return 0; 01897 } 01898 01899 #ifdef MPU6050 01900 static int get_accel_prod_shift(float *st_shift) 01901 { 01902 unsigned char tmp[4], shift_code[3], ii; 01903 01904 if (i2c_read(st.hw->addr, 0x0D, 4, tmp)) 01905 return 0x07; 01906 01907 shift_code[0] = ((tmp[0] & 0xE0) >> 3) | ((tmp[3] & 0x30) >> 4); 01908 shift_code[1] = ((tmp[1] & 0xE0) >> 3) | ((tmp[3] & 0x0C) >> 2); 01909 shift_code[2] = ((tmp[2] & 0xE0) >> 3) | (tmp[3] & 0x03); 01910 for (ii = 0; ii < 3; ii++) { 01911 if (!shift_code[ii]) { 01912 st_shift[ii] = 0.f; 01913 continue; 01914 } 01915 /* Equivalent to.. 01916 * st_shift[ii] = 0.34f * powf(0.92f/0.34f, (shift_code[ii]-1) / 30.f) 01917 */ 01918 st_shift[ii] = 0.34f; 01919 while (--shift_code[ii]) 01920 st_shift[ii] *= 1.034f; 01921 } 01922 return 0; 01923 } 01924 01925 static int accel_self_test(long *bias_regular, long *bias_st) 01926 { 01927 int jj, result = 0; 01928 float st_shift[3], st_shift_cust, st_shift_var; 01929 01930 get_accel_prod_shift(st_shift); 01931 for(jj = 0; jj < 3; jj++) { 01932 st_shift_cust = labs(bias_regular[jj] - bias_st[jj]) / 65536.f; 01933 if (st_shift[jj]) { 01934 st_shift_var = st_shift_cust / st_shift[jj] - 1.f; 01935 if (fabs(st_shift_var) > test.max_accel_var) 01936 result |= 1 << jj; 01937 } else if ((st_shift_cust < test.min_g) || 01938 (st_shift_cust > test.max_g)) 01939 result |= 1 << jj; 01940 } 01941 01942 return result; 01943 } 01944 01945 static int gyro_self_test(long *bias_regular, long *bias_st) 01946 { 01947 int jj, result = 0; 01948 unsigned char tmp[3]; 01949 float st_shift, st_shift_cust, st_shift_var; 01950 01951 if (i2c_read(st.hw->addr, 0x0D, 3, tmp)) 01952 return 0x07; 01953 01954 tmp[0] &= 0x1F; 01955 tmp[1] &= 0x1F; 01956 tmp[2] &= 0x1F; 01957 01958 for (jj = 0; jj < 3; jj++) { 01959 st_shift_cust = labs(bias_regular[jj] - bias_st[jj]) / 65536.f; 01960 if (tmp[jj]) { 01961 st_shift = 3275.f / test.gyro_sens; 01962 while (--tmp[jj]) 01963 st_shift *= 1.046f; 01964 st_shift_var = st_shift_cust / st_shift - 1.f; 01965 if (fabs(st_shift_var) > test.max_gyro_var) 01966 result |= 1 << jj; 01967 } else if ((st_shift_cust < test.min_dps) || 01968 (st_shift_cust > test.max_dps)) 01969 result |= 1 << jj; 01970 } 01971 return result; 01972 } 01973 01974 #ifdef AK89xx_SECONDARY 01975 static int compass_self_test(void) 01976 { 01977 unsigned char tmp[6]; 01978 unsigned char tries = 10; 01979 int result = 0x07; 01980 short data; 01981 01982 mpu_set_bypass(1); 01983 01984 tmp[0] = AKM_POWER_DOWN; 01985 if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp)) 01986 return 0x07; 01987 tmp[0] = AKM_BIT_SELF_TEST; 01988 if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_ASTC, 1, tmp)) 01989 goto AKM_restore; 01990 tmp[0] = AKM_MODE_SELF_TEST; 01991 if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp)) 01992 goto AKM_restore; 01993 01994 do { 01995 delay_ms(10); 01996 if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ST1, 1, tmp)) 01997 goto AKM_restore; 01998 if (tmp[0] & AKM_DATA_READY) 01999 break; 02000 } while (tries--); 02001 if (!(tmp[0] & AKM_DATA_READY)) 02002 goto AKM_restore; 02003 02004 if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_HXL, 6, tmp)) 02005 goto AKM_restore; 02006 02007 result = 0; 02008 data = (short)(tmp[1] << 8) | tmp[0]; 02009 if ((data > 100) || (data < -100)) 02010 result |= 0x01; 02011 data = (short)(tmp[3] << 8) | tmp[2]; 02012 if ((data > 100) || (data < -100)) 02013 result |= 0x02; 02014 data = (short)(tmp[5] << 8) | tmp[4]; 02015 if ((data > -300) || (data < -1000)) 02016 result |= 0x04; 02017 02018 AKM_restore: 02019 tmp[0] = 0 | SUPPORTS_AK89xx_HIGH_SENS; 02020 i2c_write(st.chip_cfg.compass_addr, AKM_REG_ASTC, 1, tmp); 02021 tmp[0] = SUPPORTS_AK89xx_HIGH_SENS; 02022 i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp); 02023 mpu_set_bypass(0); 02024 return result; 02025 } 02026 #endif 02027 #endif 02028 02029 static int get_st_biases(long *gyro, long *accel, unsigned char hw_test) 02030 { 02031 unsigned char data[MAX_PACKET_LENGTH]; 02032 unsigned char packet_count, ii; 02033 unsigned short fifo_count; 02034 02035 data[0] = 0x01; 02036 data[1] = 0; 02037 if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, data)) 02038 return -1; 02039 delay_ms(200); 02040 data[0] = 0; 02041 if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data)) 02042 return -1; 02043 if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) 02044 return -1; 02045 if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) 02046 return -1; 02047 if (i2c_write(st.hw->addr, st.reg->i2c_mst, 1, data)) 02048 return -1; 02049 if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) 02050 return -1; 02051 data[0] = BIT_FIFO_RST | BIT_DMP_RST; 02052 if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) 02053 return -1; 02054 delay_ms(15); 02055 data[0] = st.test->reg_lpf; 02056 if (i2c_write(st.hw->addr, st.reg->lpf, 1, data)) 02057 return -1; 02058 data[0] = st.test->reg_rate_div; 02059 if (i2c_write(st.hw->addr, st.reg->rate_div, 1, data)) 02060 return -1; 02061 if (hw_test) 02062 data[0] = st.test->reg_gyro_fsr | 0xE0; 02063 else 02064 data[0] = st.test->reg_gyro_fsr; 02065 if (i2c_write(st.hw->addr, st.reg->gyro_cfg, 1, data)) 02066 return -1; 02067 02068 if (hw_test) 02069 data[0] = st.test->reg_accel_fsr | 0xE0; 02070 else 02071 data[0] = test.reg_accel_fsr; 02072 if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, data)) 02073 return -1; 02074 if (hw_test) 02075 delay_ms(200); 02076 02077 /* Fill FIFO for test.wait_ms milliseconds. */ 02078 data[0] = BIT_FIFO_EN; 02079 if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) 02080 return -1; 02081 02082 data[0] = INV_XYZ_GYRO | INV_XYZ_ACCEL; 02083 if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) 02084 return -1; 02085 delay_ms(test.wait_ms); 02086 data[0] = 0; 02087 if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) 02088 return -1; 02089 02090 if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, data)) 02091 return -1; 02092 02093 fifo_count = (data[0] << 8) | data[1]; 02094 packet_count = fifo_count / MAX_PACKET_LENGTH; 02095 gyro[0] = gyro[1] = gyro[2] = 0; 02096 accel[0] = accel[1] = accel[2] = 0; 02097 02098 for (ii = 0; ii < packet_count; ii++) { 02099 short accel_cur[3], gyro_cur[3]; 02100 if (i2c_read(st.hw->addr, st.reg->fifo_r_w, MAX_PACKET_LENGTH, data)) 02101 return -1; 02102 accel_cur[0] = ((short)data[0] << 8) | data[1]; 02103 accel_cur[1] = ((short)data[2] << 8) | data[3]; 02104 accel_cur[2] = ((short)data[4] << 8) | data[5]; 02105 accel[0] += (long)accel_cur[0]; 02106 accel[1] += (long)accel_cur[1]; 02107 accel[2] += (long)accel_cur[2]; 02108 gyro_cur[0] = (((short)data[6] << 8) | data[7]); 02109 gyro_cur[1] = (((short)data[8] << 8) | data[9]); 02110 gyro_cur[2] = (((short)data[10] << 8) | data[11]); 02111 gyro[0] += (long)gyro_cur[0]; 02112 gyro[1] += (long)gyro_cur[1]; 02113 gyro[2] += (long)gyro_cur[2]; 02114 } 02115 #ifdef EMPL_NO_64BIT 02116 gyro[0] = (long)(((float)gyro[0]*65536.f) / test.gyro_sens / packet_count); 02117 gyro[1] = (long)(((float)gyro[1]*65536.f) / test.gyro_sens / packet_count); 02118 gyro[2] = (long)(((float)gyro[2]*65536.f) / test.gyro_sens / packet_count); 02119 if (has_accel) { 02120 accel[0] = (long)(((float)accel[0]*65536.f) / test.accel_sens / 02121 packet_count); 02122 accel[1] = (long)(((float)accel[1]*65536.f) / test.accel_sens / 02123 packet_count); 02124 accel[2] = (long)(((float)accel[2]*65536.f) / test.accel_sens / 02125 packet_count); 02126 /* Don't remove gravity! */ 02127 accel[2] -= 65536L; 02128 } 02129 #else 02130 gyro[0] = (long)(((long long)gyro[0]<<16) / test.gyro_sens / packet_count); 02131 gyro[1] = (long)(((long long)gyro[1]<<16) / test.gyro_sens / packet_count); 02132 gyro[2] = (long)(((long long)gyro[2]<<16) / test.gyro_sens / packet_count); 02133 accel[0] = (long)(((long long)accel[0]<<16) / test.accel_sens / 02134 packet_count); 02135 accel[1] = (long)(((long long)accel[1]<<16) / test.accel_sens / 02136 packet_count); 02137 accel[2] = (long)(((long long)accel[2]<<16) / test.accel_sens / 02138 packet_count); 02139 /* Don't remove gravity! */ 02140 if (accel[2] > 0L) 02141 accel[2] -= 65536L; 02142 else 02143 accel[2] += 65536L; 02144 #endif 02145 02146 return 0; 02147 } 02148 02169 int mpu_run_self_test(long *gyro, long *accel) 02170 { 02171 #ifdef MPU6050 02172 const unsigned char tries = 2; 02173 long gyro_st[3], accel_st[3]; 02174 unsigned char accel_result, gyro_result; 02175 #ifdef AK89xx_SECONDARY 02176 unsigned char compass_result; 02177 #endif 02178 int ii; 02179 #endif 02180 int result; 02181 unsigned char accel_fsr, fifo_sensors, sensors_on; 02182 unsigned short gyro_fsr, sample_rate, lpf; 02183 unsigned char dmp_was_on; 02184 02185 if (st.chip_cfg.dmp_on) { 02186 mpu_set_dmp_state(0); 02187 dmp_was_on = 1; 02188 } else 02189 dmp_was_on = 0; 02190 02191 /* Get initial settings. */ 02192 mpu_get_gyro_fsr(&gyro_fsr); 02193 mpu_get_accel_fsr(&accel_fsr); 02194 mpu_get_lpf(&lpf); 02195 mpu_get_sample_rate(&sample_rate); 02196 sensors_on = st.chip_cfg.sensors; 02197 mpu_get_fifo_config(&fifo_sensors); 02198 02199 /* For older chips, the self-test will be different. */ 02200 #if defined MPU6050 02201 for (ii = 0; ii < tries; ii++) 02202 if (!get_st_biases(gyro, accel, 0)) 02203 break; 02204 if (ii == tries) { 02205 /* If we reach this point, we most likely encountered an I2C error. 02206 * We'll just report an error for all three sensors. 02207 */ 02208 result = 0; 02209 goto restore; 02210 } 02211 for (ii = 0; ii < tries; ii++) 02212 if (!get_st_biases(gyro_st, accel_st, 1)) 02213 break; 02214 if (ii == tries) { 02215 /* Again, probably an I2C error. */ 02216 result = 0; 02217 goto restore; 02218 } 02219 accel_result = accel_self_test(accel, accel_st); 02220 gyro_result = gyro_self_test(gyro, gyro_st); 02221 02222 result = 0; 02223 if (!gyro_result) 02224 result |= 0x01; 02225 if (!accel_result) 02226 result |= 0x02; 02227 02228 #ifdef AK89xx_SECONDARY 02229 compass_result = compass_self_test(); 02230 if (!compass_result) 02231 result |= 0x04; 02232 #endif 02233 restore: 02234 #elif defined MPU6500 02235 /* For now, this function will return a "pass" result for all three sensors 02236 * for compatibility with current test applications. 02237 */ 02238 get_st_biases(gyro, accel, 0); 02239 result = 0x7; 02240 #endif 02241 /* Set to invalid values to ensure no I2C writes are skipped. */ 02242 st.chip_cfg.gyro_fsr = 0xFF; 02243 st.chip_cfg.accel_fsr = 0xFF; 02244 st.chip_cfg.lpf = 0xFF; 02245 st.chip_cfg.sample_rate = 0xFFFF; 02246 st.chip_cfg.sensors = 0xFF; 02247 st.chip_cfg.fifo_enable = 0xFF; 02248 st.chip_cfg.clk_src = INV_CLK_PLL; 02249 mpu_set_gyro_fsr(gyro_fsr); 02250 mpu_set_accel_fsr(accel_fsr); 02251 mpu_set_lpf(lpf); 02252 mpu_set_sample_rate(sample_rate); 02253 mpu_set_sensors(sensors_on); 02254 mpu_configure_fifo(fifo_sensors); 02255 02256 if (dmp_was_on) 02257 mpu_set_dmp_state(1); 02258 02259 return result; 02260 } 02261 02271 int mpu_write_mem(unsigned short mem_addr, unsigned short length, 02272 unsigned char *data) 02273 { 02274 unsigned char tmp[2]; 02275 02276 if (!data) 02277 return -1; 02278 if (!st.chip_cfg.sensors) 02279 return -1; 02280 02281 tmp[0] = (unsigned char)(mem_addr >> 8); 02282 tmp[1] = (unsigned char)(mem_addr & 0xFF); 02283 02284 /* Check bank boundaries. */ 02285 if (tmp[1] + length > st.hw->bank_size) 02286 return -1; 02287 02288 if (i2c_write(st.hw->addr, st.reg->bank_sel, 2, tmp)) 02289 return -1; 02290 if (i2c_write(st.hw->addr, st.reg->mem_r_w, length, data)) 02291 return -1; 02292 return 0; 02293 } 02294 02304 int mpu_read_mem(unsigned short mem_addr, unsigned short length, 02305 unsigned char *data) 02306 { 02307 unsigned char tmp[2]; 02308 02309 if (!data) 02310 return -1; 02311 if (!st.chip_cfg.sensors) 02312 return -1; 02313 02314 tmp[0] = (unsigned char)(mem_addr >> 8); 02315 tmp[1] = (unsigned char)(mem_addr & 0xFF); 02316 02317 /* Check bank boundaries. */ 02318 if (tmp[1] + length > st.hw->bank_size) 02319 return -1; 02320 02321 if (i2c_write(st.hw->addr, st.reg->bank_sel, 2, tmp)) 02322 return -1; 02323 if (i2c_read(st.hw->addr, st.reg->mem_r_w, length, data)) 02324 return -1; 02325 return 0; 02326 } 02327 02336 int mpu_load_firmware(unsigned short length, const unsigned char *firmware, 02337 unsigned short start_addr, unsigned short sample_rate) 02338 { 02339 unsigned short ii; 02340 unsigned short this_write; 02341 /* Must divide evenly into st.hw->bank_size to avoid bank crossings. */ 02342 #define LOAD_CHUNK (16) 02343 unsigned char cur[LOAD_CHUNK], tmp[2]; 02344 02345 if (st.chip_cfg.dmp_loaded) 02346 /* DMP should only be loaded once. */ 02347 return -1; 02348 02349 if (!firmware) 02350 return -1; 02351 for (ii = 0; ii < length; ii += this_write) { 02352 this_write = min(LOAD_CHUNK, length - ii); 02353 if (mpu_write_mem(ii, this_write, (unsigned char*)&firmware[ii])) 02354 return -1; 02355 if (mpu_read_mem(ii, this_write, cur)) 02356 return -1; 02357 if (memcmp(firmware+ii, cur, this_write)) 02358 return -2; 02359 } 02360 02361 /* Set program start address. */ 02362 tmp[0] = start_addr >> 8; 02363 tmp[1] = start_addr & 0xFF; 02364 if (i2c_write(st.hw->addr, st.reg->prgm_start_h, 2, tmp)) 02365 return -1; 02366 02367 st.chip_cfg.dmp_loaded = 1; 02368 st.chip_cfg.dmp_sample_rate = sample_rate; 02369 return 0; 02370 } 02371 02377 int mpu_set_dmp_state(unsigned char enable) 02378 { 02379 unsigned char tmp; 02380 if (st.chip_cfg.dmp_on == enable) 02381 return 0; 02382 02383 if (enable) { 02384 if (!st.chip_cfg.dmp_loaded) 02385 return -1; 02386 /* Disable data ready interrupt. */ 02387 set_int_enable(0); 02388 /* Disable bypass mode. */ 02389 mpu_set_bypass(0); 02390 /* Keep constant sample rate, FIFO rate controlled by DMP. */ 02391 mpu_set_sample_rate(st.chip_cfg.dmp_sample_rate); 02392 /* Remove FIFO elements. */ 02393 tmp = 0; 02394 i2c_write(st.hw->addr, 0x23, 1, &tmp); 02395 st.chip_cfg.dmp_on = 1; 02396 /* Enable DMP interrupt. */ 02397 set_int_enable(1); 02398 mpu_reset_fifo(); 02399 } else { 02400 /* Disable DMP interrupt. */ 02401 set_int_enable(0); 02402 /* Restore FIFO settings. */ 02403 tmp = st.chip_cfg.fifo_enable; 02404 i2c_write(st.hw->addr, 0x23, 1, &tmp); 02405 st.chip_cfg.dmp_on = 0; 02406 mpu_reset_fifo(); 02407 } 02408 return 0; 02409 } 02410 02416 int mpu_get_dmp_state(unsigned char *enabled) 02417 { 02418 enabled[0] = st.chip_cfg.dmp_on; 02419 return 0; 02420 } 02421 02422 02423 /* This initialization is similar to the one in ak8975.c. */ 02424 int setup_compass(void) 02425 { 02426 #ifdef AK89xx_SECONDARY 02427 unsigned char data[4], akm_addr; 02428 02429 mpu_set_bypass(1); 02430 02431 /* Find compass. Possible addresses range from 0x0C to 0x0F. */ 02432 for (akm_addr = 0x0C; akm_addr <= 0x0F; akm_addr++) { 02433 int result; 02434 result = i2c_read(akm_addr, AKM_REG_WHOAMI, 1, data); 02435 if (!result && (data[0] == AKM_WHOAMI)) 02436 break; 02437 } 02438 02439 if (akm_addr > 0x0F) { 02440 /* TODO: Handle this case in all compass-related functions. */ 02441 log_e("Compass not found.\n"); 02442 return -1; 02443 } 02444 02445 st.chip_cfg.compass_addr = akm_addr; 02446 02447 data[0] = AKM_POWER_DOWN; 02448 if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) 02449 return -1; 02450 delay_ms(1); 02451 02452 data[0] = AKM_FUSE_ROM_ACCESS; 02453 if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) 02454 return -1; 02455 delay_ms(1); 02456 02457 /* Get sensitivity adjustment data from fuse ROM. */ 02458 if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ASAX, 3, data)) 02459 return -1; 02460 st.chip_cfg.mag_sens_adj[0] = (long)data[0] + 128; 02461 st.chip_cfg.mag_sens_adj[1] = (long)data[1] + 128; 02462 st.chip_cfg.mag_sens_adj[2] = (long)data[2] + 128; 02463 02464 data[0] = AKM_POWER_DOWN; 02465 if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) 02466 return -1; 02467 delay_ms(1); 02468 02469 mpu_set_bypass(0); 02470 02471 /* Set up master mode, master clock, and ES bit. */ 02472 data[0] = 0x40; 02473 if (i2c_write(st.hw->addr, st.reg->i2c_mst, 1, data)) 02474 return -1; 02475 02476 /* Slave 0 reads from AKM data registers. */ 02477 data[0] = BIT_I2C_READ | st.chip_cfg.compass_addr; 02478 if (i2c_write(st.hw->addr, st.reg->s0_addr, 1, data)) 02479 return -1; 02480 02481 /* Compass reads start at this register. */ 02482 data[0] = AKM_REG_ST1; 02483 if (i2c_write(st.hw->addr, st.reg->s0_reg, 1, data)) 02484 return -1; 02485 02486 /* Enable slave 0, 8-byte reads. */ 02487 data[0] = BIT_SLAVE_EN | 8; 02488 if (i2c_write(st.hw->addr, st.reg->s0_ctrl, 1, data)) 02489 return -1; 02490 02491 /* Slave 1 changes AKM measurement mode. */ 02492 data[0] = st.chip_cfg.compass_addr; 02493 if (i2c_write(st.hw->addr, st.reg->s1_addr, 1, data)) 02494 return -1; 02495 02496 /* AKM measurement mode register. */ 02497 data[0] = AKM_REG_CNTL; 02498 if (i2c_write(st.hw->addr, st.reg->s1_reg, 1, data)) 02499 return -1; 02500 02501 /* Enable slave 1, 1-byte writes. */ 02502 data[0] = BIT_SLAVE_EN | 1; 02503 if (i2c_write(st.hw->addr, st.reg->s1_ctrl, 1, data)) 02504 return -1; 02505 02506 /* Set slave 1 data. */ 02507 data[0] = AKM_SINGLE_MEASUREMENT; 02508 if (i2c_write(st.hw->addr, st.reg->s1_do, 1, data)) 02509 return -1; 02510 02511 /* Trigger slave 0 and slave 1 actions at each sample. */ 02512 data[0] = 0x03; 02513 if (i2c_write(st.hw->addr, st.reg->i2c_delay_ctrl, 1, data)) 02514 return -1; 02515 02516 #ifdef MPU9150 02517 /* For the MPU9150, the auxiliary I2C bus needs to be set to VDD. */ 02518 data[0] = BIT_I2C_MST_VDDIO; 02519 if (i2c_write(st.hw->addr, st.reg->yg_offs_tc, 1, data)) 02520 return -1; 02521 #endif 02522 02523 return 0; 02524 #else 02525 return -1; 02526 #endif 02527 } 02528 02535 int mpu_get_compass_reg(short *data, unsigned long *timestamp) 02536 { 02537 #ifdef AK89xx_SECONDARY 02538 unsigned char tmp[9]; 02539 02540 if (!(st.chip_cfg.sensors & INV_XYZ_COMPASS)) 02541 return -1; 02542 02543 #ifdef AK89xx_BYPASS 02544 if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ST1, 8, tmp)) 02545 return -1; 02546 tmp[8] = AKM_SINGLE_MEASUREMENT; 02547 if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp+8)) 02548 return -1; 02549 #else 02550 if (i2c_read(st.hw->addr, st.reg->raw_compass, 8, tmp)) 02551 return -1; 02552 #endif 02553 02554 #if defined AK8975_SECONDARY 02555 /* AK8975 doesn't have the overrun error bit. */ 02556 if (!(tmp[0] & AKM_DATA_READY)) 02557 return -2; 02558 if ((tmp[7] & AKM_OVERFLOW) || (tmp[7] & AKM_DATA_ERROR)) 02559 return -3; 02560 #elif defined AK8963_SECONDARY 02561 /* AK8963 doesn't have the data read error bit. */ 02562 if (!(tmp[0] & AKM_DATA_READY) || (tmp[0] & AKM_DATA_OVERRUN)) 02563 return -2; 02564 if (tmp[7] & AKM_OVERFLOW) 02565 return -3; 02566 #endif 02567 data[0] = (tmp[2] << 8) | tmp[1]; 02568 data[1] = (tmp[4] << 8) | tmp[3]; 02569 data[2] = (tmp[6] << 8) | tmp[5]; 02570 02571 data[0] = ((long)data[0] * st.chip_cfg.mag_sens_adj[0]) >> 8; 02572 data[1] = ((long)data[1] * st.chip_cfg.mag_sens_adj[1]) >> 8; 02573 data[2] = ((long)data[2] * st.chip_cfg.mag_sens_adj[2]) >> 8; 02574 02575 if (timestamp) 02576 get_ms(timestamp); 02577 return 0; 02578 #else 02579 return -1; 02580 #endif 02581 } 02582 02588 int mpu_get_compass_fsr(unsigned short *fsr) 02589 { 02590 #ifdef AK89xx_SECONDARY 02591 fsr[0] = st.hw->compass_fsr; 02592 return 0; 02593 #else 02594 return -1; 02595 #endif 02596 } 02597 02642 int mpu_lp_motion_interrupt(unsigned short thresh, unsigned char time, 02643 unsigned char lpa_freq) 02644 { 02645 unsigned char data[3]; 02646 02647 if (lpa_freq) { 02648 unsigned char thresh_hw; 02649 02650 #if defined MPU6050 02651 /* TODO: Make these const/#defines. */ 02652 /* 1LSb = 32mg. */ 02653 if (thresh > 8160) 02654 thresh_hw = 255; 02655 else if (thresh < 32) 02656 thresh_hw = 1; 02657 else 02658 thresh_hw = thresh >> 5; 02659 #elif defined MPU6500 02660 /* 1LSb = 4mg. */ 02661 if (thresh > 1020) 02662 thresh_hw = 255; 02663 else if (thresh < 4) 02664 thresh_hw = 1; 02665 else 02666 thresh_hw = thresh >> 2; 02667 #endif 02668 02669 if (!time) 02670 /* Minimum duration must be 1ms. */ 02671 time = 1; 02672 02673 #if defined MPU6050 02674 if (lpa_freq > 40) 02675 #elif defined MPU6500 02676 if (lpa_freq > 640) 02677 #endif 02678 /* At this point, the chip has not been re-configured, so the 02679 * function can safely exit. 02680 */ 02681 return -1; 02682 02683 if (!st.chip_cfg.int_motion_only) { 02684 /* Store current settings for later. */ 02685 if (st.chip_cfg.dmp_on) { 02686 mpu_set_dmp_state(0); 02687 st.chip_cfg.cache.dmp_on = 1; 02688 } else 02689 st.chip_cfg.cache.dmp_on = 0; 02690 mpu_get_gyro_fsr(&st.chip_cfg.cache.gyro_fsr); 02691 mpu_get_accel_fsr(&st.chip_cfg.cache.accel_fsr); 02692 mpu_get_lpf(&st.chip_cfg.cache.lpf); 02693 mpu_get_sample_rate(&st.chip_cfg.cache.sample_rate); 02694 st.chip_cfg.cache.sensors_on = st.chip_cfg.sensors; 02695 mpu_get_fifo_config(&st.chip_cfg.cache.fifo_sensors); 02696 } 02697 02698 #ifdef MPU6050 02699 /* Disable hardware interrupts for now. */ 02700 set_int_enable(0); 02701 02702 /* Enter full-power accel-only mode. */ 02703 mpu_lp_accel_mode(0); 02704 02705 /* Override current LPF (and HPF) settings to obtain a valid accel 02706 * reading. 02707 */ 02708 data[0] = INV_FILTER_256HZ_NOLPF2; 02709 if (i2c_write(st.hw->addr, st.reg->lpf, 1, data)) 02710 return -1; 02711 02712 /* NOTE: Digital high pass filter should be configured here. Since this 02713 * driver doesn't modify those bits anywhere, they should already be 02714 * cleared by default. 02715 */ 02716 02717 /* Configure the device to send motion interrupts. */ 02718 /* Enable motion interrupt. */ 02719 data[0] = BIT_MOT_INT_EN; 02720 if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data)) 02721 goto lp_int_restore; 02722 02723 /* Set motion interrupt parameters. */ 02724 data[0] = thresh_hw; 02725 data[1] = time; 02726 if (i2c_write(st.hw->addr, st.reg->motion_thr, 2, data)) 02727 goto lp_int_restore; 02728 02729 /* Force hardware to "lock" current accel sample. */ 02730 delay_ms(5); 02731 data[0] = (st.chip_cfg.accel_fsr << 3) | BITS_HPF; 02732 if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, data)) 02733 goto lp_int_restore; 02734 02735 /* Set up LP accel mode. */ 02736 data[0] = BIT_LPA_CYCLE; 02737 if (lpa_freq == 1) 02738 data[1] = INV_LPA_1_25HZ; 02739 else if (lpa_freq <= 5) 02740 data[1] = INV_LPA_5HZ; 02741 else if (lpa_freq <= 20) 02742 data[1] = INV_LPA_20HZ; 02743 else 02744 data[1] = INV_LPA_40HZ; 02745 data[1] = (data[1] << 6) | BIT_STBY_XYZG; 02746 if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, data)) 02747 goto lp_int_restore; 02748 02749 st.chip_cfg.int_motion_only = 1; 02750 return 0; 02751 #elif defined MPU6500 02752 /* Disable hardware interrupts. */ 02753 set_int_enable(0); 02754 02755 /* Enter full-power accel-only mode, no FIFO/DMP. */ 02756 data[0] = 0; 02757 data[1] = 0; 02758 data[2] = BIT_STBY_XYZG; 02759 if (i2c_write(st.hw->addr, st.reg->user_ctrl, 3, data)) 02760 goto lp_int_restore; 02761 02762 /* Set motion threshold. */ 02763 data[0] = thresh_hw; 02764 if (i2c_write(st.hw->addr, st.reg->motion_thr, 1, data)) 02765 goto lp_int_restore; 02766 02767 /* Set wake frequency. */ 02768 if (lpa_freq == 1) 02769 data[0] = INV_LPA_1_25HZ; 02770 else if (lpa_freq == 2) 02771 data[0] = INV_LPA_2_5HZ; 02772 else if (lpa_freq <= 5) 02773 data[0] = INV_LPA_5HZ; 02774 else if (lpa_freq <= 10) 02775 data[0] = INV_LPA_10HZ; 02776 else if (lpa_freq <= 20) 02777 data[0] = INV_LPA_20HZ; 02778 else if (lpa_freq <= 40) 02779 data[0] = INV_LPA_40HZ; 02780 else if (lpa_freq <= 80) 02781 data[0] = INV_LPA_80HZ; 02782 else if (lpa_freq <= 160) 02783 data[0] = INV_LPA_160HZ; 02784 else if (lpa_freq <= 320) 02785 data[0] = INV_LPA_320HZ; 02786 else 02787 data[0] = INV_LPA_640HZ; 02788 if (i2c_write(st.hw->addr, st.reg->lp_accel_odr, 1, data)) 02789 goto lp_int_restore; 02790 02791 /* Enable motion interrupt (MPU6500 version). */ 02792 data[0] = BITS_WOM_EN; 02793 if (i2c_write(st.hw->addr, st.reg->accel_intel, 1, data)) 02794 goto lp_int_restore; 02795 02796 /* Enable cycle mode. */ 02797 data[0] = BIT_LPA_CYCLE; 02798 if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) 02799 goto lp_int_restore; 02800 02801 /* Enable interrupt. */ 02802 data[0] = BIT_MOT_INT_EN; 02803 if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data)) 02804 goto lp_int_restore; 02805 02806 st.chip_cfg.int_motion_only = 1; 02807 return 0; 02808 #endif 02809 } else { 02810 /* Don't "restore" the previous state if no state has been saved. */ 02811 int ii; 02812 char *cache_ptr = (char*)&st.chip_cfg.cache; 02813 for (ii = 0; ii < sizeof(st.chip_cfg.cache); ii++) { 02814 if (cache_ptr[ii] != 0) 02815 goto lp_int_restore; 02816 } 02817 /* If we reach this point, motion interrupt mode hasn't been used yet. */ 02818 return -1; 02819 } 02820 lp_int_restore: 02821 /* Set to invalid values to ensure no I2C writes are skipped. */ 02822 st.chip_cfg.gyro_fsr = 0xFF; 02823 st.chip_cfg.accel_fsr = 0xFF; 02824 st.chip_cfg.lpf = 0xFF; 02825 st.chip_cfg.sample_rate = 0xFFFF; 02826 st.chip_cfg.sensors = 0xFF; 02827 st.chip_cfg.fifo_enable = 0xFF; 02828 st.chip_cfg.clk_src = INV_CLK_PLL; 02829 mpu_set_sensors(st.chip_cfg.cache.sensors_on); 02830 mpu_set_gyro_fsr(st.chip_cfg.cache.gyro_fsr); 02831 mpu_set_accel_fsr(st.chip_cfg.cache.accel_fsr); 02832 mpu_set_lpf(st.chip_cfg.cache.lpf); 02833 mpu_set_sample_rate(st.chip_cfg.cache.sample_rate); 02834 mpu_configure_fifo(st.chip_cfg.cache.fifo_sensors); 02835 02836 if (st.chip_cfg.cache.dmp_on) 02837 mpu_set_dmp_state(1); 02838 02839 #ifdef MPU6500 02840 /* Disable motion interrupt (MPU6500 version). */ 02841 data[0] = 0; 02842 if (i2c_write(st.hw->addr, st.reg->accel_intel, 1, data)) 02843 goto lp_int_restore; 02844 #endif 02845 02846 st.chip_cfg.int_motion_only = 0; 02847 return 0; 02848 } 02850 //添加的代码部分 02852 //本程序只供学习使用,未经作者许可,不得用于其它任何用途 02853 //ALIENTEK精英STM32开发板V3 02854 //MPU6050 DMP 驱动代码 02855 //正点原子@ALIENTEK 02856 //技术论坛:www.openedv.com 02857 //创建日期:2015/1/17 02858 //版本:V1.0 02859 //版权所有,盗版必究。 02860 //Copyright(C) 广州市星翼电子科技有限公司 2009-2019 02861 //All rights reserved 02863 02864 //q30格式,long转float时的除数. 02865 #define q30 1073741824.0f 02866 02867 //陀螺仪方向设置 02868 static signed char gyro_orientation[9] = { 1, 0, 0, 02869 0, 1, 0, 02870 0, 0, 1}; 02871 //MPU6050自测试 02872 //返回值:0,正常 02873 // 其他,失败 02874 u8 run_self_test(void){ 02875 int result; 02876 //char test_packet[4] = {0}; 02877 long gyro[3], accel[3]; 02878 result = mpu_run_self_test(gyro, accel); 02879 if (result == 0x3){ 02880 /* Test passed. We can trust the gyro data here, so let's push it down 02881 * to the DMP. 02882 */ 02883 float sens; 02884 unsigned short accel_sens; 02885 mpu_get_gyro_sens(&sens); 02886 gyro[0] = (long)(gyro[0] * sens); 02887 gyro[1] = (long)(gyro[1] * sens); 02888 gyro[2] = (long)(gyro[2] * sens); 02889 dmp_set_gyro_bias(gyro); 02890 mpu_get_accel_sens(&accel_sens); 02891 accel[0] *= accel_sens; 02892 accel[1] *= accel_sens; 02893 accel[2] *= accel_sens; 02894 dmp_set_accel_bias(accel); 02895 return 0; 02896 }else return 1;} 02897 //陀螺仪方向控制 02898 unsigned short inv_orientation_matrix_to_scalar( 02899 const signed char *mtx){ 02900 unsigned short scalar; 02901 /* 02902 XYZ 010_001_000 Identity Matrix 02903 XZY 001_010_000 02904 YXZ 010_000_001 02905 YZX 000_010_001 02906 ZXY 001_000_010 02907 ZYX 000_001_010 02908 */ 02909 scalar = inv_row_2_scale(mtx); 02910 scalar |= inv_row_2_scale(mtx + 3) << 3; 02911 scalar |= inv_row_2_scale(mtx + 6) << 6; 02912 return scalar;} 02913 //方向转换 02914 unsigned short inv_row_2_scale(const signed char *row){ 02915 unsigned short b; 02916 02917 if (row[0] > 0) 02918 b = 0; 02919 else if (row[0] < 0) 02920 b = 4; 02921 else if (row[1] > 0) 02922 b = 1; 02923 else if (row[1] < 0) 02924 b = 5; 02925 else if (row[2] > 0) 02926 b = 2; 02927 else if (row[2] < 0) 02928 b = 6; 02929 else 02930 b = 7; // error 02931 return b;} 02932 //空函数,未用到. 02933 void mget_ms(unsigned long *time){} 02934 //mpu6050,dmp初始化 02935 //返回值:0,正常 02936 // 其他,失败 02937 u8 mpu_dmp_init(void) 02938 { 02939 u8 res=0; 02940 if(mpu_init()==0) //初始化MPU6050 02941 { 02942 res=mpu_set_sensors(INV_XYZ_GYRO|INV_XYZ_ACCEL); //设置所需要的传感器 02943 if(res)return 1; 02944 res=mpu_configure_fifo(INV_XYZ_GYRO|INV_XYZ_ACCEL); //设置FIFO 02945 if(res)return 2; 02946 res=mpu_set_sample_rate(DEFAULT_MPU_HZ); //设置采样率 02947 if(res)return 3; 02948 res=dmp_load_motion_driver_firmware(); //加载dmp固件 02949 if(res)return 4; 02950 res=dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation));//设置陀螺仪方向 02951 if(res)return 5; 02952 res=dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT|DMP_FEATURE_TAP| //设置dmp功能 02953 DMP_FEATURE_ANDROID_ORIENT|DMP_FEATURE_SEND_RAW_ACCEL|DMP_FEATURE_SEND_CAL_GYRO| 02954 DMP_FEATURE_GYRO_CAL); 02955 if(res)return 6; 02956 res=dmp_set_fifo_rate(DEFAULT_MPU_HZ); //设置DMP输出速率(最大不超过200Hz) 02957 if(res)return 7; 02958 res=run_self_test(); //自检 02959 if(res)return 8; 02960 res=mpu_set_dmp_state(1); //使能DMP 02961 if(res)return 9; 02962 }else return 10; 02963 return 0;} 02964 //得到dmp处理后的数据(注意,本函数需要比较多堆栈,局部变量有点多) 02965 //pitch:俯仰角 精度:0.1° 范围:-90.0° <---> +90.0° 02966 //roll:横滚角 精度:0.1° 范围:-180.0°<---> +180.0° 02967 //yaw:航向角 精度:0.1° 范围:-180.0°<---> +180.0° 02968 //返回值:0,正常 02969 // 其他,失败 02970 u8 mpu_dmp_get_data(float *pitch,float *roll,float *yaw){ 02971 float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f; 02972 unsigned long sensor_timestamp; 02973 short gyro[3], accel[3], sensors; 02974 unsigned char more; 02975 long quat[4]; 02976 if(dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,&more))return 1; 02977 /* Gyro and accel data are written to the FIFO by the DMP in chip frame and hardware units. 02978 * This behavior is convenient because it keeps the gyro and accel outputs of dmp_read_fifo and mpu_read_fifo consistent. 02979 **/ 02980 /*if (sensors & INV_XYZ_GYRO ) 02981 send_packet(PACKET_TYPE_GYRO, gyro); 02982 if (sensors & INV_XYZ_ACCEL) 02983 send_packet(PACKET_TYPE_ACCEL, accel); */ 02984 /* Unlike gyro and accel, quaternions are written to the FIFO in the body frame, q30. 02985 * The orientation is set by the scalar passed to dmp_set_orientation during initialization. 02986 **/ 02987 if(sensors&INV_WXYZ_QUAT) 02988 { 02989 q0 = quat[0] / q30; //q30格式转换为浮点数 02990 q1 = quat[1] / q30; 02991 q2 = quat[2] / q30; 02992 q3 = quat[3] / q30; 02993 //计算得到俯仰角/横滚角/航向角 02994 *pitch = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; // pitch 02995 *roll = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll 02996 *yaw = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3; //yaw 02997 }else return 2; 02998 return 0; 02999 }