andrewm@0
|
1 /*
|
andrewm@0
|
2 * SimpleGPIO.cpp
|
andrewm@0
|
3 *
|
andrewm@0
|
4 * Modifications by Derek Molloy, School of Electronic Engineering, DCU
|
andrewm@0
|
5 * www.derekmolloy.ie
|
andrewm@0
|
6 * Almost entirely based on Software by RidgeRun:
|
andrewm@0
|
7 *
|
andrewm@0
|
8 * Copyright (c) 2011, RidgeRun
|
andrewm@0
|
9 * All rights reserved.
|
andrewm@0
|
10 *
|
andrewm@0
|
11 * Redistribution and use in source and binary forms, with or without
|
andrewm@0
|
12 * modification, are permitted provided that the following conditions are met:
|
andrewm@0
|
13 * 1. Redistributions of source code must retain the above copyright
|
andrewm@0
|
14 * notice, this list of conditions and the following disclaimer.
|
andrewm@0
|
15 * 2. Redistributions in binary form must reproduce the above copyright
|
andrewm@0
|
16 * notice, this list of conditions and the following disclaimer in the
|
andrewm@0
|
17 * documentation and/or other materials provided with the distribution.
|
andrewm@0
|
18 * 3. All advertising materials mentioning features or use of this software
|
andrewm@0
|
19 * must display the following acknowledgement:
|
andrewm@0
|
20 * This product includes software developed by the RidgeRun.
|
andrewm@0
|
21 * 4. Neither the name of the RidgeRun nor the
|
andrewm@0
|
22 * names of its contributors may be used to endorse or promote products
|
andrewm@0
|
23 * derived from this software without specific prior written permission.
|
andrewm@0
|
24 *
|
andrewm@0
|
25 * THIS SOFTWARE IS PROVIDED BY RIDGERUN ''AS IS'' AND ANY
|
andrewm@0
|
26 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
andrewm@0
|
27 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
andrewm@0
|
28 * DISCLAIMED. IN NO EVENT SHALL RIDGERUN BE LIABLE FOR ANY
|
andrewm@0
|
29 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
andrewm@0
|
30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
andrewm@0
|
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
andrewm@0
|
32 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
andrewm@0
|
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
andrewm@0
|
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
andrewm@0
|
35 */
|
andrewm@0
|
36
|
andrewm@0
|
37 #include "../include/GPIOcontrol.h"
|
andrewm@0
|
38 #include <stdio.h>
|
andrewm@0
|
39 #include <stdlib.h>
|
andrewm@0
|
40 #include <string.h>
|
andrewm@0
|
41 #include <errno.h>
|
andrewm@0
|
42 #include <unistd.h>
|
andrewm@0
|
43 #include <fcntl.h>
|
andrewm@0
|
44 #include <poll.h>
|
andrewm@0
|
45
|
andrewm@0
|
46
|
andrewm@0
|
47 /****************************************************************
|
andrewm@0
|
48 * gpio_setup
|
andrewm@0
|
49 ****************************************************************/
|
andrewm@0
|
50 int gpio_setup(unsigned int gpio, int out_flag)
|
andrewm@0
|
51 {
|
andrewm@0
|
52 /* Export the GPIO pins and set their direction */
|
andrewm@0
|
53 if(gpio_export(gpio)) {
|
andrewm@0
|
54 printf("Unable to export GPIO input pin\n");
|
andrewm@0
|
55 return -1;
|
andrewm@0
|
56 }
|
andrewm@0
|
57 if(gpio_set_dir(gpio, out_flag)) {
|
andrewm@0
|
58 printf("Unable to set GPIO input direction\n");
|
andrewm@0
|
59 return -1;
|
andrewm@0
|
60 }
|
andrewm@0
|
61
|
andrewm@0
|
62 return gpio_fd_open(gpio, O_RDWR);
|
andrewm@0
|
63 }
|
andrewm@0
|
64
|
andrewm@0
|
65 /****************************************************************
|
andrewm@0
|
66 * gpio_export
|
andrewm@0
|
67 ****************************************************************/
|
andrewm@0
|
68 int gpio_export(unsigned int gpio)
|
andrewm@0
|
69 {
|
andrewm@0
|
70 int fd, len, result = 0;
|
andrewm@0
|
71 char buf[MAX_BUF];
|
andrewm@0
|
72
|
andrewm@0
|
73 fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY);
|
andrewm@0
|
74 if (fd < 0) {
|
andrewm@0
|
75 perror("gpio/export");
|
andrewm@0
|
76 return fd;
|
andrewm@0
|
77 }
|
andrewm@0
|
78
|
andrewm@0
|
79 len = snprintf(buf, sizeof(buf), "%d", gpio);
|
andrewm@0
|
80 if(write(fd, buf, len) < 0)
|
andrewm@0
|
81 result = -1;
|
andrewm@0
|
82 close(fd);
|
andrewm@0
|
83
|
andrewm@0
|
84 return result;
|
andrewm@0
|
85 }
|
andrewm@0
|
86
|
andrewm@0
|
87 /****************************************************************
|
andrewm@0
|
88 * gpio_unexport
|
andrewm@0
|
89 ****************************************************************/
|
andrewm@0
|
90 int gpio_unexport(unsigned int gpio)
|
andrewm@0
|
91 {
|
andrewm@0
|
92 int fd, len, result = 0;
|
andrewm@0
|
93 char buf[MAX_BUF];
|
andrewm@0
|
94
|
andrewm@0
|
95 fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY);
|
andrewm@0
|
96 if (fd < 0) {
|
andrewm@0
|
97 perror("gpio/export");
|
andrewm@0
|
98 return fd;
|
andrewm@0
|
99 }
|
andrewm@0
|
100
|
andrewm@0
|
101 len = snprintf(buf, sizeof(buf), "%d", gpio);
|
andrewm@0
|
102 if(write(fd, buf, len) < 0)
|
andrewm@0
|
103 result = -1;
|
andrewm@0
|
104 close(fd);
|
andrewm@0
|
105 return result;
|
andrewm@0
|
106 }
|
andrewm@0
|
107
|
andrewm@0
|
108 /****************************************************************
|
andrewm@0
|
109 * gpio_set_dir
|
andrewm@0
|
110 ****************************************************************/
|
andrewm@0
|
111 int gpio_set_dir(unsigned int gpio, int out_flag)
|
andrewm@0
|
112 {
|
andrewm@0
|
113 int fd, result = 0;
|
andrewm@0
|
114 char buf[MAX_BUF];
|
andrewm@0
|
115
|
andrewm@0
|
116 snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/direction", gpio);
|
andrewm@0
|
117
|
andrewm@0
|
118 fd = open(buf, O_WRONLY);
|
andrewm@0
|
119 if (fd < 0) {
|
andrewm@0
|
120 perror("gpio/direction");
|
andrewm@0
|
121 return fd;
|
andrewm@0
|
122 }
|
andrewm@0
|
123
|
andrewm@0
|
124 if (out_flag == OUTPUT_PIN) {
|
andrewm@0
|
125 if(write(fd, "out", 4) < 0)
|
andrewm@0
|
126 result = -1;
|
andrewm@0
|
127 }
|
andrewm@0
|
128 else {
|
andrewm@0
|
129 if(write(fd, "in", 3) < 0)
|
andrewm@0
|
130 result = -1;
|
andrewm@0
|
131 }
|
andrewm@0
|
132
|
andrewm@0
|
133 close(fd);
|
andrewm@0
|
134 return result;
|
andrewm@0
|
135 }
|
andrewm@0
|
136
|
andrewm@0
|
137 /****************************************************************
|
andrewm@0
|
138 * gpio_set_value
|
andrewm@0
|
139 ****************************************************************/
|
andrewm@0
|
140 int gpio_set_value(unsigned int gpio, int value)
|
andrewm@0
|
141 {
|
andrewm@0
|
142 int fd, result = 0;
|
andrewm@0
|
143 char buf[MAX_BUF];
|
andrewm@0
|
144
|
andrewm@0
|
145 snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
|
andrewm@0
|
146
|
andrewm@0
|
147 fd = open(buf, O_WRONLY);
|
andrewm@0
|
148 if (fd < 0) {
|
andrewm@0
|
149 perror("gpio/set-value");
|
andrewm@0
|
150 return fd;
|
andrewm@0
|
151 }
|
andrewm@0
|
152
|
andrewm@0
|
153 if (value==LOW) {
|
andrewm@0
|
154 if(write(fd, "0", 2) < 0)
|
andrewm@0
|
155 result = -1;
|
andrewm@0
|
156 }
|
andrewm@0
|
157 else {
|
andrewm@0
|
158 if(write(fd, "1", 2) < 0)
|
andrewm@0
|
159 result = -1;
|
andrewm@0
|
160 }
|
andrewm@0
|
161
|
andrewm@0
|
162 close(fd);
|
andrewm@0
|
163 return result;
|
andrewm@0
|
164 }
|
andrewm@0
|
165
|
andrewm@0
|
166 /****************************************************************
|
andrewm@0
|
167 * gpio_get_value
|
andrewm@0
|
168 ****************************************************************/
|
andrewm@0
|
169 int gpio_get_value(unsigned int gpio, unsigned int *value)
|
andrewm@0
|
170 {
|
andrewm@0
|
171 int fd, result = 0;
|
andrewm@0
|
172 char buf[MAX_BUF];
|
andrewm@0
|
173 char ch;
|
andrewm@0
|
174
|
andrewm@0
|
175 snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
|
andrewm@0
|
176
|
andrewm@0
|
177 fd = open(buf, O_RDONLY);
|
andrewm@0
|
178 if (fd < 0) {
|
andrewm@0
|
179 perror("gpio/get-value");
|
andrewm@0
|
180 return fd;
|
andrewm@0
|
181 }
|
andrewm@0
|
182
|
andrewm@0
|
183 if(read(fd, &ch, 1) <= 0) {
|
andrewm@0
|
184 result = -1;
|
andrewm@0
|
185 }
|
andrewm@0
|
186 else {
|
andrewm@0
|
187 if (ch != '0') {
|
andrewm@0
|
188 *value = 1;
|
andrewm@0
|
189 } else {
|
andrewm@0
|
190 *value = 0;
|
andrewm@0
|
191 }
|
andrewm@0
|
192 }
|
andrewm@0
|
193
|
andrewm@0
|
194 close(fd);
|
andrewm@0
|
195 return result;
|
andrewm@0
|
196 }
|
andrewm@0
|
197
|
andrewm@0
|
198
|
andrewm@0
|
199 /****************************************************************
|
andrewm@0
|
200 * gpio_set_edge
|
andrewm@0
|
201 ****************************************************************/
|
andrewm@0
|
202
|
andrewm@0
|
203 int gpio_set_edge(unsigned int gpio, char *edge)
|
andrewm@0
|
204 {
|
andrewm@0
|
205 int fd, result = 0;
|
andrewm@0
|
206 char buf[MAX_BUF];
|
andrewm@0
|
207
|
andrewm@0
|
208 snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio);
|
andrewm@0
|
209
|
andrewm@0
|
210 fd = open(buf, O_WRONLY);
|
andrewm@0
|
211 if (fd < 0) {
|
andrewm@0
|
212 perror("gpio/set-edge");
|
andrewm@0
|
213 return fd;
|
andrewm@0
|
214 }
|
andrewm@0
|
215
|
andrewm@0
|
216 if(write(fd, edge, strlen(edge) + 1) < 0)
|
andrewm@0
|
217 result = -1;
|
andrewm@0
|
218 close(fd);
|
andrewm@0
|
219 return result;
|
andrewm@0
|
220 }
|
andrewm@0
|
221
|
andrewm@0
|
222 /****************************************************************
|
andrewm@0
|
223 * gpio_fd_open
|
andrewm@0
|
224 ****************************************************************/
|
andrewm@0
|
225
|
andrewm@0
|
226 int gpio_fd_open(unsigned int gpio, int writeFlag)
|
andrewm@0
|
227 {
|
andrewm@0
|
228 int fd;
|
andrewm@0
|
229 char buf[MAX_BUF];
|
andrewm@0
|
230
|
andrewm@0
|
231 snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
|
andrewm@0
|
232
|
andrewm@0
|
233 fd = open(buf, writeFlag | O_NONBLOCK );
|
andrewm@0
|
234 if (fd < 0) {
|
andrewm@0
|
235 perror("gpio/fd_open");
|
andrewm@0
|
236 }
|
andrewm@0
|
237 return fd;
|
andrewm@0
|
238 }
|
andrewm@0
|
239
|
andrewm@0
|
240 /****************************************************************
|
andrewm@0
|
241 * gpio_fd_close
|
andrewm@0
|
242 ****************************************************************/
|
andrewm@0
|
243
|
andrewm@0
|
244 int gpio_fd_close(int fd)
|
andrewm@0
|
245 {
|
andrewm@0
|
246 return close(fd);
|
andrewm@0
|
247 }
|
andrewm@0
|
248
|
andrewm@0
|
249 /****************************************************************
|
andrewm@0
|
250 * gpio_read
|
andrewm@0
|
251 ****************************************************************/
|
andrewm@0
|
252 int gpio_read(int fd, unsigned int *value)
|
andrewm@0
|
253 {
|
andrewm@0
|
254 int result = 0;
|
andrewm@0
|
255 char ch;
|
andrewm@0
|
256
|
andrewm@0
|
257 if(read(fd, &ch, 1) <= 0) {
|
andrewm@0
|
258 result = -1;
|
andrewm@0
|
259 }
|
andrewm@0
|
260 else {
|
andrewm@0
|
261 if (ch != '0') {
|
andrewm@0
|
262 *value = 1;
|
andrewm@0
|
263 } else {
|
andrewm@0
|
264 *value = 0;
|
andrewm@0
|
265 }
|
andrewm@0
|
266 }
|
andrewm@0
|
267
|
andrewm@0
|
268 return result;
|
andrewm@0
|
269 }
|
andrewm@0
|
270
|
andrewm@0
|
271 /****************************************************************
|
andrewm@0
|
272 * gpio_write
|
andrewm@0
|
273 ****************************************************************/
|
andrewm@0
|
274 int gpio_write(int fd, int value)
|
andrewm@0
|
275 {
|
andrewm@0
|
276 int result = 0;
|
andrewm@0
|
277 //char buf[MAX_BUF];
|
andrewm@0
|
278
|
andrewm@0
|
279 if (value==LOW) {
|
andrewm@0
|
280 if(write(fd, "0", 2) < 0)
|
andrewm@0
|
281 result = -1;
|
andrewm@0
|
282 }
|
andrewm@0
|
283 else {
|
andrewm@0
|
284 if(write(fd, "1", 2) < 0)
|
andrewm@0
|
285 result = -1;
|
andrewm@0
|
286 }
|
andrewm@0
|
287
|
andrewm@0
|
288 return result;
|
andrewm@0
|
289 }
|
andrewm@0
|
290
|
andrewm@0
|
291
|
andrewm@0
|
292 /****************************************************************
|
andrewm@0
|
293 * gpio_dismiss
|
andrewm@0
|
294 ****************************************************************/
|
andrewm@0
|
295 int gpio_dismiss(int fd, unsigned int gpio)
|
andrewm@0
|
296 {
|
andrewm@0
|
297 close(fd);
|
andrewm@0
|
298 gpio_unexport(gpio);
|
andrewm@0
|
299 return 0;
|
andrewm@0
|
300 }
|
andrewm@0
|
301
|
andrewm@0
|
302 /****************************************************************
|
andrewm@0
|
303 * led_set_trigger
|
andrewm@0
|
304 ****************************************************************/
|
andrewm@0
|
305 int led_set_trigger(unsigned int lednum, const char *trigger)
|
andrewm@0
|
306 {
|
andrewm@0
|
307 // Set the trigger source for an onboard user LED
|
andrewm@0
|
308 int fd, result = 0;
|
andrewm@0
|
309 char buf[MAX_BUF];
|
andrewm@0
|
310
|
andrewm@0
|
311 snprintf(buf, sizeof(buf), SYSFS_LED_DIR "/beaglebone:green:usr%d/trigger", lednum);
|
andrewm@0
|
312
|
andrewm@0
|
313 fd = open(buf, O_WRONLY);
|
andrewm@0
|
314 if (fd < 0) {
|
andrewm@0
|
315 perror("gpio/led-set-trigger");
|
andrewm@0
|
316 return fd;
|
andrewm@0
|
317 }
|
andrewm@0
|
318
|
andrewm@0
|
319 if(write(fd, trigger, strlen(trigger) + 1) < 0)
|
andrewm@0
|
320 result = -1;
|
andrewm@0
|
321
|
andrewm@0
|
322 close(fd);
|
andrewm@0
|
323 return result;
|
andrewm@0
|
324 }
|
andrewm@0
|
325
|