Gordons Projects

--> Projects Top-Level GIT

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