generic_buffer.c 14 KB

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