blob: e71e432f310ac06ff9c5479621fc6c5948795e22 [file] [log] [blame]
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001/*
2 * gpio.c:
Gordon Henderson99095e32012-08-27 20:56:14 +01003 * Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
4 * Pi's GPIO.
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01005 * Copyright (c) 2012 Gordon Henderson
6 ***********************************************************************
7 * This file is part of wiringPi:
8 * https://projects.drogon.net/raspberry-pi/wiringpi/
9 *
10 * wiringPi is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * wiringPi is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
22 ***********************************************************************
23 */
24
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010025
26#include <stdio.h>
27#include <stdlib.h>
28#include <stdint.h>
29#include <string.h>
30#include <unistd.h>
31#include <errno.h>
32#include <sys/types.h>
33#include <fcntl.h>
34
Gordon Henderson99095e32012-08-27 20:56:14 +010035#include <wiringPi.h>
36#include <gertboard.h>
37
Gordon Henderson13bbba72013-01-14 11:31:56 +000038extern int wiringPiDebug ;
39
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010040#ifndef TRUE
41# define TRUE (1==1)
42# define FALSE (1==2)
43#endif
44
Gordon Henderson98bcb202013-02-07 21:53:49 +000045#define VERSION "1.12"
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010046
47static int wpMode ;
48
49char *usage = "Usage: gpio -v\n"
Gordon Henderson178ea082012-08-19 15:17:03 +010050 " gpio -h\n"
Gordon Henderson56c77b52013-02-01 20:19:22 +000051 " gpio [-g] <read/write/wb/pwm/clock/mode> ...\n"
Gordon Henderson25e4ec52012-12-06 21:49:41 +000052 " gpio [-p] <read/write/wb> ...\n"
Gordon Henderson183c5a62012-10-21 15:25:16 +010053 " gpio readall\n"
54 " gpio unexportall/exports ...\n"
55 " gpio export/edge/unexport ...\n"
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010056 " gpio drive <group> <value>\n"
Gordon Hendersonf99ffed2012-08-19 15:12:45 +010057 " gpio pwm-bal/pwm-ms \n"
58 " gpio pwmr <range> \n"
Gordon Henderson8cb49392012-09-16 10:15:32 +010059 " gpio pwmc <divider> \n"
Gordon Henderson99095e32012-08-27 20:56:14 +010060 " gpio load spi/i2c\n"
61 " gpio gbr <channel>\n"
Gordon Henderson8cb49392012-09-16 10:15:32 +010062 " gpio gbw <channel> <value>" ; // No trailing newline needed here.
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010063
64
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010065/*
66 * changeOwner:
67 * Change the ownership of the file to the real userId of the calling
68 * program so we can access it.
69 *********************************************************************************
70 */
71
72static void changeOwner (char *cmd, char *file)
73{
74 uid_t uid = getuid () ;
75 uid_t gid = getgid () ;
76
77 if (chown (file, uid, gid) != 0)
78 {
79 if (errno == ENOENT) // Warn that it's not there
80 fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ;
81 else
82 {
83 fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
84 exit (1) ;
85 }
86 }
87}
88
89
90/*
91 * moduleLoaded:
92 * Return true/false if the supplied module is loaded
93 *********************************************************************************
94 */
95
96static int moduleLoaded (char *modName)
97{
98 int len = strlen (modName) ;
99 int found = FALSE ;
100 FILE *fd = fopen ("/proc/modules", "r") ;
101 char line [80] ;
102
103 if (fd == NULL)
104 {
105 fprintf (stderr, "gpio: Unable to check modules: %s\n", strerror (errno)) ;
106 exit (1) ;
107 }
108
109 while (fgets (line, 80, fd) != NULL)
110 {
111 if (strncmp (line, modName, len) != 0)
112 continue ;
113
114 found = TRUE ;
115 break ;
116 }
117
118 fclose (fd) ;
119
120 return found ;
121}
122
123
124/*
125 * doLoad:
126 * Load either the spi or i2c modules and change device ownerships, etc.
127 *********************************************************************************
128 */
129
130static void _doLoadUsage (char *argv [])
131{
Gordon Hendersone8f62582013-01-28 13:00:47 +0000132 fprintf (stderr, "Usage: %s load <spi/i2c> [SPI bufferSize in KB | I2C baudrate in Kb/sec]\n", argv [0]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100133 exit (1) ;
134}
135
136static void doLoad (int argc, char *argv [])
137{
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000138 char *module1, *module2 ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100139 char cmd [80] ;
140 char *file1, *file2 ;
Gordon Hendersone8f62582013-01-28 13:00:47 +0000141 char args1 [32], args2 [32] ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100142
Gordon Henderson13bbba72013-01-14 11:31:56 +0000143 if (argc < 3)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100144 _doLoadUsage (argv) ;
145
Gordon Hendersone8f62582013-01-28 13:00:47 +0000146 args1 [0] = args2 [0] = 0 ;
Gordon Henderson13bbba72013-01-14 11:31:56 +0000147
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100148 /**/ if (strcasecmp (argv [2], "spi") == 0)
149 {
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000150 module1 = "spidev" ;
151 module2 = "spi_bcm2708" ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100152 file1 = "/dev/spidev0.0" ;
153 file2 = "/dev/spidev0.1" ;
Gordon Henderson13bbba72013-01-14 11:31:56 +0000154 if (argc == 4)
Gordon Henderson98bcb202013-02-07 21:53:49 +0000155 sprintf (args1, " bufsiz=%d", atoi (argv [3]) * 1024) ;
Gordon Henderson13bbba72013-01-14 11:31:56 +0000156 else if (argc > 4)
157 _doLoadUsage (argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100158 }
159 else if (strcasecmp (argv [2], "i2c") == 0)
160 {
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000161 module1 = "i2c_dev" ;
162 module2 = "i2c_bcm2708" ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100163 file1 = "/dev/i2c-0" ;
164 file2 = "/dev/i2c-1" ;
Gordon Hendersone8f62582013-01-28 13:00:47 +0000165 if (argc == 4)
166 sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ;
167 else if (argc > 4)
168 _doLoadUsage (argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100169 }
170 else
171 _doLoadUsage (argv) ;
172
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000173 if (!moduleLoaded (module1))
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100174 {
Gordon Hendersone8f62582013-01-28 13:00:47 +0000175 sprintf (cmd, "modprobe %s%s", module1, args1) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100176 system (cmd) ;
177 }
178
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000179 if (!moduleLoaded (module2))
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100180 {
Gordon Hendersone8f62582013-01-28 13:00:47 +0000181 sprintf (cmd, "modprobe %s%s", module2, args2) ;
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000182 system (cmd) ;
183 }
184
185 if (!moduleLoaded (module2))
186 {
187 fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100188 exit (1) ;
189 }
190
191 sleep (1) ; // To let things get settled
192
193 changeOwner (argv [0], file1) ;
194 changeOwner (argv [0], file2) ;
195}
196
197
Gordon Henderson183c5a62012-10-21 15:25:16 +0100198/*
199 * doReadall:
200 * Read all the GPIO pins
201 *********************************************************************************
202 */
203
204static char *pinNames [] =
205{
Gordon Hendersone8f62582013-01-28 13:00:47 +0000206 "GPIO 0", "GPIO 1", "GPIO 2", "GPIO 3", "GPIO 4", "GPIO 5", "GPIO 6", "GPIO 7",
207 "SDA ", "SCL ",
208 "CE0 ", "CE1 ", "MOSI ", "MISO ", "SCLK ",
209 "TxD ", "RxD ",
210 "GPIO 8", "GPIO 9", "GPIO10", "GPIO11",
211} ;
212
213static char *alts [] =
214{
Gordon Henderson4c8862e2013-02-02 20:33:51 +0000215 "IN ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3"
Gordon Henderson183c5a62012-10-21 15:25:16 +0100216} ;
217
218static void doReadall (void)
219{
220 int pin ;
221
Gordon Henderson4ba36e22013-01-28 16:06:34 +0000222 printf ("+----------+------+--------+------+-------+\n") ;
Gordon Hendersone8f62582013-01-28 13:00:47 +0000223 printf ("| wiringPi | GPIO | Name | Mode | Value |\n") ;
Gordon Henderson4ba36e22013-01-28 16:06:34 +0000224 printf ("+----------+------+--------+------+-------+\n") ;
Gordon Henderson183c5a62012-10-21 15:25:16 +0100225
Gordon Hendersone8f62582013-01-28 13:00:47 +0000226 for (pin = 0 ; pin < 64 ; ++pin)
227 {
228 if (wpiPinToGpio (pin) == -1)
229 continue ;
230
231 printf ("| %6d | %3d | %s | %s | %s |\n",
Gordon Henderson183c5a62012-10-21 15:25:16 +0100232 pin, wpiPinToGpio (pin),
233 pinNames [pin],
Gordon Hendersone8f62582013-01-28 13:00:47 +0000234 alts [getAlt (pin)],
Gordon Henderson183c5a62012-10-21 15:25:16 +0100235 digitalRead (pin) == HIGH ? "High" : "Low ") ;
Gordon Hendersone8f62582013-01-28 13:00:47 +0000236 }
Gordon Henderson183c5a62012-10-21 15:25:16 +0100237
Gordon Henderson4ba36e22013-01-28 16:06:34 +0000238 printf ("+----------+------+--------+------+-------+\n") ;
Gordon Henderson183c5a62012-10-21 15:25:16 +0100239}
240
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100241
242/*
243 * doExports:
244 * List all GPIO exports
245 *********************************************************************************
246 */
247
Gordon Henderson178ea082012-08-19 15:17:03 +0100248static void doExports (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100249{
250 int fd ;
251 int i, l, first ;
252 char fName [128] ;
253 char buf [16] ;
254
255// Rather crude, but who knows what others are up to...
256
257 for (first = 0, i = 0 ; i < 64 ; ++i)
258 {
259
260// Try to read the direction
261
262 sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
263 if ((fd = open (fName, O_RDONLY)) == -1)
264 continue ;
265
266 if (first == 0)
267 {
268 ++first ;
269 printf ("GPIO Pins exported:\n") ;
270 }
271
272 printf ("%4d: ", i) ;
273
274 if ((l = read (fd, buf, 16)) == 0)
275 sprintf (buf, "%s", "?") ;
276
277 buf [l] = 0 ;
278 if ((buf [strlen (buf) - 1]) == '\n')
279 buf [strlen (buf) - 1] = 0 ;
280
281 printf ("%-3s", buf) ;
282
283 close (fd) ;
284
285// Try to Read the value
286
287 sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
288 if ((fd = open (fName, O_RDONLY)) == -1)
289 {
290 printf ("No Value file (huh?)\n") ;
291 continue ;
292 }
293
294 if ((l = read (fd, buf, 16)) == 0)
295 sprintf (buf, "%s", "?") ;
296
297 buf [l] = 0 ;
298 if ((buf [strlen (buf) - 1]) == '\n')
299 buf [strlen (buf) - 1] = 0 ;
300
301 printf (" %s", buf) ;
302
303// Read any edge trigger file
304
305 sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ;
306 if ((fd = open (fName, O_RDONLY)) == -1)
307 {
308 printf ("\n") ;
309 continue ;
310 }
311
312 if ((l = read (fd, buf, 16)) == 0)
313 sprintf (buf, "%s", "?") ;
314
315 buf [l] = 0 ;
316 if ((buf [strlen (buf) - 1]) == '\n')
317 buf [strlen (buf) - 1] = 0 ;
318
319 printf (" %-8s\n", buf) ;
320
321 close (fd) ;
322 }
323}
324
325
326/*
327 * doExport:
328 * gpio export pin mode
329 * This uses the /sys/class/gpio device interface.
330 *********************************************************************************
331 */
332
333void doExport (int argc, char *argv [])
334{
335 FILE *fd ;
336 int pin ;
337 char *mode ;
338 char fName [128] ;
339
340 if (argc != 4)
341 {
342 fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
343 exit (1) ;
344 }
345
346 pin = atoi (argv [2]) ;
347
348 mode = argv [3] ;
349
350 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
351 {
352 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
353 exit (1) ;
354 }
355
356 fprintf (fd, "%d\n", pin) ;
357 fclose (fd) ;
358
359 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
360 if ((fd = fopen (fName, "w")) == NULL)
361 {
362 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
363 exit (1) ;
364 }
365
366 /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
367 fprintf (fd, "in\n") ;
368 else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
369 fprintf (fd, "out\n") ;
370 else
371 {
372 fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ;
373 exit (1) ;
374 }
375
376 fclose (fd) ;
377
378// Change ownership so the current user can actually use it!
379
380 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
381 changeOwner (argv [0], fName) ;
382
383 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
384 changeOwner (argv [0], fName) ;
385
386}
387
388
389/*
390 * doEdge:
391 * gpio edge pin mode
392 * Easy access to changing the edge trigger on a GPIO pin
393 * This uses the /sys/class/gpio device interface.
394 *********************************************************************************
395 */
396
397void doEdge (int argc, char *argv [])
398{
399 FILE *fd ;
400 int pin ;
401 char *mode ;
402 char fName [128] ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100403
404 if (argc != 4)
405 {
406 fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
407 exit (1) ;
408 }
409
Gordon Henderson178ea082012-08-19 15:17:03 +0100410 pin = atoi (argv [2]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100411 mode = argv [3] ;
412
413// Export the pin and set direction to input
414
415 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
416 {
417 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
418 exit (1) ;
419 }
420
421 fprintf (fd, "%d\n", pin) ;
422 fclose (fd) ;
423
424 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
425 if ((fd = fopen (fName, "w")) == NULL)
426 {
427 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
428 exit (1) ;
429 }
430
431 fprintf (fd, "in\n") ;
432 fclose (fd) ;
433
434 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
435 if ((fd = fopen (fName, "w")) == NULL)
436 {
437 fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
438 exit (1) ;
439 }
440
Gordon Henderson178ea082012-08-19 15:17:03 +0100441 /**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
442 else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
443 else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
444 else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100445 else
446 {
447 fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
448 exit (1) ;
449 }
450
Gordon Henderson178ea082012-08-19 15:17:03 +0100451// Change ownership of the value and edge files, so the current user can actually use it!
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100452
453 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100454 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100455
456 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100457 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100458
459 fclose (fd) ;
460}
461
462
463/*
464 * doUnexport:
465 * gpio unexport pin
466 * This uses the /sys/class/gpio device interface.
467 *********************************************************************************
468 */
469
470void doUnexport (int argc, char *argv [])
471{
472 FILE *fd ;
473 int pin ;
474
475 if (argc != 3)
476 {
477 fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
478 exit (1) ;
479 }
480
481 pin = atoi (argv [2]) ;
482
483 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
484 {
485 fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
486 exit (1) ;
487 }
488
489 fprintf (fd, "%d\n", pin) ;
490 fclose (fd) ;
491}
492
493
494/*
495 * doUnexportAll:
496 * gpio unexportall
497 * Un-Export all the GPIO pins.
498 * This uses the /sys/class/gpio device interface.
499 *********************************************************************************
500 */
501
502void doUnexportall (int argc, char *argv [])
503{
504 FILE *fd ;
505 int pin ;
506
507 for (pin = 0 ; pin < 63 ; ++pin)
508 {
509 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
510 {
511 fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
512 exit (1) ;
513 }
514 fprintf (fd, "%d\n", pin) ;
515 fclose (fd) ;
516 }
517}
518
519
520/*
521 * doMode:
522 * gpio mode pin mode ...
523 *********************************************************************************
524 */
525
526void doMode (int argc, char *argv [])
527{
528 int pin ;
529 char *mode ;
530
531 if (argc != 4)
532 {
533 fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
534 exit (1) ;
535 }
536
537 pin = atoi (argv [2]) ;
538
539 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
540 return ;
541
542 mode = argv [3] ;
543
Gordon Henderson56c77b52013-02-01 20:19:22 +0000544 /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
545 else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
546 else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
547 else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ;
548 else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
549 else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
550 else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100551 else
552 {
Gordon Henderson56c77b52013-02-01 20:19:22 +0000553 fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100554 exit (1) ;
555 }
556}
557
558
559/*
560 * doPadDrive:
561 * gpio drive group value
562 *********************************************************************************
563 */
564
Gordon Henderson1bb49892012-08-19 15:33:26 +0100565static void doPadDrive (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100566{
567 int group, val ;
568
569 if (argc != 4)
570 {
571 fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
572 exit (1) ;
573 }
574
575 group = atoi (argv [2]) ;
576 val = atoi (argv [3]) ;
577
578 if ((group < 0) || (group > 2))
579 {
580 fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
581 exit (1) ;
582 }
583
584 if ((val < 0) || (val > 7))
585 {
586 fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
587 exit (1) ;
588 }
589
590 setPadDrive (group, val) ;
591}
592
593
594/*
Gordon Henderson99095e32012-08-27 20:56:14 +0100595 * doGbw:
596 * gpio gbw channel value
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000597 * Gertboard Write - To the Analog output
Gordon Henderson99095e32012-08-27 20:56:14 +0100598 *********************************************************************************
599 */
600
601static void doGbw (int argc, char *argv [])
602{
603 int channel, value ;
604
605 if (argc != 4)
606 {
607 fprintf (stderr, "Usage: %s gbr <channel> <value>\n", argv [0]) ;
608 exit (1) ;
609 }
610
611 channel = atoi (argv [2]) ;
612 value = atoi (argv [3]) ;
613
614 if ((channel < 0) || (channel > 1))
615 {
616 fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
617 exit (1) ;
618 }
619
620 if ((value < 0) || (value > 1023))
621 {
622 fprintf (stderr, "%s: value must be from 0 to 255\n", argv [0]) ;
623 exit (1) ;
624 }
625
626 if (gertboardSPISetup () == -1)
627 {
628 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
629 exit (1) ;
630 }
631
632 gertboardAnalogWrite (channel, value) ;
633}
634
635
636/*
637 * doGbr:
638 * gpio gbr channel
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000639 * From the analog input
Gordon Henderson99095e32012-08-27 20:56:14 +0100640 *********************************************************************************
641 */
642
643static void doGbr (int argc, char *argv [])
644{
645 int channel ;
646
647 if (argc != 3)
648 {
649 fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
650 exit (1) ;
651 }
652
653 channel = atoi (argv [2]) ;
654
655 if ((channel < 0) || (channel > 1))
656 {
657 fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
658 exit (1) ;
659 }
660
661 if (gertboardSPISetup () == -1)
662 {
663 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
664 exit (1) ;
665 }
666
667 printf ("%d\n",gertboardAnalogRead (channel)) ;
668}
669
670
671
672/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100673 * doWrite:
674 * gpio write pin value
675 *********************************************************************************
676 */
677
Gordon Henderson1bb49892012-08-19 15:33:26 +0100678static void doWrite (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100679{
680 int pin, val ;
681
682 if (argc != 4)
683 {
684 fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
685 exit (1) ;
686 }
687
688 pin = atoi (argv [2]) ;
689
690 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
691 return ;
692
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000693 /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
694 val = 1 ;
695 else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
696 val = 0 ;
697 else
698 val = atoi (argv [3]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100699
700 /**/ if (val == 0)
701 digitalWrite (pin, LOW) ;
702 else
703 digitalWrite (pin, HIGH) ;
704}
705
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000706/*
707 * doWriteByte:
708 * gpio write value
709 *********************************************************************************
710 */
711
712static void doWriteByte (int argc, char *argv [])
713{
714 int val ;
715
716 if (argc != 3)
717 {
718 fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
719 exit (1) ;
720 }
721
722 val = (int)strtol (argv [2], NULL, 0) ;
723
724 digitalWriteByte (val) ;
725}
726
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100727
728/*
729 * doRead:
730 * Read a pin and return the value
731 *********************************************************************************
732 */
733
734void doRead (int argc, char *argv [])
735{
736 int pin, val ;
737
738 if (argc != 3)
739 {
740 fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
741 exit (1) ;
742 }
743
744 pin = atoi (argv [2]) ;
745
746 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
747 {
748 printf ("0\n") ;
749 return ;
750 }
751
752 val = digitalRead (pin) ;
753
754 printf ("%s\n", val == 0 ? "0" : "1") ;
755}
756
757
758/*
Gordon Henderson56c77b52013-02-01 20:19:22 +0000759 * doClock:
760 * Output a clock on a pin
761 *********************************************************************************
762 */
763
764void doClock (int argc, char *argv [])
765{
766 int pin, freq ;
767
768 if (argc != 4)
769 {
770 fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
771 exit (1) ;
772 }
773
774 pin = atoi (argv [2]) ;
775
776 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
777 return ;
778
779 freq = atoi (argv [3]) ;
780
781 gpioClockSet (pin, freq) ;
782}
783
784
785/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100786 * doPwm:
787 * Output a PWM value on a pin
788 *********************************************************************************
789 */
790
791void doPwm (int argc, char *argv [])
792{
793 int pin, val ;
794
795 if (argc != 4)
796 {
797 fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
798 exit (1) ;
799 }
800
801 pin = atoi (argv [2]) ;
802
803 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
804 return ;
805
806 val = atoi (argv [3]) ;
807
808 pwmWrite (pin, val) ;
809}
810
811
812/*
Gordon Henderson8cb49392012-09-16 10:15:32 +0100813 * doPwmMode: doPwmRange: doPwmClock:
814 * Change the PWM mode, range and clock divider values
Gordon Hendersonf99ffed2012-08-19 15:12:45 +0100815 *********************************************************************************
816 */
817
818static void doPwmMode (int mode)
819{
820 pwmSetMode (mode) ;
821}
822
823static void doPwmRange (int argc, char *argv [])
824{
825 unsigned int range ;
826
827 if (argc != 3)
828 {
829 fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
830 exit (1) ;
831 }
832
833 range = (unsigned int)strtoul (argv [2], NULL, 10) ;
834
835 if (range == 0)
836 {
837 fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
838 exit (1) ;
839 }
840
841 pwmSetRange (range) ;
842}
843
Gordon Henderson8cb49392012-09-16 10:15:32 +0100844static void doPwmClock (int argc, char *argv [])
845{
846 unsigned int clock ;
847
848 if (argc != 3)
849 {
850 fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
851 exit (1) ;
852 }
853
854 clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
855
856 if ((clock < 1) || (clock > 4095))
857 {
858 fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
859 exit (1) ;
860 }
861
862 pwmSetClock (clock) ;
863}
864
Gordon Hendersonf99ffed2012-08-19 15:12:45 +0100865
866/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100867 * main:
868 * Start here
869 *********************************************************************************
870 */
871
872int main (int argc, char *argv [])
873{
874 int i ;
875
Gordon Henderson13bbba72013-01-14 11:31:56 +0000876 if (getenv ("WIRINGPI_DEBUG") != NULL)
877 {
878 printf ("gpio: wiringPi debug mode enabled\n") ;
879 wiringPiDebug = TRUE ;
880 }
881
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100882 if (argc == 1)
883 {
Gordon Henderson86a5c682012-10-02 14:32:12 +0100884 fprintf (stderr, "%s\n", usage) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100885 return 1 ;
886 }
887
Gordon Henderson178ea082012-08-19 15:17:03 +0100888 if (strcasecmp (argv [1], "-h") == 0)
889 {
890 printf ("%s: %s\n", argv [0], usage) ;
891 return 0 ;
892 }
893
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100894 if (strcasecmp (argv [1], "-v") == 0)
895 {
896 printf ("gpio version: %s\n", VERSION) ;
897 printf ("Copyright (c) 2012 Gordon Henderson\n") ;
898 printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
899 printf ("For details type: %s -warranty\n", argv [0]) ;
Gordon Henderson86a5c682012-10-02 14:32:12 +0100900 printf ("\n") ;
901 printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100902 return 0 ;
903 }
904
905 if (strcasecmp (argv [1], "-warranty") == 0)
906 {
907 printf ("gpio version: %s\n", VERSION) ;
908 printf ("Copyright (c) 2012 Gordon Henderson\n") ;
909 printf ("\n") ;
910 printf (" This program is free software; you can redistribute it and/or modify\n") ;
911 printf (" it under the terms of the GNU Leser General Public License as published\n") ;
912 printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
913 printf (" (at your option) any later version.\n") ;
914 printf ("\n") ;
915 printf (" This program is distributed in the hope that it will be useful,\n") ;
916 printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
917 printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
918 printf (" GNU Lesser General Public License for more details.\n") ;
919 printf ("\n") ;
920 printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
921 printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
922 printf ("\n") ;
923 return 0 ;
924 }
925
926 if (geteuid () != 0)
927 {
928 fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
929 return 1 ;
930 }
931
932// Initial test for /sys/class/gpio operations:
933
Gordon Henderson178ea082012-08-19 15:17:03 +0100934 /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
935 else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
936 else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100937 else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; }
Gordon Henderson178ea082012-08-19 15:17:03 +0100938 else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
939
Gordon Henderson86a5c682012-10-02 14:32:12 +0100940// Check for load command:
Gordon Henderson178ea082012-08-19 15:17:03 +0100941
Gordon Henderson178ea082012-08-19 15:17:03 +0100942 if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100943
Gordon Henderson99095e32012-08-27 20:56:14 +0100944// Gertboard commands
945
946 if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
947 if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
948
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100949// Check for -g argument
950
951 if (strcasecmp (argv [1], "-g") == 0)
952 {
953 if (wiringPiSetupGpio () == -1)
954 {
Gordon Henderson178ea082012-08-19 15:17:03 +0100955 fprintf (stderr, "%s: Unable to initialise GPIO mode.\n", argv [0]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100956 exit (1) ;
957 }
958
959 for (i = 2 ; i < argc ; ++i)
960 argv [i - 1] = argv [i] ;
961 --argc ;
962 wpMode = WPI_MODE_GPIO ;
963 }
964
965// Check for -p argument for PiFace
966
967 else if (strcasecmp (argv [1], "-p") == 0)
968 {
969 if (wiringPiSetupPiFaceForGpioProg () == -1)
970 {
971 fprintf (stderr, "%s: Unable to initialise PiFace.\n", argv [0]) ;
972 exit (1) ;
973 }
974
975 for (i = 2 ; i < argc ; ++i)
976 argv [i - 1] = argv [i] ;
977 --argc ;
978 wpMode = WPI_MODE_PIFACE ;
979 }
980
981// Default to wiringPi mode
982
983 else
984 {
985 if (wiringPiSetup () == -1)
986 {
Gordon Henderson178ea082012-08-19 15:17:03 +0100987 fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100988 exit (1) ;
989 }
990 wpMode = WPI_MODE_PINS ;
991 }
992
Gordon Henderson86a5c682012-10-02 14:32:12 +0100993// Check for PWM or Pad Drive operations
Gordon Hendersonf99ffed2012-08-19 15:12:45 +0100994
995 if (wpMode != WPI_MODE_PIFACE)
996 {
Gordon Henderson86a5c682012-10-02 14:32:12 +0100997 if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode (PWM_MODE_BAL) ; return 0 ; }
998 if (strcasecmp (argv [1], "pwm-ms") == 0) { doPwmMode (PWM_MODE_MS) ; return 0 ; }
999 if (strcasecmp (argv [1], "pwmr") == 0) { doPwmRange (argc, argv) ; return 0 ; }
1000 if (strcasecmp (argv [1], "pwmc") == 0) { doPwmClock (argc, argv) ; return 0 ; }
1001 if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; }
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001002 }
1003
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001004// Check for wiring commands
1005
Gordon Henderson25e4ec52012-12-06 21:49:41 +00001006 /**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
1007 else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
1008 else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ;
1009 else if (strcasecmp (argv [1], "wb") == 0) doWriteByte (argc, argv) ;
1010 else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
Gordon Henderson56c77b52013-02-01 20:19:22 +00001011 else if (strcasecmp (argv [1], "clock") == 0) doClock (argc, argv) ;
Gordon Henderson25e4ec52012-12-06 21:49:41 +00001012 else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001013 else
1014 {
Gordon Henderson178ea082012-08-19 15:17:03 +01001015 fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001016 exit (1) ;
1017 }
1018 return 0 ;
1019}