Gordons Projects

--> Projects Top-Level GIT

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