1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Industrialio buffer test code. 3 * 4 * Copyright (c) 2008 Jonathan Cameron 5 * 6 * This program is primarily intended as an example application. 7 * Reads the current buffer setup from sysfs and starts a short capture 8 * from the specified device, pretty printing the result after appropriate 9 * conversion. 10 * 11 * Command line parameters 12 * generic_buffer -n <device_name> -t <trigger_name> 13 * If trigger name is not specified the program assumes you want a dataready 14 * trigger associated with the device and goes looking for it. 15 */ 16 17 #include <unistd.h> 18 #include <stdlib.h> 19 #include <dirent.h> 20 #include <fcntl.h> 21 #include <stdio.h> 22 #include <errno.h> 23 #include <sys/stat.h> 24 #include <sys/dir.h> 25 #include <linux/types.h> 26 #include <string.h> 27 #include <poll.h> 28 #include <endian.h> 29 #include <getopt.h> 30 #include <inttypes.h> 31 #include <stdbool.h> 32 #include <signal.h> 33 #include "iio_utils.h" 34 35 /** 36 * enum autochan - state for the automatic channel enabling mechanism 37 */ 38 enum autochan { 39 AUTOCHANNELS_DISABLED, 40 AUTOCHANNELS_ENABLED, 41 AUTOCHANNELS_ACTIVE, 42 }; 43 44 /** 45 * size_from_channelarray() - calculate the storage size of a scan 46 * @channels: the channel info array 47 * @num_channels: number of channels 48 * 49 * Has the side effect of filling the channels[i].location values used 50 * in processing the buffer output. 51 **/ 52 int size_from_channelarray(struct iio_channel_info *channels, int num_channels) 53 { 54 int bytes = 0; 55 int i = 0; 56 57 while (i < num_channels) { 58 if (bytes % channels[i].bytes == 0) 59 channels[i].location = bytes; 60 else 61 channels[i].location = bytes - bytes % channels[i].bytes 62 + channels[i].bytes; 63 64 bytes = channels[i].location + channels[i].bytes; 65 i++; 66 } 67 68 return bytes; 69 } 70 71 void print1byte(uint8_t input, struct iio_channel_info *info) 72 { 73 /* 74 * Shift before conversion to avoid sign extension 75 * of left aligned data 76 */ 77 input >>= info->shift; 78 input &= info->mask; 79 if (info->is_signed) { 80 int8_t val = (int8_t)(input << (8 - info->bits_used)) >> 81 (8 - info->bits_used); 82 printf("%05f ", ((float)val + info->offset) * info->scale); 83 } else { 84 printf("%05f ", ((float)input + info->offset) * info->scale); 85 } 86 } 87 88 void print2byte(uint16_t input, struct iio_channel_info *info) 89 { 90 /* First swap if incorrect endian */ 91 if (info->be) 92 input = be16toh(input); 93 else 94 input = le16toh(input); 95 96 /* 97 * Shift before conversion to avoid sign extension 98 * of left aligned data 99 */ 100 input >>= info->shift; 101 input &= info->mask; 102 if (info->is_signed) { 103 int16_t val = (int16_t)(input << (16 - info->bits_used)) >> 104 (16 - info->bits_used); 105 printf("%05f ", ((float)val + info->offset) * info->scale); 106 } else { 107 printf("%05f ", ((float)input + info->offset) * info->scale); 108 } 109 } 110 111 void print4byte(uint32_t input, struct iio_channel_info *info) 112 { 113 /* First swap if incorrect endian */ 114 if (info->be) 115 input = be32toh(input); 116 else 117 input = le32toh(input); 118 119 /* 120 * Shift before conversion to avoid sign extension 121 * of left aligned data 122 */ 123 input >>= info->shift; 124 input &= info->mask; 125 if (info->is_signed) { 126 int32_t val = (int32_t)(input << (32 - info->bits_used)) >> 127 (32 - info->bits_used); 128 printf("%05f ", ((float)val + info->offset) * info->scale); 129 } else { 130 printf("%05f ", ((float)input + info->offset) * info->scale); 131 } 132 } 133 134 void print8byte(uint64_t input, struct iio_channel_info *info) 135 { 136 /* First swap if incorrect endian */ 137 if (info->be) 138 input = be64toh(input); 139 else 140 input = le64toh(input); 141 142 /* 143 * Shift before conversion to avoid sign extension 144 * of left aligned data 145 */ 146 input >>= info->shift; 147 input &= info->mask; 148 if (info->is_signed) { 149 int64_t val = (int64_t)(input << (64 - info->bits_used)) >> 150 (64 - info->bits_used); 151 /* special case for timestamp */ 152 if (info->scale == 1.0f && info->offset == 0.0f) 153 printf("%" PRId64 " ", val); 154 else 155 printf("%05f ", 156 ((float)val + info->offset) * info->scale); 157 } else { 158 printf("%05f ", ((float)input + info->offset) * info->scale); 159 } 160 } 161 162 /** 163 * process_scan() - print out the values in SI units 164 * @data: pointer to the start of the scan 165 * @channels: information about the channels. 166 * Note: size_from_channelarray must have been called first 167 * to fill the location offsets. 168 * @num_channels: number of channels 169 **/ 170 void process_scan(char *data, 171 struct iio_channel_info *channels, 172 int num_channels) 173 { 174 int k; 175 176 for (k = 0; k < num_channels; k++) 177 switch (channels[k].bytes) { 178 /* only a few cases implemented so far */ 179 case 1: 180 print1byte(*(uint8_t *)(data + channels[k].location), 181 &channels[k]); 182 break; 183 case 2: 184 print2byte(*(uint16_t *)(data + channels[k].location), 185 &channels[k]); 186 break; 187 case 4: 188 print4byte(*(uint32_t *)(data + channels[k].location), 189 &channels[k]); 190 break; 191 case 8: 192 print8byte(*(uint64_t *)(data + channels[k].location), 193 &channels[k]); 194 break; 195 default: 196 break; 197 } 198 printf("\n"); 199 } 200 201 static int enable_disable_all_channels(char *dev_dir_name, int enable) 202 { 203 const struct dirent *ent; 204 char scanelemdir[256]; 205 DIR *dp; 206 int ret; 207 208 snprintf(scanelemdir, sizeof(scanelemdir), 209 FORMAT_SCAN_ELEMENTS_DIR, dev_dir_name); 210 scanelemdir[sizeof(scanelemdir)-1] = '\0'; 211 212 dp = opendir(scanelemdir); 213 if (!dp) { 214 fprintf(stderr, "Enabling/disabling channels: can't open %s\n", 215 scanelemdir); 216 return -EIO; 217 } 218 219 ret = -ENOENT; 220 while (ent = readdir(dp), ent) { 221 if (iioutils_check_suffix(ent->d_name, "_en")) { 222 printf("%sabling: %s\n", 223 enable ? "En" : "Dis", 224 ent->d_name); 225 ret = write_sysfs_int(ent->d_name, scanelemdir, 226 enable); 227 if (ret < 0) 228 fprintf(stderr, "Failed to enable/disable %s\n", 229 ent->d_name); 230 } 231 } 232 233 if (closedir(dp) == -1) { 234 perror("Enabling/disabling channels: " 235 "Failed to close directory"); 236 return -errno; 237 } 238 return 0; 239 } 240 241 void print_usage(void) 242 { 243 fprintf(stderr, "Usage: generic_buffer [options]...\n" 244 "Capture, convert and output data from IIO device buffer\n" 245 " -a Auto-activate all available channels\n" 246 " -A Force-activate ALL channels\n" 247 " -c <n> Do n conversions, or loop forever if n < 0\n" 248 " -e Disable wait for event (new data)\n" 249 " -g Use trigger-less mode\n" 250 " -l <n> Set buffer length to n samples\n" 251 " --device-name -n <name>\n" 252 " --device-num -N <num>\n" 253 " Set device by name or number (mandatory)\n" 254 " --trigger-name -t <name>\n" 255 " --trigger-num -T <num>\n" 256 " Set trigger by name or number\n" 257 " -w <n> Set delay between reads in us (event-less mode)\n"); 258 } 259 260 enum autochan autochannels = AUTOCHANNELS_DISABLED; 261 char *dev_dir_name = NULL; 262 char *buf_dir_name = NULL; 263 bool current_trigger_set = false; 264 265 void cleanup(void) 266 { 267 int ret; 268 269 /* Disable trigger */ 270 if (dev_dir_name && current_trigger_set) { 271 /* Disconnect the trigger - just write a dummy name. */ 272 ret = write_sysfs_string("trigger/current_trigger", 273 dev_dir_name, "NULL"); 274 if (ret < 0) 275 fprintf(stderr, "Failed to disable trigger: %s\n", 276 strerror(-ret)); 277 current_trigger_set = false; 278 } 279 280 /* Disable buffer */ 281 if (buf_dir_name) { 282 ret = write_sysfs_int("enable", buf_dir_name, 0); 283 if (ret < 0) 284 fprintf(stderr, "Failed to disable buffer: %s\n", 285 strerror(-ret)); 286 } 287 288 /* Disable channels if auto-enabled */ 289 if (dev_dir_name && autochannels == AUTOCHANNELS_ACTIVE) { 290 ret = enable_disable_all_channels(dev_dir_name, 0); 291 if (ret) 292 fprintf(stderr, "Failed to disable all channels\n"); 293 autochannels = AUTOCHANNELS_DISABLED; 294 } 295 } 296 297 void sig_handler(int signum) 298 { 299 fprintf(stderr, "Caught signal %d\n", signum); 300 cleanup(); 301 exit(-signum); 302 } 303 304 void register_cleanup(void) 305 { 306 struct sigaction sa = { .sa_handler = sig_handler }; 307 const int signums[] = { SIGINT, SIGTERM, SIGABRT }; 308 int ret, i; 309 310 for (i = 0; i < ARRAY_SIZE(signums); ++i) { 311 ret = sigaction(signums[i], &sa, NULL); 312 if (ret) { 313 perror("Failed to register signal handler"); 314 exit(-1); 315 } 316 } 317 } 318 319 static const struct option longopts[] = { 320 { "device-name", 1, 0, 'n' }, 321 { "device-num", 1, 0, 'N' }, 322 { "trigger-name", 1, 0, 't' }, 323 { "trigger-num", 1, 0, 'T' }, 324 { }, 325 }; 326 327 int main(int argc, char **argv) 328 { 329 long long num_loops = 2; 330 unsigned long timedelay = 1000000; 331 unsigned long buf_len = 128; 332 333 ssize_t i; 334 unsigned long long j; 335 unsigned long toread; 336 int ret, c; 337 int fp = -1; 338 339 int num_channels = 0; 340 char *trigger_name = NULL, *device_name = NULL; 341 342 char *data = NULL; 343 ssize_t read_size; 344 int dev_num = -1, trig_num = -1; 345 char *buffer_access = NULL; 346 int scan_size; 347 int noevents = 0; 348 int notrigger = 0; 349 char *dummy; 350 bool force_autochannels = false; 351 352 struct iio_channel_info *channels = NULL; 353 354 register_cleanup(); 355 356 while ((c = getopt_long(argc, argv, "aAc:egl:n:N:t:T:w:?", longopts, 357 NULL)) != -1) { 358 switch (c) { 359 case 'a': 360 autochannels = AUTOCHANNELS_ENABLED; 361 break; 362 case 'A': 363 autochannels = AUTOCHANNELS_ENABLED; 364 force_autochannels = true; 365 break; 366 case 'c': 367 errno = 0; 368 num_loops = strtoll(optarg, &dummy, 10); 369 if (errno) { 370 ret = -errno; 371 goto error; 372 } 373 374 break; 375 case 'e': 376 noevents = 1; 377 break; 378 case 'g': 379 notrigger = 1; 380 break; 381 case 'l': 382 errno = 0; 383 buf_len = strtoul(optarg, &dummy, 10); 384 if (errno) { 385 ret = -errno; 386 goto error; 387 } 388 389 break; 390 case 'n': 391 device_name = strdup(optarg); 392 break; 393 case 'N': 394 errno = 0; 395 dev_num = strtoul(optarg, &dummy, 10); 396 if (errno) { 397 ret = -errno; 398 goto error; 399 } 400 break; 401 case 't': 402 trigger_name = strdup(optarg); 403 break; 404 case 'T': 405 errno = 0; 406 trig_num = strtoul(optarg, &dummy, 10); 407 if (errno) 408 return -errno; 409 break; 410 case 'w': 411 errno = 0; 412 timedelay = strtoul(optarg, &dummy, 10); 413 if (errno) { 414 ret = -errno; 415 goto error; 416 } 417 break; 418 case '?': 419 print_usage(); 420 ret = -1; 421 goto error; 422 } 423 } 424 425 /* Find the device requested */ 426 if (dev_num < 0 && !device_name) { 427 fprintf(stderr, "Device not set\n"); 428 print_usage(); 429 ret = -1; 430 goto error; 431 } else if (dev_num >= 0 && device_name) { 432 fprintf(stderr, "Only one of --device-num or --device-name needs to be set\n"); 433 print_usage(); 434 ret = -1; 435 goto error; 436 } else if (dev_num < 0) { 437 dev_num = find_type_by_name(device_name, "iio:device"); 438 if (dev_num < 0) { 439 fprintf(stderr, "Failed to find the %s\n", device_name); 440 ret = dev_num; 441 goto error; 442 } 443 } 444 printf("iio device number being used is %d\n", dev_num); 445 446 ret = asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num); 447 if (ret < 0) 448 return -ENOMEM; 449 /* Fetch device_name if specified by number */ 450 if (!device_name) { 451 device_name = malloc(IIO_MAX_NAME_LENGTH); 452 if (!device_name) { 453 ret = -ENOMEM; 454 goto error; 455 } 456 ret = read_sysfs_string("name", dev_dir_name, device_name); 457 if (ret < 0) { 458 fprintf(stderr, "Failed to read name of device %d\n", dev_num); 459 goto error; 460 } 461 } 462 463 if (notrigger) { 464 printf("trigger-less mode selected\n"); 465 } else if (trig_num >= 0) { 466 char *trig_dev_name; 467 ret = asprintf(&trig_dev_name, "%strigger%d", iio_dir, trig_num); 468 if (ret < 0) { 469 return -ENOMEM; 470 } 471 trigger_name = malloc(IIO_MAX_NAME_LENGTH); 472 ret = read_sysfs_string("name", trig_dev_name, trigger_name); 473 free(trig_dev_name); 474 if (ret < 0) { 475 fprintf(stderr, "Failed to read trigger%d name from\n", trig_num); 476 return ret; 477 } 478 printf("iio trigger number being used is %d\n", trig_num); 479 } else { 480 if (!trigger_name) { 481 /* 482 * Build the trigger name. If it is device associated 483 * its name is <device_name>_dev[n] where n matches 484 * the device number found above. 485 */ 486 ret = asprintf(&trigger_name, 487 "%s-dev%d", device_name, dev_num); 488 if (ret < 0) { 489 ret = -ENOMEM; 490 goto error; 491 } 492 } 493 494 /* Look for this "-devN" trigger */ 495 trig_num = find_type_by_name(trigger_name, "trigger"); 496 if (trig_num < 0) { 497 /* OK try the simpler "-trigger" suffix instead */ 498 free(trigger_name); 499 ret = asprintf(&trigger_name, 500 "%s-trigger", device_name); 501 if (ret < 0) { 502 ret = -ENOMEM; 503 goto error; 504 } 505 } 506 507 trig_num = find_type_by_name(trigger_name, "trigger"); 508 if (trig_num < 0) { 509 fprintf(stderr, "Failed to find the trigger %s\n", 510 trigger_name); 511 ret = trig_num; 512 goto error; 513 } 514 515 printf("iio trigger number being used is %d\n", trig_num); 516 } 517 518 /* 519 * Parse the files in scan_elements to identify what channels are 520 * present 521 */ 522 ret = build_channel_array(dev_dir_name, &channels, &num_channels); 523 if (ret) { 524 fprintf(stderr, "Problem reading scan element information\n" 525 "diag %s\n", dev_dir_name); 526 goto error; 527 } 528 if (num_channels && autochannels == AUTOCHANNELS_ENABLED && 529 !force_autochannels) { 530 fprintf(stderr, "Auto-channels selected but some channels " 531 "are already activated in sysfs\n"); 532 fprintf(stderr, "Proceeding without activating any channels\n"); 533 } 534 535 if ((!num_channels && autochannels == AUTOCHANNELS_ENABLED) || 536 (autochannels == AUTOCHANNELS_ENABLED && force_autochannels)) { 537 fprintf(stderr, "Enabling all channels\n"); 538 539 ret = enable_disable_all_channels(dev_dir_name, 1); 540 if (ret) { 541 fprintf(stderr, "Failed to enable all channels\n"); 542 goto error; 543 } 544 545 /* This flags that we need to disable the channels again */ 546 autochannels = AUTOCHANNELS_ACTIVE; 547 548 ret = build_channel_array(dev_dir_name, &channels, 549 &num_channels); 550 if (ret) { 551 fprintf(stderr, "Problem reading scan element " 552 "information\n" 553 "diag %s\n", dev_dir_name); 554 goto error; 555 } 556 if (!num_channels) { 557 fprintf(stderr, "Still no channels after " 558 "auto-enabling, giving up\n"); 559 goto error; 560 } 561 } 562 563 if (!num_channels && autochannels == AUTOCHANNELS_DISABLED) { 564 fprintf(stderr, 565 "No channels are enabled, we have nothing to scan.\n"); 566 fprintf(stderr, "Enable channels manually in " 567 FORMAT_SCAN_ELEMENTS_DIR 568 "/*_en or pass -a to autoenable channels and " 569 "try again.\n", dev_dir_name); 570 ret = -ENOENT; 571 goto error; 572 } 573 574 /* 575 * Construct the directory name for the associated buffer. 576 * As we know that the lis3l02dq has only one buffer this may 577 * be built rather than found. 578 */ 579 ret = asprintf(&buf_dir_name, 580 "%siio:device%d/buffer", iio_dir, dev_num); 581 if (ret < 0) { 582 ret = -ENOMEM; 583 goto error; 584 } 585 586 if (!notrigger) { 587 printf("%s %s\n", dev_dir_name, trigger_name); 588 /* 589 * Set the device trigger to be the data ready trigger found 590 * above 591 */ 592 ret = write_sysfs_string_and_verify("trigger/current_trigger", 593 dev_dir_name, 594 trigger_name); 595 if (ret < 0) { 596 fprintf(stderr, 597 "Failed to write current_trigger file\n"); 598 goto error; 599 } 600 } 601 602 /* Setup ring buffer parameters */ 603 ret = write_sysfs_int("length", buf_dir_name, buf_len); 604 if (ret < 0) 605 goto error; 606 607 /* Enable the buffer */ 608 ret = write_sysfs_int("enable", buf_dir_name, 1); 609 if (ret < 0) { 610 fprintf(stderr, 611 "Failed to enable buffer: %s\n", strerror(-ret)); 612 goto error; 613 } 614 615 scan_size = size_from_channelarray(channels, num_channels); 616 data = malloc(scan_size * buf_len); 617 if (!data) { 618 ret = -ENOMEM; 619 goto error; 620 } 621 622 ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num); 623 if (ret < 0) { 624 ret = -ENOMEM; 625 goto error; 626 } 627 628 /* Attempt to open non blocking the access dev */ 629 fp = open(buffer_access, O_RDONLY | O_NONBLOCK); 630 if (fp == -1) { /* TODO: If it isn't there make the node */ 631 ret = -errno; 632 fprintf(stderr, "Failed to open %s\n", buffer_access); 633 goto error; 634 } 635 636 for (j = 0; j < num_loops || num_loops < 0; j++) { 637 if (!noevents) { 638 struct pollfd pfd = { 639 .fd = fp, 640 .events = POLLIN, 641 }; 642 643 ret = poll(&pfd, 1, -1); 644 if (ret < 0) { 645 ret = -errno; 646 goto error; 647 } else if (ret == 0) { 648 continue; 649 } 650 651 toread = buf_len; 652 } else { 653 usleep(timedelay); 654 toread = 64; 655 } 656 657 read_size = read(fp, data, toread * scan_size); 658 if (read_size < 0) { 659 if (errno == EAGAIN) { 660 fprintf(stderr, "nothing available\n"); 661 continue; 662 } else { 663 break; 664 } 665 } 666 for (i = 0; i < read_size / scan_size; i++) 667 process_scan(data + scan_size * i, channels, 668 num_channels); 669 } 670 671 error: 672 cleanup(); 673 674 if (fp >= 0 && close(fp) == -1) 675 perror("Failed to close buffer"); 676 free(buffer_access); 677 free(data); 678 free(buf_dir_name); 679 for (i = num_channels - 1; i >= 0; i--) { 680 free(channels[i].name); 681 free(channels[i].generic_name); 682 } 683 free(channels); 684 free(trigger_name); 685 free(device_name); 686 free(dev_dir_name); 687 688 return ret; 689 } 690