Gordons Projects

--> Projects Top-Level GIT

8b15eea113a5bd27a22814dbc73bf431741df2d6
[wiringPi] / gpio / gpio.c
1 /*
2  * gpio.c:
3  *      Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
4  *      Pi's GPIO.
5  *      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
25
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
35 #include <wiringPi.h>
36 #include <gertboard.h>
37
38 #ifndef TRUE
39 #  define       TRUE    (1==1)
40 #  define       FALSE   (1==2)
41 #endif
42
43 #define VERSION "1.2"
44
45 static int wpMode ;
46
47 char *usage = "Usage: gpio -v\n"
48               "       gpio -h\n"
49               "       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"
53               "       gpio pwm-bal/pwm-ms \n"
54               "       gpio pwmr <range> \n"
55               "       gpio pwmc <divider> \n"
56               "       gpio load spi/i2c\n"
57               "       gpio gbr <channel>\n"
58               "       gpio gbw <channel> <value>" ;     // No trailing newline needed here.
59
60
61 /*
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
68 static 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
92 static 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
126 static void _doLoadUsage (char *argv [])
127 {
128   fprintf (stderr, "Usage: %s load <spi/i2c>\n", argv [0]) ;
129   exit (1) ;
130 }
131
132 static 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
182 static void doExports (int argc, char *argv [])
183 {
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
267 void 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
331 void doEdge (int argc, char *argv [])
332 {
333   FILE *fd ;
334   int pin ;
335   char *mode ;
336   char fName [128] ;
337
338   if (argc != 4)
339   {
340     fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
341     exit (1) ;
342   }
343
344   pin  = atoi (argv [2]) ;
345   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
375   /**/ 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") ;
379   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
385 // Change ownership of the value and edge files, so the current user can actually use it!
386
387   sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
388   changeOwner (argv [0], fName) ;
389
390   sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
391   changeOwner (argv [0], fName) ;
392
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
404 void 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
436 void 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
460 void 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
478   /**/ 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) ;
484   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
498 static void doPadDrive (int argc, char *argv [])
499 {
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 /*
528  * doGbw:
529  *      gpio gbw channel value
530  *********************************************************************************
531  */
532
533 static 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
574 static 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 /*
604  * doWrite:
605  *      gpio write pin value
606  *********************************************************************************
607  */
608
609 static void doWrite (int argc, char *argv [])
610 {
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
639 void 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
669 void 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 /*
691  * doPwmMode: doPwmRange: doPwmClock:
692  *      Change the PWM mode, range and clock divider values
693  *********************************************************************************
694  */
695
696 static void doPwmMode (int mode)
697 {
698   pwmSetMode (mode) ;
699 }
700
701 static 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
722 static 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
743
744 /*
745  * main:
746  *      Start here
747  *********************************************************************************
748  */
749
750 int 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
760   if (strcasecmp (argv [1], "-h") == 0)
761   {
762     printf ("%s: %s\n", argv [0], usage) ;
763     return 0 ;
764   }
765
766   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
804   /**/ 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 ; }
807   else if (strcasecmp (argv [1], "unexportall") == 0)   { doUnexportall (argc, argv) ;  return 0 ; }
808   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 ; }
814
815 // 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
820 // Check for -g argument
821
822   if (strcasecmp (argv [1], "-g") == 0)
823   {
824     if (wiringPiSetupGpio () == -1)
825     {
826       fprintf (stderr, "%s: Unable to initialise GPIO mode.\n", argv [0]) ;
827       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     {
858       fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ;
859       exit (1) ;
860     }
861     wpMode = WPI_MODE_PINS ;
862   }
863
864 // 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 ; }
871     if (strcasecmp (argv [1], "pwmc")    == 0)  { doPwmClock (argc, argv) ;   return 0 ; }
872   }
873
874 // Check for wiring commands
875
876   /**/ 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) ;
880   else
881   {
882     fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
883     exit (1) ;
884   }
885   return 0 ;
886 }