Gordons Projects

--> Projects Top-Level GIT

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