Gordons Projects

--> Projects Top-Level GIT

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