Yihui Xiong
/
Seeed_nRF51822_Motion
initial
Embed:
(wiki syntax)
Show/hide line numbers
inv_mpu_dmp_motion_driver.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_dmp_motion_driver.c 00013 * @brief DMP image and interface functions. 00014 * @details All functions are preceded by the dmp_ prefix to 00015 * differentiate among MPL and general driver function calls. 00016 */ 00017 #include <stdio.h> 00018 #include <stdint.h> 00019 #include <stdlib.h> 00020 #include <string.h> 00021 #include <math.h> 00022 #include "inv_mpu.h" 00023 #include "inv_mpu_dmp_motion_driver.h" 00024 #include "dmpKey.h" 00025 #include "dmpmap.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 */ 00035 #if defined MOTION_DRIVER_TARGET_MSP430 00036 #include "msp430.h" 00037 #include "msp430_clock.h" 00038 #define delay_ms msp430_delay_ms 00039 #define get_ms msp430_get_clock_ms 00040 #define log_i(...) do {} while (0) 00041 #define log_e(...) do {} while (0) 00042 00043 #elif defined EMPL_TARGET_MSP430 00044 #include "msp430.h" 00045 #include "msp430_clock.h" 00046 #include "log.h" 00047 #define delay_ms msp430_delay_ms 00048 #define get_ms msp430_get_clock_ms 00049 #define log_i MPL_LOGI 00050 #define log_e MPL_LOGE 00051 00052 #elif defined EMPL_TARGET_UC3L0 00053 /* Instead of using the standard TWI driver from the ASF library, we're using 00054 * a TWI driver that follows the slave address + register address convention. 00055 */ 00056 #include "delay.h" 00057 #include "sysclk.h" 00058 #include "log.h" 00059 #include "uc3l0_clock.h" 00060 /* delay_ms is a function already defined in ASF. */ 00061 #define get_ms uc3l0_get_clock_ms 00062 #define log_i MPL_LOGI 00063 #define log_e MPL_LOGE 00064 00065 #elif defined __MBED__ 00066 #include "mpu_mbed_config.h" 00067 #else 00068 #error Gyro driver is missing the system layer implementations. 00069 #endif 00070 00071 /* These defines are copied from dmpDefaultMPU6050.c in the general MPL 00072 * releases. These defines may change for each DMP image, so be sure to modify 00073 * these values when switching to a new image. 00074 */ 00075 #define CFG_LP_QUAT (2712) 00076 #define END_ORIENT_TEMP (1866) 00077 #define CFG_27 (2742) 00078 #define CFG_20 (2224) 00079 #define CFG_23 (2745) 00080 #define CFG_FIFO_ON_EVENT (2690) 00081 #define END_PREDICTION_UPDATE (1761) 00082 #define CGNOTICE_INTR (2620) 00083 #define X_GRT_Y_TMP (1358) 00084 #define CFG_DR_INT (1029) 00085 #define CFG_AUTH (1035) 00086 #define UPDATE_PROP_ROT (1835) 00087 #define END_COMPARE_Y_X_TMP2 (1455) 00088 #define SKIP_X_GRT_Y_TMP (1359) 00089 #define SKIP_END_COMPARE (1435) 00090 #define FCFG_3 (1088) 00091 #define FCFG_2 (1066) 00092 #define FCFG_1 (1062) 00093 #define END_COMPARE_Y_X_TMP3 (1434) 00094 #define FCFG_7 (1073) 00095 #define FCFG_6 (1106) 00096 #define FLAT_STATE_END (1713) 00097 #define SWING_END_4 (1616) 00098 #define SWING_END_2 (1565) 00099 #define SWING_END_3 (1587) 00100 #define SWING_END_1 (1550) 00101 #define CFG_8 (2718) 00102 #define CFG_15 (2727) 00103 #define CFG_16 (2746) 00104 #define CFG_EXT_GYRO_BIAS (1189) 00105 #define END_COMPARE_Y_X_TMP (1407) 00106 #define DO_NOT_UPDATE_PROP_ROT (1839) 00107 #define CFG_7 (1205) 00108 #define FLAT_STATE_END_TEMP (1683) 00109 #define END_COMPARE_Y_X (1484) 00110 #define SKIP_SWING_END_1 (1551) 00111 #define SKIP_SWING_END_3 (1588) 00112 #define SKIP_SWING_END_2 (1566) 00113 #define TILTG75_START (1672) 00114 #define CFG_6 (2753) 00115 #define TILTL75_END (1669) 00116 #define END_ORIENT (1884) 00117 #define CFG_FLICK_IN (2573) 00118 #define TILTL75_START (1643) 00119 #define CFG_MOTION_BIAS (1208) 00120 #define X_GRT_Y (1408) 00121 #define TEMPLABEL (2324) 00122 #define CFG_ANDROID_ORIENT_INT (1853) 00123 #define CFG_GYRO_RAW_DATA (2722) 00124 #define X_GRT_Y_TMP2 (1379) 00125 00126 #define D_0_22 (22+512) 00127 #define D_0_24 (24+512) 00128 00129 #define D_0_36 (36) 00130 #define D_0_52 (52) 00131 #define D_0_96 (96) 00132 #define D_0_104 (104) 00133 #define D_0_108 (108) 00134 #define D_0_163 (163) 00135 #define D_0_188 (188) 00136 #define D_0_192 (192) 00137 #define D_0_224 (224) 00138 #define D_0_228 (228) 00139 #define D_0_232 (232) 00140 #define D_0_236 (236) 00141 00142 #define D_1_2 (256 + 2) 00143 #define D_1_4 (256 + 4) 00144 #define D_1_8 (256 + 8) 00145 #define D_1_10 (256 + 10) 00146 #define D_1_24 (256 + 24) 00147 #define D_1_28 (256 + 28) 00148 #define D_1_36 (256 + 36) 00149 #define D_1_40 (256 + 40) 00150 #define D_1_44 (256 + 44) 00151 #define D_1_72 (256 + 72) 00152 #define D_1_74 (256 + 74) 00153 #define D_1_79 (256 + 79) 00154 #define D_1_88 (256 + 88) 00155 #define D_1_90 (256 + 90) 00156 #define D_1_92 (256 + 92) 00157 #define D_1_96 (256 + 96) 00158 #define D_1_98 (256 + 98) 00159 #define D_1_106 (256 + 106) 00160 #define D_1_108 (256 + 108) 00161 #define D_1_112 (256 + 112) 00162 #define D_1_128 (256 + 144) 00163 #define D_1_152 (256 + 12) 00164 #define D_1_160 (256 + 160) 00165 #define D_1_176 (256 + 176) 00166 #define D_1_178 (256 + 178) 00167 #define D_1_218 (256 + 218) 00168 #define D_1_232 (256 + 232) 00169 #define D_1_236 (256 + 236) 00170 #define D_1_240 (256 + 240) 00171 #define D_1_244 (256 + 244) 00172 #define D_1_250 (256 + 250) 00173 #define D_1_252 (256 + 252) 00174 #define D_2_12 (512 + 12) 00175 #define D_2_96 (512 + 96) 00176 #define D_2_108 (512 + 108) 00177 #define D_2_208 (512 + 208) 00178 #define D_2_224 (512 + 224) 00179 #define D_2_236 (512 + 236) 00180 #define D_2_244 (512 + 244) 00181 #define D_2_248 (512 + 248) 00182 #define D_2_252 (512 + 252) 00183 00184 #define CPASS_BIAS_X (35 * 16 + 4) 00185 #define CPASS_BIAS_Y (35 * 16 + 8) 00186 #define CPASS_BIAS_Z (35 * 16 + 12) 00187 #define CPASS_MTX_00 (36 * 16) 00188 #define CPASS_MTX_01 (36 * 16 + 4) 00189 #define CPASS_MTX_02 (36 * 16 + 8) 00190 #define CPASS_MTX_10 (36 * 16 + 12) 00191 #define CPASS_MTX_11 (37 * 16) 00192 #define CPASS_MTX_12 (37 * 16 + 4) 00193 #define CPASS_MTX_20 (37 * 16 + 8) 00194 #define CPASS_MTX_21 (37 * 16 + 12) 00195 #define CPASS_MTX_22 (43 * 16 + 12) 00196 #define D_EXT_GYRO_BIAS_X (61 * 16) 00197 #define D_EXT_GYRO_BIAS_Y (61 * 16) + 4 00198 #define D_EXT_GYRO_BIAS_Z (61 * 16) + 8 00199 #define D_ACT0 (40 * 16) 00200 #define D_ACSX (40 * 16 + 4) 00201 #define D_ACSY (40 * 16 + 8) 00202 #define D_ACSZ (40 * 16 + 12) 00203 00204 #define FLICK_MSG (45 * 16 + 4) 00205 #define FLICK_COUNTER (45 * 16 + 8) 00206 #define FLICK_LOWER (45 * 16 + 12) 00207 #define FLICK_UPPER (46 * 16 + 12) 00208 00209 #define D_AUTH_OUT (992) 00210 #define D_AUTH_IN (996) 00211 #define D_AUTH_A (1000) 00212 #define D_AUTH_B (1004) 00213 00214 #define D_PEDSTD_BP_B (768 + 0x1C) 00215 #define D_PEDSTD_HP_A (768 + 0x78) 00216 #define D_PEDSTD_HP_B (768 + 0x7C) 00217 #define D_PEDSTD_BP_A4 (768 + 0x40) 00218 #define D_PEDSTD_BP_A3 (768 + 0x44) 00219 #define D_PEDSTD_BP_A2 (768 + 0x48) 00220 #define D_PEDSTD_BP_A1 (768 + 0x4C) 00221 #define D_PEDSTD_INT_THRSH (768 + 0x68) 00222 #define D_PEDSTD_CLIP (768 + 0x6C) 00223 #define D_PEDSTD_SB (768 + 0x28) 00224 #define D_PEDSTD_SB_TIME (768 + 0x2C) 00225 #define D_PEDSTD_PEAKTHRSH (768 + 0x98) 00226 #define D_PEDSTD_TIML (768 + 0x2A) 00227 #define D_PEDSTD_TIMH (768 + 0x2E) 00228 #define D_PEDSTD_PEAK (768 + 0X94) 00229 #define D_PEDSTD_STEPCTR (768 + 0x60) 00230 #define D_PEDSTD_TIMECTR (964) 00231 #define D_PEDSTD_DECI (768 + 0xA0) 00232 00233 #define D_HOST_NO_MOT (976) 00234 #define D_ACCEL_BIAS (660) 00235 00236 #define D_ORIENT_GAP (76) 00237 00238 #define D_TILT0_H (48) 00239 #define D_TILT0_L (50) 00240 #define D_TILT1_H (52) 00241 #define D_TILT1_L (54) 00242 #define D_TILT2_H (56) 00243 #define D_TILT2_L (58) 00244 #define D_TILT3_H (60) 00245 #define D_TILT3_L (62) 00246 00247 #define DMP_CODE_SIZE (3062) 00248 00249 static const unsigned char dmp_memory[DMP_CODE_SIZE] = { 00250 /* bank # 0 */ 00251 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 00252 0x00, 0x65, 0x00, 0x54, 0xff, 0xef, 0x00, 0x00, 0xfa, 0x80, 0x00, 0x0b, 0x12, 0x82, 0x00, 0x01, 00253 0x03, 0x0c, 0x30, 0xc3, 0x0e, 0x8c, 0x8c, 0xe9, 0x14, 0xd5, 0x40, 0x02, 0x13, 0x71, 0x0f, 0x8e, 00254 0x38, 0x83, 0xf8, 0x83, 0x30, 0x00, 0xf8, 0x83, 0x25, 0x8e, 0xf8, 0x83, 0x30, 0x00, 0xf8, 0x83, 00255 0xff, 0xff, 0xff, 0xff, 0x0f, 0xfe, 0xa9, 0xd6, 0x24, 0x00, 0x04, 0x00, 0x1a, 0x82, 0x79, 0xa1, 00256 0x00, 0x00, 0x00, 0x3c, 0xff, 0xff, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x38, 0x83, 0x6f, 0xa2, 00257 0x00, 0x3e, 0x03, 0x30, 0x40, 0x00, 0x00, 0x00, 0x02, 0xca, 0xe3, 0x09, 0x3e, 0x80, 0x00, 0x00, 00258 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 00259 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x6e, 0x00, 0x00, 0x06, 0x92, 0x0a, 0x16, 0xc0, 0xdf, 00260 0xff, 0xff, 0x02, 0x56, 0xfd, 0x8c, 0xd3, 0x77, 0xff, 0xe1, 0xc4, 0x96, 0xe0, 0xc5, 0xbe, 0xaa, 00261 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0b, 0x2b, 0x00, 0x00, 0x16, 0x57, 0x00, 0x00, 0x03, 0x59, 00262 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xfa, 0x00, 0x02, 0x6c, 0x1d, 0x00, 0x00, 0x00, 0x00, 00263 0x3f, 0xff, 0xdf, 0xeb, 0x00, 0x3e, 0xb3, 0xb6, 0x00, 0x0d, 0x22, 0x78, 0x00, 0x00, 0x2f, 0x3c, 00264 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x42, 0xb5, 0x00, 0x00, 0x39, 0xa2, 0x00, 0x00, 0xb3, 0x65, 00265 0xd9, 0x0e, 0x9f, 0xc9, 0x1d, 0xcf, 0x4c, 0x34, 0x30, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 00266 0x3b, 0xb6, 0x7a, 0xe8, 0x00, 0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00267 /* bank # 1 */ 00268 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0xfa, 0x92, 0x10, 0x00, 0x22, 0x5e, 0x00, 0x0d, 0x22, 0x9f, 00269 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0x63, 0xd4, 0x00, 0x00, 00270 0x10, 0x00, 0x00, 0x00, 0x04, 0xd6, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x00, 00271 0x00, 0x00, 0x10, 0x72, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00272 0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 00273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x64, 0x00, 0x20, 0x00, 0x00, 00274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 00275 0x00, 0x00, 0x00, 0x32, 0xf8, 0x98, 0x00, 0x00, 0xff, 0x65, 0x00, 0x00, 0x83, 0x0f, 0x00, 0x00, 00276 0xff, 0x9b, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00278 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 00279 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xb2, 0x6a, 0x00, 0x02, 0x00, 0x00, 00280 0x00, 0x01, 0xfb, 0x83, 0x00, 0x68, 0x00, 0x00, 0x00, 0xd9, 0xfc, 0x00, 0x7c, 0xf1, 0xff, 0x83, 00281 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x64, 0x03, 0xe8, 0x00, 0x64, 0x00, 0x28, 00282 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 00283 0x00, 0x00, 0x10, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x10, 0x00, 00284 /* bank # 2 */ 00285 0x00, 0x28, 0x00, 0x00, 0xff, 0xff, 0x45, 0x81, 0xff, 0xff, 0xfa, 0x72, 0x00, 0x00, 0x00, 0x00, 00286 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x05, 0x00, 0x05, 0xba, 0xc6, 0x00, 0x47, 0x78, 0xa2, 00287 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14, 00288 0x00, 0x00, 0x25, 0x4d, 0x00, 0x2f, 0x70, 0x6d, 0x00, 0x00, 0x05, 0xae, 0x00, 0x0c, 0x02, 0xd0, 00289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00290 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00291 0x00, 0x64, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00297 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 00298 0x00, 0x00, 0x0a, 0xc7, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0xff, 0xff, 0xff, 0x9c, 00299 0x00, 0x00, 0x0b, 0x2b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 00300 0xff, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00301 /* bank # 3 */ 00302 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00303 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x24, 0x26, 0xd3, 00304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x96, 0x00, 0x3c, 00305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00306 0x0c, 0x0a, 0x4e, 0x68, 0xcd, 0xcf, 0x77, 0x09, 0x50, 0x16, 0x67, 0x59, 0xc6, 0x19, 0xce, 0x82, 00307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xd7, 0x84, 0x00, 0x03, 0x00, 0x00, 0x00, 00309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x93, 0x8f, 0x9d, 0x1e, 0x1b, 0x1c, 0x19, 00310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x18, 0x85, 0x00, 0x00, 0x40, 0x00, 00312 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00313 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00316 0x00, 0x00, 0x00, 0x00, 0x67, 0x7d, 0xdf, 0x7e, 0x72, 0x90, 0x2e, 0x55, 0x4c, 0xf6, 0xe6, 0x88, 00317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00318 00319 /* bank # 4 */ 00320 0xd8, 0xdc, 0xb4, 0xb8, 0xb0, 0xd8, 0xb9, 0xab, 0xf3, 0xf8, 0xfa, 0xb3, 0xb7, 0xbb, 0x8e, 0x9e, 00321 0xae, 0xf1, 0x32, 0xf5, 0x1b, 0xf1, 0xb4, 0xb8, 0xb0, 0x80, 0x97, 0xf1, 0xa9, 0xdf, 0xdf, 0xdf, 00322 0xaa, 0xdf, 0xdf, 0xdf, 0xf2, 0xaa, 0xc5, 0xcd, 0xc7, 0xa9, 0x0c, 0xc9, 0x2c, 0x97, 0xf1, 0xa9, 00323 0x89, 0x26, 0x46, 0x66, 0xb2, 0x89, 0x99, 0xa9, 0x2d, 0x55, 0x7d, 0xb0, 0xb0, 0x8a, 0xa8, 0x96, 00324 0x36, 0x56, 0x76, 0xf1, 0xba, 0xa3, 0xb4, 0xb2, 0x80, 0xc0, 0xb8, 0xa8, 0x97, 0x11, 0xb2, 0x83, 00325 0x98, 0xba, 0xa3, 0xf0, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xb2, 0xb9, 0xb4, 0x98, 0x83, 0xf1, 00326 0xa3, 0x29, 0x55, 0x7d, 0xba, 0xb5, 0xb1, 0xa3, 0x83, 0x93, 0xf0, 0x00, 0x28, 0x50, 0xf5, 0xb2, 00327 0xb6, 0xaa, 0x83, 0x93, 0x28, 0x54, 0x7c, 0xf1, 0xb9, 0xa3, 0x82, 0x93, 0x61, 0xba, 0xa2, 0xda, 00328 0xde, 0xdf, 0xdb, 0x81, 0x9a, 0xb9, 0xae, 0xf5, 0x60, 0x68, 0x70, 0xf1, 0xda, 0xba, 0xa2, 0xdf, 00329 0xd9, 0xba, 0xa2, 0xfa, 0xb9, 0xa3, 0x82, 0x92, 0xdb, 0x31, 0xba, 0xa2, 0xd9, 0xba, 0xa2, 0xf8, 00330 0xdf, 0x85, 0xa4, 0xd0, 0xc1, 0xbb, 0xad, 0x83, 0xc2, 0xc5, 0xc7, 0xb8, 0xa2, 0xdf, 0xdf, 0xdf, 00331 0xba, 0xa0, 0xdf, 0xdf, 0xdf, 0xd8, 0xd8, 0xf1, 0xb8, 0xaa, 0xb3, 0x8d, 0xb4, 0x98, 0x0d, 0x35, 00332 0x5d, 0xb2, 0xb6, 0xba, 0xaf, 0x8c, 0x96, 0x19, 0x8f, 0x9f, 0xa7, 0x0e, 0x16, 0x1e, 0xb4, 0x9a, 00333 0xb8, 0xaa, 0x87, 0x2c, 0x54, 0x7c, 0xba, 0xa4, 0xb0, 0x8a, 0xb6, 0x91, 0x32, 0x56, 0x76, 0xb2, 00334 0x84, 0x94, 0xa4, 0xc8, 0x08, 0xcd, 0xd8, 0xb8, 0xb4, 0xb0, 0xf1, 0x99, 0x82, 0xa8, 0x2d, 0x55, 00335 0x7d, 0x98, 0xa8, 0x0e, 0x16, 0x1e, 0xa2, 0x2c, 0x54, 0x7c, 0x92, 0xa4, 0xf0, 0x2c, 0x50, 0x78, 00336 /* bank # 5 */ 00337 0xf1, 0x84, 0xa8, 0x98, 0xc4, 0xcd, 0xfc, 0xd8, 0x0d, 0xdb, 0xa8, 0xfc, 0x2d, 0xf3, 0xd9, 0xba, 00338 0xa6, 0xf8, 0xda, 0xba, 0xa6, 0xde, 0xd8, 0xba, 0xb2, 0xb6, 0x86, 0x96, 0xa6, 0xd0, 0xf3, 0xc8, 00339 0x41, 0xda, 0xa6, 0xc8, 0xf8, 0xd8, 0xb0, 0xb4, 0xb8, 0x82, 0xa8, 0x92, 0xf5, 0x2c, 0x54, 0x88, 00340 0x98, 0xf1, 0x35, 0xd9, 0xf4, 0x18, 0xd8, 0xf1, 0xa2, 0xd0, 0xf8, 0xf9, 0xa8, 0x84, 0xd9, 0xc7, 00341 0xdf, 0xf8, 0xf8, 0x83, 0xc5, 0xda, 0xdf, 0x69, 0xdf, 0x83, 0xc1, 0xd8, 0xf4, 0x01, 0x14, 0xf1, 00342 0xa8, 0x82, 0x4e, 0xa8, 0x84, 0xf3, 0x11, 0xd1, 0x82, 0xf5, 0xd9, 0x92, 0x28, 0x97, 0x88, 0xf1, 00343 0x09, 0xf4, 0x1c, 0x1c, 0xd8, 0x84, 0xa8, 0xf3, 0xc0, 0xf9, 0xd1, 0xd9, 0x97, 0x82, 0xf1, 0x29, 00344 0xf4, 0x0d, 0xd8, 0xf3, 0xf9, 0xf9, 0xd1, 0xd9, 0x82, 0xf4, 0xc2, 0x03, 0xd8, 0xde, 0xdf, 0x1a, 00345 0xd8, 0xf1, 0xa2, 0xfa, 0xf9, 0xa8, 0x84, 0x98, 0xd9, 0xc7, 0xdf, 0xf8, 0xf8, 0xf8, 0x83, 0xc7, 00346 0xda, 0xdf, 0x69, 0xdf, 0xf8, 0x83, 0xc3, 0xd8, 0xf4, 0x01, 0x14, 0xf1, 0x98, 0xa8, 0x82, 0x2e, 00347 0xa8, 0x84, 0xf3, 0x11, 0xd1, 0x82, 0xf5, 0xd9, 0x92, 0x50, 0x97, 0x88, 0xf1, 0x09, 0xf4, 0x1c, 00348 0xd8, 0x84, 0xa8, 0xf3, 0xc0, 0xf8, 0xf9, 0xd1, 0xd9, 0x97, 0x82, 0xf1, 0x49, 0xf4, 0x0d, 0xd8, 00349 0xf3, 0xf9, 0xf9, 0xd1, 0xd9, 0x82, 0xf4, 0xc4, 0x03, 0xd8, 0xde, 0xdf, 0xd8, 0xf1, 0xad, 0x88, 00350 0x98, 0xcc, 0xa8, 0x09, 0xf9, 0xd9, 0x82, 0x92, 0xa8, 0xf5, 0x7c, 0xf1, 0x88, 0x3a, 0xcf, 0x94, 00351 0x4a, 0x6e, 0x98, 0xdb, 0x69, 0x31, 0xda, 0xad, 0xf2, 0xde, 0xf9, 0xd8, 0x87, 0x95, 0xa8, 0xf2, 00352 0x21, 0xd1, 0xda, 0xa5, 0xf9, 0xf4, 0x17, 0xd9, 0xf1, 0xae, 0x8e, 0xd0, 0xc0, 0xc3, 0xae, 0x82, 00353 /* bank # 6 */ 00354 0xc6, 0x84, 0xc3, 0xa8, 0x85, 0x95, 0xc8, 0xa5, 0x88, 0xf2, 0xc0, 0xf1, 0xf4, 0x01, 0x0e, 0xf1, 00355 0x8e, 0x9e, 0xa8, 0xc6, 0x3e, 0x56, 0xf5, 0x54, 0xf1, 0x88, 0x72, 0xf4, 0x01, 0x15, 0xf1, 0x98, 00356 0x45, 0x85, 0x6e, 0xf5, 0x8e, 0x9e, 0x04, 0x88, 0xf1, 0x42, 0x98, 0x5a, 0x8e, 0x9e, 0x06, 0x88, 00357 0x69, 0xf4, 0x01, 0x1c, 0xf1, 0x98, 0x1e, 0x11, 0x08, 0xd0, 0xf5, 0x04, 0xf1, 0x1e, 0x97, 0x02, 00358 0x02, 0x98, 0x36, 0x25, 0xdb, 0xf9, 0xd9, 0x85, 0xa5, 0xf3, 0xc1, 0xda, 0x85, 0xa5, 0xf3, 0xdf, 00359 0xd8, 0x85, 0x95, 0xa8, 0xf3, 0x09, 0xda, 0xa5, 0xfa, 0xd8, 0x82, 0x92, 0xa8, 0xf5, 0x78, 0xf1, 00360 0x88, 0x1a, 0x84, 0x9f, 0x26, 0x88, 0x98, 0x21, 0xda, 0xf4, 0x1d, 0xf3, 0xd8, 0x87, 0x9f, 0x39, 00361 0xd1, 0xaf, 0xd9, 0xdf, 0xdf, 0xfb, 0xf9, 0xf4, 0x0c, 0xf3, 0xd8, 0xfa, 0xd0, 0xf8, 0xda, 0xf9, 00362 0xf9, 0xd0, 0xdf, 0xd9, 0xf9, 0xd8, 0xf4, 0x0b, 0xd8, 0xf3, 0x87, 0x9f, 0x39, 0xd1, 0xaf, 0xd9, 00363 0xdf, 0xdf, 0xf4, 0x1d, 0xf3, 0xd8, 0xfa, 0xfc, 0xa8, 0x69, 0xf9, 0xf9, 0xaf, 0xd0, 0xda, 0xde, 00364 0xfa, 0xd9, 0xf8, 0x8f, 0x9f, 0xa8, 0xf1, 0xcc, 0xf3, 0x98, 0xdb, 0x45, 0xd9, 0xaf, 0xdf, 0xd0, 00365 0xf8, 0xd8, 0xf1, 0x8f, 0x9f, 0xa8, 0xca, 0xf3, 0x88, 0x09, 0xda, 0xaf, 0x8f, 0xcb, 0xf8, 0xd8, 00366 0xf2, 0xad, 0x97, 0x8d, 0x0c, 0xd9, 0xa5, 0xdf, 0xf9, 0xba, 0xa6, 0xf3, 0xfa, 0xf4, 0x12, 0xf2, 00367 0xd8, 0x95, 0x0d, 0xd1, 0xd9, 0xba, 0xa6, 0xf3, 0xfa, 0xda, 0xa5, 0xf2, 0xc1, 0xba, 0xa6, 0xf3, 00368 0xdf, 0xd8, 0xf1, 0xba, 0xb2, 0xb6, 0x86, 0x96, 0xa6, 0xd0, 0xca, 0xf3, 0x49, 0xda, 0xa6, 0xcb, 00369 0xf8, 0xd8, 0xb0, 0xb4, 0xb8, 0xd8, 0xad, 0x84, 0xf2, 0xc0, 0xdf, 0xf1, 0x8f, 0xcb, 0xc3, 0xa8, 00370 /* bank # 7 */ 00371 0xb2, 0xb6, 0x86, 0x96, 0xc8, 0xc1, 0xcb, 0xc3, 0xf3, 0xb0, 0xb4, 0x88, 0x98, 0xa8, 0x21, 0xdb, 00372 0x71, 0x8d, 0x9d, 0x71, 0x85, 0x95, 0x21, 0xd9, 0xad, 0xf2, 0xfa, 0xd8, 0x85, 0x97, 0xa8, 0x28, 00373 0xd9, 0xf4, 0x08, 0xd8, 0xf2, 0x8d, 0x29, 0xda, 0xf4, 0x05, 0xd9, 0xf2, 0x85, 0xa4, 0xc2, 0xf2, 00374 0xd8, 0xa8, 0x8d, 0x94, 0x01, 0xd1, 0xd9, 0xf4, 0x11, 0xf2, 0xd8, 0x87, 0x21, 0xd8, 0xf4, 0x0a, 00375 0xd8, 0xf2, 0x84, 0x98, 0xa8, 0xc8, 0x01, 0xd1, 0xd9, 0xf4, 0x11, 0xd8, 0xf3, 0xa4, 0xc8, 0xbb, 00376 0xaf, 0xd0, 0xf2, 0xde, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xd8, 0xf1, 0xb8, 0xf6, 00377 0xb5, 0xb9, 0xb0, 0x8a, 0x95, 0xa3, 0xde, 0x3c, 0xa3, 0xd9, 0xf8, 0xd8, 0x5c, 0xa3, 0xd9, 0xf8, 00378 0xd8, 0x7c, 0xa3, 0xd9, 0xf8, 0xd8, 0xf8, 0xf9, 0xd1, 0xa5, 0xd9, 0xdf, 0xda, 0xfa, 0xd8, 0xb1, 00379 0x85, 0x30, 0xf7, 0xd9, 0xde, 0xd8, 0xf8, 0x30, 0xad, 0xda, 0xde, 0xd8, 0xf2, 0xb4, 0x8c, 0x99, 00380 0xa3, 0x2d, 0x55, 0x7d, 0xa0, 0x83, 0xdf, 0xdf, 0xdf, 0xb5, 0x91, 0xa0, 0xf6, 0x29, 0xd9, 0xfb, 00381 0xd8, 0xa0, 0xfc, 0x29, 0xd9, 0xfa, 0xd8, 0xa0, 0xd0, 0x51, 0xd9, 0xf8, 0xd8, 0xfc, 0x51, 0xd9, 00382 0xf9, 0xd8, 0x79, 0xd9, 0xfb, 0xd8, 0xa0, 0xd0, 0xfc, 0x79, 0xd9, 0xfa, 0xd8, 0xa1, 0xf9, 0xf9, 00383 0xf9, 0xf9, 0xf9, 0xa0, 0xda, 0xdf, 0xdf, 0xdf, 0xd8, 0xa1, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xac, 00384 0xde, 0xf8, 0xad, 0xde, 0x83, 0x93, 0xac, 0x2c, 0x54, 0x7c, 0xf1, 0xa8, 0xdf, 0xdf, 0xdf, 0xf6, 00385 0x9d, 0x2c, 0xda, 0xa0, 0xdf, 0xd9, 0xfa, 0xdb, 0x2d, 0xf8, 0xd8, 0xa8, 0x50, 0xda, 0xa0, 0xd0, 00386 0xde, 0xd9, 0xd0, 0xf8, 0xf8, 0xf8, 0xdb, 0x55, 0xf8, 0xd8, 0xa8, 0x78, 0xda, 0xa0, 0xd0, 0xdf, 00387 /* bank # 8 */ 00388 0xd9, 0xd0, 0xfa, 0xf8, 0xf8, 0xf8, 0xf8, 0xdb, 0x7d, 0xf8, 0xd8, 0x9c, 0xa8, 0x8c, 0xf5, 0x30, 00389 0xdb, 0x38, 0xd9, 0xd0, 0xde, 0xdf, 0xa0, 0xd0, 0xde, 0xdf, 0xd8, 0xa8, 0x48, 0xdb, 0x58, 0xd9, 00390 0xdf, 0xd0, 0xde, 0xa0, 0xdf, 0xd0, 0xde, 0xd8, 0xa8, 0x68, 0xdb, 0x70, 0xd9, 0xdf, 0xdf, 0xa0, 00391 0xdf, 0xdf, 0xd8, 0xf1, 0xa8, 0x88, 0x90, 0x2c, 0x54, 0x7c, 0x98, 0xa8, 0xd0, 0x5c, 0x38, 0xd1, 00392 0xda, 0xf2, 0xae, 0x8c, 0xdf, 0xf9, 0xd8, 0xb0, 0x87, 0xa8, 0xc1, 0xc1, 0xb1, 0x88, 0xa8, 0xc6, 00393 0xf9, 0xf9, 0xda, 0x36, 0xd8, 0xa8, 0xf9, 0xda, 0x36, 0xd8, 0xa8, 0xf9, 0xda, 0x36, 0xd8, 0xa8, 00394 0xf9, 0xda, 0x36, 0xd8, 0xa8, 0xf9, 0xda, 0x36, 0xd8, 0xf7, 0x8d, 0x9d, 0xad, 0xf8, 0x18, 0xda, 00395 0xf2, 0xae, 0xdf, 0xd8, 0xf7, 0xad, 0xfa, 0x30, 0xd9, 0xa4, 0xde, 0xf9, 0xd8, 0xf2, 0xae, 0xde, 00396 0xfa, 0xf9, 0x83, 0xa7, 0xd9, 0xc3, 0xc5, 0xc7, 0xf1, 0x88, 0x9b, 0xa7, 0x7a, 0xad, 0xf7, 0xde, 00397 0xdf, 0xa4, 0xf8, 0x84, 0x94, 0x08, 0xa7, 0x97, 0xf3, 0x00, 0xae, 0xf2, 0x98, 0x19, 0xa4, 0x88, 00398 0xc6, 0xa3, 0x94, 0x88, 0xf6, 0x32, 0xdf, 0xf2, 0x83, 0x93, 0xdb, 0x09, 0xd9, 0xf2, 0xaa, 0xdf, 00399 0xd8, 0xd8, 0xae, 0xf8, 0xf9, 0xd1, 0xda, 0xf3, 0xa4, 0xde, 0xa7, 0xf1, 0x88, 0x9b, 0x7a, 0xd8, 00400 0xf3, 0x84, 0x94, 0xae, 0x19, 0xf9, 0xda, 0xaa, 0xf1, 0xdf, 0xd8, 0xa8, 0x81, 0xc0, 0xc3, 0xc5, 00401 0xc7, 0xa3, 0x92, 0x83, 0xf6, 0x28, 0xad, 0xde, 0xd9, 0xf8, 0xd8, 0xa3, 0x50, 0xad, 0xd9, 0xf8, 00402 0xd8, 0xa3, 0x78, 0xad, 0xd9, 0xf8, 0xd8, 0xf8, 0xf9, 0xd1, 0xa1, 0xda, 0xde, 0xc3, 0xc5, 0xc7, 00403 0xd8, 0xa1, 0x81, 0x94, 0xf8, 0x18, 0xf2, 0xb0, 0x89, 0xac, 0xc3, 0xc5, 0xc7, 0xf1, 0xd8, 0xb8, 00404 /* bank # 9 */ 00405 0xb4, 0xb0, 0x97, 0x86, 0xa8, 0x31, 0x9b, 0x06, 0x99, 0x07, 0xab, 0x97, 0x28, 0x88, 0x9b, 0xf0, 00406 0x0c, 0x20, 0x14, 0x40, 0xb0, 0xb4, 0xb8, 0xf0, 0xa8, 0x8a, 0x9a, 0x28, 0x50, 0x78, 0xb7, 0x9b, 00407 0xa8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0xf1, 0xbb, 0xab, 00408 0x88, 0x00, 0x2c, 0x54, 0x7c, 0xf0, 0xb3, 0x8b, 0xb8, 0xa8, 0x04, 0x28, 0x50, 0x78, 0xf1, 0xb0, 00409 0x88, 0xb4, 0x97, 0x26, 0xa8, 0x59, 0x98, 0xbb, 0xab, 0xb3, 0x8b, 0x02, 0x26, 0x46, 0x66, 0xb0, 00410 0xb8, 0xf0, 0x8a, 0x9c, 0xa8, 0x29, 0x51, 0x79, 0x8b, 0x29, 0x51, 0x79, 0x8a, 0x24, 0x70, 0x59, 00411 0x8b, 0x20, 0x58, 0x71, 0x8a, 0x44, 0x69, 0x38, 0x8b, 0x39, 0x40, 0x68, 0x8a, 0x64, 0x48, 0x31, 00412 0x8b, 0x30, 0x49, 0x60, 0x88, 0xf1, 0xac, 0x00, 0x2c, 0x54, 0x7c, 0xf0, 0x8c, 0xa8, 0x04, 0x28, 00413 0x50, 0x78, 0xf1, 0x88, 0x97, 0x26, 0xa8, 0x59, 0x98, 0xac, 0x8c, 0x02, 0x26, 0x46, 0x66, 0xf0, 00414 0x89, 0x9c, 0xa8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0xa9, 00415 0x88, 0x09, 0x20, 0x59, 0x70, 0xab, 0x11, 0x38, 0x40, 0x69, 0xa8, 0x19, 0x31, 0x48, 0x60, 0x8c, 00416 0xa8, 0x3c, 0x41, 0x5c, 0x20, 0x7c, 0x00, 0xf1, 0x87, 0x98, 0x19, 0x86, 0xa8, 0x6e, 0x76, 0x7e, 00417 0xa9, 0x99, 0x88, 0x2d, 0x55, 0x7d, 0xd8, 0xb1, 0xb5, 0xb9, 0xa3, 0xdf, 0xdf, 0xdf, 0xae, 0xd0, 00418 0xdf, 0xaa, 0xd0, 0xde, 0xf2, 0xab, 0xf8, 0xf9, 0xd9, 0xb0, 0x87, 0xc4, 0xaa, 0xf1, 0xdf, 0xdf, 00419 0xbb, 0xaf, 0xdf, 0xdf, 0xb9, 0xd8, 0xb1, 0xf1, 0xa3, 0x97, 0x8e, 0x60, 0xdf, 0xb0, 0x84, 0xf2, 00420 0xc8, 0xf8, 0xf9, 0xd9, 0xde, 0xd8, 0x93, 0x85, 0xf1, 0x4a, 0xb1, 0x83, 0xa3, 0x08, 0xb5, 0x83, 00421 /* bank # 10 */ 00422 0x9a, 0x08, 0x10, 0xb7, 0x9f, 0x10, 0xd8, 0xf1, 0xb0, 0xba, 0xae, 0xb0, 0x8a, 0xc2, 0xb2, 0xb6, 00423 0x8e, 0x9e, 0xf1, 0xfb, 0xd9, 0xf4, 0x1d, 0xd8, 0xf9, 0xd9, 0x0c, 0xf1, 0xd8, 0xf8, 0xf8, 0xad, 00424 0x61, 0xd9, 0xae, 0xfb, 0xd8, 0xf4, 0x0c, 0xf1, 0xd8, 0xf8, 0xf8, 0xad, 0x19, 0xd9, 0xae, 0xfb, 00425 0xdf, 0xd8, 0xf4, 0x16, 0xf1, 0xd8, 0xf8, 0xad, 0x8d, 0x61, 0xd9, 0xf4, 0xf4, 0xac, 0xf5, 0x9c, 00426 0x9c, 0x8d, 0xdf, 0x2b, 0xba, 0xb6, 0xae, 0xfa, 0xf8, 0xf4, 0x0b, 0xd8, 0xf1, 0xae, 0xd0, 0xf8, 00427 0xad, 0x51, 0xda, 0xae, 0xfa, 0xf8, 0xf1, 0xd8, 0xb9, 0xb1, 0xb6, 0xa3, 0x83, 0x9c, 0x08, 0xb9, 00428 0xb1, 0x83, 0x9a, 0xb5, 0xaa, 0xc0, 0xfd, 0x30, 0x83, 0xb7, 0x9f, 0x10, 0xb5, 0x8b, 0x93, 0xf2, 00429 0x02, 0x02, 0xd1, 0xab, 0xda, 0xde, 0xd8, 0xf1, 0xb0, 0x80, 0xba, 0xab, 0xc0, 0xc3, 0xb2, 0x84, 00430 0xc1, 0xc3, 0xd8, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0x09, 0xb4, 0xd9, 0xab, 0xde, 0xb0, 00431 0x87, 0x9c, 0xb9, 0xa3, 0xdd, 0xf1, 0xb3, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0xb0, 0x87, 0xa3, 0xa3, 00432 0xa3, 0xa3, 0xb2, 0x8b, 0xb6, 0x9b, 0xf2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 00433 0xa3, 0xf1, 0xb0, 0x87, 0xb5, 0x9a, 0xa3, 0xf3, 0x9b, 0xa3, 0xa3, 0xdc, 0xba, 0xac, 0xdf, 0xb9, 00434 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 00435 0xd8, 0xd8, 0xd8, 0xbb, 0xb3, 0xb7, 0xf1, 0xaa, 0xf9, 0xda, 0xff, 0xd9, 0x80, 0x9a, 0xaa, 0x28, 00436 0xb4, 0x80, 0x98, 0xa7, 0x20, 0xb7, 0x97, 0x87, 0xa8, 0x66, 0x88, 0xf0, 0x79, 0x51, 0xf1, 0x90, 00437 0x2c, 0x87, 0x0c, 0xa7, 0x81, 0x97, 0x62, 0x93, 0xf0, 0x71, 0x71, 0x60, 0x85, 0x94, 0x01, 0x29, 00438 /* bank # 11 */ 00439 0x51, 0x79, 0x90, 0xa5, 0xf1, 0x28, 0x4c, 0x6c, 0x87, 0x0c, 0x95, 0x18, 0x85, 0x78, 0xa3, 0x83, 00440 0x90, 0x28, 0x4c, 0x6c, 0x88, 0x6c, 0xd8, 0xf3, 0xa2, 0x82, 0x00, 0xf2, 0x10, 0xa8, 0x92, 0x19, 00441 0x80, 0xa2, 0xf2, 0xd9, 0x26, 0xd8, 0xf1, 0x88, 0xa8, 0x4d, 0xd9, 0x48, 0xd8, 0x96, 0xa8, 0x39, 00442 0x80, 0xd9, 0x3c, 0xd8, 0x95, 0x80, 0xa8, 0x39, 0xa6, 0x86, 0x98, 0xd9, 0x2c, 0xda, 0x87, 0xa7, 00443 0x2c, 0xd8, 0xa8, 0x89, 0x95, 0x19, 0xa9, 0x80, 0xd9, 0x38, 0xd8, 0xa8, 0x89, 0x39, 0xa9, 0x80, 00444 0xda, 0x3c, 0xd8, 0xa8, 0x2e, 0xa8, 0x39, 0x90, 0xd9, 0x0c, 0xd8, 0xa8, 0x95, 0x31, 0x98, 0xd9, 00445 0x0c, 0xd8, 0xa8, 0x09, 0xd9, 0xff, 0xd8, 0x01, 0xda, 0xff, 0xd8, 0x95, 0x39, 0xa9, 0xda, 0x26, 00446 0xff, 0xd8, 0x90, 0xa8, 0x0d, 0x89, 0x99, 0xa8, 0x10, 0x80, 0x98, 0x21, 0xda, 0x2e, 0xd8, 0x89, 00447 0x99, 0xa8, 0x31, 0x80, 0xda, 0x2e, 0xd8, 0xa8, 0x86, 0x96, 0x31, 0x80, 0xda, 0x2e, 0xd8, 0xa8, 00448 0x87, 0x31, 0x80, 0xda, 0x2e, 0xd8, 0xa8, 0x82, 0x92, 0xf3, 0x41, 0x80, 0xf1, 0xd9, 0x2e, 0xd8, 00449 0xa8, 0x82, 0xf3, 0x19, 0x80, 0xf1, 0xd9, 0x2e, 0xd8, 0x82, 0xac, 0xf3, 0xc0, 0xa2, 0x80, 0x22, 00450 0xf1, 0xa6, 0x2e, 0xa7, 0x2e, 0xa9, 0x22, 0x98, 0xa8, 0x29, 0xda, 0xac, 0xde, 0xff, 0xd8, 0xa2, 00451 0xf2, 0x2a, 0xf1, 0xa9, 0x2e, 0x82, 0x92, 0xa8, 0xf2, 0x31, 0x80, 0xa6, 0x96, 0xf1, 0xd9, 0x00, 00452 0xac, 0x8c, 0x9c, 0x0c, 0x30, 0xac, 0xde, 0xd0, 0xde, 0xff, 0xd8, 0x8c, 0x9c, 0xac, 0xd0, 0x10, 00453 0xac, 0xde, 0x80, 0x92, 0xa2, 0xf2, 0x4c, 0x82, 0xa8, 0xf1, 0xca, 0xf2, 0x35, 0xf1, 0x96, 0x88, 00454 0xa6, 0xd9, 0x00, 0xd8, 0xf1, 0xff 00455 }; 00456 00457 static const unsigned short sStartAddress = 0x0400; 00458 00459 /* END OF SECTION COPIED FROM dmpDefaultMPU6050.c */ 00460 00461 #define INT_SRC_TAP (0x01) 00462 #define INT_SRC_ANDROID_ORIENT (0x08) 00463 00464 #define DMP_FEATURE_SEND_ANY_GYRO (DMP_FEATURE_SEND_RAW_GYRO | \ 00465 DMP_FEATURE_SEND_CAL_GYRO) 00466 00467 #define MAX_PACKET_LENGTH (32) 00468 00469 #define DMP_SAMPLE_RATE (200) 00470 #define GYRO_SF (46850825LL * 200 / DMP_SAMPLE_RATE) 00471 00472 #define FIFO_CORRUPTION_CHECK 00473 #ifdef FIFO_CORRUPTION_CHECK 00474 #define QUAT_ERROR_THRESH (1L<<24) 00475 #define QUAT_MAG_SQ_NORMALIZED (1L<<28) 00476 #define QUAT_MAG_SQ_MIN (QUAT_MAG_SQ_NORMALIZED - QUAT_ERROR_THRESH) 00477 #define QUAT_MAG_SQ_MAX (QUAT_MAG_SQ_NORMALIZED + QUAT_ERROR_THRESH) 00478 #endif 00479 00480 struct dmp_s { 00481 void (*tap_cb)(unsigned char count, unsigned char direction); 00482 void (*android_orient_cb)(unsigned char orientation); 00483 unsigned short orient; 00484 unsigned short feature_mask; 00485 unsigned short fifo_rate; 00486 unsigned char packet_length; 00487 }; 00488 00489 static struct dmp_s dmp = { 00490 .tap_cb = NULL, 00491 .android_orient_cb = NULL, 00492 .orient = 0, 00493 .feature_mask = 0, 00494 .fifo_rate = 0, 00495 .packet_length = 0 00496 }; 00497 00498 /** 00499 * @brief Load the DMP with this image. 00500 * @return 0 if successful. 00501 */ 00502 int dmp_load_motion_driver_firmware(void) 00503 { 00504 return mpu_load_firmware(DMP_CODE_SIZE, dmp_memory, sStartAddress, 00505 DMP_SAMPLE_RATE); 00506 } 00507 00508 /** 00509 * @brief Push gyro and accel orientation to the DMP. 00510 * The orientation is represented here as the output of 00511 * @e inv_orientation_matrix_to_scalar. 00512 * @param[in] orient Gyro and accel orientation in body frame. 00513 * @return 0 if successful. 00514 */ 00515 int dmp_set_orientation(unsigned short orient) 00516 { 00517 unsigned char gyro_regs[3], accel_regs[3]; 00518 const unsigned char gyro_axes[3] = {DINA4C, DINACD, DINA6C}; 00519 const unsigned char accel_axes[3] = {DINA0C, DINAC9, DINA2C}; 00520 const unsigned char gyro_sign[3] = {DINA36, DINA56, DINA76}; 00521 const unsigned char accel_sign[3] = {DINA26, DINA46, DINA66}; 00522 00523 gyro_regs[0] = gyro_axes[orient & 3]; 00524 gyro_regs[1] = gyro_axes[(orient >> 3) & 3]; 00525 gyro_regs[2] = gyro_axes[(orient >> 6) & 3]; 00526 accel_regs[0] = accel_axes[orient & 3]; 00527 accel_regs[1] = accel_axes[(orient >> 3) & 3]; 00528 accel_regs[2] = accel_axes[(orient >> 6) & 3]; 00529 00530 /* Chip-to-body, axes only. */ 00531 if (mpu_write_mem(FCFG_1, 3, gyro_regs)) 00532 return -1; 00533 if (mpu_write_mem(FCFG_2, 3, accel_regs)) 00534 return -1; 00535 00536 memcpy(gyro_regs, gyro_sign, 3); 00537 memcpy(accel_regs, accel_sign, 3); 00538 if (orient & 4) { 00539 gyro_regs[0] |= 1; 00540 accel_regs[0] |= 1; 00541 } 00542 if (orient & 0x20) { 00543 gyro_regs[1] |= 1; 00544 accel_regs[1] |= 1; 00545 } 00546 if (orient & 0x100) { 00547 gyro_regs[2] |= 1; 00548 accel_regs[2] |= 1; 00549 } 00550 00551 /* Chip-to-body, sign only. */ 00552 if (mpu_write_mem(FCFG_3, 3, gyro_regs)) 00553 return -1; 00554 if (mpu_write_mem(FCFG_7, 3, accel_regs)) 00555 return -1; 00556 dmp.orient = orient; 00557 return 0; 00558 } 00559 00560 /** 00561 * @brief Push gyro biases to the DMP. 00562 * Because the gyro integration is handled in the DMP, any gyro biases 00563 * calculated by the MPL should be pushed down to DMP memory to remove 00564 * 3-axis quaternion drift. 00565 * \n NOTE: If the DMP-based gyro calibration is enabled, the DMP will 00566 * overwrite the biases written to this location once a new one is computed. 00567 * @param[in] bias Gyro biases in q16. 00568 * @return 0 if successful. 00569 */ 00570 int dmp_set_gyro_bias(long *bias) 00571 { 00572 long gyro_bias_body[3]; 00573 unsigned char regs[4]; 00574 00575 gyro_bias_body[0] = bias[dmp.orient & 3]; 00576 if (dmp.orient & 4) 00577 gyro_bias_body[0] *= -1; 00578 gyro_bias_body[1] = bias[(dmp.orient >> 3) & 3]; 00579 if (dmp.orient & 0x20) 00580 gyro_bias_body[1] *= -1; 00581 gyro_bias_body[2] = bias[(dmp.orient >> 6) & 3]; 00582 if (dmp.orient & 0x100) 00583 gyro_bias_body[2] *= -1; 00584 00585 #ifdef EMPL_NO_64BIT 00586 gyro_bias_body[0] = (long)(((float)gyro_bias_body[0] * GYRO_SF) / 1073741824.f); 00587 gyro_bias_body[1] = (long)(((float)gyro_bias_body[1] * GYRO_SF) / 1073741824.f); 00588 gyro_bias_body[2] = (long)(((float)gyro_bias_body[2] * GYRO_SF) / 1073741824.f); 00589 #else 00590 gyro_bias_body[0] = (long)(((long long)gyro_bias_body[0] * GYRO_SF) >> 30); 00591 gyro_bias_body[1] = (long)(((long long)gyro_bias_body[1] * GYRO_SF) >> 30); 00592 gyro_bias_body[2] = (long)(((long long)gyro_bias_body[2] * GYRO_SF) >> 30); 00593 #endif 00594 00595 regs[0] = (unsigned char)((gyro_bias_body[0] >> 24) & 0xFF); 00596 regs[1] = (unsigned char)((gyro_bias_body[0] >> 16) & 0xFF); 00597 regs[2] = (unsigned char)((gyro_bias_body[0] >> 8) & 0xFF); 00598 regs[3] = (unsigned char)(gyro_bias_body[0] & 0xFF); 00599 if (mpu_write_mem(D_EXT_GYRO_BIAS_X, 4, regs)) 00600 return -1; 00601 00602 regs[0] = (unsigned char)((gyro_bias_body[1] >> 24) & 0xFF); 00603 regs[1] = (unsigned char)((gyro_bias_body[1] >> 16) & 0xFF); 00604 regs[2] = (unsigned char)((gyro_bias_body[1] >> 8) & 0xFF); 00605 regs[3] = (unsigned char)(gyro_bias_body[1] & 0xFF); 00606 if (mpu_write_mem(D_EXT_GYRO_BIAS_Y, 4, regs)) 00607 return -1; 00608 00609 regs[0] = (unsigned char)((gyro_bias_body[2] >> 24) & 0xFF); 00610 regs[1] = (unsigned char)((gyro_bias_body[2] >> 16) & 0xFF); 00611 regs[2] = (unsigned char)((gyro_bias_body[2] >> 8) & 0xFF); 00612 regs[3] = (unsigned char)(gyro_bias_body[2] & 0xFF); 00613 return mpu_write_mem(D_EXT_GYRO_BIAS_Z, 4, regs); 00614 } 00615 00616 /** 00617 * @brief Push accel biases to the DMP. 00618 * These biases will be removed from the DMP 6-axis quaternion. 00619 * @param[in] bias Accel biases in q16. 00620 * @return 0 if successful. 00621 */ 00622 int dmp_set_accel_bias(long *bias) 00623 { 00624 long accel_bias_body[3]; 00625 unsigned char regs[12]; 00626 long long accel_sf; 00627 unsigned short accel_sens; 00628 00629 mpu_get_accel_sens(&accel_sens); 00630 accel_sf = (long long)accel_sens << 15; 00631 __no_operation(); 00632 00633 accel_bias_body[0] = bias[dmp.orient & 3]; 00634 if (dmp.orient & 4) 00635 accel_bias_body[0] *= -1; 00636 accel_bias_body[1] = bias[(dmp.orient >> 3) & 3]; 00637 if (dmp.orient & 0x20) 00638 accel_bias_body[1] *= -1; 00639 accel_bias_body[2] = bias[(dmp.orient >> 6) & 3]; 00640 if (dmp.orient & 0x100) 00641 accel_bias_body[2] *= -1; 00642 00643 #ifdef EMPL_NO_64BIT 00644 accel_bias_body[0] = (long)(((float)accel_bias_body[0] * accel_sf) / 1073741824.f); 00645 accel_bias_body[1] = (long)(((float)accel_bias_body[1] * accel_sf) / 1073741824.f); 00646 accel_bias_body[2] = (long)(((float)accel_bias_body[2] * accel_sf) / 1073741824.f); 00647 #else 00648 accel_bias_body[0] = (long)(((long long)accel_bias_body[0] * accel_sf) >> 30); 00649 accel_bias_body[1] = (long)(((long long)accel_bias_body[1] * accel_sf) >> 30); 00650 accel_bias_body[2] = (long)(((long long)accel_bias_body[2] * accel_sf) >> 30); 00651 #endif 00652 00653 regs[0] = (unsigned char)((accel_bias_body[0] >> 24) & 0xFF); 00654 regs[1] = (unsigned char)((accel_bias_body[0] >> 16) & 0xFF); 00655 regs[2] = (unsigned char)((accel_bias_body[0] >> 8) & 0xFF); 00656 regs[3] = (unsigned char)(accel_bias_body[0] & 0xFF); 00657 regs[4] = (unsigned char)((accel_bias_body[1] >> 24) & 0xFF); 00658 regs[5] = (unsigned char)((accel_bias_body[1] >> 16) & 0xFF); 00659 regs[6] = (unsigned char)((accel_bias_body[1] >> 8) & 0xFF); 00660 regs[7] = (unsigned char)(accel_bias_body[1] & 0xFF); 00661 regs[8] = (unsigned char)((accel_bias_body[2] >> 24) & 0xFF); 00662 regs[9] = (unsigned char)((accel_bias_body[2] >> 16) & 0xFF); 00663 regs[10] = (unsigned char)((accel_bias_body[2] >> 8) & 0xFF); 00664 regs[11] = (unsigned char)(accel_bias_body[2] & 0xFF); 00665 return mpu_write_mem(D_ACCEL_BIAS, 12, regs); 00666 } 00667 00668 /** 00669 * @brief Set DMP output rate. 00670 * Only used when DMP is on. 00671 * @param[in] rate Desired fifo rate (Hz). 00672 * @return 0 if successful. 00673 */ 00674 int dmp_set_fifo_rate(unsigned short rate) 00675 { 00676 const unsigned char regs_end[12] = {DINAFE, DINAF2, DINAAB, 00677 0xc4, DINAAA, DINAF1, DINADF, DINADF, 0xBB, 0xAF, DINADF, DINADF}; 00678 unsigned short div; 00679 unsigned char tmp[8]; 00680 00681 if (rate > DMP_SAMPLE_RATE) 00682 return -1; 00683 div = DMP_SAMPLE_RATE / rate - 1; 00684 tmp[0] = (unsigned char)((div >> 8) & 0xFF); 00685 tmp[1] = (unsigned char)(div & 0xFF); 00686 if (mpu_write_mem(D_0_22, 2, tmp)) 00687 return -1; 00688 if (mpu_write_mem(CFG_6, 12, (unsigned char*)regs_end)) 00689 return -1; 00690 00691 dmp.fifo_rate = rate; 00692 return 0; 00693 } 00694 00695 /** 00696 * @brief Get DMP output rate. 00697 * @param[out] rate Current fifo rate (Hz). 00698 * @return 0 if successful. 00699 */ 00700 int dmp_get_fifo_rate(unsigned short *rate) 00701 { 00702 rate[0] = dmp.fifo_rate; 00703 return 0; 00704 } 00705 00706 /** 00707 * @brief Set tap threshold for a specific axis. 00708 * @param[in] axis 1, 2, and 4 for XYZ accel, respectively. 00709 * @param[in] thresh Tap threshold, in mg/ms. 00710 * @return 0 if successful. 00711 */ 00712 int dmp_set_tap_thresh(unsigned char axis, unsigned short thresh) 00713 { 00714 unsigned char tmp[4], accel_fsr; 00715 float scaled_thresh; 00716 unsigned short dmp_thresh, dmp_thresh_2; 00717 if (!(axis & TAP_XYZ) || thresh > 1600) 00718 return -1; 00719 00720 scaled_thresh = (float)thresh / DMP_SAMPLE_RATE; 00721 00722 mpu_get_accel_fsr(&accel_fsr); 00723 switch (accel_fsr) { 00724 case 2: 00725 dmp_thresh = (unsigned short)(scaled_thresh * 16384); 00726 /* dmp_thresh * 0.75 */ 00727 dmp_thresh_2 = (unsigned short)(scaled_thresh * 12288); 00728 break; 00729 case 4: 00730 dmp_thresh = (unsigned short)(scaled_thresh * 8192); 00731 /* dmp_thresh * 0.75 */ 00732 dmp_thresh_2 = (unsigned short)(scaled_thresh * 6144); 00733 break; 00734 case 8: 00735 dmp_thresh = (unsigned short)(scaled_thresh * 4096); 00736 /* dmp_thresh * 0.75 */ 00737 dmp_thresh_2 = (unsigned short)(scaled_thresh * 3072); 00738 break; 00739 case 16: 00740 dmp_thresh = (unsigned short)(scaled_thresh * 2048); 00741 /* dmp_thresh * 0.75 */ 00742 dmp_thresh_2 = (unsigned short)(scaled_thresh * 1536); 00743 break; 00744 default: 00745 return -1; 00746 } 00747 tmp[0] = (unsigned char)(dmp_thresh >> 8); 00748 tmp[1] = (unsigned char)(dmp_thresh & 0xFF); 00749 tmp[2] = (unsigned char)(dmp_thresh_2 >> 8); 00750 tmp[3] = (unsigned char)(dmp_thresh_2 & 0xFF); 00751 00752 if (axis & TAP_X) { 00753 if (mpu_write_mem(DMP_TAP_THX, 2, tmp)) 00754 return -1; 00755 if (mpu_write_mem(D_1_36, 2, tmp+2)) 00756 return -1; 00757 } 00758 if (axis & TAP_Y) { 00759 if (mpu_write_mem(DMP_TAP_THY, 2, tmp)) 00760 return -1; 00761 if (mpu_write_mem(D_1_40, 2, tmp+2)) 00762 return -1; 00763 } 00764 if (axis & TAP_Z) { 00765 if (mpu_write_mem(DMP_TAP_THZ, 2, tmp)) 00766 return -1; 00767 if (mpu_write_mem(D_1_44, 2, tmp+2)) 00768 return -1; 00769 } 00770 return 0; 00771 } 00772 00773 /** 00774 * @brief Set which axes will register a tap. 00775 * @param[in] axis 1, 2, and 4 for XYZ, respectively. 00776 * @return 0 if successful. 00777 */ 00778 int dmp_set_tap_axes(unsigned char axis) 00779 { 00780 unsigned char tmp = 0; 00781 00782 if (axis & TAP_X) 00783 tmp |= 0x30; 00784 if (axis & TAP_Y) 00785 tmp |= 0x0C; 00786 if (axis & TAP_Z) 00787 tmp |= 0x03; 00788 return mpu_write_mem(D_1_72, 1, &tmp); 00789 } 00790 00791 /** 00792 * @brief Set minimum number of taps needed for an interrupt. 00793 * @param[in] min_taps Minimum consecutive taps (1-4). 00794 * @return 0 if successful. 00795 */ 00796 int dmp_set_tap_count(unsigned char min_taps) 00797 { 00798 unsigned char tmp; 00799 00800 if (min_taps < 1) 00801 min_taps = 1; 00802 else if (min_taps > 4) 00803 min_taps = 4; 00804 00805 tmp = min_taps - 1; 00806 return mpu_write_mem(D_1_79, 1, &tmp); 00807 } 00808 00809 /** 00810 * @brief Set length between valid taps. 00811 * @param[in] time Milliseconds between taps. 00812 * @return 0 if successful. 00813 */ 00814 int dmp_set_tap_time(unsigned short time) 00815 { 00816 unsigned short dmp_time; 00817 unsigned char tmp[2]; 00818 00819 dmp_time = time / (1000 / DMP_SAMPLE_RATE); 00820 tmp[0] = (unsigned char)(dmp_time >> 8); 00821 tmp[1] = (unsigned char)(dmp_time & 0xFF); 00822 return mpu_write_mem(DMP_TAPW_MIN, 2, tmp); 00823 } 00824 00825 /** 00826 * @brief Set max time between taps to register as a multi-tap. 00827 * @param[in] time Max milliseconds between taps. 00828 * @return 0 if successful. 00829 */ 00830 int dmp_set_tap_time_multi(unsigned short time) 00831 { 00832 unsigned short dmp_time; 00833 unsigned char tmp[2]; 00834 00835 dmp_time = time / (1000 / DMP_SAMPLE_RATE); 00836 tmp[0] = (unsigned char)(dmp_time >> 8); 00837 tmp[1] = (unsigned char)(dmp_time & 0xFF); 00838 return mpu_write_mem(D_1_218, 2, tmp); 00839 } 00840 00841 /** 00842 * @brief Set shake rejection threshold. 00843 * If the DMP detects a gyro sample larger than @e thresh, taps are rejected. 00844 * @param[in] sf Gyro scale factor. 00845 * @param[in] thresh Gyro threshold in dps. 00846 * @return 0 if successful. 00847 */ 00848 int dmp_set_shake_reject_thresh(long sf, unsigned short thresh) 00849 { 00850 unsigned char tmp[4]; 00851 long thresh_scaled = sf / 1000 * thresh; 00852 tmp[0] = (unsigned char)(((long)thresh_scaled >> 24) & 0xFF); 00853 tmp[1] = (unsigned char)(((long)thresh_scaled >> 16) & 0xFF); 00854 tmp[2] = (unsigned char)(((long)thresh_scaled >> 8) & 0xFF); 00855 tmp[3] = (unsigned char)((long)thresh_scaled & 0xFF); 00856 return mpu_write_mem(D_1_92, 4, tmp); 00857 } 00858 00859 /** 00860 * @brief Set shake rejection time. 00861 * Sets the length of time that the gyro must be outside of the threshold set 00862 * by @e gyro_set_shake_reject_thresh before taps are rejected. A mandatory 00863 * 60 ms is added to this parameter. 00864 * @param[in] time Time in milliseconds. 00865 * @return 0 if successful. 00866 */ 00867 int dmp_set_shake_reject_time(unsigned short time) 00868 { 00869 unsigned char tmp[2]; 00870 00871 time /= (1000 / DMP_SAMPLE_RATE); 00872 tmp[0] = time >> 8; 00873 tmp[1] = time & 0xFF; 00874 return mpu_write_mem(D_1_90,2,tmp); 00875 } 00876 00877 /** 00878 * @brief Set shake rejection timeout. 00879 * Sets the length of time after a shake rejection that the gyro must stay 00880 * inside of the threshold before taps can be detected again. A mandatory 00881 * 60 ms is added to this parameter. 00882 * @param[in] time Time in milliseconds. 00883 * @return 0 if successful. 00884 */ 00885 int dmp_set_shake_reject_timeout(unsigned short time) 00886 { 00887 unsigned char tmp[2]; 00888 00889 time /= (1000 / DMP_SAMPLE_RATE); 00890 tmp[0] = time >> 8; 00891 tmp[1] = time & 0xFF; 00892 return mpu_write_mem(D_1_88,2,tmp); 00893 } 00894 00895 /** 00896 * @brief Get current step count. 00897 * @param[out] count Number of steps detected. 00898 * @return 0 if successful. 00899 */ 00900 int dmp_get_pedometer_step_count(unsigned long *count) 00901 { 00902 unsigned char tmp[4]; 00903 if (!count) 00904 return -1; 00905 00906 if (mpu_read_mem(D_PEDSTD_STEPCTR, 4, tmp)) 00907 return -1; 00908 00909 count[0] = ((unsigned long)tmp[0] << 24) | ((unsigned long)tmp[1] << 16) | 00910 ((unsigned long)tmp[2] << 8) | tmp[3]; 00911 return 0; 00912 } 00913 00914 /** 00915 * @brief Overwrite current step count. 00916 * WARNING: This function writes to DMP memory and could potentially encounter 00917 * a race condition if called while the pedometer is enabled. 00918 * @param[in] count New step count. 00919 * @return 0 if successful. 00920 */ 00921 int dmp_set_pedometer_step_count(unsigned long count) 00922 { 00923 unsigned char tmp[4]; 00924 00925 tmp[0] = (unsigned char)((count >> 24) & 0xFF); 00926 tmp[1] = (unsigned char)((count >> 16) & 0xFF); 00927 tmp[2] = (unsigned char)((count >> 8) & 0xFF); 00928 tmp[3] = (unsigned char)(count & 0xFF); 00929 return mpu_write_mem(D_PEDSTD_STEPCTR, 4, tmp); 00930 } 00931 00932 /** 00933 * @brief Get duration of walking time. 00934 * @param[in] time Walk time in milliseconds. 00935 * @return 0 if successful. 00936 */ 00937 int dmp_get_pedometer_walk_time(unsigned long *time) 00938 { 00939 unsigned char tmp[4]; 00940 if (!time) 00941 return -1; 00942 00943 if (mpu_read_mem(D_PEDSTD_TIMECTR, 4, tmp)) 00944 return -1; 00945 00946 time[0] = (((unsigned long)tmp[0] << 24) | ((unsigned long)tmp[1] << 16) | 00947 ((unsigned long)tmp[2] << 8) | tmp[3]) * 20; 00948 return 0; 00949 } 00950 00951 /** 00952 * @brief Overwrite current walk time. 00953 * WARNING: This function writes to DMP memory and could potentially encounter 00954 * a race condition if called while the pedometer is enabled. 00955 * @param[in] time New walk time in milliseconds. 00956 */ 00957 int dmp_set_pedometer_walk_time(unsigned long time) 00958 { 00959 unsigned char tmp[4]; 00960 00961 time /= 20; 00962 00963 tmp[0] = (unsigned char)((time >> 24) & 0xFF); 00964 tmp[1] = (unsigned char)((time >> 16) & 0xFF); 00965 tmp[2] = (unsigned char)((time >> 8) & 0xFF); 00966 tmp[3] = (unsigned char)(time & 0xFF); 00967 return mpu_write_mem(D_PEDSTD_TIMECTR, 4, tmp); 00968 } 00969 00970 /** 00971 * @brief Enable DMP features. 00972 * The following \#define's are used in the input mask: 00973 * \n DMP_FEATURE_TAP 00974 * \n DMP_FEATURE_ANDROID_ORIENT 00975 * \n DMP_FEATURE_LP_QUAT 00976 * \n DMP_FEATURE_6X_LP_QUAT 00977 * \n DMP_FEATURE_GYRO_CAL 00978 * \n DMP_FEATURE_SEND_RAW_ACCEL 00979 * \n DMP_FEATURE_SEND_RAW_GYRO 00980 * \n NOTE: DMP_FEATURE_LP_QUAT and DMP_FEATURE_6X_LP_QUAT are mutually 00981 * exclusive. 00982 * \n NOTE: DMP_FEATURE_SEND_RAW_GYRO and DMP_FEATURE_SEND_CAL_GYRO are also 00983 * mutually exclusive. 00984 * @param[in] mask Mask of features to enable. 00985 * @return 0 if successful. 00986 */ 00987 int dmp_enable_feature(unsigned short mask) 00988 { 00989 unsigned char tmp[10]; 00990 00991 /* TODO: All of these settings can probably be integrated into the default 00992 * DMP image. 00993 */ 00994 /* Set integration scale factor. */ 00995 tmp[0] = (unsigned char)((GYRO_SF >> 24) & 0xFF); 00996 tmp[1] = (unsigned char)((GYRO_SF >> 16) & 0xFF); 00997 tmp[2] = (unsigned char)((GYRO_SF >> 8) & 0xFF); 00998 tmp[3] = (unsigned char)(GYRO_SF & 0xFF); 00999 mpu_write_mem(D_0_104, 4, tmp); 01000 01001 /* Send sensor data to the FIFO. */ 01002 tmp[0] = 0xA3; 01003 if (mask & DMP_FEATURE_SEND_RAW_ACCEL) { 01004 tmp[1] = 0xC0; 01005 tmp[2] = 0xC8; 01006 tmp[3] = 0xC2; 01007 } else { 01008 tmp[1] = 0xA3; 01009 tmp[2] = 0xA3; 01010 tmp[3] = 0xA3; 01011 } 01012 if (mask & DMP_FEATURE_SEND_ANY_GYRO) { 01013 tmp[4] = 0xC4; 01014 tmp[5] = 0xCC; 01015 tmp[6] = 0xC6; 01016 } else { 01017 tmp[4] = 0xA3; 01018 tmp[5] = 0xA3; 01019 tmp[6] = 0xA3; 01020 } 01021 tmp[7] = 0xA3; 01022 tmp[8] = 0xA3; 01023 tmp[9] = 0xA3; 01024 mpu_write_mem(CFG_15,10,tmp); 01025 01026 /* Send gesture data to the FIFO. */ 01027 if (mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT)) 01028 tmp[0] = DINA20; 01029 else 01030 tmp[0] = 0xD8; 01031 mpu_write_mem(CFG_27,1,tmp); 01032 01033 if (mask & DMP_FEATURE_GYRO_CAL) 01034 dmp_enable_gyro_cal(1); 01035 else 01036 dmp_enable_gyro_cal(0); 01037 01038 if (mask & DMP_FEATURE_SEND_ANY_GYRO) { 01039 if (mask & DMP_FEATURE_SEND_CAL_GYRO) { 01040 tmp[0] = 0xB2; 01041 tmp[1] = 0x8B; 01042 tmp[2] = 0xB6; 01043 tmp[3] = 0x9B; 01044 } else { 01045 tmp[0] = DINAC0; 01046 tmp[1] = DINA80; 01047 tmp[2] = DINAC2; 01048 tmp[3] = DINA90; 01049 } 01050 mpu_write_mem(CFG_GYRO_RAW_DATA, 4, tmp); 01051 } 01052 01053 if (mask & DMP_FEATURE_TAP) { 01054 /* Enable tap. */ 01055 tmp[0] = 0xF8; 01056 mpu_write_mem(CFG_20, 1, tmp); 01057 dmp_set_tap_thresh(TAP_XYZ, 250); 01058 dmp_set_tap_axes(TAP_XYZ); 01059 dmp_set_tap_count(1); 01060 dmp_set_tap_time(100); 01061 dmp_set_tap_time_multi(500); 01062 01063 dmp_set_shake_reject_thresh(GYRO_SF, 200); 01064 dmp_set_shake_reject_time(40); 01065 dmp_set_shake_reject_timeout(10); 01066 } else { 01067 tmp[0] = 0xD8; 01068 mpu_write_mem(CFG_20, 1, tmp); 01069 } 01070 01071 if (mask & DMP_FEATURE_ANDROID_ORIENT) { 01072 tmp[0] = 0xD9; 01073 } else 01074 tmp[0] = 0xD8; 01075 mpu_write_mem(CFG_ANDROID_ORIENT_INT, 1, tmp); 01076 01077 if (mask & DMP_FEATURE_LP_QUAT) 01078 dmp_enable_lp_quat(1); 01079 else 01080 dmp_enable_lp_quat(0); 01081 01082 if (mask & DMP_FEATURE_6X_LP_QUAT) 01083 dmp_enable_6x_lp_quat(1); 01084 else 01085 dmp_enable_6x_lp_quat(0); 01086 01087 /* Pedometer is always enabled. */ 01088 dmp.feature_mask = mask | DMP_FEATURE_PEDOMETER; 01089 mpu_reset_fifo(); 01090 01091 dmp.packet_length = 0; 01092 if (mask & DMP_FEATURE_SEND_RAW_ACCEL) 01093 dmp.packet_length += 6; 01094 if (mask & DMP_FEATURE_SEND_ANY_GYRO) 01095 dmp.packet_length += 6; 01096 if (mask & (DMP_FEATURE_LP_QUAT | DMP_FEATURE_6X_LP_QUAT)) 01097 dmp.packet_length += 16; 01098 if (mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT)) 01099 dmp.packet_length += 4; 01100 01101 return 0; 01102 } 01103 01104 /** 01105 * @brief Get list of currently enabled DMP features. 01106 * @param[out] Mask of enabled features. 01107 * @return 0 if successful. 01108 */ 01109 int dmp_get_enabled_features(unsigned short *mask) 01110 { 01111 mask[0] = dmp.feature_mask; 01112 return 0; 01113 } 01114 01115 /** 01116 * @brief Calibrate the gyro data in the DMP. 01117 * After eight seconds of no motion, the DMP will compute gyro biases and 01118 * subtract them from the quaternion output. If @e dmp_enable_feature is 01119 * called with @e DMP_FEATURE_SEND_CAL_GYRO, the biases will also be 01120 * subtracted from the gyro output. 01121 * @param[in] enable 1 to enable gyro calibration. 01122 * @return 0 if successful. 01123 */ 01124 int dmp_enable_gyro_cal(unsigned char enable) 01125 { 01126 if (enable) { 01127 unsigned char regs[9] = {0xb8, 0xaa, 0xb3, 0x8d, 0xb4, 0x98, 0x0d, 0x35, 0x5d}; 01128 return mpu_write_mem(CFG_MOTION_BIAS, 9, regs); 01129 } else { 01130 unsigned char regs[9] = {0xb8, 0xaa, 0xaa, 0xaa, 0xb0, 0x88, 0xc3, 0xc5, 0xc7}; 01131 return mpu_write_mem(CFG_MOTION_BIAS, 9, regs); 01132 } 01133 } 01134 01135 /** 01136 * @brief Generate 3-axis quaternions from the DMP. 01137 * In this driver, the 3-axis and 6-axis DMP quaternion features are mutually 01138 * exclusive. 01139 * @param[in] enable 1 to enable 3-axis quaternion. 01140 * @return 0 if successful. 01141 */ 01142 int dmp_enable_lp_quat(unsigned char enable) 01143 { 01144 unsigned char regs[4]; 01145 if (enable) { 01146 regs[0] = DINBC0; 01147 regs[1] = DINBC2; 01148 regs[2] = DINBC4; 01149 regs[3] = DINBC6; 01150 } 01151 else 01152 memset(regs, 0x8B, 4); 01153 01154 mpu_write_mem(CFG_LP_QUAT, 4, regs); 01155 01156 return mpu_reset_fifo(); 01157 } 01158 01159 /** 01160 * @brief Generate 6-axis quaternions from the DMP. 01161 * In this driver, the 3-axis and 6-axis DMP quaternion features are mutually 01162 * exclusive. 01163 * @param[in] enable 1 to enable 6-axis quaternion. 01164 * @return 0 if successful. 01165 */ 01166 int dmp_enable_6x_lp_quat(unsigned char enable) 01167 { 01168 unsigned char regs[4]; 01169 if (enable) { 01170 regs[0] = DINA20; 01171 regs[1] = DINA28; 01172 regs[2] = DINA30; 01173 regs[3] = DINA38; 01174 } else 01175 memset(regs, 0xA3, 4); 01176 01177 mpu_write_mem(CFG_8, 4, regs); 01178 01179 return mpu_reset_fifo(); 01180 } 01181 01182 /** 01183 * @brief Decode the four-byte gesture data and execute any callbacks. 01184 * @param[in] gesture Gesture data from DMP packet. 01185 * @return 0 if successful. 01186 */ 01187 static int decode_gesture(unsigned char *gesture) 01188 { 01189 unsigned char tap, android_orient; 01190 01191 android_orient = gesture[3] & 0xC0; 01192 tap = 0x3F & gesture[3]; 01193 01194 if (gesture[1] & INT_SRC_TAP) { 01195 unsigned char direction, count; 01196 direction = tap >> 3; 01197 count = (tap % 8) + 1; 01198 if (dmp.tap_cb) 01199 dmp.tap_cb(direction, count); 01200 } 01201 01202 if (gesture[1] & INT_SRC_ANDROID_ORIENT) { 01203 if (dmp.android_orient_cb) 01204 dmp.android_orient_cb(android_orient >> 6); 01205 } 01206 01207 return 0; 01208 } 01209 01210 /** 01211 * @brief Specify when a DMP interrupt should occur. 01212 * A DMP interrupt can be configured to trigger on either of the two 01213 * conditions below: 01214 * \n a. One FIFO period has elapsed (set by @e mpu_set_sample_rate). 01215 * \n b. A tap event has been detected. 01216 * @param[in] mode DMP_INT_GESTURE or DMP_INT_CONTINUOUS. 01217 * @return 0 if successful. 01218 */ 01219 int dmp_set_interrupt_mode(unsigned char mode) 01220 { 01221 const unsigned char regs_continuous[11] = 01222 {0xd8, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0x09, 0xb4, 0xd9}; 01223 const unsigned char regs_gesture[11] = 01224 {0xda, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0xda, 0xb4, 0xda}; 01225 01226 switch (mode) { 01227 case DMP_INT_CONTINUOUS: 01228 return mpu_write_mem(CFG_FIFO_ON_EVENT, 11, 01229 (unsigned char*)regs_continuous); 01230 case DMP_INT_GESTURE: 01231 return mpu_write_mem(CFG_FIFO_ON_EVENT, 11, 01232 (unsigned char*)regs_gesture); 01233 default: 01234 return -1; 01235 } 01236 } 01237 01238 /** 01239 * @brief Get one packet from the FIFO. 01240 * If @e sensors does not contain a particular sensor, disregard the data 01241 * returned to that pointer. 01242 * \n @e sensors can contain a combination of the following flags: 01243 * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO 01244 * \n INV_XYZ_GYRO 01245 * \n INV_XYZ_ACCEL 01246 * \n INV_WXYZ_QUAT 01247 * \n If the FIFO has no new data, @e sensors will be zero. 01248 * \n If the FIFO is disabled, @e sensors will be zero and this function will 01249 * return a non-zero error code. 01250 * @param[out] gyro Gyro data in hardware units. 01251 * @param[out] accel Accel data in hardware units. 01252 * @param[out] quat 3-axis quaternion data in hardware units. 01253 * @param[out] timestamp Timestamp in milliseconds. 01254 * @param[out] sensors Mask of sensors read from FIFO. 01255 * @param[out] more Number of remaining packets. 01256 * @return 0 if successful. 01257 */ 01258 int dmp_read_fifo(short *gyro, short *accel, long *quat, 01259 unsigned long *timestamp, short *sensors, unsigned char *more) 01260 { 01261 unsigned char fifo_data[MAX_PACKET_LENGTH]; 01262 unsigned char ii = 0; 01263 01264 /* TODO: sensors[0] only changes when dmp_enable_feature is called. We can 01265 * cache this value and save some cycles. 01266 */ 01267 sensors[0] = 0; 01268 01269 /* Get a packet. */ 01270 if (mpu_read_fifo_stream(dmp.packet_length, fifo_data, more)) 01271 return -1; 01272 01273 /* Parse DMP packet. */ 01274 if (dmp.feature_mask & (DMP_FEATURE_LP_QUAT | DMP_FEATURE_6X_LP_QUAT)) { 01275 #ifdef FIFO_CORRUPTION_CHECK 01276 long quat_q14[4], quat_mag_sq; 01277 #endif 01278 quat[0] = ((long)fifo_data[0] << 24) | ((long)fifo_data[1] << 16) | 01279 ((long)fifo_data[2] << 8) | fifo_data[3]; 01280 quat[1] = ((long)fifo_data[4] << 24) | ((long)fifo_data[5] << 16) | 01281 ((long)fifo_data[6] << 8) | fifo_data[7]; 01282 quat[2] = ((long)fifo_data[8] << 24) | ((long)fifo_data[9] << 16) | 01283 ((long)fifo_data[10] << 8) | fifo_data[11]; 01284 quat[3] = ((long)fifo_data[12] << 24) | ((long)fifo_data[13] << 16) | 01285 ((long)fifo_data[14] << 8) | fifo_data[15]; 01286 ii += 16; 01287 #ifdef FIFO_CORRUPTION_CHECK 01288 /* We can detect a corrupted FIFO by monitoring the quaternion data and 01289 * ensuring that the magnitude is always normalized to one. This 01290 * shouldn't happen in normal operation, but if an I2C error occurs, 01291 * the FIFO reads might become misaligned. 01292 * 01293 * Let's start by scaling down the quaternion data to avoid long long 01294 * math. 01295 */ 01296 quat_q14[0] = quat[0] >> 16; 01297 quat_q14[1] = quat[1] >> 16; 01298 quat_q14[2] = quat[2] >> 16; 01299 quat_q14[3] = quat[3] >> 16; 01300 quat_mag_sq = quat_q14[0] * quat_q14[0] + quat_q14[1] * quat_q14[1] + 01301 quat_q14[2] * quat_q14[2] + quat_q14[3] * quat_q14[3]; 01302 if ((quat_mag_sq < QUAT_MAG_SQ_MIN) || 01303 (quat_mag_sq > QUAT_MAG_SQ_MAX)) { 01304 /* Quaternion is outside of the acceptable threshold. */ 01305 mpu_reset_fifo(); 01306 sensors[0] = 0; 01307 return -1; 01308 } 01309 sensors[0] |= INV_WXYZ_QUAT; 01310 #endif 01311 } 01312 01313 if (dmp.feature_mask & DMP_FEATURE_SEND_RAW_ACCEL) { 01314 accel[0] = ((short)fifo_data[ii+0] << 8) | fifo_data[ii+1]; 01315 accel[1] = ((short)fifo_data[ii+2] << 8) | fifo_data[ii+3]; 01316 accel[2] = ((short)fifo_data[ii+4] << 8) | fifo_data[ii+5]; 01317 ii += 6; 01318 sensors[0] |= INV_XYZ_ACCEL; 01319 } 01320 01321 if (dmp.feature_mask & DMP_FEATURE_SEND_ANY_GYRO) { 01322 gyro[0] = ((short)fifo_data[ii+0] << 8) | fifo_data[ii+1]; 01323 gyro[1] = ((short)fifo_data[ii+2] << 8) | fifo_data[ii+3]; 01324 gyro[2] = ((short)fifo_data[ii+4] << 8) | fifo_data[ii+5]; 01325 ii += 6; 01326 sensors[0] |= INV_XYZ_GYRO; 01327 } 01328 01329 /* Gesture data is at the end of the DMP packet. Parse it and call 01330 * the gesture callbacks (if registered). 01331 */ 01332 if (dmp.feature_mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT)) 01333 decode_gesture(fifo_data + ii); 01334 01335 get_ms(timestamp); 01336 return 0; 01337 } 01338 01339 /** 01340 * @brief Register a function to be executed on a tap event. 01341 * The tap direction is represented by one of the following: 01342 * \n TAP_X_UP 01343 * \n TAP_X_DOWN 01344 * \n TAP_Y_UP 01345 * \n TAP_Y_DOWN 01346 * \n TAP_Z_UP 01347 * \n TAP_Z_DOWN 01348 * @param[in] func Callback function. 01349 * @return 0 if successful. 01350 */ 01351 int dmp_register_tap_cb(void (*func)(unsigned char, unsigned char)) 01352 { 01353 dmp.tap_cb = func; 01354 return 0; 01355 } 01356 01357 /** 01358 * @brief Register a function to be executed on a android orientation event. 01359 * @param[in] func Callback function. 01360 * @return 0 if successful. 01361 */ 01362 int dmp_register_android_orient_cb(void (*func)(unsigned char)) 01363 { 01364 dmp.android_orient_cb = func; 01365 return 0; 01366 } 01367 01368 /** 01369 * @} 01370 */ 01371
Generated on Wed Jul 13 2022 20:01:33 by 1.7.2