Gordons Projects

--> Projects Top-Level GIT

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