Gordons Projects

--> Projects Top-Level GIT

Bumped version number to 2.04
[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-2013 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 <ctype.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36
37 #include <wiringPi.h>
38
39 #include <gertboard.h>
40 #include <piFace.h>
41
42 #include "extensions.h"
43
44 extern int wiringPiDebug ;
45
46 #ifndef TRUE
47 #  define       TRUE    (1==1)
48 #  define       FALSE   (1==2)
49 #endif
50
51 #define VERSION         "2.04"
52 #define I2CDETECT       "/usr/sbin/i2cdetect"
53
54 static int wpMode ;
55
56 char *usage = "Usage: gpio -v\n"
57               "       gpio -h\n"
58               "       gpio [-g|-1] [-x extension:params] ...\n"
59               "       gpio [-p] <read/write/wb> ...\n"
60               "       gpio <read/write/aread/awritewb/pwm/clock/mode> ...\n"
61               "       gpio readall/reset\n"
62               "       gpio unexportall/exports\n"
63               "       gpio export/edge/unexport ...\n"
64               "       gpio wfi <pin> <mode>\n"
65               "       gpio drive <group> <value>\n"
66               "       gpio pwm-bal/pwm-ms \n"
67               "       gpio pwmr <range> \n"
68               "       gpio pwmc <divider> \n"
69               "       gpio load spi/i2c\n"
70               "       gpio i2cd/i2cdetect\n"
71               "       gpio gbr <channel>\n"
72               "       gpio gbw <channel> <value>" ;     // No trailing newline needed here.
73
74
75 /*
76  * changeOwner:
77  *      Change the ownership of the file to the real userId of the calling
78  *      program so we can access it.
79  *********************************************************************************
80  */
81
82 static void changeOwner (char *cmd, char *file)
83 {
84   uid_t uid = getuid () ;
85   uid_t gid = getgid () ;
86
87   if (chown (file, uid, gid) != 0)
88   {
89     if (errno == ENOENT)        // Warn that it's not there
90       fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ;
91     else
92     {
93       fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
94       exit (1) ;
95     }
96   }
97 }
98
99
100 /*
101  * moduleLoaded:
102  *      Return true/false if the supplied module is loaded
103  *********************************************************************************
104  */
105
106 static int moduleLoaded (char *modName)
107 {
108   int len   = strlen (modName) ;
109   int found = FALSE ;
110   FILE *fd = fopen ("/proc/modules", "r") ;
111   char line [80] ;
112
113   if (fd == NULL)
114   {
115     fprintf (stderr, "gpio: Unable to check modules: %s\n", strerror (errno)) ;
116     exit (1) ;
117   }
118
119   while (fgets (line, 80, fd) != NULL)
120   {
121     if (strncmp (line, modName, len) != 0)
122       continue ;
123
124     found = TRUE ;
125     break ;
126   }
127
128   fclose (fd) ;
129
130   return found ;
131 }
132
133
134 /*
135  * doLoad:
136  *      Load either the spi or i2c modules and change device ownerships, etc.
137  *********************************************************************************
138  */
139
140 static void _doLoadUsage (char *argv [])
141 {
142   fprintf (stderr, "Usage: %s load <spi/i2c> [SPI bufferSize in KB | I2C baudrate in Kb/sec]\n", argv [0]) ;
143   exit (1) ;
144 }
145
146 static void doLoad (int argc, char *argv [])
147 {
148   char *module1, *module2 ;
149   char cmd [80] ;
150   char *file1, *file2 ;
151   char args1 [32], args2 [32] ;
152
153   if (argc < 3)
154     _doLoadUsage (argv) ;
155
156   args1 [0] = args2 [0] = 0 ;
157
158   /**/ if (strcasecmp (argv [2], "spi") == 0)
159   {
160     module1 = "spidev" ;
161     module2 = "spi_bcm2708" ;
162     file1  = "/dev/spidev0.0" ;
163     file2  = "/dev/spidev0.1" ;
164     if (argc == 4)
165       sprintf (args1, " bufsiz=%d", atoi (argv [3]) * 1024) ;
166     else if (argc > 4)
167       _doLoadUsage (argv) ;
168   }
169   else if (strcasecmp (argv [2], "i2c") == 0)
170   {
171     module1 = "i2c_dev" ;
172     module2 = "i2c_bcm2708" ;
173     file1  = "/dev/i2c-0" ;
174     file2  = "/dev/i2c-1" ;
175     if (argc == 4)
176       sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ;
177     else if (argc > 4)
178       _doLoadUsage (argv) ;
179   }
180   else
181     _doLoadUsage (argv) ;
182
183   if (!moduleLoaded (module1))
184   {
185     sprintf (cmd, "modprobe %s%s", module1, args1) ;
186     system (cmd) ;
187   }
188
189   if (!moduleLoaded (module2))
190   {
191     sprintf (cmd, "modprobe %s%s", module2, args2) ;
192     system (cmd) ;
193   }
194
195   if (!moduleLoaded (module2))
196   {
197     fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ;
198     exit (1) ;
199   }
200
201   sleep (1) ;   // To let things get settled
202
203   changeOwner (argv [0], file1) ;
204   changeOwner (argv [0], file2) ;
205 }
206
207
208 /*
209  * doI2Cdetect:
210  *      Run the i2cdetect command with the right runes for this Pi revision
211  *********************************************************************************
212  */
213
214 static void doI2Cdetect (int argc, char *argv [])
215 {
216   int port = piBoardRev () == 1 ? 0 : 1 ;
217   char command [128] ;
218   struct stat statBuf ;
219
220   if (stat (I2CDETECT, &statBuf) < 0)
221   {
222     fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
223     return ;
224   }
225
226   if (!moduleLoaded ("i2c_dev"))
227   {
228     fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ;
229     return ;
230   }
231
232   sprintf (command, "%s -y %d", I2CDETECT, port) ;
233   if (system (command) < 0)
234     fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;
235
236 }
237
238
239 /*
240  * doReadall:
241  *      Read all the GPIO pins
242  *********************************************************************************
243  */
244
245 static char *pinNames [] =
246 {
247   "GPIO 0", "GPIO 1", "GPIO 2", "GPIO 3", "GPIO 4", "GPIO 5", "GPIO 6", "GPIO 7",
248   "SDA   ", "SCL   ",
249   "CE0   ", "CE1   ", "MOSI  ", "MISO  ", "SCLK  ",
250   "TxD   ", "RxD   ",
251   "GPIO 8", "GPIO 9", "GPIO10", "GPIO11",
252 } ;
253
254 static char *alts [] =
255 {
256   "IN  ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3"
257 } ;
258
259 static int wpiToPhys [64] =
260 {
261   11, 12, 13, 15, 16, 18, 22,  7,       //  0...7
262    3,  5,                               //  8...9
263   24, 26, 19, 21, 23,                   // 10..14
264    8, 10,                               // 15..16
265    3,  4,  5,  6,                       // 17..20
266              0,0,0,0,0,0,0,0,0,0,0,     // 20..31
267    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,     // 32..47
268    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,     // 47..63
269 } ;
270
271 static void doReadall (void)
272 {
273   int pin ;
274
275   printf ("+----------+-Rev%d-+------+--------+------+-------+\n", piBoardRev ()) ;
276   printf ("| wiringPi | GPIO | Phys | Name   | Mode | Value |\n") ;
277   printf ("+----------+------+------+--------+------+-------+\n") ;
278
279   for (pin = 0 ; pin < 64 ; ++pin)      // Crude, but effective
280   {
281     if (wpiPinToGpio (pin) == -1)
282       continue ;
283
284     printf ("| %6d   | %3d  | %3d  | %s | %s | %s  |\n",
285         pin, wpiPinToGpio (pin), wpiToPhys [pin],
286         pinNames [pin], 
287         alts [getAlt (pin)], 
288         digitalRead (pin) == HIGH ? "High" : "Low ") ;
289   }
290
291   printf ("+----------+------+------+--------+------+-------+\n") ;
292 }
293
294
295 /*
296  * doExports:
297  *      List all GPIO exports
298  *********************************************************************************
299  */
300
301 static void doExports (int argc, char *argv [])
302 {
303   int fd ;
304   int i, l, first ;
305   char fName [128] ;
306   char buf [16] ;
307
308   for (first = 0, i = 0 ; i < 64 ; ++i) // Crude, but effective
309   {
310
311 // Try to read the direction
312
313     sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
314     if ((fd = open (fName, O_RDONLY)) == -1)
315       continue ;
316
317     if (first == 0)
318     {
319       ++first ;
320       printf ("GPIO Pins exported:\n") ;
321     }
322
323     printf ("%4d: ", i) ;
324
325     if ((l = read (fd, buf, 16)) == 0)
326       sprintf (buf, "%s", "?") ;
327  
328     buf [l] = 0 ;
329     if ((buf [strlen (buf) - 1]) == '\n')
330       buf [strlen (buf) - 1] = 0 ;
331
332     printf ("%-3s", buf) ;
333
334     close (fd) ;
335
336 // Try to Read the value
337
338     sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
339     if ((fd = open (fName, O_RDONLY)) == -1)
340     {
341       printf ("No Value file (huh?)\n") ;
342       continue ;
343     }
344
345     if ((l = read (fd, buf, 16)) == 0)
346       sprintf (buf, "%s", "?") ;
347
348     buf [l] = 0 ;
349     if ((buf [strlen (buf) - 1]) == '\n')
350       buf [strlen (buf) - 1] = 0 ;
351
352     printf ("  %s", buf) ;
353
354 // Read any edge trigger file
355
356     sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ;
357     if ((fd = open (fName, O_RDONLY)) == -1)
358     {
359       printf ("\n") ;
360       continue ;
361     }
362
363     if ((l = read (fd, buf, 16)) == 0)
364       sprintf (buf, "%s", "?") ;
365
366     buf [l] = 0 ;
367     if ((buf [strlen (buf) - 1]) == '\n')
368       buf [strlen (buf) - 1] = 0 ;
369
370     printf ("  %-8s\n", buf) ;
371
372     close (fd) ;
373   }
374 }
375
376
377 /*
378  * doExport:
379  *      gpio export pin mode
380  *      This uses the /sys/class/gpio device interface.
381  *********************************************************************************
382  */
383
384 void doExport (int argc, char *argv [])
385 {
386   FILE *fd ;
387   int pin ;
388   char *mode ;
389   char fName [128] ;
390
391   if (argc != 4)
392   {
393     fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
394     exit (1) ;
395   }
396
397   pin = atoi (argv [2]) ;
398
399   mode = argv [3] ;
400
401   if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
402   {
403     fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
404     exit (1) ;
405   }
406
407   fprintf (fd, "%d\n", pin) ;
408   fclose (fd) ;
409
410   sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
411   if ((fd = fopen (fName, "w")) == NULL)
412   {
413     fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
414     exit (1) ;
415   }
416
417   /**/ if ((strcasecmp (mode, "in")  == 0) || (strcasecmp (mode, "input")  == 0))
418     fprintf (fd, "in\n") ;
419   else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
420     fprintf (fd, "out\n") ;
421   else
422   {
423     fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ;
424     exit (1) ;
425   }
426
427   fclose (fd) ;
428
429 // Change ownership so the current user can actually use it!
430
431   sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
432   changeOwner (argv [0], fName) ;
433
434   sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
435   changeOwner (argv [0], fName) ;
436
437 }
438
439
440 /*
441  * doWfi:
442  *      gpio wfi pin mode
443  *      Wait for Interrupt on a given pin.
444  *      Slight cheat here - it's easier to actually use ISR now (which calls
445  *      gpio to set the pin modes!) then we simply sleep, and expect the thread
446  *      to exit the program. Crude but effective.
447  *********************************************************************************
448  */
449
450 static void wfi (void)
451   { exit (0) ; }
452
453 void doWfi (int argc, char *argv [])
454 {
455   int pin, mode ;
456
457   if (argc != 4)
458   {
459     fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ;
460     exit (1) ;
461   }
462
463   pin  = atoi (argv [2]) ;
464
465   /**/ if (strcasecmp (argv [3], "rising")  == 0) mode = INT_EDGE_RISING ;
466   else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
467   else if (strcasecmp (argv [3], "both")    == 0) mode = INT_EDGE_BOTH ;
468   else
469   {
470     fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ;
471     exit (1) ;
472   }
473
474   if (wiringPiISR (pin, mode, &wfi) < 0)
475   {
476     fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
477     exit (1) ;
478   }
479
480   for (;;)
481     delay (9999) ;
482 }
483
484
485
486 /*
487  * doEdge:
488  *      gpio edge pin mode
489  *      Easy access to changing the edge trigger on a GPIO pin
490  *      This uses the /sys/class/gpio device interface.
491  *********************************************************************************
492  */
493
494 void doEdge (int argc, char *argv [])
495 {
496   FILE *fd ;
497   int pin ;
498   char *mode ;
499   char fName [128] ;
500
501   if (argc != 4)
502   {
503     fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
504     exit (1) ;
505   }
506
507   pin  = atoi (argv [2]) ;
508   mode = argv [3] ;
509
510 // Export the pin and set direction to input
511
512   if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
513   {
514     fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
515     exit (1) ;
516   }
517
518   fprintf (fd, "%d\n", pin) ;
519   fclose (fd) ;
520
521   sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
522   if ((fd = fopen (fName, "w")) == NULL)
523   {
524     fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
525     exit (1) ;
526   }
527
528   fprintf (fd, "in\n") ;
529   fclose (fd) ;
530
531   sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
532   if ((fd = fopen (fName, "w")) == NULL)
533   {
534     fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
535     exit (1) ;
536   }
537
538   /**/ if (strcasecmp (mode, "none")    == 0) fprintf (fd, "none\n") ;
539   else if (strcasecmp (mode, "rising")  == 0) fprintf (fd, "rising\n") ;
540   else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
541   else if (strcasecmp (mode, "both")    == 0) fprintf (fd, "both\n") ;
542   else
543   {
544     fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
545     exit (1) ;
546   }
547
548 // Change ownership of the value and edge files, so the current user can actually use it!
549
550   sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
551   changeOwner (argv [0], fName) ;
552
553   sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
554   changeOwner (argv [0], fName) ;
555
556   fclose (fd) ;
557 }
558
559
560 /*
561  * doUnexport:
562  *      gpio unexport pin
563  *      This uses the /sys/class/gpio device interface.
564  *********************************************************************************
565  */
566
567 void doUnexport (int argc, char *argv [])
568 {
569   FILE *fd ;
570   int pin ;
571
572   if (argc != 3)
573   {
574     fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
575     exit (1) ;
576   }
577
578   pin = atoi (argv [2]) ;
579
580   if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
581   {
582     fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
583     exit (1) ;
584   }
585
586   fprintf (fd, "%d\n", pin) ;
587   fclose (fd) ;
588 }
589
590
591 /*
592  * doUnexportAll:
593  *      gpio unexportall
594  *      Un-Export all the GPIO pins.
595  *      This uses the /sys/class/gpio device interface.
596  *********************************************************************************
597  */
598
599 void doUnexportall (char *progName)
600 {
601   FILE *fd ;
602   int pin ;
603
604   for (pin = 0 ; pin < 63 ; ++pin)
605   {
606     if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
607     {
608       fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
609       exit (1) ;
610     }
611     fprintf (fd, "%d\n", pin) ;
612     fclose (fd) ;
613   }
614 }
615
616
617 /*
618  * doReset:
619  *      Reset the GPIO pins - as much as we can do
620  *********************************************************************************
621  */
622
623 static void doReset (char *progName)
624 {
625   int pin ;
626
627   doUnexportall (progName) ;
628
629   for (pin = 0 ; pin < 64 ; ++pin)
630   {
631     if (wpiPinToGpio (pin) == -1)
632       continue ;
633
634     digitalWrite    (pin, LOW) ;
635     pinMode         (pin, INPUT) ;
636     pullUpDnControl (pin, PUD_OFF) ;
637   }
638 }
639
640
641 /*
642  * doMode:
643  *      gpio mode pin mode ...
644  *********************************************************************************
645  */
646
647 void doMode (int argc, char *argv [])
648 {
649   int pin ;
650   char *mode ;
651
652   if (argc != 4)
653   {
654     fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
655     exit (1) ;
656   }
657
658   pin = atoi (argv [2]) ;
659
660   mode = argv [3] ;
661
662   /**/ if (strcasecmp (mode, "in")     == 0) pinMode         (pin, INPUT) ;
663   else if (strcasecmp (mode, "out")    == 0) pinMode         (pin, OUTPUT) ;
664   else if (strcasecmp (mode, "pwm")    == 0) pinMode         (pin, PWM_OUTPUT) ;
665   else if (strcasecmp (mode, "clock")  == 0) pinMode         (pin, GPIO_CLOCK) ;
666   else if (strcasecmp (mode, "up")     == 0) pullUpDnControl (pin, PUD_UP) ;
667   else if (strcasecmp (mode, "down")   == 0) pullUpDnControl (pin, PUD_DOWN) ;
668   else if (strcasecmp (mode, "tri")    == 0) pullUpDnControl (pin, PUD_OFF) ;
669   else
670   {
671     fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ;
672     exit (1) ;
673   }
674 }
675
676
677 /*
678  * doPadDrive:
679  *      gpio drive group value
680  *********************************************************************************
681  */
682
683 static void doPadDrive (int argc, char *argv [])
684 {
685   int group, val ;
686
687   if (argc != 4)
688   {
689     fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
690     exit (1) ;
691   }
692
693   group = atoi (argv [2]) ;
694   val   = atoi (argv [3]) ;
695
696   if ((group < 0) || (group > 2))
697   {
698     fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
699     exit (1) ;
700   }
701
702   if ((val < 0) || (val > 7))
703   {
704     fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
705     exit (1) ;
706   }
707
708   setPadDrive (group, val) ;
709 }
710
711
712 /*
713  * doGbw:
714  *      gpio gbw channel value
715  *      Gertboard Write - To the Analog output
716  *********************************************************************************
717  */
718
719 static void doGbw (int argc, char *argv [])
720 {
721   int channel, value ;
722
723   if (argc != 4)
724   {
725     fprintf (stderr, "Usage: %s gbw <channel> <value>\n", argv [0]) ;
726     exit (1) ;
727   }
728
729   channel = atoi (argv [2]) ;
730   value   = atoi (argv [3]) ;
731
732   if ((channel < 0) || (channel > 1))
733   {
734     fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ;
735     exit (1) ;
736   }
737
738   if ((value < 0) || (value > 1023))
739   {
740     fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ;
741     exit (1) ;
742   }
743
744   if (gertboardAnalogSetup (64) < 0)
745   {
746     fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
747     exit (1) ;
748   }
749
750   analogWrite (64 + channel, value) ;
751 }
752
753
754 /*
755  * doGbr:
756  *      gpio gbr channel
757  *      From the analog input
758  *********************************************************************************
759  */
760
761 static void doGbr (int argc, char *argv [])
762 {
763   int channel ;
764
765   if (argc != 3)
766   {
767     fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
768     exit (1) ;
769   }
770
771   channel = atoi (argv [2]) ;
772
773   if ((channel < 0) || (channel > 1))
774   {
775     fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ;
776     exit (1) ;
777   }
778
779   if (gertboardAnalogSetup (64) < 0)
780   {
781     fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
782     exit (1) ;
783   }
784
785   printf ("%d\n", analogRead (64 + channel)) ;
786 }
787
788
789 /*
790  * doWrite:
791  *      gpio write pin value
792  *********************************************************************************
793  */
794
795 static void doWrite (int argc, char *argv [])
796 {
797   int pin, val ;
798
799   if (argc != 4)
800   {
801     fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
802     exit (1) ;
803   }
804
805   pin = atoi (argv [2]) ;
806
807   /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
808     val = 1 ;
809   else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
810     val = 0 ;
811   else
812     val = atoi (argv [3]) ;
813
814   /**/ if (val == 0)
815     digitalWrite (pin, LOW) ;
816   else
817     digitalWrite (pin, HIGH) ;
818 }
819
820
821 /*
822  * doAwriterite:
823  *      gpio awrite pin value
824  *********************************************************************************
825  */
826
827 static void doAwrite (int argc, char *argv [])
828 {
829   int pin, val ;
830
831   if (argc != 4)
832   {
833     fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
834     exit (1) ;
835   }
836
837   pin = atoi (argv [2]) ;
838
839   val = atoi (argv [3]) ;
840
841   analogWrite (pin, val) ;
842 }
843
844
845 /*
846  * doWriteByte:
847  *      gpio write value
848  *********************************************************************************
849  */
850
851 static void doWriteByte (int argc, char *argv [])
852 {
853   int val ;
854
855   if (argc != 3)
856   {
857     fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
858     exit (1) ;
859   }
860
861   val = (int)strtol (argv [2], NULL, 0) ;
862
863   digitalWriteByte (val) ;
864 }
865
866
867 /*
868  * doRead:
869  *      Read a pin and return the value
870  *********************************************************************************
871  */
872
873 void doRead (int argc, char *argv []) 
874 {
875   int pin, val ;
876
877   if (argc != 3)
878   {
879     fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
880     exit (1) ;
881   }
882
883   pin = atoi (argv [2]) ;
884   val = digitalRead (pin) ;
885
886   printf ("%s\n", val == 0 ? "0" : "1") ;
887 }
888
889
890 /*
891  * doAread:
892  *      Read an analog pin and return the value
893  *********************************************************************************
894  */
895
896 void doAread (int argc, char *argv []) 
897 {
898   if (argc != 3)
899   {
900     fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
901     exit (1) ;
902   }
903
904   printf ("%d\n", analogRead (atoi (argv [2]))) ;
905 }
906
907
908 /*
909  * doToggle:
910  *      Toggle an IO pin
911  *********************************************************************************
912  */
913
914 void doToggle (int argc, char *argv [])
915 {
916   int pin ;
917
918   if (argc != 3)
919   {
920     fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
921     exit (1) ;
922   }
923
924   pin = atoi (argv [2]) ;
925
926   digitalWrite (pin, !digitalRead (pin)) ;
927 }
928
929 /*
930  * doClock:
931  *      Output a clock on a pin
932  *********************************************************************************
933  */
934
935 void doClock (int argc, char *argv [])
936 {
937   int pin, freq ;
938
939   if (argc != 4)
940   {
941     fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
942     exit (1) ;
943   }
944
945   pin = atoi (argv [2]) ;
946
947   freq = atoi (argv [3]) ;
948
949   gpioClockSet (pin, freq) ;
950 }
951
952
953 /*
954  * doPwm:
955  *      Output a PWM value on a pin
956  *********************************************************************************
957  */
958
959 void doPwm (int argc, char *argv [])
960 {
961   int pin, val ;
962
963   if (argc != 4)
964   {
965     fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
966     exit (1) ;
967   }
968
969   pin = atoi (argv [2]) ;
970
971   val = atoi (argv [3]) ;
972
973   pwmWrite (pin, val) ;
974 }
975
976
977 /*
978  * doPwmMode: doPwmRange: doPwmClock:
979  *      Change the PWM mode, range and clock divider values
980  *********************************************************************************
981  */
982
983 static void doPwmMode (int mode)
984 {
985   pwmSetMode (mode) ;
986 }
987
988 static void doPwmRange (int argc, char *argv [])
989 {
990   unsigned int range ;
991
992   if (argc != 3)
993   {
994     fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
995     exit (1) ;
996   }
997
998   range = (unsigned int)strtoul (argv [2], NULL, 10) ;
999
1000   if (range == 0)
1001   {
1002     fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
1003     exit (1) ;
1004   }
1005
1006   pwmSetRange (range) ;
1007 }
1008
1009 static void doPwmClock (int argc, char *argv [])
1010 {
1011   unsigned int clock ;
1012
1013   if (argc != 3)
1014   {
1015     fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
1016     exit (1) ;
1017   }
1018
1019   clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
1020
1021   if ((clock < 1) || (clock > 4095))
1022   {
1023     fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
1024     exit (1) ;
1025   }
1026
1027   pwmSetClock (clock) ;
1028 }
1029
1030
1031 /*
1032  * main:
1033  *      Start here
1034  *********************************************************************************
1035  */
1036
1037 int main (int argc, char *argv [])
1038 {
1039   int i ;
1040
1041   if (getenv ("WIRINGPI_DEBUG") != NULL)
1042   {
1043     printf ("gpio: wiringPi debug mode enabled\n") ;
1044     wiringPiDebug = TRUE ;
1045   }
1046
1047   if (argc == 1)
1048   {
1049     fprintf (stderr, "%s\n", usage) ;
1050     return 1 ;
1051   }
1052
1053 // Help
1054
1055   if (strcasecmp (argv [1], "-h") == 0)
1056   {
1057     printf ("%s: %s\n", argv [0], usage) ;
1058     return 0 ;
1059   }
1060
1061 // Sort of a special:
1062
1063   if (strcmp (argv [1], "-R") == 0)
1064   {
1065     printf ("%d\n", piBoardRev ()) ;
1066     return 0 ;
1067   }
1068
1069 // Version & Warranty
1070
1071   if (strcmp (argv [1], "-V") == 0)
1072   {
1073     printf ("%d\n", piBoardRev ()) ;
1074     return 0 ;
1075   }
1076
1077   if (strcmp (argv [1], "-v") == 0)
1078   {
1079     printf ("gpio version: %s\n", VERSION) ;
1080     printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
1081     printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
1082     printf ("For details type: %s -warranty\n", argv [0]) ;
1083     printf ("\n") ;
1084     printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ;
1085     return 0 ;
1086   }
1087
1088   if (strcasecmp (argv [1], "-warranty") == 0)
1089   {
1090     printf ("gpio version: %s\n", VERSION) ;
1091     printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
1092     printf ("\n") ;
1093     printf ("    This program is free software; you can redistribute it and/or modify\n") ;
1094     printf ("    it under the terms of the GNU Leser General Public License as published\n") ;
1095     printf ("    by the Free Software Foundation, either version 3 of the License, or\n") ;
1096     printf ("    (at your option) any later version.\n") ;
1097     printf ("\n") ;
1098     printf ("    This program is distributed in the hope that it will be useful,\n") ;
1099     printf ("    but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
1100     printf ("    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n") ;
1101     printf ("    GNU Lesser General Public License for more details.\n") ;
1102     printf ("\n") ;
1103     printf ("    You should have received a copy of the GNU Lesser General Public License\n") ;
1104     printf ("    along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
1105     printf ("\n") ;
1106     return 0 ;
1107   }
1108
1109   if (geteuid () != 0)
1110   {
1111     fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
1112     return 1 ;
1113   }
1114
1115 // Initial test for /sys/class/gpio operations:
1116
1117   /**/ if (strcasecmp (argv [1], "exports"    ) == 0)   { doExports     (argc, argv) ;  return 0 ; }
1118   else if (strcasecmp (argv [1], "export"     ) == 0)   { doExport      (argc, argv) ;  return 0 ; }
1119   else if (strcasecmp (argv [1], "edge"       ) == 0)   { doEdge        (argc, argv) ;  return 0 ; }
1120   else if (strcasecmp (argv [1], "unexport"   ) == 0)   { doUnexport    (argc, argv) ;  return 0 ; }
1121   else if (strcasecmp (argv [1], "unexportall") == 0)   { doUnexportall (argv [0]) ;    return 0 ; }
1122
1123 // Check for load command:
1124
1125   if (strcasecmp (argv [1], "load" ) == 0)      { doLoad     (argc, argv) ; return 0 ; }
1126
1127 // Gertboard commands
1128
1129   if (strcasecmp (argv [1], "gbr" ) == 0)       { doGbr (argc, argv) ; return 0 ; }
1130   if (strcasecmp (argv [1], "gbw" ) == 0)       { doGbw (argc, argv) ; return 0 ; }
1131
1132 // Check for -g argument
1133
1134   /**/ if (strcasecmp (argv [1], "-g") == 0)
1135   {
1136     wiringPiSetupGpio () ;
1137
1138     for (i = 2 ; i < argc ; ++i)
1139       argv [i - 1] = argv [i] ;
1140     --argc ;
1141     wpMode = WPI_MODE_GPIO ;
1142   }
1143
1144 // Check for -1 argument
1145
1146   else if (strcasecmp (argv [1], "-1") == 0)
1147   {
1148     wiringPiSetupPhys () ;
1149
1150     for (i = 2 ; i < argc ; ++i)
1151       argv [i - 1] = argv [i] ;
1152     --argc ;
1153     wpMode = WPI_MODE_PHYS ;
1154   }
1155
1156 // Check for -p argument for PiFace
1157
1158   else if (strcasecmp (argv [1], "-p") == 0)
1159   {
1160     piFaceSetup (200) ;
1161
1162     for (i = 2 ; i < argc ; ++i)
1163       argv [i - 1] = argv [i] ;
1164     --argc ;
1165     wpMode = WPI_MODE_PIFACE ;
1166   }
1167
1168 // Default to wiringPi mode
1169
1170   else
1171   {
1172     wiringPiSetup () ;
1173     wpMode = WPI_MODE_PINS ;
1174   }
1175
1176 // Check for -x argument to load in a new extension
1177
1178   if (strcasecmp (argv [1], "-x") == 0)
1179   {
1180     if (argc < 3)
1181     {
1182       fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ;
1183       exit (EXIT_FAILURE) ;
1184     }
1185
1186     if (!doExtension (argv [0], argv [2]))      // Prints its own error messages
1187       exit (EXIT_FAILURE) ;
1188
1189     for (i = 3 ; i < argc ; ++i)
1190       argv [i - 2] = argv [i] ;
1191     argc -= 2 ;
1192   }
1193
1194   if (argc <= 1)
1195   {
1196     fprintf (stderr, "%s: no command given\n", argv [0]) ;
1197     exit (EXIT_FAILURE) ;
1198   }
1199
1200 // Core wiringPi functions
1201
1202   /**/ if (strcasecmp (argv [1], "mode"   ) == 0) doMode      (argc, argv) ;
1203   else if (strcasecmp (argv [1], "read"   ) == 0) doRead      (argc, argv) ;
1204   else if (strcasecmp (argv [1], "write"  ) == 0) doWrite     (argc, argv) ;
1205   else if (strcasecmp (argv [1], "pwm"    ) == 0) doPwm       (argc, argv) ;
1206   else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite    (argc, argv) ;
1207   else if (strcasecmp (argv [1], "aread"  ) == 0) doAread     (argc, argv) ;
1208
1209 // GPIO Nicies
1210
1211   else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle    (argc, argv) ;
1212
1213 // Pi Specifics
1214
1215   else if (strcasecmp (argv [1], "pwm-bal"  ) == 0) doPwmMode   (PWM_MODE_BAL) ;
1216   else if (strcasecmp (argv [1], "pwm-ms"   ) == 0) doPwmMode   (PWM_MODE_MS) ;
1217   else if (strcasecmp (argv [1], "pwmr"     ) == 0) doPwmRange  (argc, argv) ;
1218   else if (strcasecmp (argv [1], "pwmc"     ) == 0) doPwmClock  (argc, argv) ;
1219   else if (strcasecmp (argv [1], "drive"    ) == 0) doPadDrive  (argc, argv) ;
1220   else if (strcasecmp (argv [1], "readall"  ) == 0) doReadall   () ;
1221   else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
1222   else if (strcasecmp (argv [1], "i2cd"     ) == 0) doI2Cdetect (argc, argv) ;
1223   else if (strcasecmp (argv [1], "reset"    ) == 0) doReset     (argv [0]) ;
1224   else if (strcasecmp (argv [1], "wb"       ) == 0) doWriteByte (argc, argv) ;
1225   else if (strcasecmp (argv [1], "clock"    ) == 0) doClock     (argc, argv) ;
1226   else if (strcasecmp (argv [1], "wfi"      ) == 0) doWfi       (argc, argv) ;
1227   else
1228   {
1229     fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
1230     exit (EXIT_FAILURE) ;
1231   }
1232   return 0 ;
1233 }