Home | History | Annotate | Download | only in stress_iio
      1 /* Industrialio buffer test code.
      2  *
      3  * Copyright (c) 2012 Invensense Inc.
      4  *
      5  * This program is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 as published by
      7  * the Free Software Foundation.
      8  *
      9  * Command line parameters
     10  * stress_iio -d time1 -e time2
     11  */
     12 
     13 #include <unistd.h>
     14 #include <dirent.h>
     15 #include <fcntl.h>
     16 #include <stdio.h>
     17 #include <errno.h>
     18 #include <sys/stat.h>
     19 #include <dirent.h>
     20 #include <linux/types.h>
     21 #include <string.h>
     22 #include <poll.h>
     23 #include <pthread.h>
     24 #include "iio_utils.h"
     25 #include "ml_load_dmp.h"
     26 #include "ml_sysfs_helper.h"
     27 #include "authenticate.h"
     28 
     29 pthread_mutex_t data_switch_lock = PTHREAD_MUTEX_INITIALIZER;
     30 
     31 static int has_compass = 0;
     32 static int has_pressure = 0;
     33 static int enable_random_delay = 0;
     34 static int enable_delay = 10;
     35 static int disable_delay = 10;
     36 static int enable_motion_on = 0;
     37 static int final_output_rate;
     38 static int first_flag;
     39 static char dmp_path[200];
     40 
     41 static int dev_num;
     42 static char *dev_dir_name;
     43 static char *buf_dir_name;
     44 static char *scan_el_dir;
     45 static int gyro_data_is_enabled, accel_data_is_enabled, compass_data_is_enabled, quaternion_data_is_enabled;
     46 static int accel_engine_is_on;
     47 
     48 struct dmp_struct {
     49 	char fname[100];
     50 	void (*action)(struct dmp_struct *, int);
     51 };
     52 
     53 static void HandleTap(struct dmp_struct *dmp, int tap);
     54 static void sipmle_print(struct dmp_struct *dmp, int d){
     55 	printf("%s:%d\n", dmp->fname, d);
     56 }
     57 
     58 static void handle_smd() {
     59 	printf("write wake lock for SMD\n");
     60 	//write_sysfs_string_and_verify("wake_lock", "/sys/power/", "hack");
     61 }
     62 
     63 static void pedo_print()
     64 {
     65 	struct timespec aa;
     66 	unsigned long long t;
     67 
     68 	clock_gettime(CLOCK_REALTIME, &aa);
     69 	t = (unsigned long long)aa.tv_sec * 1000000000 + aa.tv_nsec;
     70 	printf("steps=%lld, time=%lld, system=%lld\n",
     71 		read_sysfs_poslonglong("pedometer_steps", dev_dir_name),
     72 		read_sysfs_poslonglong("pedometer_time", dev_dir_name),
     73 		t);
     74 }
     75 
     76 struct dmp_struct event_file[] = {
     77 #if 1
     78 	{
     79 		.fname = "event_tap",
     80 		.action = HandleTap,
     81 	},
     82 #endif
     83 	{
     84 		.fname = "event_smd",
     85 		.action = handle_smd,
     86 	},
     87 	{
     88 		.fname = "event_accel_motion",
     89 		.action = sipmle_print,
     90 	},
     91 	{
     92 		.fname = "event_pedometer",
     93 		.action = pedo_print,
     94 	},
     95 };
     96 
     97 static void HandleTap(struct dmp_struct *dmp, int tap)
     98 {
     99     int tap_dir = tap/8;
    100     int tap_num = tap%8 + 1;
    101 
    102     switch (tap_dir) {
    103         case 1:
    104             printf("INV_TAP_AXIS_X_POS\n");
    105             break;
    106         case 2:
    107             printf("INV_TAP_AXIS_X_NEG\n");
    108             break;
    109         case 3:
    110             printf("INV_TAP_AXIS_Y_POS\n");
    111             break;
    112         case 4:
    113             printf("INV_TAP_AXIS_Y_NEG\n");
    114             break;
    115         case 5:
    116             printf("INV_TAP_AXIS_Z_POS\n");
    117             break;
    118         case 6:
    119             printf("INV_TAP_AXIS_Z_NEG\n");
    120             break;
    121         default:
    122             break;
    123     }
    124     printf("Tap number: %d\n", tap_num);
    125 }
    126 #define DMP_CODE_SIZE 2799
    127 static char dmp_img[DMP_CODE_SIZE];
    128 static void verify_img(){
    129     FILE *fp;
    130     int i;
    131     char dmp_path[] = "/sys/bus/iio/devices/iio:device0/dmp_firmware";
    132 
    133     printf("saving image\n");
    134     if ((fp = fopen(dmp_path, "rb")) < 0 ) {
    135         perror("dmp fail");
    136     }
    137 
    138     i = fread(dmp_img, 1, DMP_CODE_SIZE, fp);
    139     printf("Result=%d\n", i);
    140     fclose(fp);
    141     fp = fopen("/dev/read_img.h", "wt");
    142     fprintf(fp, "unsigned char rec[]={\n");
    143     for(i=0; i<DMP_CODE_SIZE; i++) {
    144       fprintf(fp, "0x%02x, ", dmp_img[i]);
    145       //printf( "0x%02x, ", dmp_img[i]);
    146       if(((i+1)%16) == 0) {
    147         fprintf(fp, "\n");
    148         //printf("\n");
    149       }
    150     }
    151     fprintf(fp, "};\n ");
    152     fclose(fp);
    153     printf("saving image Done\n");
    154 }
    155 
    156 static void inv_set_rate()
    157 {
    158 	int ret;
    159 
    160 	printf("set rate \n");
    161 	ret = write_sysfs_int_and_verify("accel_rate", dev_dir_name, 5);
    162 	ret = write_sysfs_int_and_verify("gyro_rate", dev_dir_name, 5);
    163 	if (has_compass)
    164 		ret = write_sysfs_int_and_verify("compass_rate", dev_dir_name, 10);
    165 	if (has_pressure)
    166 		ret = write_sysfs_int_and_verify("pressure_rate", dev_dir_name, 30);
    167 	ret = write_sysfs_int_and_verify("ped_q_rate", dev_dir_name, 5);
    168 	ret = write_sysfs_int_and_verify("six_axes_q_rate", dev_dir_name, 5);
    169 	ret = write_sysfs_int_and_verify("three_axes_q_rate", dev_dir_name, 5);
    170 }
    171 
    172 
    173 static int setup_offset_and_bias()
    174 {
    175 	int ret;
    176 
    177 	ret = write_sysfs_int_and_verify("in_accel_x_offset", dev_dir_name, 0);
    178 	if (ret < 0)
    179 		printf("write accel x offset failed.\n");
    180 	ret = write_sysfs_int_and_verify("in_accel_y_offset", dev_dir_name, 0);
    181 	if (ret < 0)
    182 		printf("write accel y offset failed.\n");
    183 	ret = write_sysfs_int_and_verify("in_accel_z_offset", dev_dir_name, 0);
    184 	if (ret < 0)
    185 		printf("write accel z offset failed.\n");
    186 
    187 	ret = write_sysfs_int_and_verify("in_anglvel_x_offset", dev_dir_name, 0);
    188 	if (ret < 0)
    189 		printf("write accel x offset failed.\n");
    190 	ret = write_sysfs_int_and_verify("in_anglvel_y_offset", dev_dir_name, 0);
    191 	if (ret < 0)
    192 		printf("write accel y offset failed.\n");
    193 	ret = write_sysfs_int_and_verify("in_anglvel_z_offset", dev_dir_name, 0);
    194 	if (ret < 0)
    195 		printf("write accel z offset failed.\n");
    196 
    197 	ret = write_sysfs_int_and_verify("in_accel_x_dmp_bias", dev_dir_name, 0);
    198 	if (ret < 0)
    199 		printf("write accel x offset failed.\n");
    200 	ret = write_sysfs_int_and_verify("in_accel_y_dmp_bias", dev_dir_name, 0);
    201 	if (ret < 0)
    202 		printf("write accel y offset failed.\n");
    203 	ret = write_sysfs_int_and_verify("in_accel_z_dmp_bias", dev_dir_name, 0);
    204 	if (ret < 0)
    205 		printf("write accel z offset failed.\n");
    206 
    207 	ret = write_sysfs_int_and_verify("in_anglvel_x_dmp_bias", dev_dir_name, 0);
    208 	if (ret < 0)
    209 		printf("write gyro x offset failed.\n");
    210 	ret = write_sysfs_int_and_verify("in_anglvel_y_dmp_bias", dev_dir_name, 0);
    211 	if (ret < 0)
    212 		printf("write gyro y offset failed.\n");
    213 	ret = write_sysfs_int_and_verify("in_anglvel_z_dmp_bias", dev_dir_name, 0);
    214 	if (ret < 0)
    215 		printf("write gyro z offset failed.\n");
    216 
    217 	return 0;
    218 }
    219 
    220 static void setup_dmp(char *dev_path){
    221 	char sysfs_path[200];
    222 	int  ret;
    223 	FILE *fd;
    224 	sprintf(sysfs_path, "%s", dev_path);
    225 	printf("sysfs: %s\n", sysfs_path);
    226 	ret = write_sysfs_int_and_verify("power_state", sysfs_path, 1);
    227 	if (ret < 0)
    228 		return;
    229 
    230 	ret = write_sysfs_int("in_accel_scale", dev_path, 0);
    231 	if (ret < 0)
    232 		return;
    233 	ret = write_sysfs_int("in_anglvel_scale", dev_path, 3);
    234 	if (ret < 0)
    235 		return;
    236 	ret = write_sysfs_int("sampling_frequency", sysfs_path, 200);
    237 	if (ret < 0)
    238 		return;
    239 	ret = write_sysfs_int_and_verify("firmware_loaded", sysfs_path, 0);
    240 	if (ret < 0)
    241 		return;
    242 	sprintf(dmp_path, "%s/dmp_firmware", dev_path);
    243 	if ((fd = fopen(dmp_path, "wb")) < 0 ) {
    244 		perror("dmp fail");
    245 	}
    246 	inv_load_dmp(fd);
    247 	fclose(fd);
    248 	printf("firmware_loaded=%d\n", read_sysfs_posint("firmware_loaded", sysfs_path));
    249 	ret = write_sysfs_int_and_verify("dmp_on", sysfs_path, 1);
    250 	if (ret < 0)
    251 		return;
    252 	ret = write_sysfs_int_and_verify("dmp_int_on", sysfs_path, 1);
    253 	if (ret < 0)
    254 		return;
    255 	/* selelct which event to enable and interrupt on/off here */
    256 	//enable_glu(sysfs_path, 0);
    257 //	ret = write_sysfs_int_and_verify("tap_on", sysfs_path, 0);
    258 //	if (ret < 0)
    259 //		return;
    260 	ret = write_sysfs_int_and_verify("pedometer_int_on", sysfs_path, 1);
    261 	ret = write_sysfs_int_and_verify("pedometer_on", sysfs_path, 1);
    262 
    263 	ret = write_sysfs_int_and_verify("dmp_event_int_on", sysfs_path, 1);
    264 		write_sysfs_int64("pedometer_steps", sysfs_path, 0);
    265 		write_sysfs_int64("pedometer_time", sysfs_path, 0);
    266 	if (ret < 0)
    267 		return;
    268 
    269 	ret = setup_offset_and_bias();
    270 
    271 	return;
    272 }
    273 
    274 #if 0
    275 static char reg_dump_arr[2000];
    276 static int inv_do_reg_dump(void)
    277 {
    278 	char reg_dump_name[100];
    279 	int fd, i;
    280 
    281 	sprintf(reg_dump_name, "%s/reg_dump", dev_dir_name);
    282 	printf("%s\n", reg_dump_name);
    283 	fd = open(reg_dump_name, O_RDONLY);
    284 	pread(fd, reg_dump_arr, 2000, 0);
    285 	close(fd);
    286 	for ( i = 0; i < 2000; i++) {
    287 		printf("%c", reg_dump_arr[i]);
    288 		//if((i+1)%16 == 0)
    289 			//printf("\n");
    290 	}
    291 	return 0;
    292 }
    293 #endif
    294 
    295 static void *get_dmp_event(void *param) {
    296 	char file_name[100];
    297 	int i;
    298 	int data;
    299 	char d[4];
    300 	FILE *fp;
    301 	struct pollfd pfd[ARRAY_SIZE(event_file)];
    302 
    303 	printf("get DMP event: %s\n", dev_dir_name);
    304 	while(1) {
    305 		for (i = 0; i < ARRAY_SIZE(event_file); i++) {
    306 			sprintf(file_name, "%s/%s", dev_dir_name, event_file[i].fname);
    307 			pfd[i].fd = open(file_name, O_RDONLY | O_NONBLOCK);
    308 			pfd[i].events = POLLPRI|POLLERR;
    309 			pfd[i].revents = 0;
    310 			read(pfd[i].fd, d, 4);
    311 		}
    312 
    313 		poll(pfd, ARRAY_SIZE(event_file), -1);
    314 		for (i = 0; i < ARRAY_SIZE(event_file); i++) {
    315 			close(pfd[i].fd);
    316 		}
    317 
    318 		for (i=0; i< ARRAY_SIZE(pfd); i++) {
    319 			if(pfd[i].revents != 0) {
    320 				sprintf(file_name, "%s/%s", dev_dir_name, event_file[i].fname);
    321 				fp = fopen(file_name, "rt");
    322 				fscanf(fp, "%d\n", &data);
    323 				event_file[i].action(&event_file[i], data);
    324 			}
    325 		}
    326 	}
    327 
    328 	return 0;
    329 }
    330 
    331 static int enable_gyro(int on){
    332 	int ret;
    333 	ret = write_sysfs_int_and_verify("gyro_enable", dev_dir_name, on);
    334 	if (ret < 0)
    335 		printf("write gyro_enable failed\n");
    336 
    337 	return ret;
    338 }
    339 
    340 static int enable_gyro_output(int on){
    341 	int ret;
    342 	gyro_data_is_enabled = on;
    343 	ret = write_sysfs_int_and_verify("gyro_fifo_enable", dev_dir_name, on);
    344 	if (ret < 0)
    345 		printf("write gyro_fifo_enable failed\n");
    346 
    347 	return ret;
    348 }
    349 
    350 static int enable_compass(int on){
    351 	int ret;
    352 
    353 	compass_data_is_enabled = on;
    354 	ret = write_sysfs_int_and_verify("compass_enable", dev_dir_name, on);
    355 	if (ret < 0)
    356 		printf("write gyro_enable failed\n");
    357 
    358 	return ret;
    359 }
    360 
    361 static int enable_pressure(int on){
    362 	int ret;
    363 
    364 	ret = write_sysfs_int_and_verify("pressure_enable", dev_dir_name, on);
    365 	if (ret < 0)
    366 		printf("write pressure_enable failed\n");
    367 
    368 	return ret;
    369 }
    370 
    371 static int enable_quaternion(int on) {
    372 	int ret;
    373 	ret = write_sysfs_int_and_verify("ped_q_on", dev_dir_name, on);
    374 	if (ret < 0)
    375 		printf("write quaternion_on failed\n");
    376 	ret = write_sysfs_int_and_verify("six_axes_q_on", dev_dir_name, on);
    377 	if (ret < 0)
    378 		printf("write quaternion_on failed\n");
    379 	ret = write_sysfs_int_and_verify("three_axes_q_on", dev_dir_name, on);
    380 	if (ret < 0)
    381 		printf("write quaternion_on failed\n");
    382 
    383 	return ret;
    384 }
    385 static int enable_step_detector(int on) {
    386 	int ret;
    387 
    388 	ret = write_sysfs_int_and_verify("step_detector_on", dev_dir_name, on);
    389 	if (ret < 0)
    390 		printf("write step detector on failed\n");
    391 }
    392 static int enable_step_indicator(int on) {
    393 	int ret;
    394 
    395 	ret = write_sysfs_int_and_verify("step_indicator_on", dev_dir_name, on);
    396 	if (ret < 0)
    397 		printf("write step indicator on failed\n");
    398 }
    399 
    400 static int enable_accel(int on){
    401 	int ret;
    402 	accel_data_is_enabled = on;
    403 	accel_engine_is_on = on;
    404 	ret = write_sysfs_int_and_verify("accel_enable", dev_dir_name, on);
    405 	if (ret < 0)
    406 		printf("write accel_enable failed\n");
    407 	ret = write_sysfs_int_and_verify("accel_fifo_enable", dev_dir_name, on);
    408 	if (ret < 0)
    409 		printf("write accel_fifo_enable failed\n");
    410 
    411 	return ret;
    412 }
    413 static int enable_accel_output(int on) {
    414 	int ret;
    415 	accel_data_is_enabled = on;
    416 
    417 	ret = write_sysfs_int_and_verify("accel_fifo_enable", dev_dir_name, on);
    418 	if (ret < 0)
    419 		printf("write accel_fifo_enable failed\n");
    420 
    421 	return ret;
    422 }
    423 
    424 static int enable_enable(int on){
    425 	int ret;
    426 
    427 	if (0 == on) {
    428 		//pthread_mutex_lock(&data_switch_lock);
    429 	}
    430 	ret = write_sysfs_int_and_verify("master_enable", dev_dir_name, on);
    431 	if (ret < 0)
    432 		printf("write enable failed\n");
    433 
    434 	if (on) {
    435 		//pthread_mutex_unlock(&data_switch_lock);
    436 	}
    437 
    438 	return 0;
    439 }
    440 static int write_dmp_event(int on) {
    441 	int ret;
    442 	ret = write_sysfs_int_and_verify("dmp_event_int_on", dev_dir_name, on);
    443 	if (ret < 0)
    444 		printf("write dmp_event_int_on failed\n");
    445 	return 0;
    446 }
    447 
    448 static void random_delay(){
    449 	int i;
    450 	float bb;
    451 
    452 	i = rand();
    453 	bb = i * 200.0;
    454 	bb = i * 10.0;
    455 	i = 1 + (unsigned int)(bb/(RAND_MAX + 1.0));
    456 	i *= 2;
    457 	if (i%2) {
    458 		printf("sleep %d ms\n", i);
    459 		usleep(i*1000);
    460 	} else {
    461 		printf("sleep %d s\n", i);
    462 		sleep(i);
    463 	}
    464 
    465 }
    466 static void dmp_event_control(on){
    467 	int ret;
    468 
    469 	ret = 0;
    470 
    471 //	ret = write_sysfs_int_and_verify("tap_on", dev_dir_name, on);
    472 	ret = write_sysfs_int_and_verify("smd_enable", dev_dir_name, 1);
    473 	if (ret < 0)
    474 		return;
    475 	inv_set_rate();
    476 
    477 	//ret = write_sysfs_int_and_verify("batchmode_wake_fifo_full_on", dev_dir_name, 1);
    478 	ret = write_sysfs_int_and_verify("batchmode_timeout", dev_dir_name, 10000);
    479 	ret = write_sysfs_int_and_verify("batchmode_timeout", dev_dir_name, 0);
    480 	//ret = write_sysfs_int_and_verify("smd_delay_threshold", dev_dir_name, 10);
    481 	if (ret < 0)
    482 		return;
    483 	//ret = write_sysfs_int_and_verify("smd_threshold", dev_dir_name, 5000);
    484 	if (ret < 0)
    485 		return;
    486 	//write_sysfs_int_and_verify("motion_lpa_duration", dev_dir_name, 1000);
    487 	//write_sysfs_int_and_verify("motion_lpa_threshold", dev_dir_name, 200);
    488 	write_sysfs_int_and_verify("dmp_on", dev_dir_name, 1);
    489 	ret = write_sysfs_int_and_verify("sampling_frequency", dev_dir_name, 200);
    490 	//write_sysfs_int_and_verify("motion_lpa_freq", dev_dir_name, 3);
    491 
    492 }
    493 void enable_motion(int on) {
    494 	int ret;
    495 
    496 	ret = write_sysfs_int_and_verify("motion_lpa_on", dev_dir_name, on);
    497 	if (on) {
    498 	        gyro_data_is_enabled = 0;
    499 		compass_data_is_enabled = 0;
    500 		quaternion_data_is_enabled = 0;
    501 	}
    502 }
    503 bool g, a;
    504 static int counter = 0;
    505 static unsigned char data_rate[] = {5, 10, 15, 50, 100, 200};
    506 static int run_enable_sequence()
    507 {
    508 	bool g, a, out;
    509 
    510 	counter++;
    511 	g = rand()%2;
    512 	a = rand()%2;
    513 	if (!g && !a)
    514 		a = true;
    515 
    516 	g = true;
    517 //	g = false;
    518 	a = true;
    519 //	a = false;
    520 	/*disable the master enable */
    521 	enable_enable(0);
    522 	if(g) {
    523 		enable_gyro(1);
    524 		if (rand()%2) {
    525 			out = rand()%2;
    526 			enable_quaternion(out);
    527 			enable_gyro_output(!out);
    528 		} else {
    529 			enable_quaternion(1);
    530 			enable_gyro_output(1);
    531 		}
    532 		enable_quaternion(1);
    533 		enable_gyro_output(0);
    534 
    535 	} else {
    536 		enable_gyro(0);
    537 		enable_gyro_output(0);
    538 		enable_quaternion(0);
    539 	}
    540 	if(a) {
    541 		enable_accel(1);
    542 		enable_accel_output(0);
    543 	} else {
    544 		enable_accel(0);
    545 		enable_accel_output(0);
    546 	}
    547 	if (has_compass) {
    548 		if(rand()%2)
    549 			enable_compass(1);
    550 		else
    551 			enable_compass(0);
    552 		enable_compass(counter%2);
    553 		enable_compass(0);
    554 	}
    555 	if (has_pressure) {
    556 		if(rand()%2)
    557 			enable_pressure(1);
    558 		else
    559 			enable_pressure(0);
    560 		enable_pressure(counter%3);
    561 		enable_pressure(0);
    562 	}
    563 	enable_step_detector(1);
    564 	enable_step_indicator(1);
    565 	enable_step_detector(0);
    566 	enable_step_indicator(0);
    567 
    568 	write_dmp_event(0);
    569 
    570 	enable_motion(0);
    571 	if (accel_engine_is_on)
    572 		dmp_event_control(1);
    573 	else
    574 		dmp_event_control(0);
    575 	first_flag = 1;
    576 	/*enable the master enable */
    577 	enable_enable(1);
    578 	//enable_enable(0);
    579 	//verify_img();
    580 	//while(1);
    581 	//write_sysfs_string_and_verify("wake_unlock", "/sys/power/", "hack");
    582 	if (enable_random_delay)
    583 		random_delay();
    584 	else {
    585 		printf("sleep %ds\n", enable_delay);
    586 		sleep(enable_delay);
    587 	}
    588 
    589 	return 0;
    590 }
    591 
    592 static int run_disable_sequence() {
    593 	enable_enable(0);
    594 
    595 	enable_gyro(0);
    596 	enable_accel(1);
    597 	enable_quaternion(0);
    598 	enable_accel_output(0);
    599 	write_dmp_event(1);
    600 	enable_motion(enable_motion_on);
    601 	if (accel_engine_is_on)
    602 		dmp_event_control(1);
    603 	else
    604 		dmp_event_control(0);
    605 
    606 	enable_enable(1);
    607 	if (enable_random_delay)
    608 		random_delay();
    609 	else {
    610 		printf("sleep %ds\n", disable_delay);
    611 		sleep(disable_delay);
    612 	}
    613 
    614 	if (has_pressure) {
    615 		if(rand()%2)
    616 			enable_pressure(1);
    617 		else
    618 			enable_pressure(0);
    619 		enable_pressure(counter%3);
    620 		enable_pressure(1);
    621 	}
    622 
    623 	return 0;
    624 }
    625 static int run_dmp_off() {
    626 	bool g, a, out;
    627 
    628 	counter++;
    629 	g = rand()%2;
    630 	a = rand()%2;
    631 	if (!g && !a)
    632 		a = true;
    633 
    634 	g = true;
    635 	a = true;
    636 	a = false;
    637 //	g = false;
    638 	/*disable the master enable */
    639 	enable_enable(0);
    640 	if(g) {
    641 		enable_gyro(1);
    642 		if (rand()%2) {
    643 			enable_gyro_output(!out);
    644 		} else {
    645 			enable_gyro_output(1);
    646 		}
    647 		enable_gyro_output(1);
    648 
    649 	} else {
    650 		enable_gyro(0);
    651 		enable_gyro_output(0);
    652 	}
    653 	if(a) {
    654 		enable_accel(1);
    655 		enable_accel_output(1);
    656 //		enable_accel_output(0);
    657 	} else {
    658 		enable_accel(0);
    659 		enable_accel_output(0);
    660 	}
    661 	if (has_compass) {
    662 		if(rand()%2)
    663 			enable_compass(1);
    664 		else
    665 			enable_compass(0);
    666 		enable_compass(counter%2);
    667 		enable_compass(0);
    668 	}
    669 	if (has_pressure) {
    670 		if(rand()%2)
    671 			enable_pressure(1);
    672 		else
    673 			enable_pressure(0);
    674 		enable_pressure(counter%3);
    675 		enable_pressure(1);
    676 	}
    677 	printf("111111111111111\n");
    678 
    679 	write_sysfs_int_and_verify("sampling_frequency", dev_dir_name,15);
    680 	write_sysfs_int_and_verify("dmp_on", dev_dir_name, 0);
    681 	first_flag = 1;
    682 	/*enable the master enable */
    683 	enable_enable(1);
    684 	//sleep(2);
    685 
    686 	return 0;
    687 }
    688 static void *control_switch(void *param)
    689 {
    690 	while(1) {
    691 		run_enable_sequence();
    692 		//run_dmp_off();
    693 		printf("sleeping\n");
    694 		//sleep(1000);
    695 		run_disable_sequence();
    696 	}
    697 	return 0;
    698 }
    699 
    700 void get_sensor_data(char *d, short *sensor)
    701 {
    702 	int i;
    703 
    704 	for (i = 0; i < 3; i++)
    705 		sensor[i] = *(short *)(d + 2 + i * 2);
    706 }
    707 
    708 static void *read_data(void *param)
    709 {
    710 	char *buffer_access;
    711 	char data[2048], *dptr, tmp[24];
    712 	short sensor[3];
    713 	int q[3], i, ind, left_over_size, buf_size;
    714 	int ret, fp,read_size;
    715 	unsigned short hdr;
    716 	bool done_flag;
    717 	struct timespec ts_1;
    718 	unsigned long long t0, t1;
    719 	int g_count, sq_count;
    720 
    721 #define PRESSURE_HDR             0x8000
    722 #define ACCEL_HDR                0x4000
    723 #define GYRO_HDR                 0x2000
    724 #define COMPASS_HDR              0x1000
    725 #define COMPASS_HDR_2            0x1800
    726 #define LPQUAT_HDR               0x0800
    727 #define SIXQUAT_HDR              0x0400
    728 #define PEDQUAT_HDR              0x0200
    729 #define STEP_DETECTOR_HDR        0x0100
    730 #define STEP_INDICATOR_HDR       0x0001
    731 #define END_MARKER               0x0010
    732 #define EMPTY_MARKER             0x0020
    733 
    734 	printf("read_data Thread: %s\n", dev_dir_name);
    735 	ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, dev_dir_name);
    736 	if (ret < 0)
    737 		goto error_alloc_scan_el_dir;
    738 	ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num);
    739 	if (ret < 0)
    740 		goto error_alloc_buffer_access;
    741 
    742 	fp = open(buffer_access, O_RDONLY | O_NONBLOCK);
    743 	if (fp == -1) { /*If it isn't there make the node */
    744 		printf("Failed to open %s\n", buffer_access);
    745 		ret = -errno;
    746 		goto error_open_buffer_access;
    747 	}
    748 	ind = 0;
    749 
    750 	clock_gettime(CLOCK_REALTIME, &ts_1);
    751 	t0 = (unsigned long long)ts_1.tv_sec * 1000000000 + ts_1.tv_nsec;
    752 	while(1) {
    753 
    754 		clock_gettime(CLOCK_REALTIME, &ts_1);
    755 		t1 = (unsigned long long)ts_1.tv_sec * 1000000000 + ts_1.tv_nsec;
    756 		//printf("diff=%lld, a_count=%d, sq_count=%d\n", (t1-t0), g_count, sq_count);
    757 		g_count = 0;
    758 		sq_count = 0;
    759 		t0 = t1;
    760 
    761 		struct pollfd pfd = {
    762 			.fd = fp,
    763 			.events = POLLIN,
    764 		};
    765 		poll(&pfd, 1, -1);
    766 
    767 		if (left_over_size > 0)
    768 			memcpy(data, tmp, left_over_size);
    769 		dptr = data + left_over_size;
    770 		read_size = read(fp,  dptr, 2000);
    771 		printf("readsize=%d, left_over_size=%d\n", read_size, left_over_size);
    772 		if (read_size <= 0) {
    773 			printf("Wrong size=%d\n", read_size);
    774 			pthread_mutex_unlock(&data_switch_lock);
    775 			continue;
    776 		}
    777 		ind = read_size + left_over_size;
    778 		dptr = data;
    779 		//printf("ind=%d\n", ind);
    780 		buf_size = ind - (dptr - data);
    781 		done_flag = false;
    782 
    783 		while ((buf_size > 0) && (!done_flag)) {
    784 			hdr = *((short *)(dptr));
    785 			if ((hdr & 0xf) && (hdr != STEP_INDICATOR_HDR))
    786 				printf("STEP$$$$$$$$$$$$$$$=%x  ", hdr);
    787 			switch (hdr & (~0xf)) {
    788 			case PRESSURE_HDR:
    789 				if (buf_size >= 16) {
    790 					get_sensor_data(dptr, sensor);
    791 					dptr += 8;
    792 					printf("PRESSURE:%d, %lld\n", (sensor[1] << 16) + (unsigned short)sensor[2],  *(long long *)dptr);
    793 				} else
    794 					done_flag = true;
    795 				break;
    796 			case ACCEL_HDR:
    797 				if (buf_size >= 16) {
    798 					get_sensor_data(dptr, sensor);
    799 					dptr += 8;
    800 					printf("A:%d, %d, %d,  %lld\n", sensor[0], sensor[1], sensor[2],   *(long long *)dptr);
    801 				} else
    802 					done_flag = true;
    803 				break;
    804 			case GYRO_HDR:
    805 				if (buf_size >= 16) {
    806 					get_sensor_data(dptr, sensor);
    807 					dptr += 8;
    808 					g_count++;
    809 					printf("G:%d, %d, %d,  %lld\n", sensor[0], sensor[1], sensor[2],   *(long long *)dptr);
    810 				} else
    811 					done_flag = true;
    812 				break;
    813 			case COMPASS_HDR:
    814 				if (buf_size >= 16) {
    815 					get_sensor_data(dptr, sensor);
    816 					dptr += 8;
    817 					printf("M:%d, %d, %d,  %lld\n", sensor[0], sensor[1], sensor[2],   *(long long *)dptr);
    818 				} else
    819 					done_flag = true;
    820 				break;
    821 			case PEDQUAT_HDR:
    822 				if (buf_size >= 16) {
    823 					get_sensor_data(dptr, sensor);
    824 					dptr += 8;
    825 					printf("PED:%d, %d, %d,  %lld\n", sensor[0], sensor[1], sensor[2],   *(long long *)dptr);
    826 				}  else
    827 					done_flag = true;
    828 				break;
    829 			case LPQUAT_HDR:
    830 				if (buf_size >= 24) {
    831 					q[0] = *(int *)(dptr + 4);
    832 					dptr += 8;
    833 					q[1] = *(int *)(dptr);
    834 					q[2] = *(int *)(dptr + 4);
    835 					dptr += 8;
    836 					printf("LPQ:%d, %d, %d,  %lld\n", q[0], q[1], q[2],   *(long long *)dptr);
    837 				}  else
    838 					done_flag = true;
    839 				break;
    840 			case SIXQUAT_HDR:
    841 				if (buf_size >= 24) {
    842 					q[0] = *(int *)(dptr + 4);
    843 					dptr += 8;
    844 					q[1] = *(int *)(dptr);
    845 					q[2] = *(int *)(dptr + 4);
    846 					dptr += 8;
    847 					sq_count++;
    848 					printf("SIXQ:%d, %d, %d,  %lld\n", q[0], q[1], q[2],   *(long long *)dptr);
    849 				}  else
    850 					done_flag = true;
    851 				break;
    852 			case STEP_DETECTOR_HDR:
    853 				if (buf_size >= 16) {
    854 					printf("STEP DETECTOR ");
    855 					dptr += 8;
    856 					printf(" %lld\n", *(long long *)dptr);
    857 				}  else
    858 					done_flag = true;
    859 
    860 				break;
    861 			default:
    862 				if (hdr == EMPTY_MARKER) {
    863 					printf("emptry marker !!!!!!!!!!!\n");
    864 				} else if (hdr == END_MARKER) {
    865 					printf("end marker !!!!!\n");
    866 				} else if (hdr == COMPASS_HDR_2) {
    867 					printf("bad compass data\n");
    868 				} else {
    869 					dptr +=8;
    870 					printf("%lld\n", *(long long *)dptr);
    871 				}
    872 				break;
    873 			}
    874 			if (!done_flag)
    875 				dptr += 8;
    876 			buf_size = ind - (dptr - data);
    877 		}
    878 		if (ind - (dptr - data) > 0)
    879 			memcpy(tmp, dptr, ind - (dptr - data));
    880 		left_over_size = ind - (dptr - data);
    881 	}
    882 	close(fp);
    883 
    884 error_open_buffer_access:
    885 	free(buffer_access);
    886 error_alloc_buffer_access:
    887 	free(scan_el_dir);
    888 error_alloc_scan_el_dir:
    889 
    890 	return 0;
    891 }
    892 
    893 static void inv_create_thread() {
    894 	pthread_t thread_dmp_event, thread_read_data, thread_control;
    895 
    896 	pthread_create(&thread_dmp_event, NULL, &get_dmp_event, (void *)dev_dir_name);
    897 	pthread_create(&thread_read_data, NULL, &read_data, (void *)dev_dir_name);
    898 	pthread_create(&thread_control, NULL, &control_switch, (void *)dev_dir_name);
    899 
    900 	pthread_join(thread_dmp_event, NULL);
    901 	pthread_join(thread_read_data, NULL);
    902 	pthread_join(thread_control, NULL);
    903 }
    904 
    905 static int enable_enable_main(int on){
    906 	int ret;
    907 
    908 	printf("enable_enable: %s=%d\n", dev_dir_name, on);
    909 	ret = write_sysfs_int_and_verify("enable", buf_dir_name, on);
    910 	if (ret < 0)
    911 		printf("write enable failed\n");
    912 
    913 	return 0;
    914 }
    915 
    916 int main(int argc, char **argv)
    917 {
    918 	unsigned long buf_len = 240;
    919 
    920 	int ret, c, i;
    921 
    922 	char *trigger_name = NULL;
    923 
    924 	int datardytrigger = 1;
    925 	int trig_num;
    926 	char *dummy;
    927 	char chip_name[10];
    928 	char device_name[10];
    929 	char sysfs[100];
    930 
    931 	gyro_data_is_enabled = 0;
    932 	accel_data_is_enabled = 0;
    933 	compass_data_is_enabled = 0;
    934 	quaternion_data_is_enabled = 0;
    935 
    936 	while ((c = getopt(argc, argv, "lcd:e:rmp")) != -1) {
    937 		switch (c) {
    938 		case 'c':
    939 			has_compass = 1;
    940 			break;
    941 		case 'p':
    942 			has_pressure = 1;
    943 			break;
    944 		case 'd':
    945 			disable_delay = strtoul(optarg, &dummy, 10);
    946 			break;
    947 		case 'e':
    948 			enable_delay = strtoul(optarg, &dummy, 10);
    949 			break;
    950 		case 'r':
    951 			enable_random_delay = 1;
    952 			break;
    953 		case 'm':
    954 			enable_motion_on = 1;
    955 			break;
    956 		case '?':
    957 			return -1;
    958 		}
    959 	}
    960 
    961 	inv_get_sysfs_path(sysfs);
    962 	printf("sss:::%s\n", sysfs);
    963 	if (inv_get_chip_name(chip_name) != INV_SUCCESS) {
    964 		printf("get chip name fail\n");
    965 		exit(0);
    966 	}
    967 	printf("chip_name=%s\n", chip_name);
    968 	if (INV_SUCCESS != inv_check_key())
    969         	printf("key check fail\n");
    970 	else
    971         	printf("key authenticated\n");
    972 
    973 	for (i=0; i<strlen(chip_name); i++) {
    974 		device_name[i] = tolower(chip_name[i]);
    975 	}
    976 	device_name[strlen(chip_name)] = '\0';
    977 	printf("device name: %s\n", device_name);
    978 
    979 	/* Find the device requested */
    980 	dev_num = find_type_by_name(device_name, "iio:device");
    981 	if (dev_num < 0) {
    982 		printf("Failed to find the %s\n", device_name);
    983 		ret = -ENODEV;
    984 		goto error_ret;
    985 	}
    986 	printf("iio device number being used is %d\n", dev_num);
    987 	asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
    988 	printf("allco=%x\n", (int)dev_dir_name);
    989 	if (trigger_name == NULL) {
    990 		/*
    991 		 * Build the trigger name. If it is device associated it's
    992 		 * name is <device_name>_dev[n] where n matches the device
    993 		 * number found above
    994 		 */
    995 		ret = asprintf(&trigger_name,
    996 			       "%s-dev%d", device_name, dev_num);
    997 		if (ret < 0) {
    998 			ret = -ENOMEM;
    999 			goto error_ret;
   1000 		}
   1001 	}
   1002 	/* Verify the trigger exists */
   1003 	trig_num = find_type_by_name(trigger_name, "trigger");
   1004 	if (trig_num < 0) {
   1005 		printf("Failed to find the trigger %s\n", trigger_name);
   1006 		ret = -ENODEV;
   1007 		goto error_free_triggername;
   1008 	}
   1009 	printf("iio trigger number being used is %d\n", trig_num);
   1010 	ret = asprintf(&buf_dir_name, "%siio:device%d/buffer", iio_dir, dev_num);
   1011 	if (ret < 0) {
   1012 		ret = -ENOMEM;
   1013 		goto error_free_triggername;
   1014 	}
   1015 	enable_enable_main(0);
   1016 	ret = write_sysfs_int_and_verify("power_state", dev_dir_name, 1);
   1017 	/*
   1018 	 * Parse the files in scan_elements to identify what channels are
   1019 	 * present
   1020 	 */
   1021 	ret = 0;
   1022 	setup_dmp(dev_dir_name);
   1023 
   1024 	printf("%s %s\n", dev_dir_name, trigger_name);
   1025 
   1026 	/* Set the device trigger to be the data rdy trigger found above */
   1027 	ret = write_sysfs_string_and_verify("trigger/current_trigger",
   1028 					dev_dir_name,
   1029 					trigger_name);
   1030 	if (ret < 0) {
   1031 		printf("Failed to write current_trigger file\n");
   1032 		goto error_free_buf_dir_name;
   1033 	}
   1034 	/* Setup ring buffer parameters */
   1035 	/* length must be even number because iio_store_to_sw_ring is expecting
   1036 		half pointer to be equal to the read pointer, which is impossible
   1037 		when buflen is odd number. This is actually a bug in the code */
   1038 	ret = write_sysfs_int("length", buf_dir_name, buf_len*2);
   1039 	if (ret < 0)
   1040 		goto exit_here;
   1041 	enable_enable_main(1);
   1042 	inv_create_thread();
   1043 exit_here:
   1044 error_free_buf_dir_name:
   1045 	free(buf_dir_name);
   1046 error_free_triggername:
   1047 	if (datardytrigger)
   1048 		free(trigger_name);
   1049 error_ret:
   1050 	return ret;
   1051 }
   1052