blob: 8b15eea113a5bd27a22814dbc73bf431741df2d6 [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 Hendersonbf0ad862012-08-16 15:04:43 +010038#ifndef TRUE
39# define TRUE (1==1)
40# define FALSE (1==2)
41#endif
42
Gordon Henderson99095e32012-08-27 20:56:14 +010043#define VERSION "1.2"
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010044
45static int wpMode ;
46
47char *usage = "Usage: gpio -v\n"
Gordon Henderson178ea082012-08-19 15:17:03 +010048 " gpio -h\n"
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010049 " gpio [-g] <read/write/pwm/mode> ...\n"
50 " gpio [-p] <read/write/mode> ...\n"
51 " gpio export/edge/unexport/unexportall/exports ...\n"
52 " gpio drive <group> <value>\n"
Gordon Hendersonf99ffed2012-08-19 15:12:45 +010053 " gpio pwm-bal/pwm-ms \n"
54 " gpio pwmr <range> \n"
Gordon Henderson8cb49392012-09-16 10:15:32 +010055 " gpio pwmc <divider> \n"
Gordon Henderson99095e32012-08-27 20:56:14 +010056 " gpio load spi/i2c\n"
57 " gpio gbr <channel>\n"
Gordon Henderson8cb49392012-09-16 10:15:32 +010058 " gpio gbw <channel> <value>" ; // No trailing newline needed here.
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010059
60
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010061/*
62 * changeOwner:
63 * Change the ownership of the file to the real userId of the calling
64 * program so we can access it.
65 *********************************************************************************
66 */
67
68static void changeOwner (char *cmd, char *file)
69{
70 uid_t uid = getuid () ;
71 uid_t gid = getgid () ;
72
73 if (chown (file, uid, gid) != 0)
74 {
75 if (errno == ENOENT) // Warn that it's not there
76 fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ;
77 else
78 {
79 fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
80 exit (1) ;
81 }
82 }
83}
84
85
86/*
87 * moduleLoaded:
88 * Return true/false if the supplied module is loaded
89 *********************************************************************************
90 */
91
92static int moduleLoaded (char *modName)
93{
94 int len = strlen (modName) ;
95 int found = FALSE ;
96 FILE *fd = fopen ("/proc/modules", "r") ;
97 char line [80] ;
98
99 if (fd == NULL)
100 {
101 fprintf (stderr, "gpio: Unable to check modules: %s\n", strerror (errno)) ;
102 exit (1) ;
103 }
104
105 while (fgets (line, 80, fd) != NULL)
106 {
107 if (strncmp (line, modName, len) != 0)
108 continue ;
109
110 found = TRUE ;
111 break ;
112 }
113
114 fclose (fd) ;
115
116 return found ;
117}
118
119
120/*
121 * doLoad:
122 * Load either the spi or i2c modules and change device ownerships, etc.
123 *********************************************************************************
124 */
125
126static void _doLoadUsage (char *argv [])
127{
128 fprintf (stderr, "Usage: %s load <spi/i2c>\n", argv [0]) ;
129 exit (1) ;
130}
131
132static void doLoad (int argc, char *argv [])
133{
134 char *module ;
135 char cmd [80] ;
136 char *file1, *file2 ;
137
138 if (argc != 3)
139 _doLoadUsage (argv) ;
140
141 /**/ if (strcasecmp (argv [2], "spi") == 0)
142 {
143 module = "spi_bcm2708" ;
144 file1 = "/dev/spidev0.0" ;
145 file2 = "/dev/spidev0.1" ;
146 }
147 else if (strcasecmp (argv [2], "i2c") == 0)
148 {
149 module = "i2c_bcm2708" ;
150 file1 = "/dev/i2c-0" ;
151 file2 = "/dev/i2c-1" ;
152 }
153 else
154 _doLoadUsage (argv) ;
155
156 if (!moduleLoaded (module))
157 {
158 sprintf (cmd, "modprobe %s", module) ;
159 system (cmd) ;
160 }
161
162 if (!moduleLoaded (module))
163 {
164 fprintf (stderr, "%s: Unable to load %s\n", argv [0], module) ;
165 exit (1) ;
166 }
167
168 sleep (1) ; // To let things get settled
169
170 changeOwner (argv [0], file1) ;
171 changeOwner (argv [0], file2) ;
172}
173
174
175
176/*
177 * doExports:
178 * List all GPIO exports
179 *********************************************************************************
180 */
181
Gordon Henderson178ea082012-08-19 15:17:03 +0100182static void doExports (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100183{
184 int fd ;
185 int i, l, first ;
186 char fName [128] ;
187 char buf [16] ;
188
189// Rather crude, but who knows what others are up to...
190
191 for (first = 0, i = 0 ; i < 64 ; ++i)
192 {
193
194// Try to read the direction
195
196 sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
197 if ((fd = open (fName, O_RDONLY)) == -1)
198 continue ;
199
200 if (first == 0)
201 {
202 ++first ;
203 printf ("GPIO Pins exported:\n") ;
204 }
205
206 printf ("%4d: ", i) ;
207
208 if ((l = read (fd, buf, 16)) == 0)
209 sprintf (buf, "%s", "?") ;
210
211 buf [l] = 0 ;
212 if ((buf [strlen (buf) - 1]) == '\n')
213 buf [strlen (buf) - 1] = 0 ;
214
215 printf ("%-3s", buf) ;
216
217 close (fd) ;
218
219// Try to Read the value
220
221 sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
222 if ((fd = open (fName, O_RDONLY)) == -1)
223 {
224 printf ("No Value file (huh?)\n") ;
225 continue ;
226 }
227
228 if ((l = read (fd, buf, 16)) == 0)
229 sprintf (buf, "%s", "?") ;
230
231 buf [l] = 0 ;
232 if ((buf [strlen (buf) - 1]) == '\n')
233 buf [strlen (buf) - 1] = 0 ;
234
235 printf (" %s", buf) ;
236
237// Read any edge trigger file
238
239 sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ;
240 if ((fd = open (fName, O_RDONLY)) == -1)
241 {
242 printf ("\n") ;
243 continue ;
244 }
245
246 if ((l = read (fd, buf, 16)) == 0)
247 sprintf (buf, "%s", "?") ;
248
249 buf [l] = 0 ;
250 if ((buf [strlen (buf) - 1]) == '\n')
251 buf [strlen (buf) - 1] = 0 ;
252
253 printf (" %-8s\n", buf) ;
254
255 close (fd) ;
256 }
257}
258
259
260/*
261 * doExport:
262 * gpio export pin mode
263 * This uses the /sys/class/gpio device interface.
264 *********************************************************************************
265 */
266
267void doExport (int argc, char *argv [])
268{
269 FILE *fd ;
270 int pin ;
271 char *mode ;
272 char fName [128] ;
273
274 if (argc != 4)
275 {
276 fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
277 exit (1) ;
278 }
279
280 pin = atoi (argv [2]) ;
281
282 mode = argv [3] ;
283
284 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
285 {
286 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
287 exit (1) ;
288 }
289
290 fprintf (fd, "%d\n", pin) ;
291 fclose (fd) ;
292
293 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
294 if ((fd = fopen (fName, "w")) == NULL)
295 {
296 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
297 exit (1) ;
298 }
299
300 /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
301 fprintf (fd, "in\n") ;
302 else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
303 fprintf (fd, "out\n") ;
304 else
305 {
306 fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ;
307 exit (1) ;
308 }
309
310 fclose (fd) ;
311
312// Change ownership so the current user can actually use it!
313
314 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
315 changeOwner (argv [0], fName) ;
316
317 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
318 changeOwner (argv [0], fName) ;
319
320}
321
322
323/*
324 * doEdge:
325 * gpio edge pin mode
326 * Easy access to changing the edge trigger on a GPIO pin
327 * This uses the /sys/class/gpio device interface.
328 *********************************************************************************
329 */
330
331void doEdge (int argc, char *argv [])
332{
333 FILE *fd ;
334 int pin ;
335 char *mode ;
336 char fName [128] ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100337
338 if (argc != 4)
339 {
340 fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
341 exit (1) ;
342 }
343
Gordon Henderson178ea082012-08-19 15:17:03 +0100344 pin = atoi (argv [2]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100345 mode = argv [3] ;
346
347// Export the pin and set direction to input
348
349 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
350 {
351 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
352 exit (1) ;
353 }
354
355 fprintf (fd, "%d\n", pin) ;
356 fclose (fd) ;
357
358 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
359 if ((fd = fopen (fName, "w")) == NULL)
360 {
361 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
362 exit (1) ;
363 }
364
365 fprintf (fd, "in\n") ;
366 fclose (fd) ;
367
368 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
369 if ((fd = fopen (fName, "w")) == NULL)
370 {
371 fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
372 exit (1) ;
373 }
374
Gordon Henderson178ea082012-08-19 15:17:03 +0100375 /**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
376 else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
377 else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
378 else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100379 else
380 {
381 fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
382 exit (1) ;
383 }
384
Gordon Henderson178ea082012-08-19 15:17:03 +0100385// Change ownership of the value and edge files, so the current user can actually use it!
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100386
387 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100388 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100389
390 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100391 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100392
393 fclose (fd) ;
394}
395
396
397/*
398 * doUnexport:
399 * gpio unexport pin
400 * This uses the /sys/class/gpio device interface.
401 *********************************************************************************
402 */
403
404void doUnexport (int argc, char *argv [])
405{
406 FILE *fd ;
407 int pin ;
408
409 if (argc != 3)
410 {
411 fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
412 exit (1) ;
413 }
414
415 pin = atoi (argv [2]) ;
416
417 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
418 {
419 fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
420 exit (1) ;
421 }
422
423 fprintf (fd, "%d\n", pin) ;
424 fclose (fd) ;
425}
426
427
428/*
429 * doUnexportAll:
430 * gpio unexportall
431 * Un-Export all the GPIO pins.
432 * This uses the /sys/class/gpio device interface.
433 *********************************************************************************
434 */
435
436void doUnexportall (int argc, char *argv [])
437{
438 FILE *fd ;
439 int pin ;
440
441 for (pin = 0 ; pin < 63 ; ++pin)
442 {
443 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
444 {
445 fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
446 exit (1) ;
447 }
448 fprintf (fd, "%d\n", pin) ;
449 fclose (fd) ;
450 }
451}
452
453
454/*
455 * doMode:
456 * gpio mode pin mode ...
457 *********************************************************************************
458 */
459
460void doMode (int argc, char *argv [])
461{
462 int pin ;
463 char *mode ;
464
465 if (argc != 4)
466 {
467 fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
468 exit (1) ;
469 }
470
471 pin = atoi (argv [2]) ;
472
473 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
474 return ;
475
476 mode = argv [3] ;
477
Gordon Henderson178ea082012-08-19 15:17:03 +0100478 /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
479 else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
480 else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
481 else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
482 else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
483 else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100484 else
485 {
486 fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/up/down/tri\n", argv [1], mode) ;
487 exit (1) ;
488 }
489}
490
491
492/*
493 * doPadDrive:
494 * gpio drive group value
495 *********************************************************************************
496 */
497
Gordon Henderson1bb49892012-08-19 15:33:26 +0100498static void doPadDrive (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100499{
500 int group, val ;
501
502 if (argc != 4)
503 {
504 fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
505 exit (1) ;
506 }
507
508 group = atoi (argv [2]) ;
509 val = atoi (argv [3]) ;
510
511 if ((group < 0) || (group > 2))
512 {
513 fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
514 exit (1) ;
515 }
516
517 if ((val < 0) || (val > 7))
518 {
519 fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
520 exit (1) ;
521 }
522
523 setPadDrive (group, val) ;
524}
525
526
527/*
Gordon Henderson99095e32012-08-27 20:56:14 +0100528 * doGbw:
529 * gpio gbw channel value
530 *********************************************************************************
531 */
532
533static void doGbw (int argc, char *argv [])
534{
535 int channel, value ;
536
537 if (argc != 4)
538 {
539 fprintf (stderr, "Usage: %s gbr <channel> <value>\n", argv [0]) ;
540 exit (1) ;
541 }
542
543 channel = atoi (argv [2]) ;
544 value = atoi (argv [3]) ;
545
546 if ((channel < 0) || (channel > 1))
547 {
548 fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
549 exit (1) ;
550 }
551
552 if ((value < 0) || (value > 1023))
553 {
554 fprintf (stderr, "%s: value must be from 0 to 255\n", argv [0]) ;
555 exit (1) ;
556 }
557
558 if (gertboardSPISetup () == -1)
559 {
560 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
561 exit (1) ;
562 }
563
564 gertboardAnalogWrite (channel, value) ;
565}
566
567
568/*
569 * doGbr:
570 * gpio gbr channel
571 *********************************************************************************
572 */
573
574static void doGbr (int argc, char *argv [])
575{
576 int channel ;
577
578 if (argc != 3)
579 {
580 fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
581 exit (1) ;
582 }
583
584 channel = atoi (argv [2]) ;
585
586 if ((channel < 0) || (channel > 1))
587 {
588 fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
589 exit (1) ;
590 }
591
592 if (gertboardSPISetup () == -1)
593 {
594 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
595 exit (1) ;
596 }
597
598 printf ("%d\n",gertboardAnalogRead (channel)) ;
599}
600
601
602
603/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100604 * doWrite:
605 * gpio write pin value
606 *********************************************************************************
607 */
608
Gordon Henderson1bb49892012-08-19 15:33:26 +0100609static void doWrite (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100610{
611 int pin, val ;
612
613 if (argc != 4)
614 {
615 fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
616 exit (1) ;
617 }
618
619 pin = atoi (argv [2]) ;
620
621 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
622 return ;
623
624 val = atoi (argv [3]) ;
625
626 /**/ if (val == 0)
627 digitalWrite (pin, LOW) ;
628 else
629 digitalWrite (pin, HIGH) ;
630}
631
632
633/*
634 * doRead:
635 * Read a pin and return the value
636 *********************************************************************************
637 */
638
639void doRead (int argc, char *argv [])
640{
641 int pin, val ;
642
643 if (argc != 3)
644 {
645 fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
646 exit (1) ;
647 }
648
649 pin = atoi (argv [2]) ;
650
651 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
652 {
653 printf ("0\n") ;
654 return ;
655 }
656
657 val = digitalRead (pin) ;
658
659 printf ("%s\n", val == 0 ? "0" : "1") ;
660}
661
662
663/*
664 * doPwm:
665 * Output a PWM value on a pin
666 *********************************************************************************
667 */
668
669void doPwm (int argc, char *argv [])
670{
671 int pin, val ;
672
673 if (argc != 4)
674 {
675 fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
676 exit (1) ;
677 }
678
679 pin = atoi (argv [2]) ;
680
681 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
682 return ;
683
684 val = atoi (argv [3]) ;
685
686 pwmWrite (pin, val) ;
687}
688
689
690/*
Gordon Henderson8cb49392012-09-16 10:15:32 +0100691 * doPwmMode: doPwmRange: doPwmClock:
692 * Change the PWM mode, range and clock divider values
Gordon Hendersonf99ffed2012-08-19 15:12:45 +0100693 *********************************************************************************
694 */
695
696static void doPwmMode (int mode)
697{
698 pwmSetMode (mode) ;
699}
700
701static void doPwmRange (int argc, char *argv [])
702{
703 unsigned int range ;
704
705 if (argc != 3)
706 {
707 fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
708 exit (1) ;
709 }
710
711 range = (unsigned int)strtoul (argv [2], NULL, 10) ;
712
713 if (range == 0)
714 {
715 fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
716 exit (1) ;
717 }
718
719 pwmSetRange (range) ;
720}
721
Gordon Henderson8cb49392012-09-16 10:15:32 +0100722static void doPwmClock (int argc, char *argv [])
723{
724 unsigned int clock ;
725
726 if (argc != 3)
727 {
728 fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
729 exit (1) ;
730 }
731
732 clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
733
734 if ((clock < 1) || (clock > 4095))
735 {
736 fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
737 exit (1) ;
738 }
739
740 pwmSetClock (clock) ;
741}
742
Gordon Hendersonf99ffed2012-08-19 15:12:45 +0100743
744/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100745 * main:
746 * Start here
747 *********************************************************************************
748 */
749
750int main (int argc, char *argv [])
751{
752 int i ;
753
754 if (argc == 1)
755 {
756 fprintf (stderr, "%s: %s\n", argv [0], usage) ;
757 return 1 ;
758 }
759
Gordon Henderson178ea082012-08-19 15:17:03 +0100760 if (strcasecmp (argv [1], "-h") == 0)
761 {
762 printf ("%s: %s\n", argv [0], usage) ;
763 return 0 ;
764 }
765
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100766 if (strcasecmp (argv [1], "-v") == 0)
767 {
768 printf ("gpio version: %s\n", VERSION) ;
769 printf ("Copyright (c) 2012 Gordon Henderson\n") ;
770 printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
771 printf ("For details type: %s -warranty\n", argv [0]) ;
772 return 0 ;
773 }
774
775 if (strcasecmp (argv [1], "-warranty") == 0)
776 {
777 printf ("gpio version: %s\n", VERSION) ;
778 printf ("Copyright (c) 2012 Gordon Henderson\n") ;
779 printf ("\n") ;
780 printf (" This program is free software; you can redistribute it and/or modify\n") ;
781 printf (" it under the terms of the GNU Leser General Public License as published\n") ;
782 printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
783 printf (" (at your option) any later version.\n") ;
784 printf ("\n") ;
785 printf (" This program is distributed in the hope that it will be useful,\n") ;
786 printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
787 printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
788 printf (" GNU Lesser General Public License for more details.\n") ;
789 printf ("\n") ;
790 printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
791 printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
792 printf ("\n") ;
793 return 0 ;
794 }
795
796 if (geteuid () != 0)
797 {
798 fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
799 return 1 ;
800 }
801
802// Initial test for /sys/class/gpio operations:
803
Gordon Henderson178ea082012-08-19 15:17:03 +0100804 /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
805 else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
806 else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100807 else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; }
Gordon Henderson178ea082012-08-19 15:17:03 +0100808 else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
809
810// Check for drive or load commands:
811
812 if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; }
813 if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100814
Gordon Henderson99095e32012-08-27 20:56:14 +0100815// Gertboard commands
816
817 if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
818 if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
819
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100820// Check for -g argument
821
822 if (strcasecmp (argv [1], "-g") == 0)
823 {
824 if (wiringPiSetupGpio () == -1)
825 {
Gordon Henderson178ea082012-08-19 15:17:03 +0100826 fprintf (stderr, "%s: Unable to initialise GPIO mode.\n", argv [0]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100827 exit (1) ;
828 }
829
830 for (i = 2 ; i < argc ; ++i)
831 argv [i - 1] = argv [i] ;
832 --argc ;
833 wpMode = WPI_MODE_GPIO ;
834 }
835
836// Check for -p argument for PiFace
837
838 else if (strcasecmp (argv [1], "-p") == 0)
839 {
840 if (wiringPiSetupPiFaceForGpioProg () == -1)
841 {
842 fprintf (stderr, "%s: Unable to initialise PiFace.\n", argv [0]) ;
843 exit (1) ;
844 }
845
846 for (i = 2 ; i < argc ; ++i)
847 argv [i - 1] = argv [i] ;
848 --argc ;
849 wpMode = WPI_MODE_PIFACE ;
850 }
851
852// Default to wiringPi mode
853
854 else
855 {
856 if (wiringPiSetup () == -1)
857 {
Gordon Henderson178ea082012-08-19 15:17:03 +0100858 fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100859 exit (1) ;
860 }
861 wpMode = WPI_MODE_PINS ;
862 }
863
Gordon Hendersonf99ffed2012-08-19 15:12:45 +0100864// Check for PWM operations
865
866 if (wpMode != WPI_MODE_PIFACE)
867 {
868 if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode (PWM_MODE_BAL) ; return 0 ; }
869 if (strcasecmp (argv [1], "pwm-ms") == 0) { doPwmMode (PWM_MODE_MS) ; return 0 ; }
870 if (strcasecmp (argv [1], "pwmr") == 0) { doPwmRange (argc, argv) ; return 0 ; }
Gordon Henderson8cb49392012-09-16 10:15:32 +0100871 if (strcasecmp (argv [1], "pwmc") == 0) { doPwmClock (argc, argv) ; return 0 ; }
Gordon Hendersonf99ffed2012-08-19 15:12:45 +0100872 }
873
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100874// Check for wiring commands
875
Gordon Henderson178ea082012-08-19 15:17:03 +0100876 /**/ if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
877 else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ;
878 else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
879 else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100880 else
881 {
Gordon Henderson178ea082012-08-19 15:17:03 +0100882 fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100883 exit (1) ;
884 }
885 return 0 ;
886}