blob: 6c95b212a66dd8376a8d20e634ebba06d29484f0 [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 Hendersoneb1fc2c2015-01-30 18:14:49 +00005 * Copyright (c) 2012-2015 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 Hendersoneb1fc2c2015-01-30 18:14:49 +000038#include <wpiExtensions.h>
Gordon Hendersonda384432013-05-13 19:43:26 +010039
Gordon Henderson99095e32012-08-27 20:56:14 +010040#include <gertboard.h>
Gordon Hendersonda384432013-05-13 19:43:26 +010041#include <piFace.h>
42
Gordon Henderson7cb81742015-01-31 16:43:08 +000043#include "version.h"
Gordon Henderson99095e32012-08-27 20:56:14 +010044
Gordon Henderson13bbba72013-01-14 11:31:56 +000045extern int wiringPiDebug ;
46
Gordon Henderson05e2f672014-05-20 11:43:07 +010047// External functions I can't be bothered creating a separate .h file for:
48
Gordon Henderson27698762013-06-27 21:51:55 +010049extern void doReadall (void) ;
Gordon Henderson05e2f672014-05-20 11:43:07 +010050extern void doPins (void) ;
51
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010052#ifndef TRUE
53# define TRUE (1==1)
54# define FALSE (1==2)
55#endif
56
Gordon Hendersondf453882014-07-17 22:23:57 +010057#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 Hendersoneb1fc2c2015-01-30 18:14:49 +000076 " gpio unload spi/i2c\n"
Gordon Hendersonda384432013-05-13 19:43:26 +010077 " gpio i2cd/i2cdetect\n"
Gordon Hendersondf453882014-07-17 22:23:57 +010078 " gpio usbp high/low\n"
Gordon Henderson99095e32012-08-27 20:56:14 +010079 " gpio gbr <channel>\n"
Gordon Henderson8cb49392012-09-16 10:15:32 +010080 " gpio gbw <channel> <value>" ; // No trailing newline needed here.
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010081
82
Gordon Henderson6fba4032014-06-24 19:23:31 +010083#ifdef NOT_FOR_NOW
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010084/*
Gordon Hendersonf18c8f72013-08-03 23:53:35 +010085 * decodePin:
86 * Decode a pin "number" which can actually be a pin name to represent
87 * one of the Pi's on-board pins.
88 *********************************************************************************
89 */
90
91static int decodePin (const char *str)
92{
93
94// The first case - see if it's a number:
95
96 if (isdigit (str [0]))
97 return atoi (str) ;
98
99 return 0 ;
100}
Gordon Henderson6fba4032014-06-24 19:23:31 +0100101#endif
Gordon Hendersonf18c8f72013-08-03 23:53:35 +0100102
103
104/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100105 * changeOwner:
106 * Change the ownership of the file to the real userId of the calling
107 * program so we can access it.
108 *********************************************************************************
109 */
110
111static void changeOwner (char *cmd, char *file)
112{
113 uid_t uid = getuid () ;
114 uid_t gid = getgid () ;
115
116 if (chown (file, uid, gid) != 0)
117 {
118 if (errno == ENOENT) // Warn that it's not there
Gordon Hendersonf6c40cb2015-09-24 22:35:31 +0100119 fprintf (stderr, "%s: Warning (not an error, do not report): File not present: %s\n", cmd, file) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100120 else
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000121 fprintf (stderr, "%s: Warning (not an error): Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100122 }
123}
124
125
126/*
127 * moduleLoaded:
128 * Return true/false if the supplied module is loaded
129 *********************************************************************************
130 */
131
132static int moduleLoaded (char *modName)
133{
134 int len = strlen (modName) ;
135 int found = FALSE ;
136 FILE *fd = fopen ("/proc/modules", "r") ;
137 char line [80] ;
138
139 if (fd == NULL)
140 {
141 fprintf (stderr, "gpio: Unable to check modules: %s\n", strerror (errno)) ;
142 exit (1) ;
143 }
144
145 while (fgets (line, 80, fd) != NULL)
146 {
147 if (strncmp (line, modName, len) != 0)
148 continue ;
149
150 found = TRUE ;
151 break ;
152 }
153
154 fclose (fd) ;
155
156 return found ;
157}
158
159
160/*
161 * doLoad:
162 * Load either the spi or i2c modules and change device ownerships, etc.
163 *********************************************************************************
164 */
165
Gordon Hendersonf6c40cb2015-09-24 22:35:31 +0100166static void checkDevTree (char *argv [])
167{
168 struct stat statBuf ;
169
170 if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ...
171 {
172 fprintf (stderr,
173"%s: Unable to load/unload modules as this Pi has the device tree enabled.\n"
174" You need to run the raspi-config program (as root) and select the\n"
175" modules (SPI or I2C) that you wish to load/unload there and reboot.\n"
176" There is more information here:\n"
177" https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=97314\n", argv [0]) ;
178 exit (1) ;
179 }
180}
181
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100182static void _doLoadUsage (char *argv [])
183{
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000184 fprintf (stderr, "Usage: %s load <spi/i2c> [I2C baudrate in Kb/sec]\n", argv [0]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100185 exit (1) ;
186}
187
188static void doLoad (int argc, char *argv [])
189{
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000190 char *module1, *module2 ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100191 char cmd [80] ;
192 char *file1, *file2 ;
Gordon Hendersone8f62582013-01-28 13:00:47 +0000193 char args1 [32], args2 [32] ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100194
Gordon Hendersonf6c40cb2015-09-24 22:35:31 +0100195 checkDevTree (argv) ;
196
Gordon Henderson13bbba72013-01-14 11:31:56 +0000197 if (argc < 3)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100198 _doLoadUsage (argv) ;
199
Gordon Hendersone8f62582013-01-28 13:00:47 +0000200 args1 [0] = args2 [0] = 0 ;
Gordon Henderson13bbba72013-01-14 11:31:56 +0000201
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100202 /**/ if (strcasecmp (argv [2], "spi") == 0)
203 {
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000204 module1 = "spidev" ;
205 module2 = "spi_bcm2708" ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100206 file1 = "/dev/spidev0.0" ;
207 file2 = "/dev/spidev0.1" ;
Gordon Henderson13bbba72013-01-14 11:31:56 +0000208 if (argc == 4)
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000209 {
210 fprintf (stderr, "%s: Unable to set the buffer size now. Load aborted. Please see the man page.\n", argv [0]) ;
211 exit (1) ;
212 }
Gordon Henderson13bbba72013-01-14 11:31:56 +0000213 else if (argc > 4)
214 _doLoadUsage (argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100215 }
216 else if (strcasecmp (argv [2], "i2c") == 0)
217 {
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000218 module1 = "i2c_dev" ;
219 module2 = "i2c_bcm2708" ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100220 file1 = "/dev/i2c-0" ;
221 file2 = "/dev/i2c-1" ;
Gordon Hendersone8f62582013-01-28 13:00:47 +0000222 if (argc == 4)
223 sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ;
224 else if (argc > 4)
225 _doLoadUsage (argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100226 }
227 else
228 _doLoadUsage (argv) ;
229
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000230 if (!moduleLoaded (module1))
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100231 {
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000232 sprintf (cmd, "/sbin/modprobe %s%s", module1, args1) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100233 system (cmd) ;
234 }
235
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000236 if (!moduleLoaded (module2))
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100237 {
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000238 sprintf (cmd, "/sbin/modprobe %s%s", module2, args2) ;
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000239 system (cmd) ;
240 }
241
242 if (!moduleLoaded (module2))
243 {
244 fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100245 exit (1) ;
246 }
247
248 sleep (1) ; // To let things get settled
249
250 changeOwner (argv [0], file1) ;
251 changeOwner (argv [0], file2) ;
252}
253
254
Gordon Henderson183c5a62012-10-21 15:25:16 +0100255/*
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000256 * doUnLoad:
257 * Un-Load either the spi or i2c modules and change device ownerships, etc.
258 *********************************************************************************
259 */
260
261static void _doUnLoadUsage (char *argv [])
262{
263 fprintf (stderr, "Usage: %s unload <spi/i2c>\n", argv [0]) ;
264 exit (1) ;
265}
266
267static void doUnLoad (int argc, char *argv [])
268{
269 char *module1, *module2 ;
270 char cmd [80] ;
271
Gordon Hendersonf6c40cb2015-09-24 22:35:31 +0100272 checkDevTree (argv) ;
273
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000274 if (argc != 3)
275 _doUnLoadUsage (argv) ;
276
277 /**/ if (strcasecmp (argv [2], "spi") == 0)
278 {
279 module1 = "spidev" ;
280 module2 = "spi_bcm2708" ;
281 }
282 else if (strcasecmp (argv [2], "i2c") == 0)
283 {
284 module1 = "i2c_dev" ;
285 module2 = "i2c_bcm2708" ;
286 }
287 else
288 _doUnLoadUsage (argv) ;
289
290 if (moduleLoaded (module1))
291 {
292 sprintf (cmd, "/sbin/rmmod %s", module1) ;
293 system (cmd) ;
294 }
295
296 if (moduleLoaded (module2))
297 {
298 sprintf (cmd, "/sbin/rmmod %s", module2) ;
299 system (cmd) ;
300 }
301}
302
303
304/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100305 * doI2Cdetect:
306 * Run the i2cdetect command with the right runes for this Pi revision
307 *********************************************************************************
308 */
309
310static void doI2Cdetect (int argc, char *argv [])
311{
312 int port = piBoardRev () == 1 ? 0 : 1 ;
313 char command [128] ;
314 struct stat statBuf ;
315
316 if (stat (I2CDETECT, &statBuf) < 0)
317 {
318 fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
319 return ;
320 }
321
322 if (!moduleLoaded ("i2c_dev"))
323 {
324 fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ;
325 return ;
326 }
327
328 sprintf (command, "%s -y %d", I2CDETECT, port) ;
329 if (system (command) < 0)
330 fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;
331
332}
333
334
335/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100336 * doExports:
337 * List all GPIO exports
338 *********************************************************************************
339 */
340
Gordon Henderson178ea082012-08-19 15:17:03 +0100341static void doExports (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100342{
343 int fd ;
344 int i, l, first ;
345 char fName [128] ;
346 char buf [16] ;
347
Gordon Hendersonda384432013-05-13 19:43:26 +0100348 for (first = 0, i = 0 ; i < 64 ; ++i) // Crude, but effective
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100349 {
350
351// Try to read the direction
352
353 sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
354 if ((fd = open (fName, O_RDONLY)) == -1)
355 continue ;
356
357 if (first == 0)
358 {
359 ++first ;
360 printf ("GPIO Pins exported:\n") ;
361 }
362
363 printf ("%4d: ", i) ;
364
365 if ((l = read (fd, buf, 16)) == 0)
366 sprintf (buf, "%s", "?") ;
367
368 buf [l] = 0 ;
369 if ((buf [strlen (buf) - 1]) == '\n')
370 buf [strlen (buf) - 1] = 0 ;
371
372 printf ("%-3s", buf) ;
373
374 close (fd) ;
375
376// Try to Read the value
377
378 sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
379 if ((fd = open (fName, O_RDONLY)) == -1)
380 {
381 printf ("No Value file (huh?)\n") ;
382 continue ;
383 }
384
385 if ((l = read (fd, buf, 16)) == 0)
386 sprintf (buf, "%s", "?") ;
387
388 buf [l] = 0 ;
389 if ((buf [strlen (buf) - 1]) == '\n')
390 buf [strlen (buf) - 1] = 0 ;
391
392 printf (" %s", buf) ;
393
394// Read any edge trigger file
395
396 sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ;
397 if ((fd = open (fName, O_RDONLY)) == -1)
398 {
399 printf ("\n") ;
400 continue ;
401 }
402
403 if ((l = read (fd, buf, 16)) == 0)
404 sprintf (buf, "%s", "?") ;
405
406 buf [l] = 0 ;
407 if ((buf [strlen (buf) - 1]) == '\n')
408 buf [strlen (buf) - 1] = 0 ;
409
410 printf (" %-8s\n", buf) ;
411
412 close (fd) ;
413 }
414}
415
416
417/*
418 * doExport:
419 * gpio export pin mode
420 * This uses the /sys/class/gpio device interface.
421 *********************************************************************************
422 */
423
424void doExport (int argc, char *argv [])
425{
426 FILE *fd ;
427 int pin ;
428 char *mode ;
429 char fName [128] ;
430
431 if (argc != 4)
432 {
433 fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
434 exit (1) ;
435 }
436
437 pin = atoi (argv [2]) ;
438
439 mode = argv [3] ;
440
441 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
442 {
443 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
444 exit (1) ;
445 }
446
447 fprintf (fd, "%d\n", pin) ;
448 fclose (fd) ;
449
450 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
451 if ((fd = fopen (fName, "w")) == NULL)
452 {
453 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
454 exit (1) ;
455 }
456
Gordon Henderson72b2af22015-02-03 14:53:32 +0000457 /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100458 fprintf (fd, "in\n") ;
Gordon Henderson72b2af22015-02-03 14:53:32 +0000459 else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100460 fprintf (fd, "out\n") ;
Gordon Henderson72b2af22015-02-03 14:53:32 +0000461 else if ((strcasecmp (mode, "high") == 0) || (strcasecmp (mode, "up") == 0))
462 fprintf (fd, "high\n") ;
463 else if ((strcasecmp (mode, "low") == 0) || (strcasecmp (mode, "down") == 0))
464 fprintf (fd, "low\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100465 else
466 {
Gordon Henderson72b2af22015-02-03 14:53:32 +0000467 fprintf (stderr, "%s: Invalid mode: %s. Should be in, out, high or low\n", argv [1], mode) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100468 exit (1) ;
469 }
470
471 fclose (fd) ;
472
Gordon Henderson72b2af22015-02-03 14:53:32 +0000473// Change ownership so the current user can actually use it
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100474
475 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
476 changeOwner (argv [0], fName) ;
477
478 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
479 changeOwner (argv [0], fName) ;
480
481}
482
483
484/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100485 * doWfi:
486 * gpio wfi pin mode
487 * Wait for Interrupt on a given pin.
488 * Slight cheat here - it's easier to actually use ISR now (which calls
489 * gpio to set the pin modes!) then we simply sleep, and expect the thread
490 * to exit the program. Crude but effective.
491 *********************************************************************************
492 */
493
494static void wfi (void)
495 { exit (0) ; }
496
497void doWfi (int argc, char *argv [])
498{
499 int pin, mode ;
500
501 if (argc != 4)
502 {
503 fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ;
504 exit (1) ;
505 }
506
507 pin = atoi (argv [2]) ;
508
509 /**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ;
510 else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
511 else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ;
512 else
513 {
514 fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ;
515 exit (1) ;
516 }
517
518 if (wiringPiISR (pin, mode, &wfi) < 0)
519 {
520 fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
521 exit (1) ;
522 }
523
524 for (;;)
525 delay (9999) ;
526}
527
528
529
530/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100531 * doEdge:
532 * gpio edge pin mode
533 * Easy access to changing the edge trigger on a GPIO pin
534 * This uses the /sys/class/gpio device interface.
535 *********************************************************************************
536 */
537
538void doEdge (int argc, char *argv [])
539{
540 FILE *fd ;
541 int pin ;
542 char *mode ;
543 char fName [128] ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100544
545 if (argc != 4)
546 {
547 fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
548 exit (1) ;
549 }
550
Gordon Henderson178ea082012-08-19 15:17:03 +0100551 pin = atoi (argv [2]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100552 mode = argv [3] ;
553
554// Export the pin and set direction to input
555
556 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
557 {
558 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
559 exit (1) ;
560 }
561
562 fprintf (fd, "%d\n", pin) ;
563 fclose (fd) ;
564
565 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
566 if ((fd = fopen (fName, "w")) == NULL)
567 {
568 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
569 exit (1) ;
570 }
571
572 fprintf (fd, "in\n") ;
573 fclose (fd) ;
574
575 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
576 if ((fd = fopen (fName, "w")) == NULL)
577 {
578 fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
579 exit (1) ;
580 }
581
Gordon Henderson178ea082012-08-19 15:17:03 +0100582 /**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
583 else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
584 else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
585 else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100586 else
587 {
588 fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
589 exit (1) ;
590 }
591
Gordon Henderson178ea082012-08-19 15:17:03 +0100592// Change ownership of the value and edge files, so the current user can actually use it!
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100593
594 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100595 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100596
597 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100598 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100599
600 fclose (fd) ;
601}
602
603
604/*
605 * doUnexport:
606 * gpio unexport pin
607 * This uses the /sys/class/gpio device interface.
608 *********************************************************************************
609 */
610
611void doUnexport (int argc, char *argv [])
612{
613 FILE *fd ;
614 int pin ;
615
616 if (argc != 3)
617 {
618 fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
619 exit (1) ;
620 }
621
622 pin = atoi (argv [2]) ;
623
624 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
625 {
626 fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
627 exit (1) ;
628 }
629
630 fprintf (fd, "%d\n", pin) ;
631 fclose (fd) ;
632}
633
634
635/*
636 * doUnexportAll:
637 * gpio unexportall
638 * Un-Export all the GPIO pins.
639 * This uses the /sys/class/gpio device interface.
640 *********************************************************************************
641 */
642
Gordon Hendersonda384432013-05-13 19:43:26 +0100643void doUnexportall (char *progName)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100644{
645 FILE *fd ;
646 int pin ;
647
648 for (pin = 0 ; pin < 63 ; ++pin)
649 {
650 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
651 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100652 fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100653 exit (1) ;
654 }
655 fprintf (fd, "%d\n", pin) ;
656 fclose (fd) ;
657 }
658}
659
660
661/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100662 * doReset:
663 * Reset the GPIO pins - as much as we can do
664 *********************************************************************************
665 */
666
667static void doReset (char *progName)
668{
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000669 printf ("GPIO Reset is dangerous and has been removed from the gpio command.\n") ;
670 printf (" - Please write a shell-script to reset the GPIO pins into the state\n") ;
671 printf (" that you need them in for your applications.\n") ;
Gordon Hendersonda384432013-05-13 19:43:26 +0100672}
673
674
675/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100676 * doMode:
677 * gpio mode pin mode ...
678 *********************************************************************************
679 */
680
681void doMode (int argc, char *argv [])
682{
683 int pin ;
684 char *mode ;
685
686 if (argc != 4)
687 {
688 fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
689 exit (1) ;
690 }
691
692 pin = atoi (argv [2]) ;
693
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100694 mode = argv [3] ;
695
Gordon Hendersondca8a192014-07-14 08:39:38 +0100696 /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
697 else if (strcasecmp (mode, "input") == 0) pinMode (pin, INPUT) ;
698 else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
699 else if (strcasecmp (mode, "output") == 0) pinMode (pin, OUTPUT) ;
700 else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
701 else if (strcasecmp (mode, "pwmTone") == 0) pinMode (pin, PWM_TONE_OUTPUT) ;
702 else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ;
703 else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
704 else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
705 else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
706 else if (strcasecmp (mode, "off") == 0) pullUpDnControl (pin, PUD_OFF) ;
Gordon Hendersonf18c8f72013-08-03 23:53:35 +0100707 else if (strcasecmp (mode, "alt0") == 0) pinModeAlt (pin, 0b100) ;
708 else if (strcasecmp (mode, "alt1") == 0) pinModeAlt (pin, 0b101) ;
709 else if (strcasecmp (mode, "alt2") == 0) pinModeAlt (pin, 0b110) ;
710 else if (strcasecmp (mode, "alt3") == 0) pinModeAlt (pin, 0b111) ;
711 else if (strcasecmp (mode, "alt4") == 0) pinModeAlt (pin, 0b011) ;
712 else if (strcasecmp (mode, "alt5") == 0) pinModeAlt (pin, 0b010) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100713 else
714 {
Gordon Henderson56c77b52013-02-01 20:19:22 +0000715 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 +0100716 exit (1) ;
717 }
718}
719
720
721/*
722 * doPadDrive:
723 * gpio drive group value
724 *********************************************************************************
725 */
726
Gordon Henderson1bb49892012-08-19 15:33:26 +0100727static void doPadDrive (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100728{
729 int group, val ;
730
731 if (argc != 4)
732 {
733 fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
734 exit (1) ;
735 }
736
737 group = atoi (argv [2]) ;
738 val = atoi (argv [3]) ;
739
740 if ((group < 0) || (group > 2))
741 {
742 fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
743 exit (1) ;
744 }
745
746 if ((val < 0) || (val > 7))
747 {
748 fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
749 exit (1) ;
750 }
751
752 setPadDrive (group, val) ;
753}
754
755
756/*
Gordon Hendersondf453882014-07-17 22:23:57 +0100757 * doUsbP:
758 * Control USB Power - High (1.2A) or Low (600mA)
759 * gpio usbp high/low
760 *********************************************************************************
761 */
762
763static void doUsbP (int argc, char *argv [])
764{
765 int model, rev, mem, maker, overVolted ;
766
767 if (argc != 3)
768 {
769 fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
770 exit (1) ;
771 }
772
773// Make sure we're on a B+
774
775 piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
776
777 if (model != PI_MODEL_BP)
778 {
779 fprintf (stderr, "USB power contol is applicable to B+ boards only.\n") ;
780 exit (1) ;
781 }
782
783// Need to force BCM_GPIO mode:
784
785 wiringPiSetupGpio () ;
786
787 if ((strcasecmp (argv [2], "high") == 0) || (strcasecmp (argv [2], "hi") == 0))
788 {
789 digitalWrite (PI_USB_POWER_CONTROL, 1) ;
790 pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
791 printf ("Switched to HIGH current USB (1.2A)\n") ;
792 return ;
793 }
794
795 if ((strcasecmp (argv [2], "low") == 0) || (strcasecmp (argv [2], "lo") == 0))
796 {
797 digitalWrite (PI_USB_POWER_CONTROL, 0) ;
798 pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
799 printf ("Switched to LOW current USB (600mA)\n") ;
800 return ;
801 }
802
803 fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
804 exit (1) ;
805}
806
807
808/*
Gordon Henderson99095e32012-08-27 20:56:14 +0100809 * doGbw:
810 * gpio gbw channel value
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000811 * Gertboard Write - To the Analog output
Gordon Henderson99095e32012-08-27 20:56:14 +0100812 *********************************************************************************
813 */
814
815static void doGbw (int argc, char *argv [])
816{
817 int channel, value ;
818
819 if (argc != 4)
820 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100821 fprintf (stderr, "Usage: %s gbw <channel> <value>\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100822 exit (1) ;
823 }
824
825 channel = atoi (argv [2]) ;
826 value = atoi (argv [3]) ;
827
828 if ((channel < 0) || (channel > 1))
829 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100830 fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100831 exit (1) ;
832 }
833
Gordon Hendersondca8a192014-07-14 08:39:38 +0100834 if ((value < 0) || (value > 255))
Gordon Henderson99095e32012-08-27 20:56:14 +0100835 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100836 fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100837 exit (1) ;
838 }
839
Gordon Hendersonda384432013-05-13 19:43:26 +0100840 if (gertboardAnalogSetup (64) < 0)
Gordon Henderson99095e32012-08-27 20:56:14 +0100841 {
842 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
843 exit (1) ;
844 }
845
Gordon Hendersonda384432013-05-13 19:43:26 +0100846 analogWrite (64 + channel, value) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100847}
848
849
850/*
851 * doGbr:
852 * gpio gbr channel
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000853 * From the analog input
Gordon Henderson99095e32012-08-27 20:56:14 +0100854 *********************************************************************************
855 */
856
857static void doGbr (int argc, char *argv [])
858{
859 int channel ;
860
861 if (argc != 3)
862 {
863 fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
864 exit (1) ;
865 }
866
867 channel = atoi (argv [2]) ;
868
869 if ((channel < 0) || (channel > 1))
870 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100871 fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100872 exit (1) ;
873 }
874
Gordon Hendersonda384432013-05-13 19:43:26 +0100875 if (gertboardAnalogSetup (64) < 0)
Gordon Henderson99095e32012-08-27 20:56:14 +0100876 {
877 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
878 exit (1) ;
879 }
880
Gordon Hendersonda384432013-05-13 19:43:26 +0100881 printf ("%d\n", analogRead (64 + channel)) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100882}
883
884
Gordon Henderson99095e32012-08-27 20:56:14 +0100885/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100886 * doWrite:
887 * gpio write pin value
888 *********************************************************************************
889 */
890
Gordon Henderson1bb49892012-08-19 15:33:26 +0100891static void doWrite (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100892{
893 int pin, val ;
894
895 if (argc != 4)
896 {
897 fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
898 exit (1) ;
899 }
900
901 pin = atoi (argv [2]) ;
902
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000903 /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
904 val = 1 ;
905 else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
906 val = 0 ;
907 else
908 val = atoi (argv [3]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100909
910 /**/ if (val == 0)
911 digitalWrite (pin, LOW) ;
912 else
913 digitalWrite (pin, HIGH) ;
914}
915
Gordon Hendersonda384432013-05-13 19:43:26 +0100916
917/*
918 * doAwriterite:
919 * gpio awrite pin value
920 *********************************************************************************
921 */
922
923static void doAwrite (int argc, char *argv [])
924{
925 int pin, val ;
926
927 if (argc != 4)
928 {
929 fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
930 exit (1) ;
931 }
932
933 pin = atoi (argv [2]) ;
934
935 val = atoi (argv [3]) ;
936
937 analogWrite (pin, val) ;
938}
939
940
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000941/*
942 * doWriteByte:
943 * gpio write value
944 *********************************************************************************
945 */
946
947static void doWriteByte (int argc, char *argv [])
948{
949 int val ;
950
951 if (argc != 3)
952 {
953 fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
954 exit (1) ;
955 }
956
957 val = (int)strtol (argv [2], NULL, 0) ;
958
959 digitalWriteByte (val) ;
960}
961
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100962
963/*
964 * doRead:
965 * Read a pin and return the value
966 *********************************************************************************
967 */
968
969void doRead (int argc, char *argv [])
970{
971 int pin, val ;
972
973 if (argc != 3)
974 {
975 fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
976 exit (1) ;
977 }
978
979 pin = atoi (argv [2]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100980 val = digitalRead (pin) ;
981
982 printf ("%s\n", val == 0 ? "0" : "1") ;
983}
984
985
986/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100987 * doAread:
988 * Read an analog pin and return the value
989 *********************************************************************************
990 */
991
992void doAread (int argc, char *argv [])
993{
Gordon Hendersonda384432013-05-13 19:43:26 +0100994 if (argc != 3)
995 {
996 fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
997 exit (1) ;
998 }
999
Gordon Hendersonbfaf2662013-05-20 21:13:44 +01001000 printf ("%d\n", analogRead (atoi (argv [2]))) ;
Gordon Hendersonda384432013-05-13 19:43:26 +01001001}
1002
1003
1004/*
1005 * doToggle:
1006 * Toggle an IO pin
1007 *********************************************************************************
1008 */
1009
1010void doToggle (int argc, char *argv [])
1011{
1012 int pin ;
1013
1014 if (argc != 3)
1015 {
1016 fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
1017 exit (1) ;
1018 }
1019
1020 pin = atoi (argv [2]) ;
1021
1022 digitalWrite (pin, !digitalRead (pin)) ;
1023}
1024
Gordon Hendersondca8a192014-07-14 08:39:38 +01001025
1026/*
1027 * doPwmTone:
1028 * Output a tone in a PWM pin
1029 *********************************************************************************
1030 */
1031
1032void doPwmTone (int argc, char *argv [])
1033{
1034 int pin, freq ;
1035
1036 if (argc != 4)
1037 {
1038 fprintf (stderr, "Usage: %s pwmTone <pin> <freq>\n", argv [0]) ;
1039 exit (1) ;
1040 }
1041
1042 pin = atoi (argv [2]) ;
1043 freq = atoi (argv [3]) ;
1044
1045 pwmToneWrite (pin, freq) ;
1046}
1047
1048
Gordon Hendersonda384432013-05-13 19:43:26 +01001049/*
Gordon Henderson56c77b52013-02-01 20:19:22 +00001050 * doClock:
1051 * Output a clock on a pin
1052 *********************************************************************************
1053 */
1054
1055void doClock (int argc, char *argv [])
1056{
1057 int pin, freq ;
1058
1059 if (argc != 4)
1060 {
1061 fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
1062 exit (1) ;
1063 }
1064
1065 pin = atoi (argv [2]) ;
1066
Gordon Henderson56c77b52013-02-01 20:19:22 +00001067 freq = atoi (argv [3]) ;
1068
1069 gpioClockSet (pin, freq) ;
1070}
1071
1072
1073/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001074 * doPwm:
1075 * Output a PWM value on a pin
1076 *********************************************************************************
1077 */
1078
1079void doPwm (int argc, char *argv [])
1080{
1081 int pin, val ;
1082
1083 if (argc != 4)
1084 {
1085 fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
1086 exit (1) ;
1087 }
1088
1089 pin = atoi (argv [2]) ;
1090
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001091 val = atoi (argv [3]) ;
1092
1093 pwmWrite (pin, val) ;
1094}
1095
1096
1097/*
Gordon Henderson8cb49392012-09-16 10:15:32 +01001098 * doPwmMode: doPwmRange: doPwmClock:
1099 * Change the PWM mode, range and clock divider values
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001100 *********************************************************************************
1101 */
1102
1103static void doPwmMode (int mode)
1104{
1105 pwmSetMode (mode) ;
1106}
1107
1108static void doPwmRange (int argc, char *argv [])
1109{
1110 unsigned int range ;
1111
1112 if (argc != 3)
1113 {
1114 fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
1115 exit (1) ;
1116 }
1117
1118 range = (unsigned int)strtoul (argv [2], NULL, 10) ;
1119
1120 if (range == 0)
1121 {
1122 fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
1123 exit (1) ;
1124 }
1125
1126 pwmSetRange (range) ;
1127}
1128
Gordon Henderson8cb49392012-09-16 10:15:32 +01001129static void doPwmClock (int argc, char *argv [])
1130{
1131 unsigned int clock ;
1132
1133 if (argc != 3)
1134 {
1135 fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
1136 exit (1) ;
1137 }
1138
1139 clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
1140
1141 if ((clock < 1) || (clock > 4095))
1142 {
1143 fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
1144 exit (1) ;
1145 }
1146
1147 pwmSetClock (clock) ;
1148}
1149
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001150
1151/*
Gordon Hendersonbb6f0842015-11-29 21:08:04 +00001152 * doVersion:
1153 * Handle the ever more complicated version command
1154 *********************************************************************************
1155 */
1156
1157static void doVersion (char *argv [])
1158{
1159 int model, rev, mem, maker, warranty ;
1160 struct stat statBuf ;
1161
1162 printf ("gpio version: %s\n", VERSION) ;
1163 printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
1164 printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
1165 printf ("For details type: %s -warranty\n", argv [0]) ;
1166 printf ("\n") ;
1167 piBoardId (&model, &rev, &mem, &maker, &warranty) ;
1168
1169/*************
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
1179 {
1180 printf ("Raspberry Pi Details:\n") ;
1181 printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n",
1182 piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ;
1183
1184// Check for device tree
1185
1186 if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ...
1187 printf (" Device tree is enabled.\n") ;
1188
1189 if (stat ("/dev/gpiomem", &statBuf) == 0) // User level GPIO is GO
1190 {
1191 printf (" This Raspberry Pi supports user-level GPIO access.\n") ;
1192 printf (" -> See the man-page for more details\n") ;
1193 }
1194 else
1195 printf (" * Root or sudo required for GPIO access.\n") ;
1196
1197 }
1198}
1199
1200
1201/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001202 * main:
1203 * Start here
1204 *********************************************************************************
1205 */
1206
1207int main (int argc, char *argv [])
1208{
1209 int i ;
1210
Gordon Henderson13bbba72013-01-14 11:31:56 +00001211 if (getenv ("WIRINGPI_DEBUG") != NULL)
1212 {
1213 printf ("gpio: wiringPi debug mode enabled\n") ;
1214 wiringPiDebug = TRUE ;
1215 }
1216
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001217 if (argc == 1)
1218 {
Gordon Henderson86a5c682012-10-02 14:32:12 +01001219 fprintf (stderr, "%s\n", usage) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001220 return 1 ;
1221 }
1222
Gordon Hendersonda384432013-05-13 19:43:26 +01001223// Help
1224
Gordon Henderson178ea082012-08-19 15:17:03 +01001225 if (strcasecmp (argv [1], "-h") == 0)
1226 {
1227 printf ("%s: %s\n", argv [0], usage) ;
1228 return 0 ;
1229 }
1230
Gordon Hendersonda384432013-05-13 19:43:26 +01001231// Version & Warranty
Gordon Hendersonbb6f0842015-11-29 21:08:04 +00001232// Wish I could remember why I have both -R and -V ...
Gordon Hendersonda384432013-05-13 19:43:26 +01001233
Gordon Hendersonbb6f0842015-11-29 21:08:04 +00001234 if ((strcmp (argv [1], "-R") == 0) || (strcmp (argv [1], "-V") == 0))
Gordon Hendersonda384432013-05-13 19:43:26 +01001235 {
1236 printf ("%d\n", piBoardRev ()) ;
1237 return 0 ;
1238 }
1239
Gordon Hendersonbb6f0842015-11-29 21:08:04 +00001240// Version and information
1241
Gordon Hendersonda384432013-05-13 19:43:26 +01001242 if (strcmp (argv [1], "-v") == 0)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001243 {
Gordon Hendersonbb6f0842015-11-29 21:08:04 +00001244 doVersion (argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001245 return 0 ;
1246 }
1247
1248 if (strcasecmp (argv [1], "-warranty") == 0)
1249 {
1250 printf ("gpio version: %s\n", VERSION) ;
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +00001251 printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001252 printf ("\n") ;
1253 printf (" This program is free software; you can redistribute it and/or modify\n") ;
1254 printf (" it under the terms of the GNU Leser General Public License as published\n") ;
1255 printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
1256 printf (" (at your option) any later version.\n") ;
1257 printf ("\n") ;
1258 printf (" This program is distributed in the hope that it will be useful,\n") ;
1259 printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
1260 printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
1261 printf (" GNU Lesser General Public License for more details.\n") ;
1262 printf ("\n") ;
1263 printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
1264 printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
1265 printf ("\n") ;
1266 return 0 ;
1267 }
1268
1269 if (geteuid () != 0)
1270 {
1271 fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
1272 return 1 ;
1273 }
1274
1275// Initial test for /sys/class/gpio operations:
1276
Gordon Henderson178ea082012-08-19 15:17:03 +01001277 /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
1278 else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
1279 else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
Gordon Henderson178ea082012-08-19 15:17:03 +01001280 else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
Gordon Hendersonda384432013-05-13 19:43:26 +01001281 else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; }
Gordon Henderson178ea082012-08-19 15:17:03 +01001282
Gordon Henderson86a5c682012-10-02 14:32:12 +01001283// Check for load command:
Gordon Henderson178ea082012-08-19 15:17:03 +01001284
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +00001285 if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
1286 if (strcasecmp (argv [1], "unload" ) == 0) { doUnLoad (argc, argv) ; return 0 ; }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001287
Gordon Henderson99095e32012-08-27 20:56:14 +01001288// Gertboard commands
1289
1290 if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
1291 if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
1292
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001293// Check for -g argument
1294
Gordon Hendersonda384432013-05-13 19:43:26 +01001295 /**/ if (strcasecmp (argv [1], "-g") == 0)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001296 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001297 wiringPiSetupGpio () ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001298
1299 for (i = 2 ; i < argc ; ++i)
1300 argv [i - 1] = argv [i] ;
1301 --argc ;
1302 wpMode = WPI_MODE_GPIO ;
1303 }
1304
Gordon Hendersonda384432013-05-13 19:43:26 +01001305// Check for -1 argument
1306
1307 else if (strcasecmp (argv [1], "-1") == 0)
1308 {
1309 wiringPiSetupPhys () ;
1310
1311 for (i = 2 ; i < argc ; ++i)
1312 argv [i - 1] = argv [i] ;
1313 --argc ;
1314 wpMode = WPI_MODE_PHYS ;
1315 }
1316
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001317// Check for -p argument for PiFace
1318
1319 else if (strcasecmp (argv [1], "-p") == 0)
1320 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001321 piFaceSetup (200) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001322
1323 for (i = 2 ; i < argc ; ++i)
1324 argv [i - 1] = argv [i] ;
1325 --argc ;
1326 wpMode = WPI_MODE_PIFACE ;
1327 }
1328
1329// Default to wiringPi mode
1330
1331 else
1332 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001333 wiringPiSetup () ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001334 wpMode = WPI_MODE_PINS ;
1335 }
1336
Gordon Hendersonda384432013-05-13 19:43:26 +01001337// Check for -x argument to load in a new extension
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001338
Gordon Hendersonda384432013-05-13 19:43:26 +01001339 if (strcasecmp (argv [1], "-x") == 0)
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001340 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001341 if (argc < 3)
1342 {
1343 fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ;
1344 exit (EXIT_FAILURE) ;
1345 }
1346
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +00001347 if (!loadWPiExtension (argv [0], argv [2], TRUE)) // Prints its own error messages
Gordon Hendersonda384432013-05-13 19:43:26 +01001348 exit (EXIT_FAILURE) ;
1349
1350 for (i = 3 ; i < argc ; ++i)
1351 argv [i - 2] = argv [i] ;
1352 argc -= 2 ;
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001353 }
1354
Gordon Hendersonda384432013-05-13 19:43:26 +01001355 if (argc <= 1)
1356 {
1357 fprintf (stderr, "%s: no command given\n", argv [0]) ;
1358 exit (EXIT_FAILURE) ;
1359 }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001360
Gordon Hendersonda384432013-05-13 19:43:26 +01001361// Core wiringPi functions
1362
1363 /**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
1364 else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
1365 else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ;
1366 else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
1367 else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite (argc, argv) ;
1368 else if (strcasecmp (argv [1], "aread" ) == 0) doAread (argc, argv) ;
1369
1370// GPIO Nicies
1371
1372 else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ;
1373
1374// Pi Specifics
1375
Gordon Henderson27698762013-06-27 21:51:55 +01001376 else if (strcasecmp (argv [1], "pwm-bal" ) == 0) doPwmMode (PWM_MODE_BAL) ;
1377 else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ;
1378 else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ;
1379 else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ;
Gordon Hendersondca8a192014-07-14 08:39:38 +01001380 else if (strcasecmp (argv [1], "pwmTone" ) == 0) doPwmTone (argc, argv) ;
Gordon Henderson27698762013-06-27 21:51:55 +01001381 else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
Gordon Hendersondf453882014-07-17 22:23:57 +01001382 else if (strcasecmp (argv [1], "usbp" ) == 0) doUsbP (argc, argv) ;
1383 else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
Gordon Henderson8c8578a2013-07-23 09:19:34 +01001384 else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ;
Gordon Henderson05e2f672014-05-20 11:43:07 +01001385 else if (strcasecmp (argv [1], "pins" ) == 0) doPins () ;
Gordon Henderson27698762013-06-27 21:51:55 +01001386 else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
1387 else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ;
1388 else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
1389 else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
1390 else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
1391 else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001392 else
1393 {
Gordon Henderson178ea082012-08-19 15:17:03 +01001394 fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
Gordon Hendersonda384432013-05-13 19:43:26 +01001395 exit (EXIT_FAILURE) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001396 }
1397 return 0 ;
1398}