Gordons Projects

--> Projects Top-Level GIT

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