Embedded MotionDriver 6.1 Sourced from InvenSense

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers inv_mpu.c Source File

inv_mpu.c

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