1 /* Copyright (c) 2011, RidgeRun
4 * Contributors include:
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the RidgeRun.
18 * 4. Neither the name of the RidgeRun nor the
19 * names of its contributors may be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY RIDGERUN ''AS IS'' AND ANY
23 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL RIDGERUN BE LIABLE FOR ANY
26 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 /****************************************************************
46 ****************************************************************/
48 #define SYSFS_GPIO_DIR "/sys/class/gpio"
49 #define POLL_TIMEOUT (3 * 1000) /* 3 seconds */
52 /****************************************************************
54 ****************************************************************/
55 int gpio_export(unsigned int gpio)
60 fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY);
62 perror("gpio/export");
66 len = snprintf(buf, sizeof(buf), "%d", gpio);
73 /****************************************************************
75 ****************************************************************/
76 int gpio_unexport(unsigned int gpio)
81 fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY);
83 perror("gpio/export");
87 len = snprintf(buf, sizeof(buf), "%d", gpio);
93 /****************************************************************
95 ****************************************************************/
96 int gpio_set_dir(unsigned int gpio, unsigned int out_flag)
101 len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/direction", gpio);
103 fd = open(buf, O_WRONLY);
105 perror("gpio/direction");
118 /****************************************************************
120 ****************************************************************/
121 int gpio_set_value(unsigned int gpio, unsigned int value)
126 len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
128 fd = open(buf, O_WRONLY);
130 perror("gpio/set-value");
143 /****************************************************************
145 ****************************************************************/
146 int gpio_get_value(unsigned int gpio, unsigned int *value)
152 len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
154 fd = open(buf, O_RDONLY);
156 perror("gpio/get-value");
173 /****************************************************************
175 ****************************************************************/
177 int gpio_set_edge(unsigned int gpio, char *edge)
182 len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio);
184 fd = open(buf, O_WRONLY);
186 perror("gpio/set-edge");
190 write(fd, edge, strlen(edge) + 1);
195 int gpio_set_level(unsigned int gpio, int level)
200 len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/active_low", gpio);
202 fd = open(buf, O_WRONLY);
204 perror("gpio/set-level");
208 write(fd, level?"1":"0", 2);
214 /****************************************************************
216 ****************************************************************/
218 int gpio_fd_open(unsigned int gpio)
223 len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
225 fd = open(buf, O_RDONLY | O_NONBLOCK );
227 perror("gpio/fd_open");
232 /****************************************************************
234 ****************************************************************/
236 int gpio_fd_close(int fd)
241 /****************************************************************
243 ****************************************************************/
245 #define OPTSTRING "e:l:"
247 int main(int argc, char **argv, char **envp)
249 struct pollfd *fdset;
259 char *default_edge="both";
260 struct timespec spec;
265 while (-1 != (ch = getopt(argc, argv, OPTSTRING))) {
268 default_edge=strdup(optarg);
269 if ( ! ((0 == strncmp(default_edge,"rising",8)) ||
270 (0 == strncmp(default_edge,"falling",8)) ||
271 (0 == strncmp(default_edge,"both",8)))
274 fprintf(stderr, "error: invalid edge value: %s\n", optarg);
279 if ( 0 == strncmp(optarg,"low",8) ) {
281 } else if ( 0 == strncmp(optarg,"high",8) ) {
284 fprintf(stderr, "error: invalid level value: %s\n", optarg);
289 printf("Usage: gpio-int [-l level] [-e edge ] <gpio-pin...>\n\n");
290 printf("Waits for a change in the GPIO pins voltage level\n");
297 gpios = malloc(count*sizeof(unsigned int));
298 fdset = malloc(count*sizeof(fdset[0]));
301 for (i=optind;i<argc;i++) {
302 gpio = atoi(argv[i]);
305 gpio_set_dir(gpio, 0);
306 gpio_set_edge(gpio, default_edge);
307 gpio_set_level(gpio, default_level);
308 fdset[j].fd = gpio_fd_open(gpio);
309 fdset[j].events = POLLPRI;
314 timeout = POLL_TIMEOUT;
318 rc = poll(fdset, count, timeout);
321 printf("\npoll() failed!\n");
325 clock_gettime(CLOCK_REALTIME, &spec);
326 for (i=0;i<count;i++) {
327 if (fdset[i].revents & POLLPRI) {
328 lseek(fdset[i].fd, 0, SEEK_SET);
329 len = read(fdset[i].fd, buf, MAX_BUF);
332 ms = spec.tv_nsec / 1.0e6;
333 printf("%d %c %d.%03d\n", gpios[i], valbuf, s, ms);
340 for (i=0;i<count;i++) {
341 gpio_fd_close(fdset[i].fd);