Gordons Projects

--> Projects Top-Level GIT

Bother. Small issue crept into the SPI code.
[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.03"
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   int pin, val ;
899
900   if (argc != 3)
901   {
902     fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
903     exit (1) ;
904   }
905
906   pin = atoi (argv [2]) ;
907
908   val = analogRead (pin) ;
909
910   printf ("%s\n", val == 0 ? "0" : "1") ;
911 }
912
913
914 /*
915  * doToggle:
916  *      Toggle an IO pin
917  *********************************************************************************
918  */
919
920 void doToggle (int argc, char *argv [])
921 {
922   int pin ;
923
924   if (argc != 3)
925   {
926     fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
927     exit (1) ;
928   }
929
930   pin = atoi (argv [2]) ;
931
932   digitalWrite (pin, !digitalRead (pin)) ;
933 }
934
935 /*
936  * doClock:
937  *      Output a clock on a pin
938  *********************************************************************************
939  */
940
941 void doClock (int argc, char *argv [])
942 {
943   int pin, freq ;
944
945   if (argc != 4)
946   {
947     fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
948     exit (1) ;
949   }
950
951   pin = atoi (argv [2]) ;
952
953   freq = atoi (argv [3]) ;
954
955   gpioClockSet (pin, freq) ;
956 }
957
958
959 /*
960  * doPwm:
961  *      Output a PWM value on a pin
962  *********************************************************************************
963  */
964
965 void doPwm (int argc, char *argv [])
966 {
967   int pin, val ;
968
969   if (argc != 4)
970   {
971     fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
972     exit (1) ;
973   }
974
975   pin = atoi (argv [2]) ;
976
977   val = atoi (argv [3]) ;
978
979   pwmWrite (pin, val) ;
980 }
981
982
983 /*
984  * doPwmMode: doPwmRange: doPwmClock:
985  *      Change the PWM mode, range and clock divider values
986  *********************************************************************************
987  */
988
989 static void doPwmMode (int mode)
990 {
991   pwmSetMode (mode) ;
992 }
993
994 static void doPwmRange (int argc, char *argv [])
995 {
996   unsigned int range ;
997
998   if (argc != 3)
999   {
1000     fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
1001     exit (1) ;
1002   }
1003
1004   range = (unsigned int)strtoul (argv [2], NULL, 10) ;
1005
1006   if (range == 0)
1007   {
1008     fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
1009     exit (1) ;
1010   }
1011
1012   pwmSetRange (range) ;
1013 }
1014
1015 static void doPwmClock (int argc, char *argv [])
1016 {
1017   unsigned int clock ;
1018
1019   if (argc != 3)
1020   {
1021     fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
1022     exit (1) ;
1023   }
1024
1025   clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
1026
1027   if ((clock < 1) || (clock > 4095))
1028   {
1029     fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
1030     exit (1) ;
1031   }
1032
1033   pwmSetClock (clock) ;
1034 }
1035
1036
1037 /*
1038  * main:
1039  *      Start here
1040  *********************************************************************************
1041  */
1042
1043 int main (int argc, char *argv [])
1044 {
1045   int i ;
1046
1047   if (getenv ("WIRINGPI_DEBUG") != NULL)
1048   {
1049     printf ("gpio: wiringPi debug mode enabled\n") ;
1050     wiringPiDebug = TRUE ;
1051   }
1052
1053   if (argc == 1)
1054   {
1055     fprintf (stderr, "%s\n", usage) ;
1056     return 1 ;
1057   }
1058
1059 // Help
1060
1061   if (strcasecmp (argv [1], "-h") == 0)
1062   {
1063     printf ("%s: %s\n", argv [0], usage) ;
1064     return 0 ;
1065   }
1066
1067 // Sort of a special:
1068
1069   if (strcmp (argv [1], "-R") == 0)
1070   {
1071     printf ("%d\n", piBoardRev ()) ;
1072     return 0 ;
1073   }
1074
1075 // Version & Warranty
1076
1077   if (strcmp (argv [1], "-V") == 0)
1078   {
1079     printf ("%d\n", piBoardRev ()) ;
1080     return 0 ;
1081   }
1082
1083   if (strcmp (argv [1], "-v") == 0)
1084   {
1085     printf ("gpio version: %s\n", VERSION) ;
1086     printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
1087     printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
1088     printf ("For details type: %s -warranty\n", argv [0]) ;
1089     printf ("\n") ;
1090     printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ;
1091     return 0 ;
1092   }
1093
1094   if (strcasecmp (argv [1], "-warranty") == 0)
1095   {
1096     printf ("gpio version: %s\n", VERSION) ;
1097     printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
1098     printf ("\n") ;
1099     printf ("    This program is free software; you can redistribute it and/or modify\n") ;
1100     printf ("    it under the terms of the GNU Leser General Public License as published\n") ;
1101     printf ("    by the Free Software Foundation, either version 3 of the License, or\n") ;
1102     printf ("    (at your option) any later version.\n") ;
1103     printf ("\n") ;
1104     printf ("    This program is distributed in the hope that it will be useful,\n") ;
1105     printf ("    but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
1106     printf ("    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n") ;
1107     printf ("    GNU Lesser General Public License for more details.\n") ;
1108     printf ("\n") ;
1109     printf ("    You should have received a copy of the GNU Lesser General Public License\n") ;
1110     printf ("    along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
1111     printf ("\n") ;
1112     return 0 ;
1113   }
1114
1115   if (geteuid () != 0)
1116   {
1117     fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
1118     return 1 ;
1119   }
1120
1121 // Initial test for /sys/class/gpio operations:
1122
1123   /**/ if (strcasecmp (argv [1], "exports"    ) == 0)   { doExports     (argc, argv) ;  return 0 ; }
1124   else if (strcasecmp (argv [1], "export"     ) == 0)   { doExport      (argc, argv) ;  return 0 ; }
1125   else if (strcasecmp (argv [1], "edge"       ) == 0)   { doEdge        (argc, argv) ;  return 0 ; }
1126   else if (strcasecmp (argv [1], "unexport"   ) == 0)   { doUnexport    (argc, argv) ;  return 0 ; }
1127   else if (strcasecmp (argv [1], "unexportall") == 0)   { doUnexportall (argv [0]) ;    return 0 ; }
1128
1129 // Check for load command:
1130
1131   if (strcasecmp (argv [1], "load" ) == 0)      { doLoad     (argc, argv) ; return 0 ; }
1132
1133 // Gertboard commands
1134
1135   if (strcasecmp (argv [1], "gbr" ) == 0)       { doGbr (argc, argv) ; return 0 ; }
1136   if (strcasecmp (argv [1], "gbw" ) == 0)       { doGbw (argc, argv) ; return 0 ; }
1137
1138 // Check for -g argument
1139
1140   /**/ if (strcasecmp (argv [1], "-g") == 0)
1141   {
1142     wiringPiSetupGpio () ;
1143
1144     for (i = 2 ; i < argc ; ++i)
1145       argv [i - 1] = argv [i] ;
1146     --argc ;
1147     wpMode = WPI_MODE_GPIO ;
1148   }
1149
1150 // Check for -1 argument
1151
1152   else if (strcasecmp (argv [1], "-1") == 0)
1153   {
1154     wiringPiSetupPhys () ;
1155
1156     for (i = 2 ; i < argc ; ++i)
1157       argv [i - 1] = argv [i] ;
1158     --argc ;
1159     wpMode = WPI_MODE_PHYS ;
1160   }
1161
1162 // Check for -p argument for PiFace
1163
1164   else if (strcasecmp (argv [1], "-p") == 0)
1165   {
1166     piFaceSetup (200) ;
1167
1168     for (i = 2 ; i < argc ; ++i)
1169       argv [i - 1] = argv [i] ;
1170     --argc ;
1171     wpMode = WPI_MODE_PIFACE ;
1172   }
1173
1174 // Default to wiringPi mode
1175
1176   else
1177   {
1178     wiringPiSetup () ;
1179     wpMode = WPI_MODE_PINS ;
1180   }
1181
1182 // Check for -x argument to load in a new extension
1183
1184   if (strcasecmp (argv [1], "-x") == 0)
1185   {
1186     if (argc < 3)
1187     {
1188       fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ;
1189       exit (EXIT_FAILURE) ;
1190     }
1191
1192     if (!doExtension (argv [0], argv [2]))      // Prints its own error messages
1193       exit (EXIT_FAILURE) ;
1194
1195     for (i = 3 ; i < argc ; ++i)
1196       argv [i - 2] = argv [i] ;
1197     argc -= 2 ;
1198   }
1199
1200   if (argc <= 1)
1201   {
1202     fprintf (stderr, "%s: no command given\n", argv [0]) ;
1203     exit (EXIT_FAILURE) ;
1204   }
1205
1206 // Core wiringPi functions
1207
1208   /**/ if (strcasecmp (argv [1], "mode"   ) == 0) doMode      (argc, argv) ;
1209   else if (strcasecmp (argv [1], "read"   ) == 0) doRead      (argc, argv) ;
1210   else if (strcasecmp (argv [1], "write"  ) == 0) doWrite     (argc, argv) ;
1211   else if (strcasecmp (argv [1], "pwm"    ) == 0) doPwm       (argc, argv) ;
1212   else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite    (argc, argv) ;
1213   else if (strcasecmp (argv [1], "aread"  ) == 0) doAread     (argc, argv) ;
1214
1215 // GPIO Nicies
1216
1217   else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle    (argc, argv) ;
1218
1219 // Pi Specifics
1220
1221   else if (strcasecmp (argv [1], "pwm-bal"  ) == 0) doPwmMode   (PWM_MODE_BAL) ;
1222   else if (strcasecmp (argv [1], "pwm-ms"   ) == 0) doPwmMode   (PWM_MODE_MS) ;
1223   else if (strcasecmp (argv [1], "pwmr"     ) == 0) doPwmRange  (argc, argv) ;
1224   else if (strcasecmp (argv [1], "pwmc"     ) == 0) doPwmClock  (argc, argv) ;
1225   else if (strcasecmp (argv [1], "drive"    ) == 0) doPadDrive  (argc, argv) ;
1226   else if (strcasecmp (argv [1], "readall"  ) == 0) doReadall   () ;
1227   else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
1228   else if (strcasecmp (argv [1], "i2cd"     ) == 0) doI2Cdetect (argc, argv) ;
1229   else if (strcasecmp (argv [1], "reset"    ) == 0) doReset     (argv [0]) ;
1230   else if (strcasecmp (argv [1], "wb"       ) == 0) doWriteByte (argc, argv) ;
1231   else if (strcasecmp (argv [1], "clock"    ) == 0) doClock     (argc, argv) ;
1232   else if (strcasecmp (argv [1], "wfi"      ) == 0) doWfi       (argc, argv) ;
1233   else
1234   {
1235     fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
1236     exit (EXIT_FAILURE) ;
1237   }
1238   return 0 ;
1239 }