Gordons Projects

--> Projects Top-Level GIT

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