Gordons Projects

--> Projects Top-Level GIT

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