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