blob: 4326e9e764c9f1fffca8d6a8dfcb9690b67f1a78 [file] [log] [blame]
Lars-Peter Clausen70421222012-02-13 10:25:34 +01001/* Industrialio event test code.
2 *
3 * Copyright (c) 2011-2012 Lars-Peter Clausen <lars@metafoo.de>
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 * Usage:
15 * iio_event_monitor <device_name>
16 *
17 */
18
19#define _GNU_SOURCE
20
21#include <unistd.h>
22#include <stdbool.h>
23#include <stdio.h>
24#include <errno.h>
25#include <string.h>
26#include <poll.h>
27#include <fcntl.h>
28#include <sys/ioctl.h>
29#include "iio_utils.h"
Jonathan Cameron06458e22012-04-25 15:54:58 +010030#include <linux/iio/events.h>
Lars-Peter Clausen70421222012-02-13 10:25:34 +010031
32static const char * const iio_chan_type_name_spec[] = {
33 [IIO_VOLTAGE] = "voltage",
34 [IIO_CURRENT] = "current",
35 [IIO_POWER] = "power",
36 [IIO_ACCEL] = "accel",
37 [IIO_ANGL_VEL] = "anglvel",
38 [IIO_MAGN] = "magn",
39 [IIO_LIGHT] = "illuminance",
40 [IIO_INTENSITY] = "intensity",
41 [IIO_PROXIMITY] = "proximity",
42 [IIO_TEMP] = "temp",
43 [IIO_INCLI] = "incli",
44 [IIO_ROT] = "rot",
45 [IIO_ANGL] = "angl",
46 [IIO_TIMESTAMP] = "timestamp",
47 [IIO_CAPACITANCE] = "capacitance",
Peter Meerwalda2160142012-06-15 19:25:26 +020048 [IIO_ALTVOLTAGE] = "altvoltage",
Lars-Peter Clausen70421222012-02-13 10:25:34 +010049};
50
51static const char * const iio_ev_type_text[] = {
52 [IIO_EV_TYPE_THRESH] = "thresh",
53 [IIO_EV_TYPE_MAG] = "mag",
54 [IIO_EV_TYPE_ROC] = "roc",
55 [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
56 [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
57};
58
59static const char * const iio_ev_dir_text[] = {
60 [IIO_EV_DIR_EITHER] = "either",
61 [IIO_EV_DIR_RISING] = "rising",
62 [IIO_EV_DIR_FALLING] = "falling"
63};
64
65static const char * const iio_modifier_names[] = {
66 [IIO_MOD_X] = "x",
67 [IIO_MOD_Y] = "y",
68 [IIO_MOD_Z] = "z",
69 [IIO_MOD_LIGHT_BOTH] = "both",
70 [IIO_MOD_LIGHT_IR] = "ir",
71};
72
73static bool event_is_known(struct iio_event_data *event)
74{
75 enum iio_chan_type type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event->id);
76 enum iio_modifier mod = IIO_EVENT_CODE_EXTRACT_MODIFIER(event->id);
77 enum iio_event_type ev_type = IIO_EVENT_CODE_EXTRACT_TYPE(event->id);
78 enum iio_event_direction dir = IIO_EVENT_CODE_EXTRACT_DIR(event->id);
79
80 switch (type) {
81 case IIO_VOLTAGE:
82 case IIO_CURRENT:
83 case IIO_POWER:
84 case IIO_ACCEL:
85 case IIO_ANGL_VEL:
86 case IIO_MAGN:
87 case IIO_LIGHT:
88 case IIO_INTENSITY:
89 case IIO_PROXIMITY:
90 case IIO_TEMP:
91 case IIO_INCLI:
92 case IIO_ROT:
93 case IIO_ANGL:
94 case IIO_TIMESTAMP:
95 case IIO_CAPACITANCE:
Peter Meerwalda2160142012-06-15 19:25:26 +020096 case IIO_ALTVOLTAGE:
Lars-Peter Clausen70421222012-02-13 10:25:34 +010097 break;
98 default:
99 return false;
100 }
101
102 switch (mod) {
103 case IIO_NO_MOD:
104 case IIO_MOD_X:
105 case IIO_MOD_Y:
106 case IIO_MOD_Z:
107 case IIO_MOD_LIGHT_BOTH:
108 case IIO_MOD_LIGHT_IR:
109 break;
110 default:
111 return false;
112 }
113
114 switch (ev_type) {
115 case IIO_EV_TYPE_THRESH:
116 case IIO_EV_TYPE_MAG:
117 case IIO_EV_TYPE_ROC:
118 case IIO_EV_TYPE_THRESH_ADAPTIVE:
119 case IIO_EV_TYPE_MAG_ADAPTIVE:
120 break;
121 default:
122 return false;
123 }
124
125 switch (dir) {
126 case IIO_EV_DIR_EITHER:
127 case IIO_EV_DIR_RISING:
128 case IIO_EV_DIR_FALLING:
129 break;
130 default:
131 return false;
132 }
133
134 return true;
135}
136
137static void print_event(struct iio_event_data *event)
138{
139 enum iio_chan_type type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event->id);
140 enum iio_modifier mod = IIO_EVENT_CODE_EXTRACT_MODIFIER(event->id);
141 enum iio_event_type ev_type = IIO_EVENT_CODE_EXTRACT_TYPE(event->id);
142 enum iio_event_direction dir = IIO_EVENT_CODE_EXTRACT_DIR(event->id);
143 int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event->id);
144 int chan2 = IIO_EVENT_CODE_EXTRACT_CHAN2(event->id);
145 bool diff = IIO_EVENT_CODE_EXTRACT_DIFF(event->id);
146
147 if (!event_is_known(event)) {
148 printf("Unknown event: time: %lld, id: %llx\n",
149 event->timestamp, event->id);
150 return;
151 }
152
153 printf("Event: time: %lld, ", event->timestamp);
154
155 if (mod != IIO_NO_MOD) {
156 printf("type: %s(%s), ",
157 iio_chan_type_name_spec[type],
158 iio_modifier_names[mod]);
159 } else {
160 printf("type: %s, ",
161 iio_chan_type_name_spec[type]);
162 }
163
164 if (diff && chan >= 0 && chan2 >= 0)
165 printf("channel: %d-%d, ", chan, chan2);
166 else if (chan >= 0)
167 printf("channel: %d, ", chan);
168
169 printf("evtype: %s, direction: %s\n",
170 iio_ev_type_text[ev_type],
171 iio_ev_dir_text[dir]);
172}
173
174int main(int argc, char **argv)
175{
176 struct iio_event_data event;
177 const char *device_name;
178 char *chrdev_name;
179 int ret;
180 int dev_num;
181 int fd, event_fd;
182
183 if (argc <= 1) {
184 printf("Usage: %s <device_name>\n", argv[0]);
185 return -1;
186 }
187
188 device_name = argv[1];
189
190 dev_num = find_type_by_name(device_name, "iio:device");
191 if (dev_num >= 0) {
192 printf("Found IIO device with name %s with device number %d\n",
193 device_name, dev_num);
194 ret = asprintf(&chrdev_name, "/dev/iio:device%d", dev_num);
195 if (ret < 0) {
196 ret = -ENOMEM;
197 goto error_ret;
198 }
199 } else {
200 /* If we can't find a IIO device by name assume device_name is a
201 IIO chrdev */
202 chrdev_name = strdup(device_name);
203 }
204
205 fd = open(chrdev_name, 0);
206 if (fd == -1) {
207 fprintf(stdout, "Failed to open %s\n", chrdev_name);
208 ret = -errno;
209 goto error_free_chrdev_name;
210 }
211
212 ret = ioctl(fd, IIO_GET_EVENT_FD_IOCTL, &event_fd);
213
214 close(fd);
215
216 if (ret == -1 || event_fd == -1) {
217 fprintf(stdout, "Failed to retrieve event fd\n");
218 ret = -errno;
219 goto error_free_chrdev_name;
220 }
221
222 while (true) {
223 ret = read(event_fd, &event, sizeof(event));
224 if (ret == -1) {
225 if (errno == EAGAIN) {
226 printf("nothing available\n");
227 continue;
228 } else {
229 perror("Failed to read event from device");
230 ret = -errno;
231 break;
232 }
233 }
234
235 print_event(&event);
236 }
237
238 close(event_fd);
239error_free_chrdev_name:
240 free(chrdev_name);
241error_ret:
242 return ret;
243}