blob: c4408746a69d26ee3878d2c30cf97e2e84271905 [file] [log] [blame]
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001/*
2 * gpio.c:
Gordon Henderson99095e32012-08-27 20:56:14 +01003 * Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
4 * Pi's GPIO.
Gordon Hendersonda384432013-05-13 19:43:26 +01005 * Copyright (c) 2012-2013 Gordon Henderson
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01006 ***********************************************************************
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
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010025
26#include <stdio.h>
27#include <stdlib.h>
28#include <stdint.h>
Gordon Hendersonda384432013-05-13 19:43:26 +010029#include <ctype.h>
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010030#include <string.h>
31#include <unistd.h>
32#include <errno.h>
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010033#include <fcntl.h>
Gordon Hendersonda384432013-05-13 19:43:26 +010034#include <sys/types.h>
35#include <sys/stat.h>
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010036
Gordon Henderson99095e32012-08-27 20:56:14 +010037#include <wiringPi.h>
Gordon Hendersonda384432013-05-13 19:43:26 +010038
Gordon Henderson99095e32012-08-27 20:56:14 +010039#include <gertboard.h>
Gordon Hendersonda384432013-05-13 19:43:26 +010040#include <piFace.h>
41
42#include "extensions.h"
Gordon Henderson99095e32012-08-27 20:56:14 +010043
Gordon Henderson13bbba72013-01-14 11:31:56 +000044extern int wiringPiDebug ;
45
Gordon Henderson05e2f672014-05-20 11:43:07 +010046// External functions I can't be bothered creating a separate .h file for:
47
Gordon Henderson27698762013-06-27 21:51:55 +010048extern void doReadall (void) ;
Gordon Henderson05e2f672014-05-20 11:43:07 +010049extern void doPins (void) ;
50
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010051#ifndef TRUE
52# define TRUE (1==1)
53# define FALSE (1==2)
54#endif
55
Gordon Hendersondf453882014-07-17 22:23:57 +010056#define VERSION "2.20"
57#define PI_USB_POWER_CONTROL 38
58#define I2CDETECT "/usr/sbin/i2cdetect"
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010059
Gordon Henderson27698762013-06-27 21:51:55 +010060int wpMode ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010061
62char *usage = "Usage: gpio -v\n"
Gordon Henderson178ea082012-08-19 15:17:03 +010063 " gpio -h\n"
Gordon Hendersonda384432013-05-13 19:43:26 +010064 " gpio [-g|-1] [-x extension:params] ...\n"
Gordon Henderson25e4ec52012-12-06 21:49:41 +000065 " gpio [-p] <read/write/wb> ...\n"
Gordon Hendersonda384432013-05-13 19:43:26 +010066 " gpio <read/write/aread/awritewb/pwm/clock/mode> ...\n"
67 " gpio readall/reset\n"
68 " gpio unexportall/exports\n"
Gordon Henderson183c5a62012-10-21 15:25:16 +010069 " gpio export/edge/unexport ...\n"
Gordon Hendersonda384432013-05-13 19:43:26 +010070 " gpio wfi <pin> <mode>\n"
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010071 " gpio drive <group> <value>\n"
Gordon Hendersonf99ffed2012-08-19 15:12:45 +010072 " gpio pwm-bal/pwm-ms \n"
73 " gpio pwmr <range> \n"
Gordon Henderson8cb49392012-09-16 10:15:32 +010074 " gpio pwmc <divider> \n"
Gordon Henderson99095e32012-08-27 20:56:14 +010075 " gpio load spi/i2c\n"
Gordon Hendersonda384432013-05-13 19:43:26 +010076 " gpio i2cd/i2cdetect\n"
Gordon Hendersondf453882014-07-17 22:23:57 +010077 " gpio usbp high/low\n"
Gordon Henderson99095e32012-08-27 20:56:14 +010078 " gpio gbr <channel>\n"
Gordon Henderson8cb49392012-09-16 10:15:32 +010079 " gpio gbw <channel> <value>" ; // No trailing newline needed here.
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010080
81
Gordon Henderson6fba4032014-06-24 19:23:31 +010082#ifdef NOT_FOR_NOW
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010083/*
Gordon Hendersonf18c8f72013-08-03 23:53:35 +010084 * decodePin:
85 * Decode a pin "number" which can actually be a pin name to represent
86 * one of the Pi's on-board pins.
87 *********************************************************************************
88 */
89
90static int decodePin (const char *str)
91{
92
93// The first case - see if it's a number:
94
95 if (isdigit (str [0]))
96 return atoi (str) ;
97
98 return 0 ;
99}
Gordon Henderson6fba4032014-06-24 19:23:31 +0100100#endif
Gordon Hendersonf18c8f72013-08-03 23:53:35 +0100101
102
103/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100104 * changeOwner:
105 * Change the ownership of the file to the real userId of the calling
106 * program so we can access it.
107 *********************************************************************************
108 */
109
110static void changeOwner (char *cmd, char *file)
111{
112 uid_t uid = getuid () ;
113 uid_t gid = getgid () ;
114
115 if (chown (file, uid, gid) != 0)
116 {
117 if (errno == ENOENT) // Warn that it's not there
118 fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ;
119 else
120 {
121 fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
122 exit (1) ;
123 }
124 }
125}
126
127
128/*
129 * moduleLoaded:
130 * Return true/false if the supplied module is loaded
131 *********************************************************************************
132 */
133
134static int moduleLoaded (char *modName)
135{
136 int len = strlen (modName) ;
137 int found = FALSE ;
138 FILE *fd = fopen ("/proc/modules", "r") ;
139 char line [80] ;
140
141 if (fd == NULL)
142 {
143 fprintf (stderr, "gpio: Unable to check modules: %s\n", strerror (errno)) ;
144 exit (1) ;
145 }
146
147 while (fgets (line, 80, fd) != NULL)
148 {
149 if (strncmp (line, modName, len) != 0)
150 continue ;
151
152 found = TRUE ;
153 break ;
154 }
155
156 fclose (fd) ;
157
158 return found ;
159}
160
161
162/*
163 * doLoad:
164 * Load either the spi or i2c modules and change device ownerships, etc.
165 *********************************************************************************
166 */
167
168static void _doLoadUsage (char *argv [])
169{
Gordon Hendersone8f62582013-01-28 13:00:47 +0000170 fprintf (stderr, "Usage: %s load <spi/i2c> [SPI bufferSize in KB | I2C baudrate in Kb/sec]\n", argv [0]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100171 exit (1) ;
172}
173
174static void doLoad (int argc, char *argv [])
175{
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000176 char *module1, *module2 ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100177 char cmd [80] ;
178 char *file1, *file2 ;
Gordon Hendersone8f62582013-01-28 13:00:47 +0000179 char args1 [32], args2 [32] ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100180
Gordon Henderson13bbba72013-01-14 11:31:56 +0000181 if (argc < 3)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100182 _doLoadUsage (argv) ;
183
Gordon Hendersone8f62582013-01-28 13:00:47 +0000184 args1 [0] = args2 [0] = 0 ;
Gordon Henderson13bbba72013-01-14 11:31:56 +0000185
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100186 /**/ if (strcasecmp (argv [2], "spi") == 0)
187 {
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000188 module1 = "spidev" ;
189 module2 = "spi_bcm2708" ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100190 file1 = "/dev/spidev0.0" ;
191 file2 = "/dev/spidev0.1" ;
Gordon Henderson13bbba72013-01-14 11:31:56 +0000192 if (argc == 4)
Gordon Henderson98bcb202013-02-07 21:53:49 +0000193 sprintf (args1, " bufsiz=%d", atoi (argv [3]) * 1024) ;
Gordon Henderson13bbba72013-01-14 11:31:56 +0000194 else if (argc > 4)
195 _doLoadUsage (argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100196 }
197 else if (strcasecmp (argv [2], "i2c") == 0)
198 {
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000199 module1 = "i2c_dev" ;
200 module2 = "i2c_bcm2708" ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100201 file1 = "/dev/i2c-0" ;
202 file2 = "/dev/i2c-1" ;
Gordon Hendersone8f62582013-01-28 13:00:47 +0000203 if (argc == 4)
204 sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ;
205 else if (argc > 4)
206 _doLoadUsage (argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100207 }
208 else
209 _doLoadUsage (argv) ;
210
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000211 if (!moduleLoaded (module1))
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100212 {
Gordon Hendersone8f62582013-01-28 13:00:47 +0000213 sprintf (cmd, "modprobe %s%s", module1, args1) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100214 system (cmd) ;
215 }
216
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000217 if (!moduleLoaded (module2))
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100218 {
Gordon Hendersone8f62582013-01-28 13:00:47 +0000219 sprintf (cmd, "modprobe %s%s", module2, args2) ;
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000220 system (cmd) ;
221 }
222
223 if (!moduleLoaded (module2))
224 {
225 fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100226 exit (1) ;
227 }
228
229 sleep (1) ; // To let things get settled
230
231 changeOwner (argv [0], file1) ;
232 changeOwner (argv [0], file2) ;
233}
234
235
Gordon Henderson183c5a62012-10-21 15:25:16 +0100236/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100237 * doI2Cdetect:
238 * Run the i2cdetect command with the right runes for this Pi revision
239 *********************************************************************************
240 */
241
242static void doI2Cdetect (int argc, char *argv [])
243{
244 int port = piBoardRev () == 1 ? 0 : 1 ;
245 char command [128] ;
246 struct stat statBuf ;
247
248 if (stat (I2CDETECT, &statBuf) < 0)
249 {
250 fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
251 return ;
252 }
253
254 if (!moduleLoaded ("i2c_dev"))
255 {
256 fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ;
257 return ;
258 }
259
260 sprintf (command, "%s -y %d", I2CDETECT, port) ;
261 if (system (command) < 0)
262 fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;
263
264}
265
266
267/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100268 * doExports:
269 * List all GPIO exports
270 *********************************************************************************
271 */
272
Gordon Henderson178ea082012-08-19 15:17:03 +0100273static void doExports (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100274{
275 int fd ;
276 int i, l, first ;
277 char fName [128] ;
278 char buf [16] ;
279
Gordon Hendersonda384432013-05-13 19:43:26 +0100280 for (first = 0, i = 0 ; i < 64 ; ++i) // Crude, but effective
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100281 {
282
283// Try to read the direction
284
285 sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
286 if ((fd = open (fName, O_RDONLY)) == -1)
287 continue ;
288
289 if (first == 0)
290 {
291 ++first ;
292 printf ("GPIO Pins exported:\n") ;
293 }
294
295 printf ("%4d: ", i) ;
296
297 if ((l = read (fd, buf, 16)) == 0)
298 sprintf (buf, "%s", "?") ;
299
300 buf [l] = 0 ;
301 if ((buf [strlen (buf) - 1]) == '\n')
302 buf [strlen (buf) - 1] = 0 ;
303
304 printf ("%-3s", buf) ;
305
306 close (fd) ;
307
308// Try to Read the value
309
310 sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
311 if ((fd = open (fName, O_RDONLY)) == -1)
312 {
313 printf ("No Value file (huh?)\n") ;
314 continue ;
315 }
316
317 if ((l = read (fd, buf, 16)) == 0)
318 sprintf (buf, "%s", "?") ;
319
320 buf [l] = 0 ;
321 if ((buf [strlen (buf) - 1]) == '\n')
322 buf [strlen (buf) - 1] = 0 ;
323
324 printf (" %s", buf) ;
325
326// Read any edge trigger file
327
328 sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ;
329 if ((fd = open (fName, O_RDONLY)) == -1)
330 {
331 printf ("\n") ;
332 continue ;
333 }
334
335 if ((l = read (fd, buf, 16)) == 0)
336 sprintf (buf, "%s", "?") ;
337
338 buf [l] = 0 ;
339 if ((buf [strlen (buf) - 1]) == '\n')
340 buf [strlen (buf) - 1] = 0 ;
341
342 printf (" %-8s\n", buf) ;
343
344 close (fd) ;
345 }
346}
347
348
349/*
350 * doExport:
351 * gpio export pin mode
352 * This uses the /sys/class/gpio device interface.
353 *********************************************************************************
354 */
355
356void doExport (int argc, char *argv [])
357{
358 FILE *fd ;
359 int pin ;
360 char *mode ;
361 char fName [128] ;
362
363 if (argc != 4)
364 {
365 fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
366 exit (1) ;
367 }
368
369 pin = atoi (argv [2]) ;
370
371 mode = argv [3] ;
372
373 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
374 {
375 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
376 exit (1) ;
377 }
378
379 fprintf (fd, "%d\n", pin) ;
380 fclose (fd) ;
381
382 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
383 if ((fd = fopen (fName, "w")) == NULL)
384 {
385 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
386 exit (1) ;
387 }
388
389 /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
390 fprintf (fd, "in\n") ;
391 else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
392 fprintf (fd, "out\n") ;
393 else
394 {
395 fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ;
396 exit (1) ;
397 }
398
399 fclose (fd) ;
400
401// Change ownership so the current user can actually use it!
402
403 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
404 changeOwner (argv [0], fName) ;
405
406 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
407 changeOwner (argv [0], fName) ;
408
409}
410
411
412/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100413 * doWfi:
414 * gpio wfi pin mode
415 * Wait for Interrupt on a given pin.
416 * Slight cheat here - it's easier to actually use ISR now (which calls
417 * gpio to set the pin modes!) then we simply sleep, and expect the thread
418 * to exit the program. Crude but effective.
419 *********************************************************************************
420 */
421
422static void wfi (void)
423 { exit (0) ; }
424
425void doWfi (int argc, char *argv [])
426{
427 int pin, mode ;
428
429 if (argc != 4)
430 {
431 fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ;
432 exit (1) ;
433 }
434
435 pin = atoi (argv [2]) ;
436
437 /**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ;
438 else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
439 else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ;
440 else
441 {
442 fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ;
443 exit (1) ;
444 }
445
446 if (wiringPiISR (pin, mode, &wfi) < 0)
447 {
448 fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
449 exit (1) ;
450 }
451
452 for (;;)
453 delay (9999) ;
454}
455
456
457
458/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100459 * doEdge:
460 * gpio edge pin mode
461 * Easy access to changing the edge trigger on a GPIO pin
462 * This uses the /sys/class/gpio device interface.
463 *********************************************************************************
464 */
465
466void doEdge (int argc, char *argv [])
467{
468 FILE *fd ;
469 int pin ;
470 char *mode ;
471 char fName [128] ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100472
473 if (argc != 4)
474 {
475 fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
476 exit (1) ;
477 }
478
Gordon Henderson178ea082012-08-19 15:17:03 +0100479 pin = atoi (argv [2]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100480 mode = argv [3] ;
481
482// Export the pin and set direction to input
483
484 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
485 {
486 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
487 exit (1) ;
488 }
489
490 fprintf (fd, "%d\n", pin) ;
491 fclose (fd) ;
492
493 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
494 if ((fd = fopen (fName, "w")) == NULL)
495 {
496 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
497 exit (1) ;
498 }
499
500 fprintf (fd, "in\n") ;
501 fclose (fd) ;
502
503 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
504 if ((fd = fopen (fName, "w")) == NULL)
505 {
506 fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
507 exit (1) ;
508 }
509
Gordon Henderson178ea082012-08-19 15:17:03 +0100510 /**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
511 else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
512 else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
513 else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100514 else
515 {
516 fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
517 exit (1) ;
518 }
519
Gordon Henderson178ea082012-08-19 15:17:03 +0100520// Change ownership of the value and edge files, so the current user can actually use it!
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100521
522 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100523 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100524
525 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100526 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100527
528 fclose (fd) ;
529}
530
531
532/*
533 * doUnexport:
534 * gpio unexport pin
535 * This uses the /sys/class/gpio device interface.
536 *********************************************************************************
537 */
538
539void doUnexport (int argc, char *argv [])
540{
541 FILE *fd ;
542 int pin ;
543
544 if (argc != 3)
545 {
546 fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
547 exit (1) ;
548 }
549
550 pin = atoi (argv [2]) ;
551
552 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
553 {
554 fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
555 exit (1) ;
556 }
557
558 fprintf (fd, "%d\n", pin) ;
559 fclose (fd) ;
560}
561
562
563/*
564 * doUnexportAll:
565 * gpio unexportall
566 * Un-Export all the GPIO pins.
567 * This uses the /sys/class/gpio device interface.
568 *********************************************************************************
569 */
570
Gordon Hendersonda384432013-05-13 19:43:26 +0100571void doUnexportall (char *progName)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100572{
573 FILE *fd ;
574 int pin ;
575
576 for (pin = 0 ; pin < 63 ; ++pin)
577 {
578 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
579 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100580 fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100581 exit (1) ;
582 }
583 fprintf (fd, "%d\n", pin) ;
584 fclose (fd) ;
585 }
586}
587
588
589/*
Gordon Henderson348bc732013-05-25 13:02:02 +0100590 * doResetExternal:
591 * Load readallExternal, we try to do this with an external device.
592 *********************************************************************************
593 */
594
595static void doResetExternal (void)
596{
597 int pin ;
598
599 for (pin = wiringPiNodes->pinBase ; pin <= wiringPiNodes->pinMax ; ++pin)
600 {
601 pinMode (pin, INPUT) ;
602 pullUpDnControl (pin, PUD_OFF) ;
603 }
604}
605
606
607/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100608 * doReset:
609 * Reset the GPIO pins - as much as we can do
610 *********************************************************************************
611 */
612
613static void doReset (char *progName)
614{
615 int pin ;
616
Gordon Henderson348bc732013-05-25 13:02:02 +0100617 if (wiringPiNodes != NULL) // External reset
618 doResetExternal () ;
619 else
Gordon Hendersonda384432013-05-13 19:43:26 +0100620 {
Gordon Henderson348bc732013-05-25 13:02:02 +0100621 doUnexportall (progName) ;
Gordon Hendersonda384432013-05-13 19:43:26 +0100622
Gordon Henderson348bc732013-05-25 13:02:02 +0100623 for (pin = 0 ; pin < 64 ; ++pin)
624 {
625 if (wpiPinToGpio (pin) == -1)
626 continue ;
627
628 digitalWrite (pin, LOW) ;
629 pinMode (pin, INPUT) ;
630 pullUpDnControl (pin, PUD_OFF) ;
631 }
Gordon Hendersonda384432013-05-13 19:43:26 +0100632 }
633}
634
635
636/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100637 * doMode:
638 * gpio mode pin mode ...
639 *********************************************************************************
640 */
641
642void doMode (int argc, char *argv [])
643{
644 int pin ;
645 char *mode ;
646
647 if (argc != 4)
648 {
649 fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
650 exit (1) ;
651 }
652
653 pin = atoi (argv [2]) ;
654
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100655 mode = argv [3] ;
656
Gordon Hendersondca8a192014-07-14 08:39:38 +0100657 /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
658 else if (strcasecmp (mode, "input") == 0) pinMode (pin, INPUT) ;
659 else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
660 else if (strcasecmp (mode, "output") == 0) pinMode (pin, OUTPUT) ;
661 else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
662 else if (strcasecmp (mode, "pwmTone") == 0) pinMode (pin, PWM_TONE_OUTPUT) ;
663 else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ;
664 else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
665 else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
666 else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
667 else if (strcasecmp (mode, "off") == 0) pullUpDnControl (pin, PUD_OFF) ;
Gordon Hendersonf18c8f72013-08-03 23:53:35 +0100668
669// Undocumented
670
671 else if (strcasecmp (mode, "alt0") == 0) pinModeAlt (pin, 0b100) ;
672 else if (strcasecmp (mode, "alt1") == 0) pinModeAlt (pin, 0b101) ;
673 else if (strcasecmp (mode, "alt2") == 0) pinModeAlt (pin, 0b110) ;
674 else if (strcasecmp (mode, "alt3") == 0) pinModeAlt (pin, 0b111) ;
675 else if (strcasecmp (mode, "alt4") == 0) pinModeAlt (pin, 0b011) ;
676 else if (strcasecmp (mode, "alt5") == 0) pinModeAlt (pin, 0b010) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100677 else
678 {
Gordon Henderson56c77b52013-02-01 20:19:22 +0000679 fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100680 exit (1) ;
681 }
682}
683
684
685/*
686 * doPadDrive:
687 * gpio drive group value
688 *********************************************************************************
689 */
690
Gordon Henderson1bb49892012-08-19 15:33:26 +0100691static void doPadDrive (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100692{
693 int group, val ;
694
695 if (argc != 4)
696 {
697 fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
698 exit (1) ;
699 }
700
701 group = atoi (argv [2]) ;
702 val = atoi (argv [3]) ;
703
704 if ((group < 0) || (group > 2))
705 {
706 fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
707 exit (1) ;
708 }
709
710 if ((val < 0) || (val > 7))
711 {
712 fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
713 exit (1) ;
714 }
715
716 setPadDrive (group, val) ;
717}
718
719
720/*
Gordon Hendersondf453882014-07-17 22:23:57 +0100721 * doUsbP:
722 * Control USB Power - High (1.2A) or Low (600mA)
723 * gpio usbp high/low
724 *********************************************************************************
725 */
726
727static void doUsbP (int argc, char *argv [])
728{
729 int model, rev, mem, maker, overVolted ;
730
731 if (argc != 3)
732 {
733 fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
734 exit (1) ;
735 }
736
737// Make sure we're on a B+
738
739 piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
740
741 if (model != PI_MODEL_BP)
742 {
743 fprintf (stderr, "USB power contol is applicable to B+ boards only.\n") ;
744 exit (1) ;
745 }
746
747// Need to force BCM_GPIO mode:
748
749 wiringPiSetupGpio () ;
750
751 if ((strcasecmp (argv [2], "high") == 0) || (strcasecmp (argv [2], "hi") == 0))
752 {
753 digitalWrite (PI_USB_POWER_CONTROL, 1) ;
754 pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
755 printf ("Switched to HIGH current USB (1.2A)\n") ;
756 return ;
757 }
758
759 if ((strcasecmp (argv [2], "low") == 0) || (strcasecmp (argv [2], "lo") == 0))
760 {
761 digitalWrite (PI_USB_POWER_CONTROL, 0) ;
762 pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
763 printf ("Switched to LOW current USB (600mA)\n") ;
764 return ;
765 }
766
767 fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
768 exit (1) ;
769}
770
771
772/*
Gordon Henderson99095e32012-08-27 20:56:14 +0100773 * doGbw:
774 * gpio gbw channel value
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000775 * Gertboard Write - To the Analog output
Gordon Henderson99095e32012-08-27 20:56:14 +0100776 *********************************************************************************
777 */
778
779static void doGbw (int argc, char *argv [])
780{
781 int channel, value ;
782
783 if (argc != 4)
784 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100785 fprintf (stderr, "Usage: %s gbw <channel> <value>\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100786 exit (1) ;
787 }
788
789 channel = atoi (argv [2]) ;
790 value = atoi (argv [3]) ;
791
792 if ((channel < 0) || (channel > 1))
793 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100794 fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100795 exit (1) ;
796 }
797
Gordon Hendersondca8a192014-07-14 08:39:38 +0100798 if ((value < 0) || (value > 255))
Gordon Henderson99095e32012-08-27 20:56:14 +0100799 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100800 fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100801 exit (1) ;
802 }
803
Gordon Hendersonda384432013-05-13 19:43:26 +0100804 if (gertboardAnalogSetup (64) < 0)
Gordon Henderson99095e32012-08-27 20:56:14 +0100805 {
806 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
807 exit (1) ;
808 }
809
Gordon Hendersonda384432013-05-13 19:43:26 +0100810 analogWrite (64 + channel, value) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100811}
812
813
814/*
815 * doGbr:
816 * gpio gbr channel
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000817 * From the analog input
Gordon Henderson99095e32012-08-27 20:56:14 +0100818 *********************************************************************************
819 */
820
821static void doGbr (int argc, char *argv [])
822{
823 int channel ;
824
825 if (argc != 3)
826 {
827 fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
828 exit (1) ;
829 }
830
831 channel = atoi (argv [2]) ;
832
833 if ((channel < 0) || (channel > 1))
834 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100835 fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100836 exit (1) ;
837 }
838
Gordon Hendersonda384432013-05-13 19:43:26 +0100839 if (gertboardAnalogSetup (64) < 0)
Gordon Henderson99095e32012-08-27 20:56:14 +0100840 {
841 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
842 exit (1) ;
843 }
844
Gordon Hendersonda384432013-05-13 19:43:26 +0100845 printf ("%d\n", analogRead (64 + channel)) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100846}
847
848
Gordon Henderson99095e32012-08-27 20:56:14 +0100849/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100850 * doWrite:
851 * gpio write pin value
852 *********************************************************************************
853 */
854
Gordon Henderson1bb49892012-08-19 15:33:26 +0100855static void doWrite (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100856{
857 int pin, val ;
858
859 if (argc != 4)
860 {
861 fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
862 exit (1) ;
863 }
864
865 pin = atoi (argv [2]) ;
866
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000867 /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
868 val = 1 ;
869 else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
870 val = 0 ;
871 else
872 val = atoi (argv [3]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100873
874 /**/ if (val == 0)
875 digitalWrite (pin, LOW) ;
876 else
877 digitalWrite (pin, HIGH) ;
878}
879
Gordon Hendersonda384432013-05-13 19:43:26 +0100880
881/*
882 * doAwriterite:
883 * gpio awrite pin value
884 *********************************************************************************
885 */
886
887static void doAwrite (int argc, char *argv [])
888{
889 int pin, val ;
890
891 if (argc != 4)
892 {
893 fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
894 exit (1) ;
895 }
896
897 pin = atoi (argv [2]) ;
898
899 val = atoi (argv [3]) ;
900
901 analogWrite (pin, val) ;
902}
903
904
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000905/*
906 * doWriteByte:
907 * gpio write value
908 *********************************************************************************
909 */
910
911static void doWriteByte (int argc, char *argv [])
912{
913 int val ;
914
915 if (argc != 3)
916 {
917 fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
918 exit (1) ;
919 }
920
921 val = (int)strtol (argv [2], NULL, 0) ;
922
923 digitalWriteByte (val) ;
924}
925
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100926
927/*
928 * doRead:
929 * Read a pin and return the value
930 *********************************************************************************
931 */
932
933void doRead (int argc, char *argv [])
934{
935 int pin, val ;
936
937 if (argc != 3)
938 {
939 fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
940 exit (1) ;
941 }
942
943 pin = atoi (argv [2]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100944 val = digitalRead (pin) ;
945
946 printf ("%s\n", val == 0 ? "0" : "1") ;
947}
948
949
950/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100951 * doAread:
952 * Read an analog pin and return the value
953 *********************************************************************************
954 */
955
956void doAread (int argc, char *argv [])
957{
Gordon Hendersonda384432013-05-13 19:43:26 +0100958 if (argc != 3)
959 {
960 fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
961 exit (1) ;
962 }
963
Gordon Hendersonbfaf2662013-05-20 21:13:44 +0100964 printf ("%d\n", analogRead (atoi (argv [2]))) ;
Gordon Hendersonda384432013-05-13 19:43:26 +0100965}
966
967
968/*
969 * doToggle:
970 * Toggle an IO pin
971 *********************************************************************************
972 */
973
974void doToggle (int argc, char *argv [])
975{
976 int pin ;
977
978 if (argc != 3)
979 {
980 fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
981 exit (1) ;
982 }
983
984 pin = atoi (argv [2]) ;
985
986 digitalWrite (pin, !digitalRead (pin)) ;
987}
988
Gordon Hendersondca8a192014-07-14 08:39:38 +0100989
990/*
991 * doPwmTone:
992 * Output a tone in a PWM pin
993 *********************************************************************************
994 */
995
996void doPwmTone (int argc, char *argv [])
997{
998 int pin, freq ;
999
1000 if (argc != 4)
1001 {
1002 fprintf (stderr, "Usage: %s pwmTone <pin> <freq>\n", argv [0]) ;
1003 exit (1) ;
1004 }
1005
1006 pin = atoi (argv [2]) ;
1007 freq = atoi (argv [3]) ;
1008
1009 pwmToneWrite (pin, freq) ;
1010}
1011
1012
Gordon Hendersonda384432013-05-13 19:43:26 +01001013/*
Gordon Henderson56c77b52013-02-01 20:19:22 +00001014 * doClock:
1015 * Output a clock on a pin
1016 *********************************************************************************
1017 */
1018
1019void doClock (int argc, char *argv [])
1020{
1021 int pin, freq ;
1022
1023 if (argc != 4)
1024 {
1025 fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
1026 exit (1) ;
1027 }
1028
1029 pin = atoi (argv [2]) ;
1030
Gordon Henderson56c77b52013-02-01 20:19:22 +00001031 freq = atoi (argv [3]) ;
1032
1033 gpioClockSet (pin, freq) ;
1034}
1035
1036
1037/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001038 * doPwm:
1039 * Output a PWM value on a pin
1040 *********************************************************************************
1041 */
1042
1043void doPwm (int argc, char *argv [])
1044{
1045 int pin, val ;
1046
1047 if (argc != 4)
1048 {
1049 fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
1050 exit (1) ;
1051 }
1052
1053 pin = atoi (argv [2]) ;
1054
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001055 val = atoi (argv [3]) ;
1056
1057 pwmWrite (pin, val) ;
1058}
1059
1060
1061/*
Gordon Henderson8cb49392012-09-16 10:15:32 +01001062 * doPwmMode: doPwmRange: doPwmClock:
1063 * Change the PWM mode, range and clock divider values
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001064 *********************************************************************************
1065 */
1066
1067static void doPwmMode (int mode)
1068{
1069 pwmSetMode (mode) ;
1070}
1071
1072static void doPwmRange (int argc, char *argv [])
1073{
1074 unsigned int range ;
1075
1076 if (argc != 3)
1077 {
1078 fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
1079 exit (1) ;
1080 }
1081
1082 range = (unsigned int)strtoul (argv [2], NULL, 10) ;
1083
1084 if (range == 0)
1085 {
1086 fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
1087 exit (1) ;
1088 }
1089
1090 pwmSetRange (range) ;
1091}
1092
Gordon Henderson8cb49392012-09-16 10:15:32 +01001093static void doPwmClock (int argc, char *argv [])
1094{
1095 unsigned int clock ;
1096
1097 if (argc != 3)
1098 {
1099 fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
1100 exit (1) ;
1101 }
1102
1103 clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
1104
1105 if ((clock < 1) || (clock > 4095))
1106 {
1107 fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
1108 exit (1) ;
1109 }
1110
1111 pwmSetClock (clock) ;
1112}
1113
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001114
1115/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001116 * main:
1117 * Start here
1118 *********************************************************************************
1119 */
1120
1121int main (int argc, char *argv [])
1122{
1123 int i ;
Gordon Hendersondf453882014-07-17 22:23:57 +01001124 int model, rev, mem, maker, overVolted ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001125
Gordon Henderson13bbba72013-01-14 11:31:56 +00001126 if (getenv ("WIRINGPI_DEBUG") != NULL)
1127 {
1128 printf ("gpio: wiringPi debug mode enabled\n") ;
1129 wiringPiDebug = TRUE ;
1130 }
1131
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001132 if (argc == 1)
1133 {
Gordon Henderson86a5c682012-10-02 14:32:12 +01001134 fprintf (stderr, "%s\n", usage) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001135 return 1 ;
1136 }
1137
Gordon Hendersonda384432013-05-13 19:43:26 +01001138// Help
1139
Gordon Henderson178ea082012-08-19 15:17:03 +01001140 if (strcasecmp (argv [1], "-h") == 0)
1141 {
1142 printf ("%s: %s\n", argv [0], usage) ;
1143 return 0 ;
1144 }
1145
Gordon Hendersonda384432013-05-13 19:43:26 +01001146// Sort of a special:
1147
1148 if (strcmp (argv [1], "-R") == 0)
1149 {
1150 printf ("%d\n", piBoardRev ()) ;
1151 return 0 ;
1152 }
1153
1154// Version & Warranty
1155
1156 if (strcmp (argv [1], "-V") == 0)
1157 {
1158 printf ("%d\n", piBoardRev ()) ;
1159 return 0 ;
1160 }
1161
1162 if (strcmp (argv [1], "-v") == 0)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001163 {
1164 printf ("gpio version: %s\n", VERSION) ;
Gordon Henderson05e2f672014-05-20 11:43:07 +01001165 printf ("Copyright (c) 2012-2014 Gordon Henderson\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001166 printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
1167 printf ("For details type: %s -warranty\n", argv [0]) ;
Gordon Henderson86a5c682012-10-02 14:32:12 +01001168 printf ("\n") ;
Gordon Hendersondf453882014-07-17 22:23:57 +01001169 piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
1170 if (model == PI_MODEL_UNKNOWN)
1171 {
1172 printf ("Your Raspberry Pi has an unknown model type. Please report this to\n") ;
1173 printf (" projects@drogon.net\n") ;
1174 printf ("with a copy of your /proc/cpuinfo if possible\n") ;
1175 }
1176 else
1177 {
1178 printf ("Raspberry Pi Details:\n") ;
1179 printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n",
1180 piModelNames [model], piRevisionNames [rev], mem, piMakerNames [maker], overVolted ? "[OV]" : "") ;
1181 }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001182 return 0 ;
1183 }
1184
1185 if (strcasecmp (argv [1], "-warranty") == 0)
1186 {
1187 printf ("gpio version: %s\n", VERSION) ;
Gordon Hendersondca8a192014-07-14 08:39:38 +01001188 printf ("Copyright (c) 2012-2014 Gordon Henderson\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001189 printf ("\n") ;
1190 printf (" This program is free software; you can redistribute it and/or modify\n") ;
1191 printf (" it under the terms of the GNU Leser General Public License as published\n") ;
1192 printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
1193 printf (" (at your option) any later version.\n") ;
1194 printf ("\n") ;
1195 printf (" This program is distributed in the hope that it will be useful,\n") ;
1196 printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
1197 printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
1198 printf (" GNU Lesser General Public License for more details.\n") ;
1199 printf ("\n") ;
1200 printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
1201 printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
1202 printf ("\n") ;
1203 return 0 ;
1204 }
1205
1206 if (geteuid () != 0)
1207 {
1208 fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
1209 return 1 ;
1210 }
1211
1212// Initial test for /sys/class/gpio operations:
1213
Gordon Henderson178ea082012-08-19 15:17:03 +01001214 /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
1215 else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
1216 else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
Gordon Henderson178ea082012-08-19 15:17:03 +01001217 else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
Gordon Hendersonda384432013-05-13 19:43:26 +01001218 else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; }
Gordon Henderson178ea082012-08-19 15:17:03 +01001219
Gordon Henderson86a5c682012-10-02 14:32:12 +01001220// Check for load command:
Gordon Henderson178ea082012-08-19 15:17:03 +01001221
Gordon Henderson178ea082012-08-19 15:17:03 +01001222 if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001223
Gordon Henderson99095e32012-08-27 20:56:14 +01001224// Gertboard commands
1225
1226 if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
1227 if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
1228
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001229// Check for -g argument
1230
Gordon Hendersonda384432013-05-13 19:43:26 +01001231 /**/ if (strcasecmp (argv [1], "-g") == 0)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001232 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001233 wiringPiSetupGpio () ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001234
1235 for (i = 2 ; i < argc ; ++i)
1236 argv [i - 1] = argv [i] ;
1237 --argc ;
1238 wpMode = WPI_MODE_GPIO ;
1239 }
1240
Gordon Hendersonda384432013-05-13 19:43:26 +01001241// Check for -1 argument
1242
1243 else if (strcasecmp (argv [1], "-1") == 0)
1244 {
1245 wiringPiSetupPhys () ;
1246
1247 for (i = 2 ; i < argc ; ++i)
1248 argv [i - 1] = argv [i] ;
1249 --argc ;
1250 wpMode = WPI_MODE_PHYS ;
1251 }
1252
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001253// Check for -p argument for PiFace
1254
1255 else if (strcasecmp (argv [1], "-p") == 0)
1256 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001257 piFaceSetup (200) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001258
1259 for (i = 2 ; i < argc ; ++i)
1260 argv [i - 1] = argv [i] ;
1261 --argc ;
1262 wpMode = WPI_MODE_PIFACE ;
1263 }
1264
1265// Default to wiringPi mode
1266
1267 else
1268 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001269 wiringPiSetup () ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001270 wpMode = WPI_MODE_PINS ;
1271 }
1272
Gordon Hendersonda384432013-05-13 19:43:26 +01001273// Check for -x argument to load in a new extension
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001274
Gordon Hendersonda384432013-05-13 19:43:26 +01001275 if (strcasecmp (argv [1], "-x") == 0)
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001276 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001277 if (argc < 3)
1278 {
1279 fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ;
1280 exit (EXIT_FAILURE) ;
1281 }
1282
1283 if (!doExtension (argv [0], argv [2])) // Prints its own error messages
1284 exit (EXIT_FAILURE) ;
1285
1286 for (i = 3 ; i < argc ; ++i)
1287 argv [i - 2] = argv [i] ;
1288 argc -= 2 ;
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001289 }
1290
Gordon Hendersonda384432013-05-13 19:43:26 +01001291 if (argc <= 1)
1292 {
1293 fprintf (stderr, "%s: no command given\n", argv [0]) ;
1294 exit (EXIT_FAILURE) ;
1295 }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001296
Gordon Hendersonda384432013-05-13 19:43:26 +01001297// Core wiringPi functions
1298
1299 /**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
1300 else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
1301 else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ;
1302 else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
1303 else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite (argc, argv) ;
1304 else if (strcasecmp (argv [1], "aread" ) == 0) doAread (argc, argv) ;
1305
1306// GPIO Nicies
1307
1308 else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ;
1309
1310// Pi Specifics
1311
Gordon Henderson27698762013-06-27 21:51:55 +01001312 else if (strcasecmp (argv [1], "pwm-bal" ) == 0) doPwmMode (PWM_MODE_BAL) ;
1313 else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ;
1314 else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ;
1315 else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ;
Gordon Hendersondca8a192014-07-14 08:39:38 +01001316 else if (strcasecmp (argv [1], "pwmTone" ) == 0) doPwmTone (argc, argv) ;
Gordon Henderson27698762013-06-27 21:51:55 +01001317 else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
Gordon Hendersondf453882014-07-17 22:23:57 +01001318 else if (strcasecmp (argv [1], "usbp" ) == 0) doUsbP (argc, argv) ;
1319 else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
Gordon Henderson8c8578a2013-07-23 09:19:34 +01001320 else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ;
Gordon Henderson05e2f672014-05-20 11:43:07 +01001321 else if (strcasecmp (argv [1], "pins" ) == 0) doPins () ;
Gordon Henderson27698762013-06-27 21:51:55 +01001322 else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
1323 else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ;
1324 else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
1325 else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
1326 else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
1327 else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001328 else
1329 {
Gordon Henderson178ea082012-08-19 15:17:03 +01001330 fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
Gordon Hendersonda384432013-05-13 19:43:26 +01001331 exit (EXIT_FAILURE) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001332 }
1333 return 0 ;
1334}