Gordons Projects

--> Projects Top-Level GIT

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