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