Yihui Xiong
/
Seeed_nRF51822_Motion
initial
Embed:
(wiki syntax)
Show/hide line numbers
inv_mpu.c
Go to the documentation of this file.
00001 /* 00002 $License: 00003 Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. 00004 See included License.txt for License information. 00005 $ 00006 */ 00007 /** 00008 * @addtogroup DRIVERS Sensor Driver Layer 00009 * @brief Hardware drivers to communicate with sensors via I2C. 00010 * 00011 * @{ 00012 * @file inv_mpu.c 00013 * @brief An I2C-based driver for Invensense gyroscopes. 00014 * @details This driver currently works for the following devices: 00015 * MPU6050 00016 * MPU6500 00017 * MPU9150 (or MPU6050 w/ AK8975 on the auxiliary bus) 00018 * MPU9250 (or MPU6500 w/ AK8963 on the auxiliary bus) 00019 */ 00020 #include <stdio.h> 00021 #include <stdint.h> 00022 #include <stdlib.h> 00023 #include <string.h> 00024 #include <math.h> 00025 #include "inv_mpu.h" 00026 00027 /* The following functions must be defined for this platform: 00028 * mpu_hal_write(unsigned char slave_addr, unsigned char reg_addr, 00029 * unsigned char length, unsigned char const *data) 00030 * mpu_hal_read(unsigned char slave_addr, unsigned char reg_addr, 00031 * unsigned char length, unsigned char *data) 00032 * delay_ms(unsigned long num_ms) 00033 * get_ms(unsigned long *count) 00034 * reg_int_cb(void (*cb)(void), unsigned char port, unsigned char pin) 00035 * labs(long x) 00036 * fabsf(float x) 00037 * min(int a, int b) 00038 */ 00039 #if defined __MBED__ // for mbed platform 00040 #include "mpu_mbed_config.h" 00041 #elif defined MOTION_DRIVER_TARGET_MSP430 00042 #include "msp430.h" 00043 #include "msp430_i2c.h" 00044 #include "msp430_clock.h" 00045 #include "msp430_interrupt.h" 00046 #define mpu_hal_write msp430_mpu_hal_write 00047 #define mpu_hal_read msp430_mpu_hal_read 00048 #define delay_ms msp430_delay_ms 00049 #define get_ms msp430_get_clock_ms 00050 static inline int reg_int_cb(struct int_param_s *int_param) 00051 { 00052 return msp430_reg_int_cb(int_param->cb, int_param->pin, int_param->lp_exit, 00053 int_param->active_low); 00054 } 00055 #define log_i(...) do {} while (0) 00056 #define log_e(...) do {} while (0) 00057 /* labs is already defined by TI's toolchain. */ 00058 /* fabs is for doubles. fabsf is for floats. */ 00059 #define fabs fabsf 00060 #define min(a,b) ((a<b)?a:b) 00061 #elif defined EMPL_TARGET_MSP430 00062 #include "msp430.h" 00063 #include "msp430_i2c.h" 00064 #include "msp430_clock.h" 00065 #include "msp430_interrupt.h" 00066 #include "log.h" 00067 #define mpu_hal_write msp430_mpu_hal_write 00068 #define mpu_hal_read msp430_mpu_hal_read 00069 #define delay_ms msp430_delay_ms 00070 #define get_ms msp430_get_clock_ms 00071 static inline int reg_int_cb(struct int_param_s *int_param) 00072 { 00073 return msp430_reg_int_cb(int_param->cb, int_param->pin, int_param->lp_exit, 00074 int_param->active_low); 00075 } 00076 #define log_i MPL_LOGI 00077 #define log_e MPL_LOGE 00078 /* labs is already defined by TI's toolchain. */ 00079 /* fabs is for doubles. fabsf is for floats. */ 00080 #define fabs fabsf 00081 #define min(a,b) ((a<b)?a:b) 00082 #elif defined EMPL_TARGET_UC3L0 00083 /* Instead of using the standard TWI driver from the ASF library, we're using 00084 * a TWI driver that follows the slave address + register address convention. 00085 */ 00086 #include "twi.h" 00087 #include "delay.h" 00088 #include "sysclk.h" 00089 #include "log.h" 00090 #include "sensors_xplained.h" 00091 #include "uc3l0_clock.h" 00092 #define mpu_hal_write(a, b, c, d) twi_write(a, b, d, c) 00093 #define mpu_hal_read(a, b, c, d) twi_read(a, b, d, c) 00094 /* delay_ms is a function already defined in ASF. */ 00095 #define get_ms uc3l0_get_clock_ms 00096 static inline int reg_int_cb(struct int_param_s *int_param) 00097 { 00098 sensor_board_irq_connect(int_param->pin, int_param->cb, int_param->arg); 00099 return 0; 00100 } 00101 #define log_i MPL_LOGI 00102 #define log_e MPL_LOGE 00103 /* UC3 is a 32-bit processor, so abs and labs are equivalent. */ 00104 #define labs abs 00105 #define fabs(x) (((x)>0)?(x):-(x)) 00106 00107 #else 00108 #error Gyro driver is missing the system layer implementations. 00109 #endif 00110 00111 #if !defined MPU6050 && !defined MPU9150 && !defined MPU6500 && !defined MPU9250 00112 #error Which gyro are you using? Define MPUxxxx in your compiler options. 00113 #endif 00114 00115 /* Time for some messy macro work. =] 00116 * #define MPU9150 00117 * is equivalent to.. 00118 * #define MPU6050 00119 * #define AK8975_SECONDARY 00120 * 00121 * #define MPU9250 00122 * is equivalent to.. 00123 * #define MPU6500 00124 * #define AK8963_SECONDARY 00125 */ 00126 #if defined MPU9150 00127 #ifndef MPU6050 00128 #define MPU6050 00129 #endif /* #ifndef MPU6050 */ 00130 #if defined AK8963_SECONDARY 00131 #error "MPU9150 and AK8963_SECONDARY cannot both be defined." 00132 #elif !defined AK8975_SECONDARY /* #if defined AK8963_SECONDARY */ 00133 #define AK8975_SECONDARY 00134 #endif /* #if defined AK8963_SECONDARY */ 00135 #elif defined MPU9250 /* #if defined MPU9150 */ 00136 #ifndef MPU6500 00137 #define MPU6500 00138 #endif /* #ifndef MPU6500 */ 00139 #if defined AK8975_SECONDARY 00140 #error "MPU9250 and AK8975_SECONDARY cannot both be defined." 00141 #elif !defined AK8963_SECONDARY /* #if defined AK8975_SECONDARY */ 00142 #define AK8963_SECONDARY 00143 #endif /* #if defined AK8975_SECONDARY */ 00144 #endif /* #if defined MPU9150 */ 00145 00146 #if defined AK8975_SECONDARY || defined AK8963_SECONDARY 00147 #define AK89xx_SECONDARY 00148 #else 00149 /* #warning "No compass = less profit for Invensense. Lame." */ 00150 #endif 00151 00152 static int set_int_enable(unsigned char enable); 00153 00154 /* Hardware registers needed by driver. */ 00155 struct gyro_reg_s { 00156 unsigned char who_am_i; 00157 unsigned char rate_div; 00158 unsigned char lpf; 00159 unsigned char prod_id; 00160 unsigned char user_ctrl; 00161 unsigned char fifo_en; 00162 unsigned char gyro_cfg; 00163 unsigned char accel_cfg; 00164 unsigned char accel_cfg2; 00165 unsigned char lp_accel_odr; 00166 unsigned char motion_thr; 00167 unsigned char motion_dur; 00168 unsigned char fifo_count_h; 00169 unsigned char fifo_r_w; 00170 unsigned char raw_gyro; 00171 unsigned char raw_accel; 00172 unsigned char temp; 00173 unsigned char int_enable; 00174 unsigned char dmp_int_status; 00175 unsigned char int_status; 00176 unsigned char accel_intel; 00177 unsigned char pwr_mgmt_1; 00178 unsigned char pwr_mgmt_2; 00179 unsigned char int_pin_cfg; 00180 unsigned char mem_r_w; 00181 unsigned char accel_offs; 00182 unsigned char i2c_mst; 00183 unsigned char bank_sel; 00184 unsigned char mem_start_addr; 00185 unsigned char prgm_start_h; 00186 #if defined AK89xx_SECONDARY 00187 unsigned char s0_addr; 00188 unsigned char s0_reg; 00189 unsigned char s0_ctrl; 00190 unsigned char s1_addr; 00191 unsigned char s1_reg; 00192 unsigned char s1_ctrl; 00193 unsigned char s4_ctrl; 00194 unsigned char s0_do; 00195 unsigned char s1_do; 00196 unsigned char i2c_delay_ctrl; 00197 unsigned char raw_compass; 00198 /* The I2C_MST_VDDIO bit is in this register. */ 00199 unsigned char yg_offs_tc; 00200 #endif 00201 }; 00202 00203 /* Information specific to a particular device. */ 00204 struct hw_s { 00205 unsigned char addr; 00206 unsigned short max_fifo; 00207 unsigned char num_reg; 00208 unsigned short temp_sens; 00209 short temp_offset; 00210 unsigned short bank_size; 00211 #if defined AK89xx_SECONDARY 00212 unsigned short compass_fsr; 00213 #endif 00214 }; 00215 00216 /* When entering motion interrupt mode, the driver keeps track of the 00217 * previous state so that it can be restored at a later time. 00218 * TODO: This is tacky. Fix it. 00219 */ 00220 struct motion_int_cache_s { 00221 unsigned short gyro_fsr; 00222 unsigned char accel_fsr; 00223 unsigned short lpf; 00224 unsigned short sample_rate; 00225 unsigned char sensors_on; 00226 unsigned char fifo_sensors; 00227 unsigned char dmp_on; 00228 }; 00229 00230 /* Cached chip configuration data. 00231 * TODO: A lot of these can be handled with a bitmask. 00232 */ 00233 struct chip_cfg_s { 00234 /* Matches gyro_cfg >> 3 & 0x03 */ 00235 unsigned char gyro_fsr; 00236 /* Matches accel_cfg >> 3 & 0x03 */ 00237 unsigned char accel_fsr; 00238 /* Enabled sensors. Uses same masks as fifo_en, NOT pwr_mgmt_2. */ 00239 unsigned char sensors; 00240 /* Matches config register. */ 00241 unsigned char lpf; 00242 unsigned char clk_src; 00243 /* Sample rate, NOT rate divider. */ 00244 unsigned short sample_rate; 00245 /* Matches fifo_en register. */ 00246 unsigned char fifo_enable; 00247 /* Matches int enable register. */ 00248 unsigned char int_enable; 00249 /* 1 if devices on auxiliary I2C bus appear on the primary. */ 00250 unsigned char bypass_mode; 00251 /* 1 if half-sensitivity. 00252 * NOTE: This doesn't belong here, but everything else in hw_s is const, 00253 * and this allows us to save some precious RAM. 00254 */ 00255 unsigned char accel_half; 00256 /* 1 if device in low-power accel-only mode. */ 00257 unsigned char lp_accel_mode; 00258 /* 1 if interrupts are only triggered on motion events. */ 00259 unsigned char int_motion_only; 00260 struct motion_int_cache_s cache; 00261 /* 1 for active low interrupts. */ 00262 unsigned char active_low_int; 00263 /* 1 for latched interrupts. */ 00264 unsigned char latched_int; 00265 /* 1 if DMP is enabled. */ 00266 unsigned char dmp_on; 00267 /* Ensures that DMP will only be loaded once. */ 00268 unsigned char dmp_loaded; 00269 /* Sampling rate used when DMP is enabled. */ 00270 unsigned short dmp_sample_rate; 00271 #ifdef AK89xx_SECONDARY 00272 /* Compass sample rate. */ 00273 unsigned short compass_sample_rate; 00274 unsigned char compass_addr; 00275 short mag_sens_adj[3]; 00276 #endif 00277 }; 00278 00279 /* Information for self-test. */ 00280 struct test_s { 00281 unsigned long gyro_sens; 00282 unsigned long accel_sens; 00283 unsigned char reg_rate_div; 00284 unsigned char reg_lpf; 00285 unsigned char reg_gyro_fsr; 00286 unsigned char reg_accel_fsr; 00287 unsigned short wait_ms; 00288 unsigned char packet_thresh; 00289 float min_dps; 00290 float max_dps; 00291 float max_gyro_var; 00292 float min_g; 00293 float max_g; 00294 float max_accel_var; 00295 #ifdef MPU6500 00296 float max_g_offset; 00297 unsigned short sample_wait_ms; 00298 #endif 00299 }; 00300 00301 /* Gyro driver state variables. */ 00302 struct gyro_state_s { 00303 const struct gyro_reg_s *reg; 00304 const struct hw_s *hw; 00305 struct chip_cfg_s chip_cfg; 00306 const struct test_s *test; 00307 }; 00308 00309 /* Filter configurations. */ 00310 enum lpf_e { 00311 INV_FILTER_256HZ_NOLPF2 = 0, 00312 INV_FILTER_188HZ, 00313 INV_FILTER_98HZ, 00314 INV_FILTER_42HZ, 00315 INV_FILTER_20HZ, 00316 INV_FILTER_10HZ, 00317 INV_FILTER_5HZ, 00318 INV_FILTER_2100HZ_NOLPF, 00319 NUM_FILTER 00320 }; 00321 00322 /* Full scale ranges. */ 00323 enum gyro_fsr_e { 00324 INV_FSR_250DPS = 0, 00325 INV_FSR_500DPS, 00326 INV_FSR_1000DPS, 00327 INV_FSR_2000DPS, 00328 NUM_GYRO_FSR 00329 }; 00330 00331 /* Full scale ranges. */ 00332 enum accel_fsr_e { 00333 INV_FSR_2G = 0, 00334 INV_FSR_4G, 00335 INV_FSR_8G, 00336 INV_FSR_16G, 00337 NUM_ACCEL_FSR 00338 }; 00339 00340 /* Clock sources. */ 00341 enum clock_sel_e { 00342 INV_CLK_INTERNAL = 0, 00343 INV_CLK_PLL, 00344 NUM_CLK 00345 }; 00346 00347 /* Low-power accel wakeup rates. */ 00348 enum lp_accel_rate_e { 00349 #if defined MPU6050 00350 INV_LPA_1_25HZ, 00351 INV_LPA_5HZ, 00352 INV_LPA_20HZ, 00353 INV_LPA_40HZ 00354 #elif defined MPU6500 00355 INV_LPA_0_3125HZ, 00356 INV_LPA_0_625HZ, 00357 INV_LPA_1_25HZ, 00358 INV_LPA_2_5HZ, 00359 INV_LPA_5HZ, 00360 INV_LPA_10HZ, 00361 INV_LPA_20HZ, 00362 INV_LPA_40HZ, 00363 INV_LPA_80HZ, 00364 INV_LPA_160HZ, 00365 INV_LPA_320HZ, 00366 INV_LPA_640HZ 00367 #endif 00368 }; 00369 00370 #define BIT_I2C_MST_VDDIO (0x80) 00371 #define BIT_FIFO_EN (0x40) 00372 #define BIT_DMP_EN (0x80) 00373 #define BIT_FIFO_RST (0x04) 00374 #define BIT_DMP_RST (0x08) 00375 #define BIT_FIFO_OVERFLOW (0x10) 00376 #define BIT_DATA_RDY_EN (0x01) 00377 #define BIT_DMP_INT_EN (0x02) 00378 #define BIT_MOT_INT_EN (0x40) 00379 #define BITS_FSR (0x18) 00380 #define BITS_LPF (0x07) 00381 #define BITS_HPF (0x07) 00382 #define BITS_CLK (0x07) 00383 #define BIT_FIFO_SIZE_1024 (0x40) 00384 #define BIT_FIFO_SIZE_2048 (0x80) 00385 #define BIT_FIFO_SIZE_4096 (0xC0) 00386 #define BIT_RESET (0x80) 00387 #define BIT_SLEEP (0x40) 00388 #define BIT_S0_DELAY_EN (0x01) 00389 #define BIT_S2_DELAY_EN (0x04) 00390 #define BITS_SLAVE_LENGTH (0x0F) 00391 #define BIT_SLAVE_BYTE_SW (0x40) 00392 #define BIT_SLAVE_GROUP (0x10) 00393 #define BIT_SLAVE_EN (0x80) 00394 #define BIT_I2C_READ (0x80) 00395 #define BITS_I2C_MASTER_DLY (0x1F) 00396 #define BIT_AUX_IF_EN (0x20) 00397 #define BIT_ACTL (0x80) 00398 #define BIT_LATCH_EN (0x20) 00399 #define BIT_ANY_RD_CLR (0x10) 00400 #define BIT_BYPASS_EN (0x02) 00401 #define BITS_WOM_EN (0xC0) 00402 #define BIT_LPA_CYCLE (0x20) 00403 #define BIT_STBY_XA (0x20) 00404 #define BIT_STBY_YA (0x10) 00405 #define BIT_STBY_ZA (0x08) 00406 #define BIT_STBY_XG (0x04) 00407 #define BIT_STBY_YG (0x02) 00408 #define BIT_STBY_ZG (0x01) 00409 #define BIT_STBY_XYZA (BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA) 00410 #define BIT_STBY_XYZG (BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG) 00411 00412 #if defined AK8975_SECONDARY 00413 #define SUPPORTS_AK89xx_HIGH_SENS (0x00) 00414 #define AK89xx_FSR (9830) 00415 #elif defined AK8963_SECONDARY 00416 #define SUPPORTS_AK89xx_HIGH_SENS (0x10) 00417 #define AK89xx_FSR (4915) 00418 #endif 00419 00420 #ifdef AK89xx_SECONDARY 00421 #define AKM_REG_WHOAMI (0x00) 00422 00423 #define AKM_REG_ST1 (0x02) 00424 #define AKM_REG_HXL (0x03) 00425 #define AKM_REG_ST2 (0x09) 00426 00427 #define AKM_REG_CNTL (0x0A) 00428 #define AKM_REG_ASTC (0x0C) 00429 #define AKM_REG_ASAX (0x10) 00430 #define AKM_REG_ASAY (0x11) 00431 #define AKM_REG_ASAZ (0x12) 00432 00433 #define AKM_DATA_READY (0x01) 00434 #define AKM_DATA_OVERRUN (0x02) 00435 #define AKM_OVERFLOW (0x80) 00436 #define AKM_DATA_ERROR (0x40) 00437 00438 #define AKM_BIT_SELF_TEST (0x40) 00439 00440 #define AKM_POWER_DOWN (0x00 | SUPPORTS_AK89xx_HIGH_SENS) 00441 #define AKM_SINGLE_MEASUREMENT (0x01 | SUPPORTS_AK89xx_HIGH_SENS) 00442 #define AKM_FUSE_ROM_ACCESS (0x0F | SUPPORTS_AK89xx_HIGH_SENS) 00443 #define AKM_MODE_SELF_TEST (0x08 | SUPPORTS_AK89xx_HIGH_SENS) 00444 00445 #define AKM_WHOAMI (0x48) 00446 #endif 00447 00448 #if defined MPU6050 00449 const struct gyro_reg_s reg = { 00450 .who_am_i = 0x75, 00451 .rate_div = 0x19, 00452 .lpf = 0x1A, 00453 .prod_id = 0x0C, 00454 .user_ctrl = 0x6A, 00455 .fifo_en = 0x23, 00456 .gyro_cfg = 0x1B, 00457 .accel_cfg = 0x1C, 00458 .motion_thr = 0x1F, 00459 .motion_dur = 0x20, 00460 .fifo_count_h = 0x72, 00461 .fifo_r_w = 0x74, 00462 .raw_gyro = 0x43, 00463 .raw_accel = 0x3B, 00464 .temp = 0x41, 00465 .int_enable = 0x38, 00466 .dmp_int_status = 0x39, 00467 .int_status = 0x3A, 00468 .pwr_mgmt_1 = 0x6B, 00469 .pwr_mgmt_2 = 0x6C, 00470 .int_pin_cfg = 0x37, 00471 .mem_r_w = 0x6F, 00472 .accel_offs = 0x06, 00473 .i2c_mst = 0x24, 00474 .bank_sel = 0x6D, 00475 .mem_start_addr = 0x6E, 00476 .prgm_start_h = 0x70 00477 #ifdef AK89xx_SECONDARY 00478 ,.raw_compass = 0x49, 00479 .yg_offs_tc = 0x01, 00480 .s0_addr = 0x25, 00481 .s0_reg = 0x26, 00482 .s0_ctrl = 0x27, 00483 .s1_addr = 0x28, 00484 .s1_reg = 0x29, 00485 .s1_ctrl = 0x2A, 00486 .s4_ctrl = 0x34, 00487 .s0_do = 0x63, 00488 .s1_do = 0x64, 00489 .i2c_delay_ctrl = 0x67 00490 #endif 00491 }; 00492 const struct hw_s hw = { 00493 .addr = 0x69, 00494 .max_fifo = 1024, 00495 .num_reg = 118, 00496 .temp_sens = 340, 00497 .temp_offset = -521, 00498 .bank_size = 256 00499 #if defined AK89xx_SECONDARY 00500 ,.compass_fsr = AK89xx_FSR 00501 #endif 00502 }; 00503 00504 const struct test_s test = { 00505 .gyro_sens = 32768/250, 00506 .accel_sens = 32768/16, 00507 .reg_rate_div = 0, /* 1kHz. */ 00508 .reg_lpf = 1, /* 188Hz. */ 00509 .reg_gyro_fsr = 0, /* 250dps. */ 00510 .reg_accel_fsr = 0x18, /* 16g. */ 00511 .wait_ms = 50, 00512 .packet_thresh = 5, /* 5% */ 00513 .min_dps = 10.f, 00514 .max_dps = 105.f, 00515 .max_gyro_var = 0.14f, 00516 .min_g = 0.3f, 00517 .max_g = 0.95f, 00518 .max_accel_var = 0.14f 00519 }; 00520 00521 static struct gyro_state_s st = { 00522 .reg = ®, 00523 .hw = &hw, 00524 .test = &test 00525 }; 00526 #elif defined MPU6500 00527 const struct gyro_reg_s reg = { 00528 .who_am_i = 0x75, 00529 .rate_div = 0x19, 00530 .lpf = 0x1A, 00531 .prod_id = 0x0C, 00532 .user_ctrl = 0x6A, 00533 .fifo_en = 0x23, 00534 .gyro_cfg = 0x1B, 00535 .accel_cfg = 0x1C, 00536 .accel_cfg2 = 0x1D, 00537 .lp_accel_odr = 0x1E, 00538 .motion_thr = 0x1F, 00539 .motion_dur = 0x20, 00540 .fifo_count_h = 0x72, 00541 .fifo_r_w = 0x74, 00542 .raw_gyro = 0x43, 00543 .raw_accel = 0x3B, 00544 .temp = 0x41, 00545 .int_enable = 0x38, 00546 .dmp_int_status = 0x39, 00547 .int_status = 0x3A, 00548 .accel_intel = 0x69, 00549 .pwr_mgmt_1 = 0x6B, 00550 .pwr_mgmt_2 = 0x6C, 00551 .int_pin_cfg = 0x37, 00552 .mem_r_w = 0x6F, 00553 .accel_offs = 0x77, 00554 .i2c_mst = 0x24, 00555 .bank_sel = 0x6D, 00556 .mem_start_addr = 0x6E, 00557 .prgm_start_h = 0x70 00558 #ifdef AK89xx_SECONDARY 00559 ,.raw_compass = 0x49, 00560 .s0_addr = 0x25, 00561 .s0_reg = 0x26, 00562 .s0_ctrl = 0x27, 00563 .s1_addr = 0x28, 00564 .s1_reg = 0x29, 00565 .s1_ctrl = 0x2A, 00566 .s4_ctrl = 0x34, 00567 .s0_do = 0x63, 00568 .s1_do = 0x64, 00569 .i2c_delay_ctrl = 0x67 00570 #endif 00571 }; 00572 const struct hw_s hw = { 00573 .addr = 0x68, 00574 .max_fifo = 1024, 00575 .num_reg = 128, 00576 .temp_sens = 321, 00577 .temp_offset = 0, 00578 .bank_size = 256 00579 #if defined AK89xx_SECONDARY 00580 ,.compass_fsr = AK89xx_FSR 00581 #endif 00582 }; 00583 00584 const struct test_s test = { 00585 .gyro_sens = 32768/250, 00586 .accel_sens = 32768/2, //FSR = +-2G = 16384 LSB/G 00587 .reg_rate_div = 0, /* 1kHz. */ 00588 .reg_lpf = 2, /* 92Hz low pass filter*/ 00589 .reg_gyro_fsr = 0, /* 250dps. */ 00590 .reg_accel_fsr = 0x0, /* Accel FSR setting = 2g. */ 00591 .wait_ms = 200, //200ms stabilization time 00592 .packet_thresh = 200, /* 200 samples */ 00593 .min_dps = 20.f, //20 dps for Gyro Criteria C 00594 .max_dps = 60.f, //Must exceed 60 dps threshold for Gyro Criteria B 00595 .max_gyro_var = .5f, //Must exceed +50% variation for Gyro Criteria A 00596 .min_g = .225f, //Accel must exceed Min 225 mg for Criteria B 00597 .max_g = .675f, //Accel cannot exceed Max 675 mg for Criteria B 00598 .max_accel_var = .5f, //Accel must be within 50% variation for Criteria A 00599 .max_g_offset = .5f, //500 mg for Accel Criteria C 00600 .sample_wait_ms = 10 //10ms sample time wait 00601 }; 00602 00603 static struct gyro_state_s st = { 00604 .reg = ®, 00605 .hw = &hw, 00606 .test = &test 00607 }; 00608 #endif 00609 00610 #define MAX_PACKET_LENGTH (12) 00611 #ifdef MPU6500 00612 #define HWST_MAX_PACKET_LENGTH (512) 00613 #endif 00614 00615 #ifdef AK89xx_SECONDARY 00616 static int setup_compass(void); 00617 #define MAX_COMPASS_SAMPLE_RATE (100) 00618 #endif 00619 00620 /** 00621 * @brief Enable/disable data ready interrupt. 00622 * If the DMP is on, the DMP interrupt is enabled. Otherwise, the data ready 00623 * interrupt is used. 00624 * @param[in] enable 1 to enable interrupt. 00625 * @return 0 if successful. 00626 */ 00627 static int set_int_enable(unsigned char enable) 00628 { 00629 unsigned char tmp; 00630 00631 if (st.chip_cfg.dmp_on) { 00632 if (enable) 00633 tmp = BIT_DMP_INT_EN; 00634 else 00635 tmp = 0x00; 00636 if (mpu_hal_write(st.hw->addr, st.reg->int_enable, 1, &tmp)) 00637 return -1; 00638 st.chip_cfg.int_enable = tmp; 00639 } else { 00640 if (!st.chip_cfg.sensors) 00641 return -1; 00642 if (enable && st.chip_cfg.int_enable) 00643 return 0; 00644 if (enable) 00645 tmp = BIT_DATA_RDY_EN; 00646 else 00647 tmp = 0x00; 00648 if (mpu_hal_write(st.hw->addr, st.reg->int_enable, 1, &tmp)) 00649 return -1; 00650 st.chip_cfg.int_enable = tmp; 00651 } 00652 return 0; 00653 } 00654 00655 /** 00656 * @brief Register dump for testing. 00657 * @return 0 if successful. 00658 */ 00659 int mpu_reg_dump(void) 00660 { 00661 unsigned char ii; 00662 unsigned char data; 00663 00664 for (ii = 0; ii < st.hw->num_reg; ii++) { 00665 if (ii == st.reg->fifo_r_w || ii == st.reg->mem_r_w) 00666 continue; 00667 if (mpu_hal_read(st.hw->addr, ii, 1, &data)) 00668 return -1; 00669 log_i("%#5x: %#5x\r\n", ii, data); 00670 } 00671 return 0; 00672 } 00673 00674 /** 00675 * @brief Read from a single register. 00676 * NOTE: The memory and FIFO read/write registers cannot be accessed. 00677 * @param[in] reg Register address. 00678 * @param[out] data Register data. 00679 * @return 0 if successful. 00680 */ 00681 int mpu_read_reg(unsigned char reg, unsigned char *data) 00682 { 00683 if (reg == st.reg->fifo_r_w || reg == st.reg->mem_r_w) 00684 return -1; 00685 if (reg >= st.hw->num_reg) 00686 return -1; 00687 return mpu_hal_read(st.hw->addr, reg, 1, data); 00688 } 00689 00690 /** 00691 * @brief Initialize hardware. 00692 * Initial configuration:\n 00693 * Gyro FSR: +/- 2000DPS\n 00694 * Accel FSR +/- 2G\n 00695 * DLPF: 42Hz\n 00696 * FIFO rate: 50Hz\n 00697 * Clock source: Gyro PLL\n 00698 * FIFO: Disabled.\n 00699 * Data ready interrupt: Disabled, active low, unlatched. 00700 * @param[in] int_param Platform-specific parameters to interrupt API. 00701 * @return 0 if successful. 00702 */ 00703 int mpu_init(struct int_param_s *int_param) 00704 { 00705 unsigned char data[6]; 00706 00707 /* Reset device. */ 00708 data[0] = BIT_RESET; 00709 if (mpu_hal_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) 00710 return -1; 00711 delay_ms(100); 00712 00713 /* Wake up chip. */ 00714 data[0] = 0x00; 00715 if (mpu_hal_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) 00716 return -1; 00717 00718 st.chip_cfg.accel_half = 0; 00719 00720 #ifdef MPU6500 00721 /* MPU6500 shares 4kB of memory between the DMP and the FIFO. Since the 00722 * first 3kB are needed by the DMP, we'll use the last 1kB for the FIFO. 00723 */ 00724 data[0] = BIT_FIFO_SIZE_1024 | 0x8; 00725 if (mpu_hal_write(st.hw->addr, st.reg->accel_cfg2, 1, data)) 00726 return -1; 00727 #endif 00728 00729 /* Set to invalid values to ensure no I2C writes are skipped. */ 00730 st.chip_cfg.sensors = 0xFF; 00731 st.chip_cfg.gyro_fsr = 0xFF; 00732 st.chip_cfg.accel_fsr = 0xFF; 00733 st.chip_cfg.lpf = 0xFF; 00734 st.chip_cfg.sample_rate = 0xFFFF; 00735 st.chip_cfg.fifo_enable = 0xFF; 00736 st.chip_cfg.bypass_mode = 0xFF; 00737 #ifdef AK89xx_SECONDARY 00738 st.chip_cfg.compass_sample_rate = 0xFFFF; 00739 #endif 00740 /* mpu_set_sensors always preserves this setting. */ 00741 st.chip_cfg.clk_src = INV_CLK_PLL; 00742 /* Handled in next call to mpu_set_bypass. */ 00743 st.chip_cfg.active_low_int = 1; 00744 st.chip_cfg.latched_int = 0; 00745 st.chip_cfg.int_motion_only = 0; 00746 st.chip_cfg.lp_accel_mode = 0; 00747 memset(&st.chip_cfg.cache, 0, sizeof(st.chip_cfg.cache)); 00748 st.chip_cfg.dmp_on = 0; 00749 st.chip_cfg.dmp_loaded = 0; 00750 st.chip_cfg.dmp_sample_rate = 0; 00751 00752 if (mpu_set_gyro_fsr(2000)) 00753 return -1; 00754 if (mpu_set_accel_fsr(2)) 00755 return -1; 00756 if (mpu_set_lpf(42)) 00757 return -1; 00758 if (mpu_set_sample_rate(50)) 00759 return -1; 00760 if (mpu_configure_fifo(0)) 00761 return -1; 00762 00763 if (int_param) 00764 reg_int_cb(int_param); 00765 00766 #ifdef AK89xx_SECONDARY 00767 setup_compass(); 00768 if (mpu_set_compass_sample_rate(10)) 00769 return -1; 00770 #else 00771 /* Already disabled by setup_compass. */ 00772 if (mpu_set_bypass(0)) 00773 return -1; 00774 #endif 00775 00776 mpu_set_sensors(0); 00777 return 0; 00778 } 00779 00780 /** 00781 * @brief Enter low-power accel-only mode. 00782 * In low-power accel mode, the chip goes to sleep and only wakes up to sample 00783 * the accelerometer at one of the following frequencies: 00784 * \n MPU6050: 1.25Hz, 5Hz, 20Hz, 40Hz 00785 * \n MPU6500: 1.25Hz, 2.5Hz, 5Hz, 10Hz, 20Hz, 40Hz, 80Hz, 160Hz, 320Hz, 640Hz 00786 * \n If the requested rate is not one listed above, the device will be set to 00787 * the next highest rate. Requesting a rate above the maximum supported 00788 * frequency will result in an error. 00789 * \n To select a fractional wake-up frequency, round down the value passed to 00790 * @e rate. 00791 * @param[in] rate Minimum sampling rate, or zero to disable LP 00792 * accel mode. 00793 * @return 0 if successful. 00794 */ 00795 int mpu_lp_accel_mode(unsigned char rate) 00796 { 00797 unsigned char tmp[2]; 00798 00799 if (rate > 40) 00800 return -1; 00801 00802 if (!rate) { 00803 mpu_set_int_latched(0); 00804 tmp[0] = 0; 00805 tmp[1] = BIT_STBY_XYZG; 00806 if (mpu_hal_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, tmp)) 00807 return -1; 00808 st.chip_cfg.lp_accel_mode = 0; 00809 return 0; 00810 } 00811 /* For LP accel, we automatically configure the hardware to produce latched 00812 * interrupts. In LP accel mode, the hardware cycles into sleep mode before 00813 * it gets a chance to deassert the interrupt pin; therefore, we shift this 00814 * responsibility over to the MCU. 00815 * 00816 * Any register read will clear the interrupt. 00817 */ 00818 mpu_set_int_latched(1); 00819 #if defined MPU6050 00820 tmp[0] = BIT_LPA_CYCLE; 00821 if (rate == 1) { 00822 tmp[1] = INV_LPA_1_25HZ; 00823 mpu_set_lpf(5); 00824 } else if (rate <= 5) { 00825 tmp[1] = INV_LPA_5HZ; 00826 mpu_set_lpf(5); 00827 } else if (rate <= 20) { 00828 tmp[1] = INV_LPA_20HZ; 00829 mpu_set_lpf(10); 00830 } else { 00831 tmp[1] = INV_LPA_40HZ; 00832 mpu_set_lpf(20); 00833 } 00834 tmp[1] = (tmp[1] << 6) | BIT_STBY_XYZG; 00835 if (mpu_hal_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, tmp)) 00836 return -1; 00837 #elif defined MPU6500 00838 /* Set wake frequency. */ 00839 if (rate == 1) 00840 tmp[0] = INV_LPA_1_25HZ; 00841 else if (rate == 2) 00842 tmp[0] = INV_LPA_2_5HZ; 00843 else if (rate <= 5) 00844 tmp[0] = INV_LPA_5HZ; 00845 else if (rate <= 10) 00846 tmp[0] = INV_LPA_10HZ; 00847 else if (rate <= 20) 00848 tmp[0] = INV_LPA_20HZ; 00849 else if (rate <= 40) 00850 tmp[0] = INV_LPA_40HZ; 00851 else if (rate <= 80) 00852 tmp[0] = INV_LPA_80HZ; 00853 else if (rate <= 160) 00854 tmp[0] = INV_LPA_160HZ; 00855 else if (rate <= 320) 00856 tmp[0] = INV_LPA_320HZ; 00857 else 00858 tmp[0] = INV_LPA_640HZ; 00859 if (mpu_hal_write(st.hw->addr, st.reg->lp_accel_odr, 1, tmp)) 00860 return -1; 00861 tmp[0] = BIT_LPA_CYCLE; 00862 if (mpu_hal_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, tmp)) 00863 return -1; 00864 #endif 00865 st.chip_cfg.sensors = INV_XYZ_ACCEL; 00866 st.chip_cfg.clk_src = 0; 00867 st.chip_cfg.lp_accel_mode = 1; 00868 mpu_configure_fifo(0); 00869 00870 return 0; 00871 } 00872 00873 /** 00874 * @brief Read raw gyro data directly from the registers. 00875 * @param[out] data Raw data in hardware units. 00876 * @param[out] timestamp Timestamp in milliseconds. Null if not needed. 00877 * @return 0 if successful. 00878 */ 00879 int mpu_get_gyro_reg(short *data, unsigned long *timestamp) 00880 { 00881 unsigned char tmp[6]; 00882 00883 if (!(st.chip_cfg.sensors & INV_XYZ_GYRO)) 00884 return -1; 00885 00886 if (mpu_hal_read(st.hw->addr, st.reg->raw_gyro, 6, tmp)) 00887 return -1; 00888 data[0] = (tmp[0] << 8) | tmp[1]; 00889 data[1] = (tmp[2] << 8) | tmp[3]; 00890 data[2] = (tmp[4] << 8) | tmp[5]; 00891 if (timestamp) 00892 get_ms(timestamp); 00893 return 0; 00894 } 00895 00896 /** 00897 * @brief Read raw accel data directly from the registers. 00898 * @param[out] data Raw data in hardware units. 00899 * @param[out] timestamp Timestamp in milliseconds. Null if not needed. 00900 * @return 0 if successful. 00901 */ 00902 int mpu_get_accel_reg(short *data, unsigned long *timestamp) 00903 { 00904 unsigned char tmp[6]; 00905 00906 if (!(st.chip_cfg.sensors & INV_XYZ_ACCEL)) 00907 return -1; 00908 00909 if (mpu_hal_read(st.hw->addr, st.reg->raw_accel, 6, tmp)) 00910 return -1; 00911 data[0] = (tmp[0] << 8) | tmp[1]; 00912 data[1] = (tmp[2] << 8) | tmp[3]; 00913 data[2] = (tmp[4] << 8) | tmp[5]; 00914 if (timestamp) 00915 get_ms(timestamp); 00916 return 0; 00917 } 00918 00919 /** 00920 * @brief Read temperature data directly from the registers. 00921 * @param[out] data Data in q16 format. 00922 * @param[out] timestamp Timestamp in milliseconds. Null if not needed. 00923 * @return 0 if successful. 00924 */ 00925 int mpu_get_temperature(long *data, unsigned long *timestamp) 00926 { 00927 unsigned char tmp[2]; 00928 short raw; 00929 00930 if (!(st.chip_cfg.sensors)) 00931 return -1; 00932 00933 if (mpu_hal_read(st.hw->addr, st.reg->temp, 2, tmp)) 00934 return -1; 00935 raw = (tmp[0] << 8) | tmp[1]; 00936 if (timestamp) 00937 get_ms(timestamp); 00938 00939 data[0] = (long)((35 + ((raw - (float)st.hw->temp_offset) / st.hw->temp_sens)) * 65536L); 00940 return 0; 00941 } 00942 00943 /** 00944 * @brief Read biases to the accel bias 6500 registers. 00945 * This function reads from the MPU6500 accel offset cancellations registers. 00946 * The format are G in +-8G format. The register is initialized with OTP 00947 * factory trim values. 00948 * @param[in] accel_bias returned structure with the accel bias 00949 * @return 0 if successful. 00950 */ 00951 int mpu_read_6500_accel_bias(long *accel_bias) { 00952 unsigned char data[6]; 00953 if (mpu_hal_read(st.hw->addr, 0x77, 2, &data[0])) 00954 return -1; 00955 if (mpu_hal_read(st.hw->addr, 0x7A, 2, &data[2])) 00956 return -1; 00957 if (mpu_hal_read(st.hw->addr, 0x7D, 2, &data[4])) 00958 return -1; 00959 accel_bias[0] = ((long)data[0]<<8) | data[1]; 00960 accel_bias[1] = ((long)data[2]<<8) | data[3]; 00961 accel_bias[2] = ((long)data[4]<<8) | data[5]; 00962 return 0; 00963 } 00964 00965 /** 00966 * @brief Read biases to the accel bias 6050 registers. 00967 * This function reads from the MPU6050 accel offset cancellations registers. 00968 * The format are G in +-8G format. The register is initialized with OTP 00969 * factory trim values. 00970 * @param[in] accel_bias returned structure with the accel bias 00971 * @return 0 if successful. 00972 */ 00973 int mpu_read_6050_accel_bias(long *accel_bias) { 00974 unsigned char data[6]; 00975 if (mpu_hal_read(st.hw->addr, 0x06, 2, &data[0])) 00976 return -1; 00977 if (mpu_hal_read(st.hw->addr, 0x08, 2, &data[2])) 00978 return -1; 00979 if (mpu_hal_read(st.hw->addr, 0x0A, 2, &data[4])) 00980 return -1; 00981 accel_bias[0] = ((long)data[0]<<8) | data[1]; 00982 accel_bias[1] = ((long)data[2]<<8) | data[3]; 00983 accel_bias[2] = ((long)data[4]<<8) | data[5]; 00984 return 0; 00985 } 00986 00987 int mpu_read_6500_gyro_bias(long *gyro_bias) { 00988 unsigned char data[6]; 00989 if (mpu_hal_read(st.hw->addr, 0x13, 2, &data[0])) 00990 return -1; 00991 if (mpu_hal_read(st.hw->addr, 0x15, 2, &data[2])) 00992 return -1; 00993 if (mpu_hal_read(st.hw->addr, 0x17, 2, &data[4])) 00994 return -1; 00995 gyro_bias[0] = ((long)data[0]<<8) | data[1]; 00996 gyro_bias[1] = ((long)data[2]<<8) | data[3]; 00997 gyro_bias[2] = ((long)data[4]<<8) | data[5]; 00998 return 0; 00999 } 01000 01001 /** 01002 * @brief Push biases to the gyro bias 6500/6050 registers. 01003 * This function expects biases relative to the current sensor output, and 01004 * these biases will be added to the factory-supplied values. Bias inputs are LSB 01005 * in +-1000dps format. 01006 * @param[in] gyro_bias New biases. 01007 * @return 0 if successful. 01008 */ 01009 int mpu_set_gyro_bias_reg(long *gyro_bias) 01010 { 01011 unsigned char data[6] = {0, 0, 0, 0, 0, 0}; 01012 int i=0; 01013 for(i=0;i<3;i++) { 01014 gyro_bias[i]= (-gyro_bias[i]); 01015 } 01016 data[0] = (gyro_bias[0] >> 8) & 0xff; 01017 data[1] = (gyro_bias[0]) & 0xff; 01018 data[2] = (gyro_bias[1] >> 8) & 0xff; 01019 data[3] = (gyro_bias[1]) & 0xff; 01020 data[4] = (gyro_bias[2] >> 8) & 0xff; 01021 data[5] = (gyro_bias[2]) & 0xff; 01022 if (mpu_hal_write(st.hw->addr, 0x13, 2, &data[0])) 01023 return -1; 01024 if (mpu_hal_write(st.hw->addr, 0x15, 2, &data[2])) 01025 return -1; 01026 if (mpu_hal_write(st.hw->addr, 0x17, 2, &data[4])) 01027 return -1; 01028 return 0; 01029 } 01030 01031 /** 01032 * @brief Push biases to the accel bias 6050 registers. 01033 * This function expects biases relative to the current sensor output, and 01034 * these biases will be added to the factory-supplied values. Bias inputs are LSB 01035 * in +-8G format. 01036 * @param[in] accel_bias New biases. 01037 * @return 0 if successful. 01038 */ 01039 int mpu_set_accel_bias_6050_reg(const long *accel_bias) 01040 { 01041 unsigned char data[6] = {0, 0, 0, 0, 0, 0}; 01042 long accel_reg_bias[3] = {0, 0, 0}; 01043 long mask = 0x0001; 01044 unsigned char mask_bit[3] = {0, 0, 0}; 01045 unsigned char i = 0; 01046 if(mpu_read_6050_accel_bias(accel_reg_bias)) 01047 return -1; 01048 01049 //bit 0 of the 2 byte bias is for temp comp 01050 //calculations need to compensate for this and not change it 01051 for(i=0; i<3; i++) { 01052 if(accel_reg_bias[i]&mask) 01053 mask_bit[i] = 0x01; 01054 } 01055 01056 accel_reg_bias[0] -= accel_bias[0]; 01057 accel_reg_bias[1] -= accel_bias[1]; 01058 accel_reg_bias[2] -= accel_bias[2]; 01059 01060 data[0] = (accel_reg_bias[0] >> 8) & 0xff; 01061 data[1] = (accel_reg_bias[0]) & 0xff; 01062 data[1] = data[1]|mask_bit[0]; 01063 data[2] = (accel_reg_bias[1] >> 8) & 0xff; 01064 data[3] = (accel_reg_bias[1]) & 0xff; 01065 data[3] = data[3]|mask_bit[1]; 01066 data[4] = (accel_reg_bias[2] >> 8) & 0xff; 01067 data[5] = (accel_reg_bias[2]) & 0xff; 01068 data[5] = data[5]|mask_bit[2]; 01069 01070 if (mpu_hal_write(st.hw->addr, 0x06, 2, &data[0])) 01071 return -1; 01072 if (mpu_hal_write(st.hw->addr, 0x08, 2, &data[2])) 01073 return -1; 01074 if (mpu_hal_write(st.hw->addr, 0x0A, 2, &data[4])) 01075 return -1; 01076 01077 return 0; 01078 } 01079 01080 01081 /** 01082 * @brief Push biases to the accel bias 6500 registers. 01083 * This function expects biases relative to the current sensor output, and 01084 * these biases will be added to the factory-supplied values. Bias inputs are LSB 01085 * in +-8G format. 01086 * @param[in] accel_bias New biases. 01087 * @return 0 if successful. 01088 */ 01089 int mpu_set_accel_bias_6500_reg(const long *accel_bias) 01090 { 01091 unsigned char data[6] = {0, 0, 0, 0, 0, 0}; 01092 long accel_reg_bias[3] = {0, 0, 0}; 01093 long mask = 0x0001; 01094 unsigned char mask_bit[3] = {0, 0, 0}; 01095 unsigned char i = 0; 01096 01097 if(mpu_read_6500_accel_bias(accel_reg_bias)) 01098 return -1; 01099 01100 //bit 0 of the 2 byte bias is for temp comp 01101 //calculations need to compensate for this 01102 for(i=0; i<3; i++) { 01103 if(accel_reg_bias[i]&mask) 01104 mask_bit[i] = 0x01; 01105 } 01106 01107 accel_reg_bias[0] -= accel_bias[0]; 01108 accel_reg_bias[1] -= accel_bias[1]; 01109 accel_reg_bias[2] -= accel_bias[2]; 01110 01111 data[0] = (accel_reg_bias[0] >> 8) & 0xff; 01112 data[1] = (accel_reg_bias[0]) & 0xff; 01113 data[1] = data[1]|mask_bit[0]; 01114 data[2] = (accel_reg_bias[1] >> 8) & 0xff; 01115 data[3] = (accel_reg_bias[1]) & 0xff; 01116 data[3] = data[3]|mask_bit[1]; 01117 data[4] = (accel_reg_bias[2] >> 8) & 0xff; 01118 data[5] = (accel_reg_bias[2]) & 0xff; 01119 data[5] = data[5]|mask_bit[2]; 01120 01121 if (mpu_hal_write(st.hw->addr, 0x77, 2, &data[0])) 01122 return -1; 01123 if (mpu_hal_write(st.hw->addr, 0x7A, 2, &data[2])) 01124 return -1; 01125 if (mpu_hal_write(st.hw->addr, 0x7D, 2, &data[4])) 01126 return -1; 01127 01128 return 0; 01129 } 01130 01131 /** 01132 * @brief Reset FIFO read/write pointers. 01133 * @return 0 if successful. 01134 */ 01135 int mpu_reset_fifo(void) 01136 { 01137 unsigned char data; 01138 01139 if (!(st.chip_cfg.sensors)) 01140 return -1; 01141 01142 data = 0; 01143 if (mpu_hal_write(st.hw->addr, st.reg->int_enable, 1, &data)) 01144 return -1; 01145 if (mpu_hal_write(st.hw->addr, st.reg->fifo_en, 1, &data)) 01146 return -1; 01147 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) 01148 return -1; 01149 01150 if (st.chip_cfg.dmp_on) { 01151 data = BIT_FIFO_RST | BIT_DMP_RST; 01152 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) 01153 return -1; 01154 delay_ms(50); 01155 data = BIT_DMP_EN | BIT_FIFO_EN; 01156 if (st.chip_cfg.sensors & INV_XYZ_COMPASS) 01157 data |= BIT_AUX_IF_EN; 01158 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) 01159 return -1; 01160 if (st.chip_cfg.int_enable) 01161 data = BIT_DMP_INT_EN; 01162 else 01163 data = 0; 01164 if (mpu_hal_write(st.hw->addr, st.reg->int_enable, 1, &data)) 01165 return -1; 01166 data = 0; 01167 if (mpu_hal_write(st.hw->addr, st.reg->fifo_en, 1, &data)) 01168 return -1; 01169 } else { 01170 data = BIT_FIFO_RST; 01171 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) 01172 return -1; 01173 if (st.chip_cfg.bypass_mode || !(st.chip_cfg.sensors & INV_XYZ_COMPASS)) 01174 data = BIT_FIFO_EN; 01175 else 01176 data = BIT_FIFO_EN | BIT_AUX_IF_EN; 01177 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) 01178 return -1; 01179 delay_ms(50); 01180 if (st.chip_cfg.int_enable) 01181 data = BIT_DATA_RDY_EN; 01182 else 01183 data = 0; 01184 if (mpu_hal_write(st.hw->addr, st.reg->int_enable, 1, &data)) 01185 return -1; 01186 if (mpu_hal_write(st.hw->addr, st.reg->fifo_en, 1, &st.chip_cfg.fifo_enable)) 01187 return -1; 01188 } 01189 return 0; 01190 } 01191 01192 /** 01193 * @brief Get the gyro full-scale range. 01194 * @param[out] fsr Current full-scale range. 01195 * @return 0 if successful. 01196 */ 01197 int mpu_get_gyro_fsr(unsigned short *fsr) 01198 { 01199 switch (st.chip_cfg.gyro_fsr) { 01200 case INV_FSR_250DPS: 01201 fsr[0] = 250; 01202 break; 01203 case INV_FSR_500DPS: 01204 fsr[0] = 500; 01205 break; 01206 case INV_FSR_1000DPS: 01207 fsr[0] = 1000; 01208 break; 01209 case INV_FSR_2000DPS: 01210 fsr[0] = 2000; 01211 break; 01212 default: 01213 fsr[0] = 0; 01214 break; 01215 } 01216 return 0; 01217 } 01218 01219 /** 01220 * @brief Set the gyro full-scale range. 01221 * @param[in] fsr Desired full-scale range. 01222 * @return 0 if successful. 01223 */ 01224 int mpu_set_gyro_fsr(unsigned short fsr) 01225 { 01226 unsigned char data; 01227 01228 if (!(st.chip_cfg.sensors)) 01229 return -1; 01230 01231 switch (fsr) { 01232 case 250: 01233 data = INV_FSR_250DPS << 3; 01234 break; 01235 case 500: 01236 data = INV_FSR_500DPS << 3; 01237 break; 01238 case 1000: 01239 data = INV_FSR_1000DPS << 3; 01240 break; 01241 case 2000: 01242 data = INV_FSR_2000DPS << 3; 01243 break; 01244 default: 01245 return -1; 01246 } 01247 01248 if (st.chip_cfg.gyro_fsr == (data >> 3)) 01249 return 0; 01250 if (mpu_hal_write(st.hw->addr, st.reg->gyro_cfg, 1, &data)) 01251 return -1; 01252 st.chip_cfg.gyro_fsr = data >> 3; 01253 return 0; 01254 } 01255 01256 /** 01257 * @brief Get the accel full-scale range. 01258 * @param[out] fsr Current full-scale range. 01259 * @return 0 if successful. 01260 */ 01261 int mpu_get_accel_fsr(unsigned char *fsr) 01262 { 01263 switch (st.chip_cfg.accel_fsr) { 01264 case INV_FSR_2G: 01265 fsr[0] = 2; 01266 break; 01267 case INV_FSR_4G: 01268 fsr[0] = 4; 01269 break; 01270 case INV_FSR_8G: 01271 fsr[0] = 8; 01272 break; 01273 case INV_FSR_16G: 01274 fsr[0] = 16; 01275 break; 01276 default: 01277 return -1; 01278 } 01279 if (st.chip_cfg.accel_half) 01280 fsr[0] <<= 1; 01281 return 0; 01282 } 01283 01284 /** 01285 * @brief Set the accel full-scale range. 01286 * @param[in] fsr Desired full-scale range. 01287 * @return 0 if successful. 01288 */ 01289 int mpu_set_accel_fsr(unsigned char fsr) 01290 { 01291 unsigned char data; 01292 01293 if (!(st.chip_cfg.sensors)) 01294 return -1; 01295 01296 switch (fsr) { 01297 case 2: 01298 data = INV_FSR_2G << 3; 01299 break; 01300 case 4: 01301 data = INV_FSR_4G << 3; 01302 break; 01303 case 8: 01304 data = INV_FSR_8G << 3; 01305 break; 01306 case 16: 01307 data = INV_FSR_16G << 3; 01308 break; 01309 default: 01310 return -1; 01311 } 01312 01313 if (st.chip_cfg.accel_fsr == (data >> 3)) 01314 return 0; 01315 if (mpu_hal_write(st.hw->addr, st.reg->accel_cfg, 1, &data)) 01316 return -1; 01317 st.chip_cfg.accel_fsr = data >> 3; 01318 return 0; 01319 } 01320 01321 /** 01322 * @brief Get the current DLPF setting. 01323 * @param[out] lpf Current LPF setting. 01324 * 0 if successful. 01325 */ 01326 int mpu_get_lpf(unsigned short *lpf) 01327 { 01328 switch (st.chip_cfg.lpf) { 01329 case INV_FILTER_188HZ: 01330 lpf[0] = 188; 01331 break; 01332 case INV_FILTER_98HZ: 01333 lpf[0] = 98; 01334 break; 01335 case INV_FILTER_42HZ: 01336 lpf[0] = 42; 01337 break; 01338 case INV_FILTER_20HZ: 01339 lpf[0] = 20; 01340 break; 01341 case INV_FILTER_10HZ: 01342 lpf[0] = 10; 01343 break; 01344 case INV_FILTER_5HZ: 01345 lpf[0] = 5; 01346 break; 01347 case INV_FILTER_256HZ_NOLPF2: 01348 case INV_FILTER_2100HZ_NOLPF: 01349 default: 01350 lpf[0] = 0; 01351 break; 01352 } 01353 return 0; 01354 } 01355 01356 /** 01357 * @brief Set digital low pass filter. 01358 * The following LPF settings are supported: 188, 98, 42, 20, 10, 5. 01359 * @param[in] lpf Desired LPF setting. 01360 * @return 0 if successful. 01361 */ 01362 int mpu_set_lpf(unsigned short lpf) 01363 { 01364 unsigned char data; 01365 01366 if (!(st.chip_cfg.sensors)) 01367 return -1; 01368 01369 if (lpf >= 188) 01370 data = INV_FILTER_188HZ; 01371 else if (lpf >= 98) 01372 data = INV_FILTER_98HZ; 01373 else if (lpf >= 42) 01374 data = INV_FILTER_42HZ; 01375 else if (lpf >= 20) 01376 data = INV_FILTER_20HZ; 01377 else if (lpf >= 10) 01378 data = INV_FILTER_10HZ; 01379 else 01380 data = INV_FILTER_5HZ; 01381 01382 if (st.chip_cfg.lpf == data) 01383 return 0; 01384 if (mpu_hal_write(st.hw->addr, st.reg->lpf, 1, &data)) 01385 return -1; 01386 st.chip_cfg.lpf = data; 01387 return 0; 01388 } 01389 01390 /** 01391 * @brief Get sampling rate. 01392 * @param[out] rate Current sampling rate (Hz). 01393 * @return 0 if successful. 01394 */ 01395 int mpu_get_sample_rate(unsigned short *rate) 01396 { 01397 if (st.chip_cfg.dmp_on) 01398 return -1; 01399 else 01400 rate[0] = st.chip_cfg.sample_rate; 01401 return 0; 01402 } 01403 01404 /** 01405 * @brief Set sampling rate. 01406 * Sampling rate must be between 4Hz and 1kHz. 01407 * @param[in] rate Desired sampling rate (Hz). 01408 * @return 0 if successful. 01409 */ 01410 int mpu_set_sample_rate(unsigned short rate) 01411 { 01412 unsigned char data; 01413 01414 if (!(st.chip_cfg.sensors)) 01415 return -1; 01416 01417 if (st.chip_cfg.dmp_on) 01418 return -1; 01419 else { 01420 if (st.chip_cfg.lp_accel_mode) { 01421 if (rate && (rate <= 40)) { 01422 /* Just stay in low-power accel mode. */ 01423 mpu_lp_accel_mode(rate); 01424 return 0; 01425 } 01426 /* Requested rate exceeds the allowed frequencies in LP accel mode, 01427 * switch back to full-power mode. 01428 */ 01429 mpu_lp_accel_mode(0); 01430 } 01431 if (rate < 4) 01432 rate = 4; 01433 else if (rate > 1000) 01434 rate = 1000; 01435 01436 data = 1000 / rate - 1; 01437 if (mpu_hal_write(st.hw->addr, st.reg->rate_div, 1, &data)) 01438 return -1; 01439 01440 st.chip_cfg.sample_rate = 1000 / (1 + data); 01441 01442 #ifdef AK89xx_SECONDARY 01443 mpu_set_compass_sample_rate(min(st.chip_cfg.compass_sample_rate, MAX_COMPASS_SAMPLE_RATE)); 01444 #endif 01445 01446 /* Automatically set LPF to 1/2 sampling rate. */ 01447 mpu_set_lpf(st.chip_cfg.sample_rate >> 1); 01448 return 0; 01449 } 01450 } 01451 01452 /** 01453 * @brief Get compass sampling rate. 01454 * @param[out] rate Current compass sampling rate (Hz). 01455 * @return 0 if successful. 01456 */ 01457 int mpu_get_compass_sample_rate(unsigned short *rate) 01458 { 01459 #ifdef AK89xx_SECONDARY 01460 rate[0] = st.chip_cfg.compass_sample_rate; 01461 return 0; 01462 #else 01463 rate[0] = 0; 01464 return -1; 01465 #endif 01466 } 01467 01468 /** 01469 * @brief Set compass sampling rate. 01470 * The compass on the auxiliary I2C bus is read by the MPU hardware at a 01471 * maximum of 100Hz. The actual rate can be set to a fraction of the gyro 01472 * sampling rate. 01473 * 01474 * \n WARNING: The new rate may be different than what was requested. Call 01475 * mpu_get_compass_sample_rate to check the actual setting. 01476 * @param[in] rate Desired compass sampling rate (Hz). 01477 * @return 0 if successful. 01478 */ 01479 int mpu_set_compass_sample_rate(unsigned short rate) 01480 { 01481 #ifdef AK89xx_SECONDARY 01482 unsigned char div; 01483 if (!rate || rate > st.chip_cfg.sample_rate || rate > MAX_COMPASS_SAMPLE_RATE) 01484 return -1; 01485 01486 div = st.chip_cfg.sample_rate / rate - 1; 01487 if (mpu_hal_write(st.hw->addr, st.reg->s4_ctrl, 1, &div)) 01488 return -1; 01489 st.chip_cfg.compass_sample_rate = st.chip_cfg.sample_rate / (div + 1); 01490 return 0; 01491 #else 01492 return -1; 01493 #endif 01494 } 01495 01496 /** 01497 * @brief Get gyro sensitivity scale factor. 01498 * @param[out] sens Conversion from hardware units to dps. 01499 * @return 0 if successful. 01500 */ 01501 int mpu_get_gyro_sens(float *sens) 01502 { 01503 switch (st.chip_cfg.gyro_fsr) { 01504 case INV_FSR_250DPS: 01505 sens[0] = 131.f; 01506 break; 01507 case INV_FSR_500DPS: 01508 sens[0] = 65.5f; 01509 break; 01510 case INV_FSR_1000DPS: 01511 sens[0] = 32.8f; 01512 break; 01513 case INV_FSR_2000DPS: 01514 sens[0] = 16.4f; 01515 break; 01516 default: 01517 return -1; 01518 } 01519 return 0; 01520 } 01521 01522 /** 01523 * @brief Get accel sensitivity scale factor. 01524 * @param[out] sens Conversion from hardware units to g's. 01525 * @return 0 if successful. 01526 */ 01527 int mpu_get_accel_sens(unsigned short *sens) 01528 { 01529 switch (st.chip_cfg.accel_fsr) { 01530 case INV_FSR_2G: 01531 sens[0] = 16384; 01532 break; 01533 case INV_FSR_4G: 01534 sens[0] = 8092; 01535 break; 01536 case INV_FSR_8G: 01537 sens[0] = 4096; 01538 break; 01539 case INV_FSR_16G: 01540 sens[0] = 2048; 01541 break; 01542 default: 01543 return -1; 01544 } 01545 if (st.chip_cfg.accel_half) 01546 sens[0] >>= 1; 01547 return 0; 01548 } 01549 01550 /** 01551 * @brief Get current FIFO configuration. 01552 * @e sensors can contain a combination of the following flags: 01553 * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO 01554 * \n INV_XYZ_GYRO 01555 * \n INV_XYZ_ACCEL 01556 * @param[out] sensors Mask of sensors in FIFO. 01557 * @return 0 if successful. 01558 */ 01559 int mpu_get_fifo_config(unsigned char *sensors) 01560 { 01561 sensors[0] = st.chip_cfg.fifo_enable; 01562 return 0; 01563 } 01564 01565 /** 01566 * @brief Select which sensors are pushed to FIFO. 01567 * @e sensors can contain a combination of the following flags: 01568 * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO 01569 * \n INV_XYZ_GYRO 01570 * \n INV_XYZ_ACCEL 01571 * @param[in] sensors Mask of sensors to push to FIFO. 01572 * @return 0 if successful. 01573 */ 01574 int mpu_configure_fifo(unsigned char sensors) 01575 { 01576 unsigned char prev; 01577 int result = 0; 01578 01579 /* Compass data isn't going into the FIFO. Stop trying. */ 01580 sensors &= ~INV_XYZ_COMPASS; 01581 01582 if (st.chip_cfg.dmp_on) 01583 return 0; 01584 else { 01585 if (!(st.chip_cfg.sensors)) 01586 return -1; 01587 prev = st.chip_cfg.fifo_enable; 01588 st.chip_cfg.fifo_enable = sensors & st.chip_cfg.sensors; 01589 if (st.chip_cfg.fifo_enable != sensors) 01590 /* You're not getting what you asked for. Some sensors are 01591 * asleep. 01592 */ 01593 result = -1; 01594 else 01595 result = 0; 01596 if (sensors || st.chip_cfg.lp_accel_mode) 01597 set_int_enable(1); 01598 else 01599 set_int_enable(0); 01600 if (sensors) { 01601 if (mpu_reset_fifo()) { 01602 st.chip_cfg.fifo_enable = prev; 01603 return -1; 01604 } 01605 } 01606 } 01607 01608 return result; 01609 } 01610 01611 /** 01612 * @brief Get current power state. 01613 * @param[in] power_on 1 if turned on, 0 if suspended. 01614 * @return 0 if successful. 01615 */ 01616 int mpu_get_power_state(unsigned char *power_on) 01617 { 01618 if (st.chip_cfg.sensors) 01619 power_on[0] = 1; 01620 else 01621 power_on[0] = 0; 01622 return 0; 01623 } 01624 01625 /** 01626 * @brief Turn specific sensors on/off. 01627 * @e sensors can contain a combination of the following flags: 01628 * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO 01629 * \n INV_XYZ_GYRO 01630 * \n INV_XYZ_ACCEL 01631 * \n INV_XYZ_COMPASS 01632 * @param[in] sensors Mask of sensors to wake. 01633 * @return 0 if successful. 01634 */ 01635 int mpu_set_sensors(unsigned char sensors) 01636 { 01637 unsigned char data; 01638 #ifdef AK89xx_SECONDARY 01639 unsigned char user_ctrl; 01640 #endif 01641 01642 if (sensors & INV_XYZ_GYRO) 01643 data = INV_CLK_PLL; 01644 else if (sensors) 01645 data = 0; 01646 else 01647 data = BIT_SLEEP; 01648 if (mpu_hal_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, &data)) { 01649 st.chip_cfg.sensors = 0; 01650 return -1; 01651 } 01652 st.chip_cfg.clk_src = data & ~BIT_SLEEP; 01653 01654 data = 0; 01655 if (!(sensors & INV_X_GYRO)) 01656 data |= BIT_STBY_XG; 01657 if (!(sensors & INV_Y_GYRO)) 01658 data |= BIT_STBY_YG; 01659 if (!(sensors & INV_Z_GYRO)) 01660 data |= BIT_STBY_ZG; 01661 if (!(sensors & INV_XYZ_ACCEL)) 01662 data |= BIT_STBY_XYZA; 01663 if (mpu_hal_write(st.hw->addr, st.reg->pwr_mgmt_2, 1, &data)) { 01664 st.chip_cfg.sensors = 0; 01665 return -1; 01666 } 01667 01668 if (sensors && (sensors != INV_XYZ_ACCEL)) 01669 /* Latched interrupts only used in LP accel mode. */ 01670 mpu_set_int_latched(0); 01671 01672 #ifdef AK89xx_SECONDARY 01673 #ifdef AK89xx_BYPASS 01674 if (sensors & INV_XYZ_COMPASS) 01675 mpu_set_bypass(1); 01676 else 01677 mpu_set_bypass(0); 01678 #else 01679 if (mpu_hal_read(st.hw->addr, st.reg->user_ctrl, 1, &user_ctrl)) 01680 return -1; 01681 /* Handle AKM power management. */ 01682 if (sensors & INV_XYZ_COMPASS) { 01683 data = AKM_SINGLE_MEASUREMENT; 01684 user_ctrl |= BIT_AUX_IF_EN; 01685 } else { 01686 data = AKM_POWER_DOWN; 01687 user_ctrl &= ~BIT_AUX_IF_EN; 01688 } 01689 if (st.chip_cfg.dmp_on) 01690 user_ctrl |= BIT_DMP_EN; 01691 else 01692 user_ctrl &= ~BIT_DMP_EN; 01693 if (mpu_hal_write(st.hw->addr, st.reg->s1_do, 1, &data)) 01694 return -1; 01695 /* Enable/disable I2C master mode. */ 01696 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, &user_ctrl)) 01697 return -1; 01698 #endif 01699 #endif 01700 01701 st.chip_cfg.sensors = sensors; 01702 st.chip_cfg.lp_accel_mode = 0; 01703 delay_ms(50); 01704 return 0; 01705 } 01706 01707 /** 01708 * @brief Read the MPU interrupt status registers. 01709 * @param[out] status Mask of interrupt bits. 01710 * @return 0 if successful. 01711 */ 01712 int mpu_get_int_status(short *status) 01713 { 01714 unsigned char tmp[2]; 01715 if (!st.chip_cfg.sensors) 01716 return -1; 01717 if (mpu_hal_read(st.hw->addr, st.reg->dmp_int_status, 2, tmp)) 01718 return -1; 01719 status[0] = (tmp[0] << 8) | tmp[1]; 01720 return 0; 01721 } 01722 01723 /** 01724 * @brief Get one packet from the FIFO. 01725 * If @e sensors does not contain a particular sensor, disregard the data 01726 * returned to that pointer. 01727 * \n @e sensors can contain a combination of the following flags: 01728 * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO 01729 * \n INV_XYZ_GYRO 01730 * \n INV_XYZ_ACCEL 01731 * \n If the FIFO has no new data, @e sensors will be zero. 01732 * \n If the FIFO is disabled, @e sensors will be zero and this function will 01733 * return a non-zero error code. 01734 * @param[out] gyro Gyro data in hardware units. 01735 * @param[out] accel Accel data in hardware units. 01736 * @param[out] timestamp Timestamp in milliseconds. 01737 * @param[out] sensors Mask of sensors read from FIFO. 01738 * @param[out] more Number of remaining packets. 01739 * @return 0 if successful. 01740 */ 01741 int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp, 01742 unsigned char *sensors, unsigned char *more) 01743 { 01744 /* Assumes maximum packet size is gyro (6) + accel (6). */ 01745 unsigned char data[MAX_PACKET_LENGTH]; 01746 unsigned char packet_size = 0; 01747 unsigned short fifo_count, index = 0; 01748 01749 if (st.chip_cfg.dmp_on) 01750 return -1; 01751 01752 sensors[0] = 0; 01753 if (!st.chip_cfg.sensors) 01754 return -1; 01755 if (!st.chip_cfg.fifo_enable) 01756 return -1; 01757 01758 if (st.chip_cfg.fifo_enable & INV_X_GYRO) 01759 packet_size += 2; 01760 if (st.chip_cfg.fifo_enable & INV_Y_GYRO) 01761 packet_size += 2; 01762 if (st.chip_cfg.fifo_enable & INV_Z_GYRO) 01763 packet_size += 2; 01764 if (st.chip_cfg.fifo_enable & INV_XYZ_ACCEL) 01765 packet_size += 6; 01766 01767 if (mpu_hal_read(st.hw->addr, st.reg->fifo_count_h, 2, data)) 01768 return -1; 01769 fifo_count = (data[0] << 8) | data[1]; 01770 if (fifo_count < packet_size) 01771 return 0; 01772 // log_i("FIFO count: %hd\n", fifo_count); 01773 if (fifo_count > (st.hw->max_fifo >> 1)) { 01774 /* FIFO is 50% full, better check overflow bit. */ 01775 if (mpu_hal_read(st.hw->addr, st.reg->int_status, 1, data)) 01776 return -1; 01777 if (data[0] & BIT_FIFO_OVERFLOW) { 01778 mpu_reset_fifo(); 01779 return -2; 01780 } 01781 } 01782 get_ms((unsigned long*)timestamp); 01783 01784 if (mpu_hal_read(st.hw->addr, st.reg->fifo_r_w, packet_size, data)) 01785 return -1; 01786 more[0] = fifo_count / packet_size - 1; 01787 sensors[0] = 0; 01788 01789 if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_XYZ_ACCEL) { 01790 accel[0] = (data[index+0] << 8) | data[index+1]; 01791 accel[1] = (data[index+2] << 8) | data[index+3]; 01792 accel[2] = (data[index+4] << 8) | data[index+5]; 01793 sensors[0] |= INV_XYZ_ACCEL; 01794 index += 6; 01795 } 01796 if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_X_GYRO) { 01797 gyro[0] = (data[index+0] << 8) | data[index+1]; 01798 sensors[0] |= INV_X_GYRO; 01799 index += 2; 01800 } 01801 if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_Y_GYRO) { 01802 gyro[1] = (data[index+0] << 8) | data[index+1]; 01803 sensors[0] |= INV_Y_GYRO; 01804 index += 2; 01805 } 01806 if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_Z_GYRO) { 01807 gyro[2] = (data[index+0] << 8) | data[index+1]; 01808 sensors[0] |= INV_Z_GYRO; 01809 index += 2; 01810 } 01811 01812 return 0; 01813 } 01814 01815 /** 01816 * @brief Get one unparsed packet from the FIFO. 01817 * This function should be used if the packet is to be parsed elsewhere. 01818 * @param[in] length Length of one FIFO packet. 01819 * @param[in] data FIFO packet. 01820 * @param[in] more Number of remaining packets. 01821 */ 01822 int mpu_read_fifo_stream(unsigned short length, unsigned char *data, 01823 unsigned char *more) 01824 { 01825 unsigned char tmp[2]; 01826 unsigned short fifo_count; 01827 if (!st.chip_cfg.dmp_on) 01828 return -1; 01829 if (!st.chip_cfg.sensors) 01830 return -1; 01831 01832 if (mpu_hal_read(st.hw->addr, st.reg->fifo_count_h, 2, tmp)) 01833 return -1; 01834 fifo_count = (tmp[0] << 8) | tmp[1]; 01835 if (fifo_count < length) { 01836 more[0] = 0; 01837 return -1; 01838 } 01839 if (fifo_count > (st.hw->max_fifo >> 1)) { 01840 /* FIFO is 50% full, better check overflow bit. */ 01841 if (mpu_hal_read(st.hw->addr, st.reg->int_status, 1, tmp)) 01842 return -1; 01843 if (tmp[0] & BIT_FIFO_OVERFLOW) { 01844 mpu_reset_fifo(); 01845 return -2; 01846 } 01847 } 01848 01849 if (mpu_hal_read(st.hw->addr, st.reg->fifo_r_w, length, data)) 01850 return -1; 01851 more[0] = fifo_count / length - 1; 01852 return 0; 01853 } 01854 01855 /** 01856 * @brief Set device to bypass mode. 01857 * @param[in] bypass_on 1 to enable bypass mode. 01858 * @return 0 if successful. 01859 */ 01860 int mpu_set_bypass(unsigned char bypass_on) 01861 { 01862 unsigned char tmp; 01863 01864 if (st.chip_cfg.bypass_mode == bypass_on) 01865 return 0; 01866 01867 if (bypass_on) { 01868 if (mpu_hal_read(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) 01869 return -1; 01870 tmp &= ~BIT_AUX_IF_EN; 01871 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) 01872 return -1; 01873 delay_ms(3); 01874 tmp = BIT_BYPASS_EN; 01875 if (st.chip_cfg.active_low_int) 01876 tmp |= BIT_ACTL; 01877 if (st.chip_cfg.latched_int) 01878 tmp |= BIT_LATCH_EN | BIT_ANY_RD_CLR; 01879 if (mpu_hal_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) 01880 return -1; 01881 } else { 01882 /* Enable I2C master mode if compass is being used. */ 01883 if (mpu_hal_read(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) 01884 return -1; 01885 if (st.chip_cfg.sensors & INV_XYZ_COMPASS) 01886 tmp |= BIT_AUX_IF_EN; 01887 else 01888 tmp &= ~BIT_AUX_IF_EN; 01889 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) 01890 return -1; 01891 delay_ms(3); 01892 if (st.chip_cfg.active_low_int) 01893 tmp = BIT_ACTL; 01894 else 01895 tmp = 0; 01896 if (st.chip_cfg.latched_int) 01897 tmp |= BIT_LATCH_EN | BIT_ANY_RD_CLR; 01898 if (mpu_hal_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) 01899 return -1; 01900 } 01901 st.chip_cfg.bypass_mode = bypass_on; 01902 return 0; 01903 } 01904 01905 /** 01906 * @brief Set interrupt level. 01907 * @param[in] active_low 1 for active low, 0 for active high. 01908 * @return 0 if successful. 01909 */ 01910 int mpu_set_int_level(unsigned char active_low) 01911 { 01912 st.chip_cfg.active_low_int = active_low; 01913 return 0; 01914 } 01915 01916 /** 01917 * @brief Enable latched interrupts. 01918 * Any MPU register will clear the interrupt. 01919 * @param[in] enable 1 to enable, 0 to disable. 01920 * @return 0 if successful. 01921 */ 01922 int mpu_set_int_latched(unsigned char enable) 01923 { 01924 unsigned char tmp; 01925 if (st.chip_cfg.latched_int == enable) 01926 return 0; 01927 01928 if (enable) 01929 tmp = BIT_LATCH_EN | BIT_ANY_RD_CLR; 01930 else 01931 tmp = 0; 01932 if (st.chip_cfg.bypass_mode) 01933 tmp |= BIT_BYPASS_EN; 01934 if (st.chip_cfg.active_low_int) 01935 tmp |= BIT_ACTL; 01936 if (mpu_hal_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) 01937 return -1; 01938 st.chip_cfg.latched_int = enable; 01939 return 0; 01940 } 01941 01942 #ifdef MPU6050 01943 static int get_accel_prod_shift(float *st_shift) 01944 { 01945 unsigned char tmp[4], shift_code[3], ii; 01946 01947 if (mpu_hal_read(st.hw->addr, 0x0D, 4, tmp)) 01948 return 0x07; 01949 01950 shift_code[0] = ((tmp[0] & 0xE0) >> 3) | ((tmp[3] & 0x30) >> 4); 01951 shift_code[1] = ((tmp[1] & 0xE0) >> 3) | ((tmp[3] & 0x0C) >> 2); 01952 shift_code[2] = ((tmp[2] & 0xE0) >> 3) | (tmp[3] & 0x03); 01953 for (ii = 0; ii < 3; ii++) { 01954 if (!shift_code[ii]) { 01955 st_shift[ii] = 0.f; 01956 continue; 01957 } 01958 /* Equivalent to.. 01959 * st_shift[ii] = 0.34f * powf(0.92f/0.34f, (shift_code[ii]-1) / 30.f) 01960 */ 01961 st_shift[ii] = 0.34f; 01962 while (--shift_code[ii]) 01963 st_shift[ii] *= 1.034f; 01964 } 01965 return 0; 01966 } 01967 01968 static int accel_self_test(long *bias_regular, long *bias_st) 01969 { 01970 int jj, result = 0; 01971 float st_shift[3], st_shift_cust, st_shift_var; 01972 01973 get_accel_prod_shift(st_shift); 01974 for(jj = 0; jj < 3; jj++) { 01975 st_shift_cust = labs(bias_regular[jj] - bias_st[jj]) / 65536.f; 01976 if (st_shift[jj]) { 01977 st_shift_var = st_shift_cust / st_shift[jj] - 1.f; 01978 if (fabs(st_shift_var) > test.max_accel_var) 01979 result |= 1 << jj; 01980 } else if ((st_shift_cust < test.min_g) || 01981 (st_shift_cust > test.max_g)) 01982 result |= 1 << jj; 01983 } 01984 01985 return result; 01986 } 01987 01988 static int gyro_self_test(long *bias_regular, long *bias_st) 01989 { 01990 int jj, result = 0; 01991 unsigned char tmp[3]; 01992 float st_shift, st_shift_cust, st_shift_var; 01993 01994 if (mpu_hal_read(st.hw->addr, 0x0D, 3, tmp)) 01995 return 0x07; 01996 01997 tmp[0] &= 0x1F; 01998 tmp[1] &= 0x1F; 01999 tmp[2] &= 0x1F; 02000 02001 for (jj = 0; jj < 3; jj++) { 02002 st_shift_cust = labs(bias_regular[jj] - bias_st[jj]) / 65536.f; 02003 if (tmp[jj]) { 02004 st_shift = 3275.f / test.gyro_sens; 02005 while (--tmp[jj]) 02006 st_shift *= 1.046f; 02007 st_shift_var = st_shift_cust / st_shift - 1.f; 02008 if (fabs(st_shift_var) > test.max_gyro_var) 02009 result |= 1 << jj; 02010 } else if ((st_shift_cust < test.min_dps) || 02011 (st_shift_cust > test.max_dps)) 02012 result |= 1 << jj; 02013 } 02014 return result; 02015 } 02016 02017 #endif 02018 #ifdef AK89xx_SECONDARY 02019 static int compass_self_test(void) 02020 { 02021 int result = 0x07; 02022 02023 #ifndef MPU_USE_SPI 02024 unsigned char tmp[6]; 02025 unsigned char tries = 10; 02026 short data; 02027 02028 mpu_set_bypass(1); 02029 02030 tmp[0] = AKM_POWER_DOWN; 02031 if (mpu_hal_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp)) 02032 return 0x07; 02033 tmp[0] = AKM_BIT_SELF_TEST; 02034 if (mpu_hal_write(st.chip_cfg.compass_addr, AKM_REG_ASTC, 1, tmp)) 02035 goto AKM_restore; 02036 tmp[0] = AKM_MODE_SELF_TEST; 02037 if (mpu_hal_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp)) 02038 goto AKM_restore; 02039 02040 do { 02041 delay_ms(10); 02042 if (mpu_hal_read(st.chip_cfg.compass_addr, AKM_REG_ST1, 1, tmp)) 02043 goto AKM_restore; 02044 if (tmp[0] & AKM_DATA_READY) 02045 break; 02046 } while (tries--); 02047 if (!(tmp[0] & AKM_DATA_READY)) 02048 goto AKM_restore; 02049 02050 if (mpu_hal_read(st.chip_cfg.compass_addr, AKM_REG_HXL, 6, tmp)) 02051 goto AKM_restore; 02052 02053 result = 0; 02054 #if defined MPU9150 02055 data = (short)(tmp[1] << 8) | tmp[0]; 02056 if ((data > 100) || (data < -100)) 02057 result |= 0x01; 02058 data = (short)(tmp[3] << 8) | tmp[2]; 02059 if ((data > 100) || (data < -100)) 02060 result |= 0x02; 02061 data = (short)(tmp[5] << 8) | tmp[4]; 02062 if ((data > -300) || (data < -1000)) 02063 result |= 0x04; 02064 #elif defined MPU9250 02065 data = (short)(tmp[1] << 8) | tmp[0]; 02066 if ((data > 200) || (data < -200)) 02067 result |= 0x01; 02068 data = (short)(tmp[3] << 8) | tmp[2]; 02069 if ((data > 200) || (data < -200)) 02070 result |= 0x02; 02071 data = (short)(tmp[5] << 8) | tmp[4]; 02072 if ((data > -800) || (data < -3200)) 02073 result |= 0x04; 02074 #endif 02075 AKM_restore: 02076 tmp[0] = 0 | SUPPORTS_AK89xx_HIGH_SENS; 02077 mpu_hal_write(st.chip_cfg.compass_addr, AKM_REG_ASTC, 1, tmp); 02078 tmp[0] = SUPPORTS_AK89xx_HIGH_SENS; 02079 mpu_hal_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp); 02080 mpu_set_bypass(0); 02081 #else 02082 // to do - compass self test through spi interface 02083 #endif 02084 02085 return result; 02086 } 02087 #endif 02088 02089 static int get_st_biases(long *gyro, long *accel, unsigned char hw_test) 02090 { 02091 unsigned char data[MAX_PACKET_LENGTH]; 02092 unsigned char packet_count, ii; 02093 unsigned short fifo_count; 02094 02095 data[0] = 0x01; 02096 data[1] = 0; 02097 if (mpu_hal_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, data)) 02098 return -1; 02099 delay_ms(200); 02100 data[0] = 0; 02101 if (mpu_hal_write(st.hw->addr, st.reg->int_enable, 1, data)) 02102 return -1; 02103 if (mpu_hal_write(st.hw->addr, st.reg->fifo_en, 1, data)) 02104 return -1; 02105 if (mpu_hal_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) 02106 return -1; 02107 if (mpu_hal_write(st.hw->addr, st.reg->i2c_mst, 1, data)) 02108 return -1; 02109 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, data)) 02110 return -1; 02111 data[0] = BIT_FIFO_RST | BIT_DMP_RST; 02112 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, data)) 02113 return -1; 02114 delay_ms(15); 02115 data[0] = st.test->reg_lpf; 02116 if (mpu_hal_write(st.hw->addr, st.reg->lpf, 1, data)) 02117 return -1; 02118 data[0] = st.test->reg_rate_div; 02119 if (mpu_hal_write(st.hw->addr, st.reg->rate_div, 1, data)) 02120 return -1; 02121 if (hw_test) 02122 data[0] = st.test->reg_gyro_fsr | 0xE0; 02123 else 02124 data[0] = st.test->reg_gyro_fsr; 02125 if (mpu_hal_write(st.hw->addr, st.reg->gyro_cfg, 1, data)) 02126 return -1; 02127 02128 if (hw_test) 02129 data[0] = st.test->reg_accel_fsr | 0xE0; 02130 else 02131 data[0] = test.reg_accel_fsr; 02132 if (mpu_hal_write(st.hw->addr, st.reg->accel_cfg, 1, data)) 02133 return -1; 02134 if (hw_test) 02135 delay_ms(200); 02136 02137 /* Fill FIFO for test.wait_ms milliseconds. */ 02138 data[0] = BIT_FIFO_EN; 02139 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, data)) 02140 return -1; 02141 02142 data[0] = INV_XYZ_GYRO | INV_XYZ_ACCEL; 02143 if (mpu_hal_write(st.hw->addr, st.reg->fifo_en, 1, data)) 02144 return -1; 02145 delay_ms(test.wait_ms); 02146 data[0] = 0; 02147 if (mpu_hal_write(st.hw->addr, st.reg->fifo_en, 1, data)) 02148 return -1; 02149 02150 if (mpu_hal_read(st.hw->addr, st.reg->fifo_count_h, 2, data)) 02151 return -1; 02152 02153 fifo_count = (data[0] << 8) | data[1]; 02154 packet_count = fifo_count / MAX_PACKET_LENGTH; 02155 gyro[0] = gyro[1] = gyro[2] = 0; 02156 accel[0] = accel[1] = accel[2] = 0; 02157 02158 for (ii = 0; ii < packet_count; ii++) { 02159 short accel_cur[3], gyro_cur[3]; 02160 if (mpu_hal_read(st.hw->addr, st.reg->fifo_r_w, MAX_PACKET_LENGTH, data)) 02161 return -1; 02162 accel_cur[0] = ((short)data[0] << 8) | data[1]; 02163 accel_cur[1] = ((short)data[2] << 8) | data[3]; 02164 accel_cur[2] = ((short)data[4] << 8) | data[5]; 02165 accel[0] += (long)accel_cur[0]; 02166 accel[1] += (long)accel_cur[1]; 02167 accel[2] += (long)accel_cur[2]; 02168 gyro_cur[0] = (((short)data[6] << 8) | data[7]); 02169 gyro_cur[1] = (((short)data[8] << 8) | data[9]); 02170 gyro_cur[2] = (((short)data[10] << 8) | data[11]); 02171 gyro[0] += (long)gyro_cur[0]; 02172 gyro[1] += (long)gyro_cur[1]; 02173 gyro[2] += (long)gyro_cur[2]; 02174 } 02175 #ifdef EMPL_NO_64BIT 02176 gyro[0] = (long)(((float)gyro[0]*65536.f) / test.gyro_sens / packet_count); 02177 gyro[1] = (long)(((float)gyro[1]*65536.f) / test.gyro_sens / packet_count); 02178 gyro[2] = (long)(((float)gyro[2]*65536.f) / test.gyro_sens / packet_count); 02179 if (has_accel) { 02180 accel[0] = (long)(((float)accel[0]*65536.f) / test.accel_sens / 02181 packet_count); 02182 accel[1] = (long)(((float)accel[1]*65536.f) / test.accel_sens / 02183 packet_count); 02184 accel[2] = (long)(((float)accel[2]*65536.f) / test.accel_sens / 02185 packet_count); 02186 /* Don't remove gravity! */ 02187 accel[2] -= 65536L; 02188 } 02189 #else 02190 gyro[0] = (long)(((long long)gyro[0]<<16) / test.gyro_sens / packet_count); 02191 gyro[1] = (long)(((long long)gyro[1]<<16) / test.gyro_sens / packet_count); 02192 gyro[2] = (long)(((long long)gyro[2]<<16) / test.gyro_sens / packet_count); 02193 accel[0] = (long)(((long long)accel[0]<<16) / test.accel_sens / 02194 packet_count); 02195 accel[1] = (long)(((long long)accel[1]<<16) / test.accel_sens / 02196 packet_count); 02197 accel[2] = (long)(((long long)accel[2]<<16) / test.accel_sens / 02198 packet_count); 02199 /* Don't remove gravity! */ 02200 if (accel[2] > 0L) 02201 accel[2] -= 65536L; 02202 else 02203 accel[2] += 65536L; 02204 #endif 02205 02206 return 0; 02207 } 02208 02209 #ifdef MPU6500 02210 #define REG_6500_XG_ST_DATA 0x0 02211 #define REG_6500_XA_ST_DATA 0xD 02212 static const unsigned short mpu_6500_st_tb[256] = { 02213 2620,2646,2672,2699,2726,2753,2781,2808, //7 02214 2837,2865,2894,2923,2952,2981,3011,3041, //15 02215 3072,3102,3133,3165,3196,3228,3261,3293, //23 02216 3326,3359,3393,3427,3461,3496,3531,3566, //31 02217 3602,3638,3674,3711,3748,3786,3823,3862, //39 02218 3900,3939,3979,4019,4059,4099,4140,4182, //47 02219 4224,4266,4308,4352,4395,4439,4483,4528, //55 02220 4574,4619,4665,4712,4759,4807,4855,4903, //63 02221 4953,5002,5052,5103,5154,5205,5257,5310, //71 02222 5363,5417,5471,5525,5581,5636,5693,5750, //79 02223 5807,5865,5924,5983,6043,6104,6165,6226, //87 02224 6289,6351,6415,6479,6544,6609,6675,6742, //95 02225 6810,6878,6946,7016,7086,7157,7229,7301, //103 02226 7374,7448,7522,7597,7673,7750,7828,7906, //111 02227 7985,8065,8145,8227,8309,8392,8476,8561, //119 02228 8647,8733,8820,8909,8998,9088,9178,9270, 02229 9363,9457,9551,9647,9743,9841,9939,10038, 02230 10139,10240,10343,10446,10550,10656,10763,10870, 02231 10979,11089,11200,11312,11425,11539,11654,11771, 02232 11889,12008,12128,12249,12371,12495,12620,12746, 02233 12874,13002,13132,13264,13396,13530,13666,13802, 02234 13940,14080,14221,14363,14506,14652,14798,14946, 02235 15096,15247,15399,15553,15709,15866,16024,16184, 02236 16346,16510,16675,16842,17010,17180,17352,17526, 02237 17701,17878,18057,18237,18420,18604,18790,18978, 02238 19167,19359,19553,19748,19946,20145,20347,20550, 02239 20756,20963,21173,21385,21598,21814,22033,22253, 02240 22475,22700,22927,23156,23388,23622,23858,24097, 02241 24338,24581,24827,25075,25326,25579,25835,26093, 02242 26354,26618,26884,27153,27424,27699,27976,28255, 02243 28538,28823,29112,29403,29697,29994,30294,30597, 02244 30903,31212,31524,31839,32157,32479,32804,33132 02245 }; 02246 static int accel_6500_self_test(long *bias_regular, long *bias_st, int debug) 02247 { 02248 int i, result = 0, otp_value_zero = 0; 02249 float accel_st_al_min, accel_st_al_max; 02250 float st_shift_cust[3], st_shift_ratio[3], ct_shift_prod[3], accel_offset_max; 02251 unsigned char regs[3]; 02252 if (mpu_hal_read(st.hw->addr, REG_6500_XA_ST_DATA, 3, regs)) { 02253 if(debug) 02254 log_i("Reading OTP Register Error.\n"); 02255 return 0x07; 02256 } 02257 if(debug) 02258 log_i("Accel OTP:%d, %d, %d\n", regs[0], regs[1], regs[2]); 02259 for (i = 0; i < 3; i++) { 02260 if (regs[i] != 0) { 02261 ct_shift_prod[i] = mpu_6500_st_tb[regs[i] - 1]; 02262 ct_shift_prod[i] *= 65536.f; 02263 ct_shift_prod[i] /= test.accel_sens; 02264 } 02265 else { 02266 ct_shift_prod[i] = 0; 02267 otp_value_zero = 1; 02268 } 02269 } 02270 if(otp_value_zero == 0) { 02271 if(debug) 02272 log_i("ACCEL:CRITERIA A\n"); 02273 for (i = 0; i < 3; i++) { 02274 st_shift_cust[i] = bias_st[i] - bias_regular[i]; 02275 if(debug) { 02276 log_i("Bias_Shift=%7.4f, Bias_Reg=%7.4f, Bias_HWST=%7.4f\r\n", 02277 st_shift_cust[i]/1.f, bias_regular[i]/1.f, 02278 bias_st[i]/1.f); 02279 log_i("OTP value: %7.4f\r\n", ct_shift_prod[i]/1.f); 02280 } 02281 02282 st_shift_ratio[i] = st_shift_cust[i] / ct_shift_prod[i] - 1.f; 02283 02284 if(debug) 02285 log_i("ratio=%7.4f, threshold=%7.4f\r\n", st_shift_ratio[i]/1.f, 02286 test.max_accel_var/1.f); 02287 02288 if (fabs(st_shift_ratio[i]) > test.max_accel_var) { 02289 if(debug) 02290 log_i("ACCEL Fail Axis = %d\n", i); 02291 result |= 1 << i; //Error condition 02292 } 02293 } 02294 } 02295 else { 02296 /* Self Test Pass/Fail Criteria B */ 02297 accel_st_al_min = test.min_g * 65536.f; 02298 accel_st_al_max = test.max_g * 65536.f; 02299 02300 if(debug) { 02301 log_i("ACCEL:CRITERIA B\r\n"); 02302 log_i("Min MG: %7.4f\r\n", accel_st_al_min/1.f); 02303 log_i("Max MG: %7.4f\r\n", accel_st_al_max/1.f); 02304 } 02305 02306 for (i = 0; i < 3; i++) { 02307 st_shift_cust[i] = bias_st[i] - bias_regular[i]; 02308 02309 if(debug) 02310 log_i("Bias_shift=%7.4f, st=%7.4f, reg=%7.4f\n", st_shift_cust[i]/1.f, bias_st[i]/1.f, bias_regular[i]/1.f); 02311 if(st_shift_cust[i] < accel_st_al_min || st_shift_cust[i] > accel_st_al_max) { 02312 if(debug) 02313 log_i("Accel FAIL axis:%d <= 225mg or >= 675mg\n", i); 02314 result |= 1 << i; //Error condition 02315 } 02316 } 02317 } 02318 02319 if(result == 0) { 02320 /* Self Test Pass/Fail Criteria C */ 02321 accel_offset_max = test.max_g_offset * 65536.f; 02322 if(debug) 02323 log_i("Accel:CRITERIA C: bias less than %7.4f\n", accel_offset_max/1.f); 02324 for (i = 0; i < 3; i++) { 02325 if(fabs(bias_regular[i]) > accel_offset_max) { 02326 if(debug) 02327 log_i("FAILED: Accel axis:%d = %d > 500mg\n", i, bias_regular[i]); 02328 result |= 1 << i; //Error condition 02329 } 02330 } 02331 } 02332 02333 return result; 02334 } 02335 02336 static int gyro_6500_self_test(long *bias_regular, long *bias_st, int debug) 02337 { 02338 int i, result = 0, otp_value_zero = 0; 02339 float gyro_st_al_max; 02340 float st_shift_cust[3], st_shift_ratio[3], ct_shift_prod[3], gyro_offset_max; 02341 unsigned char regs[3]; 02342 02343 if (mpu_hal_read(st.hw->addr, REG_6500_XG_ST_DATA, 3, regs)) { 02344 if(debug) 02345 log_i("Reading OTP Register Error.\n"); 02346 return 0x07; 02347 } 02348 02349 if(debug) 02350 log_i("Gyro OTP:%d, %d, %d\r\n", regs[0], regs[1], regs[2]); 02351 02352 for (i = 0; i < 3; i++) { 02353 if (regs[i] != 0) { 02354 ct_shift_prod[i] = mpu_6500_st_tb[regs[i] - 1]; 02355 ct_shift_prod[i] *= 65536.f; 02356 ct_shift_prod[i] /= test.gyro_sens; 02357 } 02358 else { 02359 ct_shift_prod[i] = 0; 02360 otp_value_zero = 1; 02361 } 02362 } 02363 02364 if(otp_value_zero == 0) { 02365 if(debug) 02366 log_i("GYRO:CRITERIA A\n"); 02367 /* Self Test Pass/Fail Criteria A */ 02368 for (i = 0; i < 3; i++) { 02369 st_shift_cust[i] = bias_st[i] - bias_regular[i]; 02370 02371 if(debug) { 02372 log_i("Bias_Shift=%7.4f, Bias_Reg=%7.4f, Bias_HWST=%7.4f\r\n", 02373 st_shift_cust[i]/1.f, bias_regular[i]/1.f, 02374 bias_st[i]/1.f); 02375 log_i("OTP value: %7.4f\r\n", ct_shift_prod[i]/1.f); 02376 } 02377 02378 st_shift_ratio[i] = st_shift_cust[i] / ct_shift_prod[i]; 02379 02380 if(debug) 02381 log_i("ratio=%7.4f, threshold=%7.4f\r\n", st_shift_ratio[i]/1.f, 02382 test.max_gyro_var/1.f); 02383 02384 if (fabs(st_shift_ratio[i]) < test.max_gyro_var) { 02385 if(debug) 02386 log_i("Gyro Fail Axis = %d\n", i); 02387 result |= 1 << i; //Error condition 02388 } 02389 } 02390 } 02391 else { 02392 /* Self Test Pass/Fail Criteria B */ 02393 gyro_st_al_max = test.max_dps * 65536.f; 02394 02395 if(debug) { 02396 log_i("GYRO:CRITERIA B\r\n"); 02397 log_i("Max DPS: %7.4f\r\n", gyro_st_al_max/1.f); 02398 } 02399 02400 for (i = 0; i < 3; i++) { 02401 st_shift_cust[i] = bias_st[i] - bias_regular[i]; 02402 02403 if(debug) 02404 log_i("Bias_shift=%7.4f, st=%7.4f, reg=%7.4f\n", st_shift_cust[i]/1.f, bias_st[i]/1.f, bias_regular[i]/1.f); 02405 if(st_shift_cust[i] < gyro_st_al_max) { 02406 if(debug) 02407 log_i("GYRO FAIL axis:%d greater than 60dps\n", i); 02408 result |= 1 << i; //Error condition 02409 } 02410 } 02411 } 02412 02413 if(result == 0) { 02414 /* Self Test Pass/Fail Criteria C */ 02415 gyro_offset_max = test.min_dps * 65536.f; 02416 if(debug) 02417 log_i("Gyro:CRITERIA C: bias less than %7.4f\n", gyro_offset_max/1.f); 02418 for (i = 0; i < 3; i++) { 02419 if(fabs(bias_regular[i]) > gyro_offset_max) { 02420 if(debug) 02421 log_i("FAILED: Gyro axis:%d = %d > 20dps\n", i, bias_regular[i]); 02422 result |= 1 << i; //Error condition 02423 } 02424 } 02425 } 02426 return result; 02427 } 02428 02429 static int get_st_6500_biases(long *gyro, long *accel, unsigned char hw_test, int debug) 02430 { 02431 unsigned char data[HWST_MAX_PACKET_LENGTH]; 02432 unsigned char packet_count, ii; 02433 unsigned short fifo_count; 02434 int s = 0, read_size = 0, ind; 02435 02436 data[0] = 0x01; 02437 data[1] = 0; 02438 if (mpu_hal_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, data)) 02439 return -1; 02440 delay_ms(200); 02441 data[0] = 0; 02442 if (mpu_hal_write(st.hw->addr, st.reg->int_enable, 1, data)) 02443 return -1; 02444 if (mpu_hal_write(st.hw->addr, st.reg->fifo_en, 1, data)) 02445 return -1; 02446 if (mpu_hal_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) 02447 return -1; 02448 if (mpu_hal_write(st.hw->addr, st.reg->i2c_mst, 1, data)) 02449 return -1; 02450 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, data)) 02451 return -1; 02452 data[0] = BIT_FIFO_RST | BIT_DMP_RST; 02453 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, data)) 02454 return -1; 02455 delay_ms(15); 02456 data[0] = st.test->reg_lpf; 02457 if (mpu_hal_write(st.hw->addr, st.reg->lpf, 1, data)) 02458 return -1; 02459 data[0] = st.test->reg_rate_div; 02460 if (mpu_hal_write(st.hw->addr, st.reg->rate_div, 1, data)) 02461 return -1; 02462 if (hw_test) 02463 data[0] = st.test->reg_gyro_fsr | 0xE0; 02464 else 02465 data[0] = st.test->reg_gyro_fsr; 02466 if (mpu_hal_write(st.hw->addr, st.reg->gyro_cfg, 1, data)) 02467 return -1; 02468 02469 if (hw_test) 02470 data[0] = st.test->reg_accel_fsr | 0xE0; 02471 else 02472 data[0] = test.reg_accel_fsr; 02473 if (mpu_hal_write(st.hw->addr, st.reg->accel_cfg, 1, data)) 02474 return -1; 02475 02476 delay_ms(test.wait_ms); //wait 200ms for sensors to stabilize 02477 02478 /* Enable FIFO */ 02479 data[0] = BIT_FIFO_EN; 02480 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 1, data)) 02481 return -1; 02482 data[0] = INV_XYZ_GYRO | INV_XYZ_ACCEL; 02483 if (mpu_hal_write(st.hw->addr, st.reg->fifo_en, 1, data)) 02484 return -1; 02485 02486 //initialize the bias return values 02487 gyro[0] = gyro[1] = gyro[2] = 0; 02488 accel[0] = accel[1] = accel[2] = 0; 02489 02490 if(debug) 02491 log_i("Starting Bias Loop Reads\n"); 02492 02493 //start reading samples 02494 while (s < test.packet_thresh) { 02495 delay_ms(test.sample_wait_ms); //wait 10ms to fill FIFO 02496 if (mpu_hal_read(st.hw->addr, st.reg->fifo_count_h, 2, data)) 02497 return -1; 02498 fifo_count = (data[0] << 8) | data[1]; 02499 packet_count = fifo_count / MAX_PACKET_LENGTH; 02500 if ((test.packet_thresh - s) < packet_count) 02501 packet_count = test.packet_thresh - s; 02502 read_size = packet_count * MAX_PACKET_LENGTH; 02503 02504 //burst read from FIFO 02505 if (mpu_hal_read(st.hw->addr, st.reg->fifo_r_w, read_size, data)) 02506 return -1; 02507 ind = 0; 02508 for (ii = 0; ii < packet_count; ii++) { 02509 short accel_cur[3], gyro_cur[3]; 02510 accel_cur[0] = ((short)data[ind + 0] << 8) | data[ind + 1]; 02511 accel_cur[1] = ((short)data[ind + 2] << 8) | data[ind + 3]; 02512 accel_cur[2] = ((short)data[ind + 4] << 8) | data[ind + 5]; 02513 accel[0] += (long)accel_cur[0]; 02514 accel[1] += (long)accel_cur[1]; 02515 accel[2] += (long)accel_cur[2]; 02516 gyro_cur[0] = (((short)data[ind + 6] << 8) | data[ind + 7]); 02517 gyro_cur[1] = (((short)data[ind + 8] << 8) | data[ind + 9]); 02518 gyro_cur[2] = (((short)data[ind + 10] << 8) | data[ind + 11]); 02519 gyro[0] += (long)gyro_cur[0]; 02520 gyro[1] += (long)gyro_cur[1]; 02521 gyro[2] += (long)gyro_cur[2]; 02522 ind += MAX_PACKET_LENGTH; 02523 } 02524 s += packet_count; 02525 } 02526 02527 if(debug) 02528 log_i("Samples: %d\n", s); 02529 02530 //stop FIFO 02531 data[0] = 0; 02532 if (mpu_hal_write(st.hw->addr, st.reg->fifo_en, 1, data)) 02533 return -1; 02534 02535 gyro[0] = (long)(((long long)gyro[0]<<16) / test.gyro_sens / s); 02536 gyro[1] = (long)(((long long)gyro[1]<<16) / test.gyro_sens / s); 02537 gyro[2] = (long)(((long long)gyro[2]<<16) / test.gyro_sens / s); 02538 accel[0] = (long)(((long long)accel[0]<<16) / test.accel_sens / s); 02539 accel[1] = (long)(((long long)accel[1]<<16) / test.accel_sens / s); 02540 accel[2] = (long)(((long long)accel[2]<<16) / test.accel_sens / s); 02541 /* remove gravity from bias calculation */ 02542 if (accel[2] > 0L) 02543 accel[2] -= 65536L; 02544 else 02545 accel[2] += 65536L; 02546 02547 02548 if(debug) { 02549 log_i("Accel offset data HWST bit=%d: %7.4f %7.4f %7.4f\r\n", hw_test, accel[0]/65536.f, accel[1]/65536.f, accel[2]/65536.f); 02550 log_i("Gyro offset data HWST bit=%d: %7.4f %7.4f %7.4f\r\n", hw_test, gyro[0]/65536.f, gyro[1]/65536.f, gyro[2]/65536.f); 02551 } 02552 02553 return 0; 02554 } 02555 /** 02556 * @brief Trigger gyro/accel/compass self-test for MPU6500/MPU9250 02557 * On success/error, the self-test returns a mask representing the sensor(s) 02558 * that failed. For each bit, a one (1) represents a "pass" case; conversely, 02559 * a zero (0) indicates a failure. 02560 * 02561 * \n The mask is defined as follows: 02562 * \n Bit 0: Gyro. 02563 * \n Bit 1: Accel. 02564 * \n Bit 2: Compass. 02565 * 02566 * @param[out] gyro Gyro biases in q16 format. 02567 * @param[out] accel Accel biases (if applicable) in q16 format. 02568 * @param[in] debug Debug flag used to print out more detailed logs. Must first set up logging in Motion Driver. 02569 * @return Result mask (see above). 02570 */ 02571 int mpu_run_6500_self_test(long *gyro, long *accel, unsigned char debug) 02572 { 02573 const unsigned char tries = 2; 02574 long gyro_st[3], accel_st[3]; 02575 unsigned char accel_result, gyro_result; 02576 #ifdef AK89xx_SECONDARY 02577 unsigned char compass_result; 02578 #endif 02579 int ii; 02580 02581 int result; 02582 unsigned char accel_fsr, fifo_sensors, sensors_on; 02583 unsigned short gyro_fsr, sample_rate, lpf; 02584 unsigned char dmp_was_on; 02585 02586 02587 02588 if(debug) 02589 log_i("Starting MPU6500 HWST!\r\n"); 02590 02591 if (st.chip_cfg.dmp_on) { 02592 mpu_set_dmp_state(0); 02593 dmp_was_on = 1; 02594 } else 02595 dmp_was_on = 0; 02596 02597 /* Get initial settings. */ 02598 mpu_get_gyro_fsr(&gyro_fsr); 02599 mpu_get_accel_fsr(&accel_fsr); 02600 mpu_get_lpf(&lpf); 02601 mpu_get_sample_rate(&sample_rate); 02602 sensors_on = st.chip_cfg.sensors; 02603 mpu_get_fifo_config(&fifo_sensors); 02604 02605 if(debug) 02606 log_i("Retrieving Biases\r\n"); 02607 02608 for (ii = 0; ii < tries; ii++) 02609 if (!get_st_6500_biases(gyro, accel, 0, debug)) 02610 break; 02611 if (ii == tries) { 02612 /* If we reach this point, we most likely encountered an I2C error. 02613 * We'll just report an error for all three sensors. 02614 */ 02615 if(debug) 02616 log_i("Retrieving Biases Error - possible I2C error\n"); 02617 02618 result = 0; 02619 goto restore; 02620 } 02621 02622 if(debug) 02623 log_i("Retrieving ST Biases\n"); 02624 02625 for (ii = 0; ii < tries; ii++) 02626 if (!get_st_6500_biases(gyro_st, accel_st, 1, debug)) 02627 break; 02628 if (ii == tries) { 02629 02630 if(debug) 02631 log_i("Retrieving ST Biases Error - possible I2C error\n"); 02632 02633 /* Again, probably an I2C error. */ 02634 result = 0; 02635 goto restore; 02636 } 02637 02638 accel_result = accel_6500_self_test(accel, accel_st, debug); 02639 if(debug) 02640 log_i("Accel Self Test Results: %d\n", accel_result); 02641 02642 gyro_result = gyro_6500_self_test(gyro, gyro_st, debug); 02643 if(debug) 02644 log_i("Gyro Self Test Results: %d\n", gyro_result); 02645 02646 result = 0; 02647 if (!gyro_result) 02648 result |= 0x01; 02649 if (!accel_result) 02650 result |= 0x02; 02651 02652 #ifdef AK89xx_SECONDARY 02653 compass_result = compass_self_test(); 02654 if(debug) 02655 log_i("Compass Self Test Results: %d\n", compass_result); 02656 if (!compass_result) 02657 result |= 0x04; 02658 #else 02659 result |= 0x04; 02660 #endif 02661 restore: 02662 if(debug) 02663 log_i("Exiting HWST\n"); 02664 /* Set to invalid values to ensure no I2C writes are skipped. */ 02665 st.chip_cfg.gyro_fsr = 0xFF; 02666 st.chip_cfg.accel_fsr = 0xFF; 02667 st.chip_cfg.lpf = 0xFF; 02668 st.chip_cfg.sample_rate = 0xFFFF; 02669 st.chip_cfg.sensors = 0xFF; 02670 st.chip_cfg.fifo_enable = 0xFF; 02671 st.chip_cfg.clk_src = INV_CLK_PLL; 02672 mpu_set_gyro_fsr(gyro_fsr); 02673 mpu_set_accel_fsr(accel_fsr); 02674 mpu_set_lpf(lpf); 02675 mpu_set_sample_rate(sample_rate); 02676 mpu_set_sensors(sensors_on); 02677 mpu_configure_fifo(fifo_sensors); 02678 02679 if (dmp_was_on) 02680 mpu_set_dmp_state(1); 02681 02682 return result; 02683 } 02684 #endif 02685 /* 02686 * \n This function must be called with the device either face-up or face-down 02687 * (z-axis is parallel to gravity). 02688 * @param[out] gyro Gyro biases in q16 format. 02689 * @param[out] accel Accel biases (if applicable) in q16 format. 02690 * @return Result mask (see above). 02691 */ 02692 int mpu_run_self_test(long *gyro, long *accel) 02693 { 02694 #ifdef MPU6050 02695 const unsigned char tries = 2; 02696 long gyro_st[3], accel_st[3]; 02697 unsigned char accel_result, gyro_result; 02698 #ifdef AK89xx_SECONDARY 02699 unsigned char compass_result; 02700 #endif 02701 int ii; 02702 #endif 02703 int result; 02704 unsigned char accel_fsr, fifo_sensors, sensors_on; 02705 unsigned short gyro_fsr, sample_rate, lpf; 02706 unsigned char dmp_was_on; 02707 02708 if (st.chip_cfg.dmp_on) { 02709 mpu_set_dmp_state(0); 02710 dmp_was_on = 1; 02711 } else 02712 dmp_was_on = 0; 02713 02714 /* Get initial settings. */ 02715 mpu_get_gyro_fsr(&gyro_fsr); 02716 mpu_get_accel_fsr(&accel_fsr); 02717 mpu_get_lpf(&lpf); 02718 mpu_get_sample_rate(&sample_rate); 02719 sensors_on = st.chip_cfg.sensors; 02720 mpu_get_fifo_config(&fifo_sensors); 02721 02722 /* For older chips, the self-test will be different. */ 02723 #if defined MPU6050 02724 for (ii = 0; ii < tries; ii++) 02725 if (!get_st_biases(gyro, accel, 0)) 02726 break; 02727 if (ii == tries) { 02728 /* If we reach this point, we most likely encountered an I2C error. 02729 * We'll just report an error for all three sensors. 02730 */ 02731 result = 0; 02732 goto restore; 02733 } 02734 for (ii = 0; ii < tries; ii++) 02735 if (!get_st_biases(gyro_st, accel_st, 1)) 02736 break; 02737 if (ii == tries) { 02738 /* Again, probably an I2C error. */ 02739 result = 0; 02740 goto restore; 02741 } 02742 accel_result = accel_self_test(accel, accel_st); 02743 gyro_result = gyro_self_test(gyro, gyro_st); 02744 02745 result = 0; 02746 if (!gyro_result) 02747 result |= 0x01; 02748 if (!accel_result) 02749 result |= 0x02; 02750 02751 #ifdef AK89xx_SECONDARY 02752 compass_result = compass_self_test(); 02753 if (!compass_result) 02754 result |= 0x04; 02755 #else 02756 result |= 0x04; 02757 #endif 02758 restore: 02759 #elif defined MPU6500 02760 /* For now, this function will return a "pass" result for all three sensors 02761 * for compatibility with current test applications. 02762 */ 02763 get_st_biases(gyro, accel, 0); 02764 result = 0x7; 02765 #endif 02766 /* Set to invalid values to ensure no I2C writes are skipped. */ 02767 st.chip_cfg.gyro_fsr = 0xFF; 02768 st.chip_cfg.accel_fsr = 0xFF; 02769 st.chip_cfg.lpf = 0xFF; 02770 st.chip_cfg.sample_rate = 0xFFFF; 02771 st.chip_cfg.sensors = 0xFF; 02772 st.chip_cfg.fifo_enable = 0xFF; 02773 st.chip_cfg.clk_src = INV_CLK_PLL; 02774 mpu_set_gyro_fsr(gyro_fsr); 02775 mpu_set_accel_fsr(accel_fsr); 02776 mpu_set_lpf(lpf); 02777 mpu_set_sample_rate(sample_rate); 02778 mpu_set_sensors(sensors_on); 02779 mpu_configure_fifo(fifo_sensors); 02780 02781 if (dmp_was_on) 02782 mpu_set_dmp_state(1); 02783 02784 return result; 02785 } 02786 02787 /** 02788 * @brief Write to the DMP memory. 02789 * This function prevents I2C writes past the bank boundaries. The DMP memory 02790 * is only accessible when the chip is awake. 02791 * @param[in] mem_addr Memory location (bank << 8 | start address) 02792 * @param[in] length Number of bytes to write. 02793 * @param[in] data Bytes to write to memory. 02794 * @return 0 if successful. 02795 */ 02796 int mpu_write_mem(unsigned short mem_addr, unsigned short length, 02797 unsigned char *data) 02798 { 02799 unsigned char tmp[2]; 02800 02801 if (!data) 02802 return -1; 02803 if (!st.chip_cfg.sensors) 02804 return -1; 02805 02806 tmp[0] = (unsigned char)(mem_addr >> 8); 02807 tmp[1] = (unsigned char)(mem_addr & 0xFF); 02808 02809 /* Check bank boundaries. */ 02810 if (tmp[1] + length > st.hw->bank_size) 02811 return -1; 02812 02813 if (mpu_hal_write(st.hw->addr, st.reg->bank_sel, 2, tmp)) 02814 return -1; 02815 if (mpu_hal_write(st.hw->addr, st.reg->mem_r_w, length, data)) 02816 return -1; 02817 return 0; 02818 } 02819 02820 /** 02821 * @brief Read from the DMP memory. 02822 * This function prevents I2C reads past the bank boundaries. The DMP memory 02823 * is only accessible when the chip is awake. 02824 * @param[in] mem_addr Memory location (bank << 8 | start address) 02825 * @param[in] length Number of bytes to read. 02826 * @param[out] data Bytes read from memory. 02827 * @return 0 if successful. 02828 */ 02829 int mpu_read_mem(unsigned short mem_addr, unsigned short length, 02830 unsigned char *data) 02831 { 02832 unsigned char tmp[2]; 02833 02834 if (!data) 02835 return -1; 02836 if (!st.chip_cfg.sensors) 02837 return -1; 02838 02839 tmp[0] = (unsigned char)(mem_addr >> 8); 02840 tmp[1] = (unsigned char)(mem_addr & 0xFF); 02841 02842 /* Check bank boundaries. */ 02843 if (tmp[1] + length > st.hw->bank_size) 02844 return -1; 02845 02846 if (mpu_hal_write(st.hw->addr, st.reg->bank_sel, 2, tmp)) 02847 return -1; 02848 if (mpu_hal_read(st.hw->addr, st.reg->mem_r_w, length, data)) 02849 return -1; 02850 return 0; 02851 } 02852 02853 /** 02854 * @brief Load and verify DMP image. 02855 * @param[in] length Length of DMP image. 02856 * @param[in] firmware DMP code. 02857 * @param[in] start_addr Starting address of DMP code memory. 02858 * @param[in] sample_rate Fixed sampling rate used when DMP is enabled. 02859 * @return 0 if successful. 02860 */ 02861 int mpu_load_firmware(unsigned short length, const unsigned char *firmware, 02862 unsigned short start_addr, unsigned short sample_rate) 02863 { 02864 unsigned short ii; 02865 unsigned short this_write; 02866 /* Must divide evenly into st.hw->bank_size to avoid bank crossings. */ 02867 #define LOAD_CHUNK (16) 02868 static unsigned char cur[LOAD_CHUNK], tmp[2]; 02869 02870 if (st.chip_cfg.dmp_loaded) 02871 /* DMP should only be loaded once. */ 02872 return -1; 02873 02874 if (!firmware) 02875 return -1; 02876 for (ii = 0; ii < length; ii += this_write) { 02877 this_write = min(LOAD_CHUNK, length - ii); 02878 if (mpu_write_mem(ii, this_write, (unsigned char*)&firmware[ii])) 02879 return -1; 02880 if (mpu_read_mem(ii, this_write, cur)) 02881 return -1; 02882 if (memcmp(firmware+ii, cur, this_write)) 02883 return -2; 02884 } 02885 02886 /* Set program start address. */ 02887 tmp[0] = start_addr >> 8; 02888 tmp[1] = start_addr & 0xFF; 02889 if (mpu_hal_write(st.hw->addr, st.reg->prgm_start_h, 2, tmp)) 02890 return -1; 02891 02892 st.chip_cfg.dmp_loaded = 1; 02893 st.chip_cfg.dmp_sample_rate = sample_rate; 02894 return 0; 02895 } 02896 02897 /** 02898 * @brief Enable/disable DMP support. 02899 * @param[in] enable 1 to turn on the DMP. 02900 * @return 0 if successful. 02901 */ 02902 int mpu_set_dmp_state(unsigned char enable) 02903 { 02904 unsigned char tmp; 02905 if (st.chip_cfg.dmp_on == enable) 02906 return 0; 02907 02908 if (enable) { 02909 if (!st.chip_cfg.dmp_loaded) 02910 return -1; 02911 /* Disable data ready interrupt. */ 02912 set_int_enable(0); 02913 /* Disable bypass mode. */ 02914 mpu_set_bypass(0); 02915 /* Keep constant sample rate, FIFO rate controlled by DMP. */ 02916 mpu_set_sample_rate(st.chip_cfg.dmp_sample_rate); 02917 /* Remove FIFO elements. */ 02918 tmp = 0; 02919 mpu_hal_write(st.hw->addr, 0x23, 1, &tmp); 02920 st.chip_cfg.dmp_on = 1; 02921 /* Enable DMP interrupt. */ 02922 set_int_enable(1); 02923 mpu_reset_fifo(); 02924 } else { 02925 /* Disable DMP interrupt. */ 02926 set_int_enable(0); 02927 /* Restore FIFO settings. */ 02928 tmp = st.chip_cfg.fifo_enable; 02929 mpu_hal_write(st.hw->addr, 0x23, 1, &tmp); 02930 st.chip_cfg.dmp_on = 0; 02931 mpu_reset_fifo(); 02932 } 02933 return 0; 02934 } 02935 02936 /** 02937 * @brief Get DMP state. 02938 * @param[out] enabled 1 if enabled. 02939 * @return 0 if successful. 02940 */ 02941 int mpu_get_dmp_state(unsigned char *enabled) 02942 { 02943 enabled[0] = st.chip_cfg.dmp_on; 02944 return 0; 02945 } 02946 02947 #ifdef AK89xx_SECONDARY 02948 /* This initialization is similar to the one in ak8975.c. */ 02949 static int setup_compass(void) 02950 { 02951 unsigned char data[4], akm_addr; 02952 02953 #ifndef MPU_USE_SPI 02954 mpu_set_bypass(1); 02955 02956 /* Find compass. Possible addresses range from 0x0C to 0x0F. */ 02957 for (akm_addr = 0x0C; akm_addr <= 0x0F; akm_addr++) { 02958 int result; 02959 result = mpu_hal_read(akm_addr, AKM_REG_WHOAMI, 1, data); 02960 if (!result && (data[0] == AKM_WHOAMI)) 02961 break; 02962 } 02963 02964 if (akm_addr > 0x0F) { 02965 /* TODO: Handle this case in all compass-related functions. */ 02966 log_e("Compass not found.\n"); 02967 return -1; 02968 } 02969 02970 st.chip_cfg.compass_addr = akm_addr; 02971 02972 data[0] = AKM_POWER_DOWN; 02973 if (mpu_hal_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) 02974 return -1; 02975 delay_ms(1); 02976 02977 data[0] = AKM_FUSE_ROM_ACCESS; 02978 if (mpu_hal_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) 02979 return -1; 02980 delay_ms(1); 02981 02982 /* Get sensitivity adjustment data from fuse ROM. */ 02983 if (mpu_hal_read(st.chip_cfg.compass_addr, AKM_REG_ASAX, 3, data)) 02984 return -1; 02985 st.chip_cfg.mag_sens_adj[0] = (long)data[0] + 128; 02986 st.chip_cfg.mag_sens_adj[1] = (long)data[1] + 128; 02987 st.chip_cfg.mag_sens_adj[2] = (long)data[2] + 128; 02988 02989 data[0] = AKM_POWER_DOWN; 02990 if (mpu_hal_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) 02991 return -1; 02992 delay_ms(1); 02993 02994 mpu_set_bypass(0); 02995 02996 /* Set up master mode, master clock, and ES bit. */ 02997 data[0] = 0x40; 02998 if (mpu_hal_write(st.hw->addr, st.reg->i2c_mst, 1, data)) 02999 return -1; 03000 03001 #else 03002 akm_addr = 0x0C; 03003 st.chip_cfg.compass_addr = akm_addr; 03004 03005 /* Set up master mode, master clock, and ES bit. */ 03006 data[0] = 0x40; 03007 if (mpu_hal_write(st.hw->addr, st.reg->i2c_mst, 1, data)) 03008 return -1; 03009 03010 /* Slave 0 reads from AKM adj registers. */ 03011 data[0] = BIT_I2C_READ | st.chip_cfg.compass_addr; 03012 if (mpu_hal_write(st.hw->addr, st.reg->s0_addr, 1, data)) 03013 return -1; 03014 03015 /* Compass reads start at this register. */ 03016 data[0] = AKM_REG_ASAX; 03017 if (mpu_hal_write(st.hw->addr, st.reg->s0_reg, 1, data)) 03018 return -1; 03019 03020 /* Enable slave 0, 8-byte reads. */ 03021 data[0] = BIT_SLAVE_EN | 3; 03022 if (mpu_hal_write(st.hw->addr, st.reg->s0_ctrl, 1, data)) 03023 return -1; 03024 03025 if (mpu_hal_read(st.hw->addr, st.reg->raw_compass, 3, data)) 03026 return -1; 03027 03028 st.chip_cfg.mag_sens_adj[0] = (long)data[0] + 128; 03029 st.chip_cfg.mag_sens_adj[1] = (long)data[1] + 128; 03030 st.chip_cfg.mag_sens_adj[2] = (long)data[2] + 128; 03031 03032 #endif 03033 03034 /* Slave 0 reads from AKM data registers. */ 03035 data[0] = BIT_I2C_READ | st.chip_cfg.compass_addr; 03036 if (mpu_hal_write(st.hw->addr, st.reg->s0_addr, 1, data)) 03037 return -1; 03038 03039 /* Compass reads start at this register. */ 03040 data[0] = AKM_REG_ST1; 03041 if (mpu_hal_write(st.hw->addr, st.reg->s0_reg, 1, data)) 03042 return -1; 03043 03044 /* Enable slave 0, 8-byte reads. */ 03045 data[0] = BIT_SLAVE_EN | 8; 03046 if (mpu_hal_write(st.hw->addr, st.reg->s0_ctrl, 1, data)) 03047 return -1; 03048 03049 /* Slave 1 changes AKM measurement mode. */ 03050 data[0] = st.chip_cfg.compass_addr; 03051 if (mpu_hal_write(st.hw->addr, st.reg->s1_addr, 1, data)) 03052 return -1; 03053 03054 /* AKM measurement mode register. */ 03055 data[0] = AKM_REG_CNTL; 03056 if (mpu_hal_write(st.hw->addr, st.reg->s1_reg, 1, data)) 03057 return -1; 03058 03059 /* Enable slave 1, 1-byte writes. */ 03060 data[0] = BIT_SLAVE_EN | 1; 03061 if (mpu_hal_write(st.hw->addr, st.reg->s1_ctrl, 1, data)) 03062 return -1; 03063 03064 /* Set slave 1 data. */ 03065 data[0] = AKM_SINGLE_MEASUREMENT; 03066 if (mpu_hal_write(st.hw->addr, st.reg->s1_do, 1, data)) 03067 return -1; 03068 03069 /* Trigger slave 0 and slave 1 actions at each sample. */ 03070 data[0] = 0x03; 03071 if (mpu_hal_write(st.hw->addr, st.reg->i2c_delay_ctrl, 1, data)) 03072 return -1; 03073 03074 #ifdef MPU9150 03075 /* For the MPU9150, the auxiliary I2C bus needs to be set to VDD. */ 03076 data[0] = BIT_I2C_MST_VDDIO; 03077 if (mpu_hal_write(st.hw->addr, st.reg->yg_offs_tc, 1, data)) 03078 return -1; 03079 #endif 03080 03081 return 0; 03082 } 03083 #endif 03084 03085 /** 03086 * @brief Read raw compass data. 03087 * @param[out] data Raw data in hardware units. 03088 * @param[out] timestamp Timestamp in milliseconds. Null if not needed. 03089 * @return 0 if successful. 03090 */ 03091 int mpu_get_compass_reg(short *data, unsigned long *timestamp) 03092 { 03093 #ifdef AK89xx_SECONDARY 03094 unsigned char tmp[9]; 03095 03096 if (!(st.chip_cfg.sensors & INV_XYZ_COMPASS)) 03097 return -1; 03098 03099 #ifdef AK89xx_BYPASS 03100 if (mpu_hal_read(st.chip_cfg.compass_addr, AKM_REG_ST1, 8, tmp)) 03101 return -1; 03102 tmp[8] = AKM_SINGLE_MEASUREMENT; 03103 if (mpu_hal_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp+8)) 03104 return -1; 03105 #else 03106 if (mpu_hal_read(st.hw->addr, st.reg->raw_compass, 8, tmp)) 03107 return -1; 03108 #endif 03109 03110 #if defined AK8975_SECONDARY 03111 /* AK8975 doesn't have the overrun error bit. */ 03112 if (!(tmp[0] & AKM_DATA_READY)) 03113 return -2; 03114 if ((tmp[7] & AKM_OVERFLOW) || (tmp[7] & AKM_DATA_ERROR)) 03115 return -3; 03116 #elif defined AK8963_SECONDARY 03117 /* AK8963 doesn't have the data read error bit. */ 03118 if (!(tmp[0] & AKM_DATA_READY) || (tmp[0] & AKM_DATA_OVERRUN)) 03119 return -2; 03120 if (tmp[7] & AKM_OVERFLOW) 03121 return -3; 03122 #endif 03123 data[0] = (tmp[2] << 8) | tmp[1]; 03124 data[1] = (tmp[4] << 8) | tmp[3]; 03125 data[2] = (tmp[6] << 8) | tmp[5]; 03126 03127 data[0] = ((long)data[0] * st.chip_cfg.mag_sens_adj[0]) >> 8; 03128 data[1] = ((long)data[1] * st.chip_cfg.mag_sens_adj[1]) >> 8; 03129 data[2] = ((long)data[2] * st.chip_cfg.mag_sens_adj[2]) >> 8; 03130 03131 if (timestamp) 03132 get_ms(timestamp); 03133 return 0; 03134 #else 03135 return -1; 03136 #endif 03137 } 03138 03139 /** 03140 * @brief Get the compass full-scale range. 03141 * @param[out] fsr Current full-scale range. 03142 * @return 0 if successful. 03143 */ 03144 int mpu_get_compass_fsr(unsigned short *fsr) 03145 { 03146 #ifdef AK89xx_SECONDARY 03147 fsr[0] = st.hw->compass_fsr; 03148 return 0; 03149 #else 03150 return -1; 03151 #endif 03152 } 03153 03154 /** 03155 * @brief Enters LP accel motion interrupt mode. 03156 * The behaviour of this feature is very different between the MPU6050 and the 03157 * MPU6500. Each chip's version of this feature is explained below. 03158 * 03159 * \n The hardware motion threshold can be between 32mg and 8160mg in 32mg 03160 * increments. 03161 * 03162 * \n Low-power accel mode supports the following frequencies: 03163 * \n 1.25Hz, 5Hz, 20Hz, 40Hz 03164 * 03165 * \n MPU6500: 03166 * \n Unlike the MPU6050 version, the hardware does not "lock in" a reference 03167 * sample. The hardware monitors the accel data and detects any large change 03168 * over a short period of time. 03169 * 03170 * \n The hardware motion threshold can be between 4mg and 1020mg in 4mg 03171 * increments. 03172 * 03173 * \n MPU6500 Low-power accel mode supports the following frequencies: 03174 * \n 1.25Hz, 2.5Hz, 5Hz, 10Hz, 20Hz, 40Hz, 80Hz, 160Hz, 320Hz, 640Hz 03175 * 03176 * \n\n NOTES: 03177 * \n The driver will round down @e thresh to the nearest supported value if 03178 * an unsupported threshold is selected. 03179 * \n To select a fractional wake-up frequency, round down the value passed to 03180 * @e lpa_freq. 03181 * \n The MPU6500 does not support a delay parameter. If this function is used 03182 * for the MPU6500, the value passed to @e time will be ignored. 03183 * \n To disable this mode, set @e lpa_freq to zero. The driver will restore 03184 * the previous configuration. 03185 * 03186 * @param[in] thresh Motion threshold in mg. 03187 * @param[in] time Duration in milliseconds that the accel data must 03188 * exceed @e thresh before motion is reported. 03189 * @param[in] lpa_freq Minimum sampling rate, or zero to disable. 03190 * @return 0 if successful. 03191 */ 03192 int mpu_lp_motion_interrupt(unsigned short thresh, unsigned char time, 03193 unsigned char lpa_freq) 03194 { 03195 03196 #if defined MPU6500 03197 unsigned char data[3]; 03198 #endif 03199 if (lpa_freq) { 03200 #if defined MPU6500 03201 unsigned char thresh_hw; 03202 03203 /* 1LSb = 4mg. */ 03204 if (thresh > 1020) 03205 thresh_hw = 255; 03206 else if (thresh < 4) 03207 thresh_hw = 1; 03208 else 03209 thresh_hw = thresh >> 2; 03210 #endif 03211 03212 if (!time) 03213 /* Minimum duration must be 1ms. */ 03214 time = 1; 03215 03216 #if defined MPU6500 03217 if (lpa_freq > 640) 03218 /* At this point, the chip has not been re-configured, so the 03219 * function can safely exit. 03220 */ 03221 return -1; 03222 #endif 03223 03224 if (!st.chip_cfg.int_motion_only) { 03225 /* Store current settings for later. */ 03226 if (st.chip_cfg.dmp_on) { 03227 mpu_set_dmp_state(0); 03228 st.chip_cfg.cache.dmp_on = 1; 03229 } else 03230 st.chip_cfg.cache.dmp_on = 0; 03231 mpu_get_gyro_fsr(&st.chip_cfg.cache.gyro_fsr); 03232 mpu_get_accel_fsr(&st.chip_cfg.cache.accel_fsr); 03233 mpu_get_lpf(&st.chip_cfg.cache.lpf); 03234 mpu_get_sample_rate(&st.chip_cfg.cache.sample_rate); 03235 st.chip_cfg.cache.sensors_on = st.chip_cfg.sensors; 03236 mpu_get_fifo_config(&st.chip_cfg.cache.fifo_sensors); 03237 } 03238 03239 #if defined MPU6500 03240 /* Disable hardware interrupts. */ 03241 set_int_enable(0); 03242 03243 /* Enter full-power accel-only mode, no FIFO/DMP. */ 03244 data[0] = 0; 03245 data[1] = 0; 03246 data[2] = BIT_STBY_XYZG; 03247 if (mpu_hal_write(st.hw->addr, st.reg->user_ctrl, 3, data)) 03248 goto lp_int_restore; 03249 03250 /* Set motion threshold. */ 03251 data[0] = thresh_hw; 03252 if (mpu_hal_write(st.hw->addr, st.reg->motion_thr, 1, data)) 03253 goto lp_int_restore; 03254 03255 /* Set wake frequency. */ 03256 if (lpa_freq == 1) 03257 data[0] = INV_LPA_1_25HZ; 03258 else if (lpa_freq == 2) 03259 data[0] = INV_LPA_2_5HZ; 03260 else if (lpa_freq <= 5) 03261 data[0] = INV_LPA_5HZ; 03262 else if (lpa_freq <= 10) 03263 data[0] = INV_LPA_10HZ; 03264 else if (lpa_freq <= 20) 03265 data[0] = INV_LPA_20HZ; 03266 else if (lpa_freq <= 40) 03267 data[0] = INV_LPA_40HZ; 03268 else if (lpa_freq <= 80) 03269 data[0] = INV_LPA_80HZ; 03270 else if (lpa_freq <= 160) 03271 data[0] = INV_LPA_160HZ; 03272 else if (lpa_freq <= 320) 03273 data[0] = INV_LPA_320HZ; 03274 else 03275 data[0] = INV_LPA_640HZ; 03276 if (mpu_hal_write(st.hw->addr, st.reg->lp_accel_odr, 1, data)) 03277 goto lp_int_restore; 03278 03279 /* Enable motion interrupt (MPU6500 version). */ 03280 data[0] = BITS_WOM_EN; 03281 if (mpu_hal_write(st.hw->addr, st.reg->accel_intel, 1, data)) 03282 goto lp_int_restore; 03283 03284 /* Enable cycle mode. */ 03285 data[0] = BIT_LPA_CYCLE; 03286 if (mpu_hal_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) 03287 goto lp_int_restore; 03288 03289 /* Enable interrupt. */ 03290 data[0] = BIT_MOT_INT_EN; 03291 if (mpu_hal_write(st.hw->addr, st.reg->int_enable, 1, data)) 03292 goto lp_int_restore; 03293 03294 st.chip_cfg.int_motion_only = 1; 03295 return 0; 03296 #endif 03297 } else { 03298 /* Don't "restore" the previous state if no state has been saved. */ 03299 int ii; 03300 char *cache_ptr = (char*)&st.chip_cfg.cache; 03301 for (ii = 0; ii < sizeof(st.chip_cfg.cache); ii++) { 03302 if (cache_ptr[ii] != 0) 03303 goto lp_int_restore; 03304 } 03305 /* If we reach this point, motion interrupt mode hasn't been used yet. */ 03306 return -1; 03307 } 03308 lp_int_restore: 03309 /* Set to invalid values to ensure no I2C writes are skipped. */ 03310 st.chip_cfg.gyro_fsr = 0xFF; 03311 st.chip_cfg.accel_fsr = 0xFF; 03312 st.chip_cfg.lpf = 0xFF; 03313 st.chip_cfg.sample_rate = 0xFFFF; 03314 st.chip_cfg.sensors = 0xFF; 03315 st.chip_cfg.fifo_enable = 0xFF; 03316 st.chip_cfg.clk_src = INV_CLK_PLL; 03317 mpu_set_sensors(st.chip_cfg.cache.sensors_on); 03318 mpu_set_gyro_fsr(st.chip_cfg.cache.gyro_fsr); 03319 mpu_set_accel_fsr(st.chip_cfg.cache.accel_fsr); 03320 mpu_set_lpf(st.chip_cfg.cache.lpf); 03321 mpu_set_sample_rate(st.chip_cfg.cache.sample_rate); 03322 mpu_configure_fifo(st.chip_cfg.cache.fifo_sensors); 03323 03324 if (st.chip_cfg.cache.dmp_on) 03325 mpu_set_dmp_state(1); 03326 03327 #ifdef MPU6500 03328 /* Disable motion interrupt (MPU6500 version). */ 03329 data[0] = 0; 03330 if (mpu_hal_write(st.hw->addr, st.reg->accel_intel, 1, data)) 03331 goto lp_int_restore; 03332 #endif 03333 03334 st.chip_cfg.int_motion_only = 0; 03335 return 0; 03336 } 03337 03338 /** 03339 * @} 03340 */ 03341
Generated on Wed Jul 13 2022 20:01:33 by 1.7.2