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