1 /* 2 * Copyright (c) Invensense Inc. 2012 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 as published by 6 * the Free Software Foundation. 7 */ 8 9 #include <unistd.h> 10 #include <dirent.h> 11 #include <fcntl.h> 12 #include <stdio.h> 13 #include <errno.h> 14 #include <sys/stat.h> 15 #include <dirent.h> 16 #include <linux/types.h> 17 #include <string.h> 18 #include <poll.h> 19 #include <termios.h> 20 21 #include "iio_utils.h" 22 #include "ml_load_dmp.h" 23 #include "ml_sysfs_helper.h" 24 #include "authenticate.h" 25 #include "mlos.h" 26 27 #define DMP_CODE_SIZE (3060) 28 #define POLL_TIME (2000) // 2sec 29 30 // settings 31 static int accel_only = false; 32 static int test_motion = false; 33 static int test_flick = false; 34 static int test_pedometer = false; 35 static int test_orientation = false; 36 int verbose = false; 37 38 // paths 39 char *dev_dir_name, *buf_dir_name; 40 41 // all the DMP features supported 42 enum { 43 FEAT_TAP = 0, 44 FEAT_ORIENTATION, 45 FEAT_DISPLAY_ORIENTATION, 46 FEAT_MOTION, 47 FEAT_FLICK, 48 49 FEAT_NUM, 50 } features; 51 52 typedef void (*handler_t) (int data); 53 54 struct dmp_feat_t { 55 int enabled; 56 struct pollfd *pollfd; 57 char *sysfs_name; 58 handler_t phandler; 59 }; 60 61 static struct dmp_feat_t dmp_feat[FEAT_NUM] = {{0}}; 62 static struct pollfd pollfds[FEAT_NUM]; 63 static int pollfds_used = 0; 64 65 /************************************************** 66 This _kbhit() function is courtesy of the web 67 ***************************************************/ 68 int _kbhit(void) 69 { 70 static const int STDIN = 0; 71 static bool initialized = false; 72 73 if (!initialized) { 74 // Use termios to turn off line buffering 75 struct termios term; 76 tcgetattr(STDIN, &term); 77 term.c_lflag &= ~ICANON; 78 tcsetattr(STDIN, TCSANOW, &term); 79 setbuf(stdin, NULL); 80 initialized = true; 81 } 82 83 int bytesWaiting; 84 ioctl(STDIN, FIONREAD, &bytesWaiting); 85 return bytesWaiting; 86 } 87 88 /** 89 * size_from_channelarray() - calculate the storage size of a scan 90 * @channels: the channel info array 91 * @num_channels: size of the channel info array 92 * 93 * Has the side effect of filling the channels[i].location values used 94 * in processing the buffer output. 95 */ 96 int size_from_channelarray(struct iio_channel_info *channels, int num_channels) 97 { 98 int bytes = 0; 99 int i = 0; 100 while (i < num_channels) { 101 if (bytes % channels[i].bytes == 0) 102 channels[i].location = bytes; 103 else 104 channels[i].location = bytes - bytes%channels[i].bytes 105 + channels[i].bytes; 106 bytes = channels[i].location + channels[i].bytes; 107 i++; 108 } 109 return bytes; 110 } 111 112 void print2byte(int input, struct iio_channel_info *info) 113 { 114 /* shift before conversion to avoid sign extension 115 of left aligned data */ 116 input = input >> info->shift; 117 if (info->is_signed) { 118 int16_t val = input; 119 val &= (1 << info->bits_used) - 1; 120 val = (int16_t)(val << (16 - info->bits_used)) >> 121 (16 - info->bits_used); 122 /*printf("%d, %05f, scale=%05f", val, 123 (float)(val + info->offset)*info->scale, info->scale);*/ 124 printf("%d, ", val); 125 126 } else { 127 uint16_t val = input; 128 val &= (1 << info->bits_used) - 1; 129 printf("%05f ", ((float)val + info->offset)*info->scale); 130 } 131 } 132 133 /** 134 * process_scan() - print out the values in SI units 135 * @data: pointer to the start of the scan 136 * @infoarray: information about the channels. Note 137 * size_from_channelarray must have been called first to fill the 138 * location offsets. 139 * @num_channels: the number of active channels 140 */ 141 void process_scan(char *data, struct iio_channel_info *infoarray, 142 int num_channels) 143 { 144 int k; 145 //char *tmp; 146 for (k = 0; k < num_channels; k++) { 147 switch (infoarray[k].bytes) { 148 /* only a few cases implemented so far */ 149 case 2: 150 print2byte(*(uint16_t *)(data + infoarray[k].location), 151 &infoarray[k]); 152 //tmp = data + infoarray[k].location; 153 break; 154 case 4: 155 if (infoarray[k].is_signed) { 156 int32_t val = *(int32_t *)(data + infoarray[k].location); 157 if ((val >> infoarray[k].bits_used) & 1) 158 val = (val & infoarray[k].mask) | ~infoarray[k].mask; 159 /* special case for timestamp */ 160 printf(" %d ", val); 161 } 162 break; 163 case 8: 164 if (infoarray[k].is_signed) { 165 int64_t val = *(int64_t *)(data + infoarray[k].location); 166 if ((val >> infoarray[k].bits_used) & 1) 167 val = (val & infoarray[k].mask) | ~infoarray[k].mask; 168 /* special case for timestamp */ 169 if (infoarray[k].scale == 1.0f && 170 infoarray[k].offset == 0.0f) 171 printf(" %lld", val); 172 else 173 printf("%05f ", ((float)val + infoarray[k].offset) 174 * infoarray[k].scale); 175 } 176 break; 177 default: 178 break; 179 } 180 } 181 printf("\n"); 182 } 183 184 /* 185 Enablers for the gestures 186 */ 187 188 int enable_flick(char *p, int on) 189 { 190 int ret; 191 printf("flick:%s\n", p); 192 ret = write_sysfs_int_and_verify("flick_int_on", p, on); 193 if (ret < 0) 194 return ret; 195 ret = write_sysfs_int_and_verify("flick_upper", p, 3147790); 196 if (ret < 0) 197 return ret; 198 ret = write_sysfs_int_and_verify("flick_lower", p, -3147790); 199 if (ret < 0) 200 return ret; 201 ret = write_sysfs_int_and_verify("flick_counter", p, 50); 202 if (ret < 0) 203 return ret; 204 ret = write_sysfs_int_and_verify("flick_message_on", p, 0); 205 if (ret < 0) 206 return ret; 207 ret = write_sysfs_int_and_verify("flick_axis", p, 0); 208 if (ret < 0) 209 return ret; 210 211 return 0; 212 } 213 214 void verify_img(char *dmp_path) 215 { 216 FILE *fp; 217 int i; 218 char dmp_img[DMP_CODE_SIZE]; 219 220 if ((fp = fopen(dmp_path, "rb")) < 0) { 221 perror("dmp fail"); 222 } 223 i = fread(dmp_img, 1, DMP_CODE_SIZE, fp); 224 printf("Result=%d\n", i); 225 fclose(fp); 226 fp = fopen("/dev/read_img.h", "wt"); 227 fprintf(fp, "char rec[]={\n"); 228 for(i = 0; i < DMP_CODE_SIZE; i++) { 229 fprintf(fp, "0x%02x, ", dmp_img[i]); 230 if(((i + 1) % 16) == 0) { 231 fprintf(fp, "\n"); 232 } 233 } 234 fprintf(fp, "};\n "); 235 fclose(fp); 236 } 237 238 int setup_dmp(char *dev_path, int p_event) 239 { 240 char dmp_path[100]; 241 int ret; 242 FILE *fd; 243 244 printf("INFO: sysfs path=%s\n", dev_path); 245 246 ret = write_sysfs_int_and_verify("power_state", dev_path, 1); 247 if (ret < 0) 248 return ret; 249 250 ret = write_sysfs_int("in_accel_scale", dev_path, 0); 251 if (ret < 0) 252 return ret; 253 ret = write_sysfs_int("in_anglvel_scale", dev_path, 3); 254 if (ret < 0) 255 return ret; 256 ret = write_sysfs_int("sampling_frequency", dev_path, 200); 257 if (ret < 0) 258 return ret; 259 ret = write_sysfs_int_and_verify("firmware_loaded", dev_path, 0); 260 if (ret < 0) 261 return ret; 262 263 sprintf(dmp_path, "%s/dmp_firmware", dev_path); 264 if ((fd = fopen(dmp_path, "wb")) < 0 ) { 265 perror("dmp fail"); 266 } 267 inv_load_dmp(fd); 268 fclose(fd); 269 270 printf("INFO: firmware_loaded=%d\n", 271 read_sysfs_posint("firmware_loaded", dev_path)); 272 273 // set accel offsets 274 //ret = write_sysfs_int_and_verify("in_accel_x_offset", 275 // dev_path, 0xabcd0000); 276 //if (ret < 0) 277 // return ret; 278 //ret = write_sysfs_int_and_verify("in_accel_y_offset", 279 // dev_path, 0xffff0000); 280 //if (ret < 0) 281 // return ret; 282 //ret = write_sysfs_int_and_verify("in_accel_z_offset", 283 // dev_path, 0xcdef0000); 284 //if (ret < 0) 285 // return ret; 286 287 ret = write_sysfs_int_and_verify("dmp_on", dev_path, 1); 288 if (ret < 0) 289 return ret; 290 ret = write_sysfs_int_and_verify("dmp_int_on", dev_path, 1); 291 if (ret < 0) 292 return ret; 293 294 /* select which event to enable and interrupt on/off here */ 295 if (test_flick) { 296 ret = enable_flick(dev_path, 1); 297 if (ret < 0) 298 return ret; 299 } 300 301 /* 302 ret = write_sysfs_int_and_verify("tap_on", dev_path, 1); 303 if (ret < 0) 304 return ret; 305 */ 306 307 /*ret = write_sysfs_int_and_verify("display_orientation_on", 308 dev_path, 1); 309 if (ret < 0) 310 return ret;*/ 311 if (test_orientation) { 312 ret = write_sysfs_int_and_verify("orientation_on", dev_path, 1); 313 if (ret < 0) 314 return ret; 315 } 316 /* ret = write_sysfs_int_and_verify("dmp_output_rate", dev_path, 25); 317 if (ret < 0) 318 return ret;*/ 319 ret = write_sysfs_int_and_verify("dmp_event_int_on", dev_path, p_event); 320 if (ret < 0) 321 return ret; 322 323 //verify_img(dmp_path); 324 return 0; 325 } 326 327 /* 328 Handlers for the gestures 329 */ 330 331 void handle_flick(int flick) 332 { 333 printf("flick=%x\n", flick); 334 } 335 336 void handle_display_orientation(int orient) 337 { 338 printf("display_orientation=%x\n", orient); 339 } 340 341 void handle_motion(int motion) 342 { 343 printf("motion=%x\n", motion); 344 } 345 346 void handle_orientation(int orient) 347 { 348 printf("orientation="); 349 if (orient & 0x01) 350 printf("+X, "); 351 if (orient & 0x02) 352 printf("-X, "); 353 if (orient & 0x04) 354 printf("+Y, "); 355 if (orient & 0x08) 356 printf("-Y, "); 357 if (orient & 0x10) 358 printf("+Z, "); 359 if (orient & 0x20) 360 printf("-Z, "); 361 if (orient & 0x40) 362 printf("flip"); 363 printf("\n"); 364 } 365 366 void handle_tap(int tap) 367 { 368 int tap_dir = tap / 8; 369 int tap_num = tap % 8 + 1; 370 371 printf("tap="); 372 switch (tap_dir) { 373 case 1: 374 printf("+X, "); 375 break; 376 case 2: 377 printf("-X, "); 378 break; 379 case 3: 380 printf("+Y, "); 381 break; 382 case 4: 383 printf("-Y, "); 384 break; 385 case 5: 386 printf("+Z, "); 387 break; 388 case 6: 389 printf("-Z, "); 390 break; 391 default: 392 break; 393 } 394 printf("#%d\n", tap_num); 395 } 396 397 int handle_pedometer(int *got_event) 398 { 399 static int last_pedometer_steps = -1; 400 static long last_pedometer_time = -1; 401 static unsigned long last_pedometer_poll = 0L; 402 static unsigned long pedometer_poll_timeout = 500L; // .5 second 403 404 unsigned long now; 405 int pedometer_steps; 406 long pedometer_time; 407 408 #ifdef DEBUG_PRINT 409 printf("GT:Pedometer Handler\n"); 410 #endif 411 412 if ((now = inv_get_tick_count()) - last_pedometer_poll 413 < pedometer_poll_timeout) { 414 return 0; 415 } 416 last_pedometer_poll = now; 417 418 pedometer_steps = read_sysfs_posint("pedometer_steps", dev_dir_name); 419 pedometer_time = read_sysfs_posint("pedometer_time", dev_dir_name); 420 421 if (last_pedometer_steps == -1 && last_pedometer_time == -1) { 422 if (!*got_event) 423 printf("\n"); 424 printf("p> pedometer=%d, %ld ", 425 pedometer_steps, pedometer_time); 426 if (pedometer_steps > 10 427 || pedometer_time > (pedometer_poll_timeout * 2)) 428 printf("(resumed)\n"); 429 else 430 printf("\n"); 431 *got_event = true; 432 } else if (last_pedometer_steps != pedometer_steps 433 || last_pedometer_time != pedometer_time) { 434 if (!*got_event) 435 printf("\n"); 436 printf("p> pedometer=%d, %ld\n", 437 pedometer_steps, pedometer_time); 438 *got_event = true; 439 } 440 441 last_pedometer_steps = pedometer_steps; 442 last_pedometer_time = pedometer_time; 443 444 return 0; 445 } 446 447 /* 448 Main processing functions 449 */ 450 451 void dump_dmp_event_struct(void) 452 { 453 #define VARVAL(f, v) printf("\t%s : " f "\n", #v, v); 454 int i; 455 456 printf("dmp_feat structure content:\n"); 457 for (i = 0; i < FEAT_NUM; i++) { 458 printf("%d - ", i); 459 VARVAL("%d", dmp_feat[i].enabled); 460 VARVAL("%s", dmp_feat[i].sysfs_name); 461 VARVAL("%p", dmp_feat[i].phandler); 462 VARVAL("%p", dmp_feat[i].pollfd); 463 if (dmp_feat[i].pollfd) { 464 VARVAL("%d", dmp_feat[i].pollfd->events); 465 VARVAL("%d", dmp_feat[i].pollfd->revents); 466 VARVAL("%d", dmp_feat[i].pollfd->fd); 467 } 468 } 469 printf("dmp_feat structure content:\n"); 470 for (i = 0; i < FEAT_NUM; i++) { 471 printf("%d - ", i); 472 VARVAL("%d", pollfds[i].fd); 473 VARVAL("%d", pollfds[i].events); 474 VARVAL("%d", pollfds[i].revents); 475 } 476 printf("end.\n"); 477 } 478 479 void init_dmp_event_fds(void) 480 { 481 int i, j = 0; 482 char file_name[100]; 483 484 for (i = 0; i < FEAT_NUM; i++) { 485 if (!dmp_feat[i].enabled) 486 continue; 487 sprintf(file_name, "%s/%s", dev_dir_name, dmp_feat[i].sysfs_name); 488 pollfds[j].fd = open(file_name, O_RDONLY | O_NONBLOCK); 489 if (pollfds[j].fd < 0) { 490 printf("Err: cannot open requested event file '%s'\n", file_name); 491 } else { 492 printf("INFO: opened event node '%s'\n", file_name); 493 } 494 pollfds[j].events = POLLPRI | POLLERR; 495 pollfds[j].revents = 0; 496 497 dmp_feat[i].pollfd = &pollfds[j]; 498 j++; 499 } 500 } 501 502 void close_dmp_event_fds(void) 503 { 504 int i; 505 for (i = 0; i < pollfds_used; i++) 506 close(pollfds[i].fd); 507 } 508 509 void poll_dmp_event_fds(void) 510 { 511 int i; 512 char d[4]; 513 static int got_event = 1; 514 515 // read the pollable fds 516 for (i = 0; i < pollfds_used; i++) 517 read(pollfds[i].fd, d, 4); 518 519 // poll 520 if (got_event) 521 printf("e> "); 522 got_event = false; 523 poll(pollfds, pollfds_used, POLL_TIME); 524 525 for (i = 0; i < FEAT_NUM; i++) { 526 if (!dmp_feat[i].enabled) 527 continue; 528 529 if (dmp_feat[i].pollfd->revents != 0) { 530 char file_name[200]; 531 int data; 532 533 sprintf(file_name, "%s/%s", 534 dev_dir_name, dmp_feat[i].sysfs_name); 535 FILE *fp = fopen(file_name, "rt"); 536 if (!fp) { 537 printf("Err:cannot open requested event file '%s'\n", 538 dmp_feat[i].sysfs_name); 539 continue; 540 } 541 fscanf(fp, "%d\n", &data); 542 fclose(fp); 543 dmp_feat[i].pollfd->revents = 0; 544 545 dmp_feat[i].phandler(data); 546 got_event = true; 547 } 548 } 549 550 if (test_pedometer) { 551 /* pedometer is not event based, therefore we poll using a timer every 552 pedometer_poll_timeout milliseconds */ 553 handle_pedometer(&got_event); 554 } 555 } 556 557 /* 558 Main 559 */ 560 561 int main(int argc, char **argv) 562 { 563 unsigned long num_loops = 2; 564 unsigned long timedelay = 100000; 565 unsigned long buf_len = 128; 566 567 int ret, c, i, j, toread; 568 int fp; 569 570 int num_channels; 571 char *trigger_name = NULL; 572 573 int datardytrigger = 1; 574 char *data; 575 int read_size; 576 int dev_num, trig_num; 577 char *buffer_access; 578 int scan_size; 579 int noevents = 0; 580 int p_event = 0, nodmp = 0; 581 char *dummy; 582 char chip_name[10]; 583 char device_name[10]; 584 char sysfs[100]; 585 586 struct iio_channel_info *infoarray; 587 588 // all output to stdout must be delivered immediately, no buffering 589 setvbuf(stdout, NULL, _IONBF, 0); 590 591 // get info about the device and driver 592 inv_get_sysfs_path(sysfs); 593 if (inv_get_chip_name(chip_name) != INV_SUCCESS) { 594 printf("get chip name fail\n"); 595 exit(0); 596 } 597 printf("INFO: chip_name=%s\n", chip_name); 598 599 for (i = 0; i < strlen(chip_name); i++) 600 device_name[i] = tolower(chip_name[i]); 601 device_name[strlen(chip_name)] = '\0'; 602 printf("INFO: device name=%s\n", device_name); 603 604 /* parse the command line parameters 605 -r means no DMP is enabled (raw) -> should be used for mpu3050. 606 -p means no print of data 607 when using -p, 1 means orientation, 2 means tap, 3 means flick */ 608 while ((c = getopt(argc, argv, "l:w:c:premavt:")) != -1) { 609 switch (c) { 610 case 't': 611 trigger_name = optarg; 612 datardytrigger = 0; 613 break; 614 case 'e': 615 noevents = 1; 616 break; 617 case 'p': 618 p_event = 1; 619 break; 620 case 'r': 621 nodmp = 1; 622 break; 623 case 'c': 624 num_loops = strtoul(optarg, &dummy, 10); 625 break; 626 case 'w': 627 timedelay = strtoul(optarg, &dummy, 10); 628 break; 629 case 'l': 630 buf_len = strtoul(optarg, &dummy, 10); 631 break; 632 case 'm': 633 test_motion = true; 634 break; 635 case 'a': 636 accel_only = true; 637 break; 638 case 'v': 639 verbose = true; 640 break; 641 case '?': 642 return -1; 643 } 644 } 645 646 pollfds_used = 0; 647 648 // comment out/remove/if(0) the block corresponding to the feature 649 // that you want to disable 650 651 if (0) { 652 struct dmp_feat_t f = { 653 true, 654 NULL, 655 "event_tap", 656 handle_tap 657 }; 658 dmp_feat[pollfds_used] = f; 659 pollfds_used++; 660 } 661 if (test_orientation) { 662 struct dmp_feat_t f = { 663 true, 664 NULL, 665 "event_orientation", 666 handle_orientation 667 }; 668 dmp_feat[pollfds_used] = f; 669 pollfds_used++; 670 } 671 /*if (1) { 672 struct dmp_feat_t f = { 673 true, 674 NULL, 675 "event_display_orientation", 676 handle_display_orientation 677 }; 678 dmp_feat[pollfds_used] = f; 679 pollfds_used++; 680 }*/ 681 if (test_motion) { 682 struct dmp_feat_t f = { 683 true, 684 NULL, 685 "event_accel_motion", 686 handle_motion 687 }; 688 dmp_feat[pollfds_used] = f; 689 pollfds_used++; 690 } 691 if (test_flick) { 692 struct dmp_feat_t f = { 693 true, 694 NULL, 695 "event_flick", 696 handle_flick 697 }; 698 dmp_feat[pollfds_used] = f; 699 pollfds_used++; 700 } 701 702 // debug 703 printf("INFO\n"); 704 printf("INFO: Configured features:\n"); 705 for (i = 0; i < pollfds_used; i++) 706 printf("INFO: %d -> %s\n", i, dmp_feat[i].sysfs_name); 707 printf("INFO\n"); 708 709 /* Find the device requested */ 710 dev_num = find_type_by_name(device_name, "iio:device"); 711 if (dev_num < 0) { 712 printf("Failed to find the %s\n", device_name); 713 ret = -ENODEV; 714 goto error_ret; 715 } 716 printf("INFO: iio device number=%d\n", dev_num); 717 asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num); 718 if (trigger_name == NULL) { 719 /* 720 * Build the trigger name. If it is device associated it's 721 * name is <device_name>_dev[n] where n matches the device 722 * number found above 723 */ 724 ret = asprintf(&trigger_name, "%s-dev%d", device_name, dev_num); 725 if (ret < 0) { 726 ret = -ENOMEM; 727 goto error_ret; 728 } 729 } 730 731 ret = write_sysfs_int_and_verify("master_enable", dev_dir_name, 0); 732 if (ret < 0) 733 return ret; 734 ret = write_sysfs_int_and_verify("buffer/enable", dev_dir_name, 0); 735 if (ret < 0) 736 return ret; 737 ret = write_sysfs_int_and_verify("power_state", dev_dir_name, 1); 738 739 // 740 // motion interrupt in low power accel mode 741 // 742 if (test_motion) { 743 ret = write_sysfs_int_and_verify("motion_lpa_on", dev_dir_name, 1); 744 if (ret < 0) 745 return ret; 746 // magnitude threshold - range [0, 1020] in 32 mg increments 747 ret = write_sysfs_int_and_verify("motion_lpa_threshold", dev_dir_name, 748 3 * 32); 749 if (ret < 0) 750 return ret; 751 // duration in ms up to 2^16 752 // ret = write_sysfs_int_and_verify("motion_lpa_dur", dev_dir_name, 753 // 200 * 1); 754 //if (ret < 0) 755 // return ret; 756 // motion_lpa_freq: 0 for 1.25, 1 for 5, 2 for 20, 3 for 40 Hz update rate 757 // of the low power accel mode. 758 // The higher the rate, the better responsiveness of the motion interrupt. 759 ret = write_sysfs_int("motion_lpa_freq", dev_dir_name, 2); 760 if (ret < 0) 761 return ret; 762 } else { 763 ret = write_sysfs_int_and_verify("motion_lpa_on", dev_dir_name, 0); 764 if (ret < 0) 765 return ret; 766 } 767 768 /* Verify the trigger exists */ 769 trig_num = find_type_by_name(trigger_name, "trigger"); 770 if (trig_num < 0) { 771 printf("Failed to find the trigger %s\n", trigger_name); 772 ret = -ENODEV; 773 goto error_free_triggername; 774 } 775 printf("INFO: iio trigger number=%d\n", trig_num); 776 777 if (!nodmp) 778 setup_dmp(dev_dir_name, p_event); 779 780 /* 781 * Construct the directory name for the associated buffer. 782 * As we know that the lis3l02dq has only one buffer this may 783 * be built rather than found. 784 */ 785 ret = asprintf(&buf_dir_name, "%siio:device%d/buffer", iio_dir, dev_num); 786 if (ret < 0) { 787 ret = -ENOMEM; 788 goto error_free_triggername; 789 } 790 791 /* Set the device trigger to be the data rdy trigger found above */ 792 ret = write_sysfs_string_and_verify("trigger/current_trigger", 793 dev_dir_name, 794 trigger_name); 795 if (ret < 0) { 796 printf("Failed to write current_trigger file\n"); 797 goto error_free_buf_dir_name; 798 } 799 800 /* Setup ring buffer parameters 801 length must be even number because iio_store_to_sw_ring is expecting 802 half pointer to be equal to the read pointer, which is impossible 803 when buflen is odd number. This is actually a bug in the code */ 804 ret = write_sysfs_int("length", buf_dir_name, buf_len * 2); 805 if (ret < 0) 806 goto exit_here; 807 808 // gyro 809 if (accel_only) { 810 ret = enable_anglvel_se(dev_dir_name, &infoarray, &num_channels, 0); 811 if (ret < 0) 812 return ret; 813 ret = write_sysfs_int_and_verify("gyro_enable", dev_dir_name, 0); 814 if (ret < 0) 815 return ret; 816 } else { 817 ret = enable_anglvel_se(dev_dir_name, &infoarray, &num_channels, 1); 818 if (ret < 0) 819 return ret; 820 ret = write_sysfs_int_and_verify("gyro_enable", dev_dir_name, 1); 821 if (ret < 0) 822 return ret; 823 } 824 825 // accel 826 ret = enable_accel_se(dev_dir_name, &infoarray, &num_channels, 1); 827 if (ret < 0) 828 return ret; 829 ret = write_sysfs_int_and_verify("accel_enable", dev_dir_name, 1); 830 if (ret < 0) 831 return ret; 832 833 // quaternion 834 if (!nodmp) { 835 ret = enable_quaternion_se(dev_dir_name, &infoarray, &num_channels, 1); 836 if (ret < 0) 837 return ret; 838 ret = write_sysfs_int_and_verify("three_axes_q_on", dev_dir_name, 1); 839 if (ret < 0) 840 return ret; 841 } else { 842 ret = enable_quaternion_se(dev_dir_name, &infoarray, &num_channels, 0); 843 if (ret < 0) 844 return ret; 845 ret = write_sysfs_int_and_verify("dmp_on", dev_dir_name, 0); 846 if (ret < 0) 847 return ret; 848 } 849 850 //sprintf(dmp_path, "%s/dmp_firmware", dev_dir_name); 851 //verify_img(dmp_path); 852 853 ret = build_channel_array(dev_dir_name, &infoarray, &num_channels); 854 if (ret) { 855 printf("Problem reading scan element information\n"); 856 goto exit_here; 857 } 858 859 /* enable the buffer */ 860 ret = write_sysfs_int_and_verify("enable", buf_dir_name, 1); 861 if (ret < 0) 862 goto exit_here; 863 scan_size = size_from_channelarray(infoarray, num_channels); 864 data = malloc(scan_size * buf_len); 865 if (!data) { 866 ret = -ENOMEM; 867 goto exit_here; 868 } 869 /*ADDED*/ 870 ret = write_sysfs_int_and_verify("master_enable", dev_dir_name, 1); 871 if (ret < 0) 872 return ret; 873 if (p_event) { 874 875 /* polling events from the DMP */ 876 init_dmp_event_fds(); 877 while(!_kbhit()) 878 poll_dmp_event_fds(); 879 close_dmp_event_fds(); 880 881 } else { 882 883 /* attempt to open non blocking the access dev */ 884 ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num); 885 if (ret < 0) { 886 ret = -ENOMEM; 887 goto error_free_data; 888 } 889 fp = open(buffer_access, O_RDONLY | O_NONBLOCK); 890 if (fp == -1) { /*If it isn't there make the node */ 891 printf("Failed to open %s\n", buffer_access); 892 ret = -errno; 893 goto error_free_buffer_access; 894 } 895 /* wait for events num_loops times */ 896 for (j = 0; j < num_loops; j++) { 897 if (!noevents) { 898 struct pollfd pfd = { 899 .fd = fp, 900 .events = POLLIN, 901 }; 902 poll(&pfd, 1, -1); 903 toread = 1; 904 if (j % 128 == 0) 905 usleep(timedelay); 906 907 } else { 908 usleep(timedelay); 909 toread = 1; 910 } 911 read_size = read(fp, data, toread * scan_size); 912 if (read_size == -EAGAIN) { 913 printf("nothing available\n"); 914 continue; 915 } 916 if (!p_event) { 917 for (i = 0; i < read_size / scan_size; i++) 918 process_scan(data + scan_size * i, infoarray, num_channels); 919 } 920 } 921 close(fp); 922 } 923 924 error_free_buffer_access: 925 free(buffer_access); 926 error_free_data: 927 free(data); 928 exit_here: 929 /* stop the ring buffer */ 930 ret = write_sysfs_int_and_verify("enable", buf_dir_name, 0); 931 /* disable the dmp */ 932 if (p_event) 933 ret = write_sysfs_int_and_verify("dmp_on", dev_dir_name, 0); 934 935 error_free_buf_dir_name: 936 free(buf_dir_name); 937 error_free_triggername: 938 if (datardytrigger) 939 free(trigger_name); 940 error_ret: 941 return ret; 942 } 943