1 /* 2 $License: 3 Copyright (C) 2012 InvenSense Corporation, All Rights Reserved. 4 $ 5 */ 6 7 /******************************************************************************* 8 * 9 * $Id:$ 10 * 11 ******************************************************************************/ 12 13 /* 14 Includes, Defines, and Macros 15 */ 16 17 #undef MPL_LOG_NDEBUG 18 #define MPL_LOG_NDEBUG 0 /* turn to 0 to enable verbose logging */ 19 20 #include "log.h" 21 #undef MPL_LOG_TAG 22 #define MPL_LOG_TAG "MPL-playback" 23 24 #include "and_constructor.h" 25 #include "mlos.h" 26 #include "invensense.h" 27 #include "invensense_adv.h" 28 29 /* 30 Typedef 31 */ 32 struct inv_construct_t { 33 int product; /**< Gyro Product Number */ 34 int debug_mode; 35 int last_mode; 36 FILE *file; 37 int dmp_version; 38 int left_in_buffer; 39 #define FIFO_READ_SIZE 100 40 unsigned char fifo_data[FIFO_READ_SIZE]; 41 int gyro_enable; 42 int accel_enable; 43 int compass_enable; 44 int quat_enable; 45 }; 46 47 /* 48 Globals 49 */ 50 static struct inv_construct_t inv_construct = {0}; 51 static void (*s_func_cb)(void); 52 static char playback_filename[101] = "/data/playback.bin"; 53 struct fifo_dmp_config fifo_dmp_cfg = {0}; 54 55 /* 56 Functions 57 */ 58 void inv_set_playback_filename(char *filename, int length) 59 { 60 if (length > 100) { 61 MPL_LOGE("Error : file name and path too long, 100 characters limit\n"); 62 return; 63 } 64 strncpy(playback_filename, filename, length); 65 } 66 67 inv_error_t inv_constructor_setup(void) 68 { 69 unsigned short orient; 70 extern signed char g_gyro_orientation[9]; 71 extern signed char g_accel_orientation[9]; 72 extern signed char g_compass_orientation[9]; 73 float scale = 2.f; 74 long sens; 75 76 // gyro setup 77 orient = inv_orientation_matrix_to_scalar(g_gyro_orientation); 78 inv_set_gyro_orientation_and_scale(orient, 2000L << 15); 79 80 // accel setup 81 orient = inv_orientation_matrix_to_scalar(g_accel_orientation); 82 scale = 2.f; 83 sens = (long)(scale * (1L << 15)); 84 inv_set_accel_orientation_and_scale(orient, sens); 85 86 // compass setup 87 orient = inv_orientation_matrix_to_scalar(g_compass_orientation); 88 // scale is the max value of the compass in micro Tesla. 89 scale = 5000.f; 90 sens = (long)(scale * (1L << 15)); 91 inv_set_compass_orientation_and_scale(orient, sens); 92 93 return INV_SUCCESS; 94 } 95 96 inv_error_t inv_set_fifo_processed_callback(void (*func_cb)(void)) 97 { 98 s_func_cb = func_cb; 99 return INV_SUCCESS; 100 } 101 102 void int32_to_long(int32_t in[], long out[], int length) 103 { 104 int ii; 105 for (ii = 0; ii < length; ii++) 106 out[ii] = (long)in[ii]; 107 } 108 109 inv_error_t inv_playback(void) 110 { 111 inv_rd_dbg_states type; 112 inv_time_t ts; 113 int32_t buffer[4]; 114 short gyro[3]; 115 size_t r = 1; 116 int32_t orientation; 117 int32_t sensitivity, sample_rate_us = 0; 118 119 // Check to make sure we were request to playback 120 if (inv_construct.debug_mode != RD_PLAYBACK) { 121 MPL_LOGE("%s|%s|%d error: debug_mode != RD_PLAYBACK\n", 122 __FILE__, __func__, __LINE__); 123 return INV_ERROR; 124 } 125 126 if (inv_construct.file == NULL) { 127 inv_construct.file = fopen(playback_filename, "rb"); 128 if (!inv_construct.file) { 129 MPL_LOGE("Error : cannot find or open playback file '%s'\n", 130 playback_filename); 131 return INV_ERROR_FILE_OPEN; 132 } 133 } 134 135 while (1) { 136 r = fread(&type, sizeof(type), 1, inv_construct.file); 137 if (r == 0) { 138 MPL_LOGV("read 0 bytes, PLAYBACK file closed\n"); 139 inv_construct.debug_mode = RD_NO_DEBUG; 140 fclose(inv_construct.file); 141 break; 142 } 143 //MPL_LOGV("TYPE : %d, %d\n", type); 144 switch (type) { 145 case PLAYBACK_DBG_TYPE_GYRO: 146 r = fread(gyro, sizeof(gyro[0]), 3, inv_construct.file); 147 r = fread(&ts, sizeof(ts), 1, inv_construct.file); 148 inv_build_gyro(gyro, ts); 149 MPL_LOGV("PLAYBACK_DBG_TYPE_GYRO, %+d, %+d, %+d, %+lld\n", 150 gyro[0], gyro[1], gyro[2], ts); 151 break; 152 case PLAYBACK_DBG_TYPE_ACCEL: 153 { 154 long accel[3]; 155 r = fread(buffer, sizeof(buffer[0]), 3, inv_construct.file); 156 r = fread(&ts, sizeof(ts), 1, inv_construct.file); 157 int32_to_long(buffer, accel, 3); 158 inv_build_accel(accel, 0, ts); 159 MPL_LOGV("PLAYBACK_DBG_TYPE_ACCEL, %+d, %+d, %+d, %lld\n", 160 buffer[0], buffer[1], buffer[2], ts); 161 break; 162 } 163 case PLAYBACK_DBG_TYPE_COMPASS: 164 { 165 long compass[3]; 166 r = fread(buffer, sizeof(buffer[0]), 3, inv_construct.file); 167 r = fread(&ts, sizeof(ts), 1, inv_construct.file); 168 int32_to_long(buffer, compass, 3); 169 inv_build_compass(compass, 0, ts); 170 MPL_LOGV("PLAYBACK_DBG_TYPE_COMPASS, %+d, %+d, %+d, %lld\n", 171 buffer[0], buffer[1], buffer[2], ts); 172 break; 173 } 174 case PLAYBACK_DBG_TYPE_TEMPERATURE: 175 r = fread(buffer, sizeof(buffer[0]), 1, inv_construct.file); 176 r = fread(&ts, sizeof(ts), 1, inv_construct.file); 177 inv_build_temp(buffer[0], ts); 178 MPL_LOGV("PLAYBACK_DBG_TYPE_TEMPERATURE, %+d, %lld\n", 179 buffer[0], ts); 180 break; 181 case PLAYBACK_DBG_TYPE_QUAT: 182 { 183 long quat[4]; 184 r = fread(buffer, sizeof(buffer[0]), 4, inv_construct.file); 185 r = fread(&ts, sizeof(ts), 1, inv_construct.file); 186 int32_to_long(buffer, quat, 4); 187 inv_build_quat(quat, INV_BIAS_APPLIED, ts); 188 MPL_LOGV("PLAYBACK_DBG_TYPE_QUAT, %+d, %+d, %+d, %+d, %lld\n", 189 buffer[0], buffer[1], buffer[2], buffer[3], ts); 190 break; 191 } 192 case PLAYBACK_DBG_TYPE_EXECUTE: 193 MPL_LOGV("PLAYBACK_DBG_TYPE_EXECUTE\n"); 194 inv_execute_on_data(); 195 if (s_func_cb) 196 s_func_cb(); 197 //done = 1; 198 break; 199 200 case PLAYBACK_DBG_TYPE_G_ORIENT: 201 MPL_LOGV("PLAYBACK_DBG_TYPE_G_ORIENT\n"); 202 r = fread(&orientation, sizeof(orientation), 1, inv_construct.file); 203 r = fread(&sensitivity, sizeof(sensitivity), 1, inv_construct.file); 204 inv_set_gyro_orientation_and_scale(orientation, sensitivity); 205 break; 206 case PLAYBACK_DBG_TYPE_A_ORIENT: 207 MPL_LOGV("PLAYBACK_DBG_TYPE_A_ORIENT\n"); 208 r = fread(&orientation, sizeof(orientation), 1, inv_construct.file); 209 r = fread(&sensitivity, sizeof(sensitivity), 1, inv_construct.file); 210 inv_set_accel_orientation_and_scale(orientation, sensitivity); 211 break; 212 case PLAYBACK_DBG_TYPE_C_ORIENT: 213 MPL_LOGV("PLAYBACK_DBG_TYPE_C_ORIENT\n"); 214 r = fread(&orientation, sizeof(orientation), 1, inv_construct.file); 215 r = fread(&sensitivity, sizeof(sensitivity), 1, inv_construct.file); 216 inv_set_compass_orientation_and_scale(orientation, sensitivity); 217 break; 218 219 case PLAYBACK_DBG_TYPE_G_SAMPLE_RATE: 220 r = fread(&sample_rate_us, sizeof(sample_rate_us), 221 1, inv_construct.file); 222 inv_set_gyro_sample_rate(sample_rate_us); 223 MPL_LOGV("PLAYBACK_DBG_TYPE_G_SAMPLE_RATE => %d\n", 224 sample_rate_us); 225 break; 226 case PLAYBACK_DBG_TYPE_A_SAMPLE_RATE: 227 r = fread(&sample_rate_us, sizeof(sample_rate_us), 228 1, inv_construct.file); 229 inv_set_accel_sample_rate(sample_rate_us); 230 MPL_LOGV("PLAYBACK_DBG_TYPE_A_SAMPLE_RATE => %d\n", 231 sample_rate_us); 232 break; 233 case PLAYBACK_DBG_TYPE_C_SAMPLE_RATE: 234 r = fread(&sample_rate_us, sizeof(sample_rate_us), 235 1, inv_construct.file); 236 inv_set_compass_sample_rate(sample_rate_us); 237 MPL_LOGV("PLAYBACK_DBG_TYPE_C_SAMPLE_RATE => %d\n", 238 sample_rate_us); 239 break; 240 241 case PLAYBACK_DBG_TYPE_GYRO_OFF: 242 MPL_LOGV("PLAYBACK_DBG_TYPE_GYRO_OFF\n"); 243 inv_gyro_was_turned_off(); 244 break; 245 case PLAYBACK_DBG_TYPE_ACCEL_OFF: 246 MPL_LOGV("PLAYBACK_DBG_TYPE_ACCEL_OFF\n"); 247 inv_accel_was_turned_off(); 248 break; 249 case PLAYBACK_DBG_TYPE_COMPASS_OFF: 250 MPL_LOGV("PLAYBACK_DBG_TYPE_COMPASS_OFF\n"); 251 inv_compass_was_turned_off(); 252 break; 253 case PLAYBACK_DBG_TYPE_QUAT_OFF: 254 MPL_LOGV("PLAYBACK_DBG_TYPE_QUAT_OFF\n"); 255 inv_quaternion_sensor_was_turned_off(); 256 break; 257 258 case PLAYBACK_DBG_TYPE_Q_SAMPLE_RATE: 259 MPL_LOGV("PLAYBACK_DBG_TYPE_Q_SAMPLE_RATE\n"); 260 r = fread(&sample_rate_us, sizeof(sample_rate_us), 261 1, inv_construct.file); 262 inv_set_quat_sample_rate(sample_rate_us); 263 break; 264 default: 265 //MPL_LOGV("PLAYBACK file closed\n"); 266 fclose(inv_construct.file); 267 MPL_LOGE("%s|%s|%d error: unrecognized log type '%d', " 268 "PLAYBACK file closed\n", 269 __FILE__, __func__, __LINE__, type); 270 return INV_ERROR; 271 } 272 } 273 msleep(1); 274 275 inv_construct.debug_mode = RD_NO_DEBUG; 276 fclose(inv_construct.file); 277 278 return INV_SUCCESS; 279 } 280 281 /** Turns on/off playback and record modes 282 * @param mode Turn on recording mode with RD_RECORD and turn off recording mode with 283 * RD_NO_DBG. Turn on playback mode with RD_PLAYBACK. 284 */ 285 void inv_set_debug_mode(rd_dbg_mode mode) 286 { 287 #ifdef INV_PLAYBACK_DBG 288 inv_construct.debug_mode = mode; 289 #endif 290 } 291 292 inv_error_t inv_constructor_start(void) 293 { 294 inv_error_t result; 295 unsigned char divider; 296 //int gest_enabled = inv_get_gesture_enable(); 297 298 // start the software 299 result = inv_start_mpl(); 300 if (result) { 301 LOG_RESULT_LOCATION(result); 302 return result; 303 } 304 305 /* 306 if (inv_construct.dmp_version == WIN8_DMP_VERSION) { 307 int fifo_divider; 308 divider = 4; // 4 means 200Hz DMP 309 fifo_divider = 3; 310 // Set Gyro Sample Rate in MPL in micro seconds 311 inv_set_gyro_sample_rate(1000L*(divider+1)*(fifo_divider+1)); 312 313 // Set Gyro Sample Rate in MPL in micro seconds 314 inv_set_quat_sample_rate(1000L*(divider+1)*(fifo_divider+1)); 315 316 // Set Compass Sample Rate in MPL in micro seconds 317 inv_set_compass_sample_rate(1000L*(divider+1)*(fifo_divider+1)); 318 319 // Set Accel Sample Rate in MPL in micro seconds 320 inv_set_accel_sample_rate(1000L*(divider+1)*(fifo_divider+1)); 321 } else if (gest_enabled) { 322 int fifo_divider; 323 unsigned char mpl_divider; 324 325 inv_send_interrupt_word(); 326 inv_send_sensor_data(INV_ALL & INV_GYRO_ACC_MASK); 327 inv_send_quaternion(); 328 329 divider = fifo_dmp_cfg.sample_divider; 330 mpl_divider = fifo_dmp_cfg.mpl_divider; 331 332 // Set Gyro Sample Rate in MPL in micro seconds 333 inv_set_gyro_sample_rate(1000L*(mpl_divider+1)); 334 335 // Set Gyro Sample Rate in MPL in micro seconds 336 inv_set_quat_sample_rate(1000L*(mpl_divider+1)); 337 338 // Set Compass Sample Rate in MPL in micro seconds 339 inv_set_compass_sample_rate(1000L*(mpl_divider+1)); 340 341 // Set Accel Sample Rate in MPL in micro seconds 342 inv_set_accel_sample_rate(1000L*(mpl_divider+1)); 343 } else 344 */ 345 { 346 divider = 9; 347 // set gyro sample sate in MPL in micro seconds 348 inv_set_gyro_sample_rate(1000L*(divider+1)); 349 // set compass sample rate in MPL in micro seconds 350 inv_set_compass_sample_rate(1000L*(divider+1)); 351 // set accel sample rate in MPL in micro seconds 352 inv_set_accel_sample_rate(1000L*(divider+1)); 353 } 354 355 // setup the scale factors and orientations and other parameters 356 result = inv_constructor_setup(); 357 358 return result; 359 } 360 361 inv_error_t inv_constructor_default_enable() 362 { 363 INV_ERROR_CHECK(inv_enable_quaternion()); 364 INV_ERROR_CHECK(inv_enable_fast_nomot()); 365 INV_ERROR_CHECK(inv_enable_heading_from_gyro()); 366 INV_ERROR_CHECK(inv_enable_compass_bias_w_gyro()); 367 INV_ERROR_CHECK(inv_enable_hal_outputs()); 368 INV_ERROR_CHECK(inv_enable_vector_compass_cal()); 369 INV_ERROR_CHECK(inv_enable_9x_sensor_fusion()); 370 INV_ERROR_CHECK(inv_enable_gyro_tc()); 371 INV_ERROR_CHECK(inv_enable_no_gyro_fusion()); 372 INV_ERROR_CHECK(inv_enable_in_use_auto_calibration()); 373 INV_ERROR_CHECK(inv_enable_magnetic_disturbance()); 374 return INV_SUCCESS; 375 } 376 377 /** 378 * @} 379 */ 380