generic_buffer.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  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. * size_from_channelarray() - calculate the storage size of a scan
  37. * @channels: the channel info array
  38. * @num_channels: number of channels
  39. *
  40. * Has the side effect of filling the channels[i].location values used
  41. * in processing the buffer output.
  42. **/
  43. int size_from_channelarray(struct iio_channel_info *channels, int num_channels)
  44. {
  45. int bytes = 0;
  46. int i = 0;
  47. while (i < num_channels) {
  48. if (bytes % channels[i].bytes == 0)
  49. channels[i].location = bytes;
  50. else
  51. channels[i].location = bytes - bytes%channels[i].bytes
  52. + channels[i].bytes;
  53. bytes = channels[i].location + channels[i].bytes;
  54. i++;
  55. }
  56. return bytes;
  57. }
  58. void print2byte(int input, struct iio_channel_info *info)
  59. {
  60. /* First swap if incorrect endian */
  61. if (info->be)
  62. input = be16toh((uint16_t)input);
  63. else
  64. input = le16toh((uint16_t)input);
  65. /*
  66. * Shift before conversion to avoid sign extension
  67. * of left aligned data
  68. */
  69. input >>= info->shift;
  70. if (info->is_signed) {
  71. int16_t val = input;
  72. val &= (1 << info->bits_used) - 1;
  73. val = (int16_t)(val << (16 - info->bits_used)) >>
  74. (16 - info->bits_used);
  75. printf("%05f ", ((float)val + info->offset)*info->scale);
  76. } else {
  77. uint16_t val = input;
  78. val &= (1 << info->bits_used) - 1;
  79. printf("%05f ", ((float)val + info->offset)*info->scale);
  80. }
  81. }
  82. /**
  83. * process_scan() - print out the values in SI units
  84. * @data: pointer to the start of the scan
  85. * @channels: information about the channels. Note
  86. * size_from_channelarray must have been called first to fill the
  87. * location offsets.
  88. * @num_channels: number of channels
  89. **/
  90. void process_scan(char *data,
  91. struct iio_channel_info *channels,
  92. int num_channels)
  93. {
  94. int k;
  95. for (k = 0; k < num_channels; k++)
  96. switch (channels[k].bytes) {
  97. /* only a few cases implemented so far */
  98. case 2:
  99. print2byte(*(uint16_t *)(data + channels[k].location),
  100. &channels[k]);
  101. break;
  102. case 4:
  103. if (!channels[k].is_signed) {
  104. uint32_t val = *(uint32_t *)
  105. (data + channels[k].location);
  106. printf("%05f ", ((float)val +
  107. channels[k].offset)*
  108. channels[k].scale);
  109. }
  110. break;
  111. case 8:
  112. if (channels[k].is_signed) {
  113. int64_t val = *(int64_t *)
  114. (data +
  115. channels[k].location);
  116. if ((val >> channels[k].bits_used) & 1)
  117. val = (val & channels[k].mask) |
  118. ~channels[k].mask;
  119. /* special case for timestamp */
  120. if (channels[k].scale == 1.0f &&
  121. channels[k].offset == 0.0f)
  122. printf("%" PRId64 " ", val);
  123. else
  124. printf("%05f ", ((float)val +
  125. channels[k].offset)*
  126. channels[k].scale);
  127. }
  128. break;
  129. default:
  130. break;
  131. }
  132. printf("\n");
  133. }
  134. int main(int argc, char **argv)
  135. {
  136. unsigned long num_loops = 2;
  137. unsigned long timedelay = 1000000;
  138. unsigned long buf_len = 128;
  139. int ret, c, i, j, toread;
  140. int fp;
  141. int num_channels;
  142. char *trigger_name = NULL, *device_name = NULL;
  143. char *dev_dir_name, *buf_dir_name;
  144. int datardytrigger = 1;
  145. char *data;
  146. ssize_t read_size;
  147. int dev_num, trig_num;
  148. char *buffer_access;
  149. int scan_size;
  150. int noevents = 0;
  151. int notrigger = 0;
  152. char *dummy;
  153. struct iio_channel_info *channels;
  154. while ((c = getopt(argc, argv, "l:w:c:et:n:g")) != -1) {
  155. switch (c) {
  156. case 'n':
  157. device_name = optarg;
  158. break;
  159. case 't':
  160. trigger_name = optarg;
  161. datardytrigger = 0;
  162. break;
  163. case 'e':
  164. noevents = 1;
  165. break;
  166. case 'c':
  167. num_loops = strtoul(optarg, &dummy, 10);
  168. break;
  169. case 'w':
  170. timedelay = strtoul(optarg, &dummy, 10);
  171. break;
  172. case 'l':
  173. buf_len = strtoul(optarg, &dummy, 10);
  174. break;
  175. case 'g':
  176. notrigger = 1;
  177. break;
  178. case '?':
  179. return -1;
  180. }
  181. }
  182. if (device_name == NULL)
  183. return -1;
  184. /* Find the device requested */
  185. dev_num = find_type_by_name(device_name, "iio:device");
  186. if (dev_num < 0) {
  187. printf("Failed to find the %s\n", device_name);
  188. ret = -ENODEV;
  189. goto error_ret;
  190. }
  191. printf("iio device number being used is %d\n", dev_num);
  192. asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
  193. if (!notrigger) {
  194. if (trigger_name == NULL) {
  195. /*
  196. * Build the trigger name. If it is device associated
  197. * its name is <device_name>_dev[n] where n matches
  198. * the device number found above.
  199. */
  200. ret = asprintf(&trigger_name,
  201. "%s-dev%d", device_name, dev_num);
  202. if (ret < 0) {
  203. ret = -ENOMEM;
  204. goto error_ret;
  205. }
  206. }
  207. /* Verify the trigger exists */
  208. trig_num = find_type_by_name(trigger_name, "trigger");
  209. if (trig_num < 0) {
  210. printf("Failed to find the trigger %s\n", trigger_name);
  211. ret = -ENODEV;
  212. goto error_free_triggername;
  213. }
  214. printf("iio trigger number being used is %d\n", trig_num);
  215. } else
  216. printf("trigger-less mode selected\n");
  217. /*
  218. * Parse the files in scan_elements to identify what channels are
  219. * present
  220. */
  221. ret = build_channel_array(dev_dir_name, &channels, &num_channels);
  222. if (ret) {
  223. printf("Problem reading scan element information\n");
  224. printf("diag %s\n", dev_dir_name);
  225. goto error_free_triggername;
  226. }
  227. /*
  228. * Construct the directory name for the associated buffer.
  229. * As we know that the lis3l02dq has only one buffer this may
  230. * be built rather than found.
  231. */
  232. ret = asprintf(&buf_dir_name,
  233. "%siio:device%d/buffer", iio_dir, dev_num);
  234. if (ret < 0) {
  235. ret = -ENOMEM;
  236. goto error_free_triggername;
  237. }
  238. if (!notrigger) {
  239. printf("%s %s\n", dev_dir_name, trigger_name);
  240. /* Set the device trigger to be the data ready trigger found
  241. * above */
  242. ret = write_sysfs_string_and_verify("trigger/current_trigger",
  243. dev_dir_name,
  244. trigger_name);
  245. if (ret < 0) {
  246. printf("Failed to write current_trigger file\n");
  247. goto error_free_buf_dir_name;
  248. }
  249. }
  250. /* Setup ring buffer parameters */
  251. ret = write_sysfs_int("length", buf_dir_name, buf_len);
  252. if (ret < 0)
  253. goto error_free_buf_dir_name;
  254. /* Enable the buffer */
  255. ret = write_sysfs_int("enable", buf_dir_name, 1);
  256. if (ret < 0)
  257. goto error_free_buf_dir_name;
  258. scan_size = size_from_channelarray(channels, num_channels);
  259. data = malloc(scan_size*buf_len);
  260. if (!data) {
  261. ret = -ENOMEM;
  262. goto error_free_buf_dir_name;
  263. }
  264. ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num);
  265. if (ret < 0) {
  266. ret = -ENOMEM;
  267. goto error_free_data;
  268. }
  269. /* Attempt to open non blocking the access dev */
  270. fp = open(buffer_access, O_RDONLY | O_NONBLOCK);
  271. if (fp == -1) { /* If it isn't there make the node */
  272. printf("Failed to open %s\n", buffer_access);
  273. ret = -errno;
  274. goto error_free_buffer_access;
  275. }
  276. /* Wait for events 10 times */
  277. for (j = 0; j < num_loops; j++) {
  278. if (!noevents) {
  279. struct pollfd pfd = {
  280. .fd = fp,
  281. .events = POLLIN,
  282. };
  283. poll(&pfd, 1, -1);
  284. toread = buf_len;
  285. } else {
  286. usleep(timedelay);
  287. toread = 64;
  288. }
  289. read_size = read(fp,
  290. data,
  291. toread*scan_size);
  292. if (read_size < 0) {
  293. if (errno == -EAGAIN) {
  294. printf("nothing available\n");
  295. continue;
  296. } else
  297. break;
  298. }
  299. for (i = 0; i < read_size/scan_size; i++)
  300. process_scan(data + scan_size*i,
  301. channels,
  302. num_channels);
  303. }
  304. /* Stop the buffer */
  305. ret = write_sysfs_int("enable", buf_dir_name, 0);
  306. if (ret < 0)
  307. goto error_close_buffer_access;
  308. if (!notrigger)
  309. /* Disconnect the trigger - just write a dummy name. */
  310. write_sysfs_string("trigger/current_trigger",
  311. dev_dir_name, "NULL");
  312. error_close_buffer_access:
  313. close(fp);
  314. error_free_data:
  315. free(data);
  316. error_free_buffer_access:
  317. free(buffer_access);
  318. error_free_buf_dir_name:
  319. free(buf_dir_name);
  320. error_free_triggername:
  321. if (datardytrigger)
  322. free(trigger_name);
  323. error_ret:
  324. return ret;
  325. }