blob: 461274f615815242cc9a1abd6215b594354e9175 [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 Hendersoneb1fc2c2015-01-30 18:14:49 +0000119 fprintf (stderr, "%s: Warning (not an error): 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
166static void _doLoadUsage (char *argv [])
167{
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000168 fprintf (stderr, "Usage: %s load <spi/i2c> [I2C baudrate in Kb/sec]\n", argv [0]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100169 exit (1) ;
170}
171
172static void doLoad (int argc, char *argv [])
173{
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000174 char *module1, *module2 ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100175 char cmd [80] ;
176 char *file1, *file2 ;
Gordon Hendersone8f62582013-01-28 13:00:47 +0000177 char args1 [32], args2 [32] ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100178
Gordon Henderson13bbba72013-01-14 11:31:56 +0000179 if (argc < 3)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100180 _doLoadUsage (argv) ;
181
Gordon Hendersone8f62582013-01-28 13:00:47 +0000182 args1 [0] = args2 [0] = 0 ;
Gordon Henderson13bbba72013-01-14 11:31:56 +0000183
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100184 /**/ if (strcasecmp (argv [2], "spi") == 0)
185 {
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000186 module1 = "spidev" ;
187 module2 = "spi_bcm2708" ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100188 file1 = "/dev/spidev0.0" ;
189 file2 = "/dev/spidev0.1" ;
Gordon Henderson13bbba72013-01-14 11:31:56 +0000190 if (argc == 4)
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000191 {
192 fprintf (stderr, "%s: Unable to set the buffer size now. Load aborted. Please see the man page.\n", argv [0]) ;
193 exit (1) ;
194 }
Gordon Henderson13bbba72013-01-14 11:31:56 +0000195 else if (argc > 4)
196 _doLoadUsage (argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100197 }
198 else if (strcasecmp (argv [2], "i2c") == 0)
199 {
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000200 module1 = "i2c_dev" ;
201 module2 = "i2c_bcm2708" ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100202 file1 = "/dev/i2c-0" ;
203 file2 = "/dev/i2c-1" ;
Gordon Hendersone8f62582013-01-28 13:00:47 +0000204 if (argc == 4)
205 sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ;
206 else if (argc > 4)
207 _doLoadUsage (argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100208 }
209 else
210 _doLoadUsage (argv) ;
211
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000212 if (!moduleLoaded (module1))
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100213 {
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000214 sprintf (cmd, "/sbin/modprobe %s%s", module1, args1) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100215 system (cmd) ;
216 }
217
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000218 if (!moduleLoaded (module2))
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100219 {
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000220 sprintf (cmd, "/sbin/modprobe %s%s", module2, args2) ;
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000221 system (cmd) ;
222 }
223
224 if (!moduleLoaded (module2))
225 {
226 fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100227 exit (1) ;
228 }
229
230 sleep (1) ; // To let things get settled
231
232 changeOwner (argv [0], file1) ;
233 changeOwner (argv [0], file2) ;
234}
235
236
Gordon Henderson183c5a62012-10-21 15:25:16 +0100237/*
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000238 * doUnLoad:
239 * Un-Load either the spi or i2c modules and change device ownerships, etc.
240 *********************************************************************************
241 */
242
243static void _doUnLoadUsage (char *argv [])
244{
245 fprintf (stderr, "Usage: %s unload <spi/i2c>\n", argv [0]) ;
246 exit (1) ;
247}
248
249static void doUnLoad (int argc, char *argv [])
250{
251 char *module1, *module2 ;
252 char cmd [80] ;
253
254 if (argc != 3)
255 _doUnLoadUsage (argv) ;
256
257 /**/ if (strcasecmp (argv [2], "spi") == 0)
258 {
259 module1 = "spidev" ;
260 module2 = "spi_bcm2708" ;
261 }
262 else if (strcasecmp (argv [2], "i2c") == 0)
263 {
264 module1 = "i2c_dev" ;
265 module2 = "i2c_bcm2708" ;
266 }
267 else
268 _doUnLoadUsage (argv) ;
269
270 if (moduleLoaded (module1))
271 {
272 sprintf (cmd, "/sbin/rmmod %s", module1) ;
273 system (cmd) ;
274 }
275
276 if (moduleLoaded (module2))
277 {
278 sprintf (cmd, "/sbin/rmmod %s", module2) ;
279 system (cmd) ;
280 }
281}
282
283
284/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100285 * doI2Cdetect:
286 * Run the i2cdetect command with the right runes for this Pi revision
287 *********************************************************************************
288 */
289
290static void doI2Cdetect (int argc, char *argv [])
291{
292 int port = piBoardRev () == 1 ? 0 : 1 ;
293 char command [128] ;
294 struct stat statBuf ;
295
296 if (stat (I2CDETECT, &statBuf) < 0)
297 {
298 fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
299 return ;
300 }
301
302 if (!moduleLoaded ("i2c_dev"))
303 {
304 fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ;
305 return ;
306 }
307
308 sprintf (command, "%s -y %d", I2CDETECT, port) ;
309 if (system (command) < 0)
310 fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;
311
312}
313
314
315/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100316 * doExports:
317 * List all GPIO exports
318 *********************************************************************************
319 */
320
Gordon Henderson178ea082012-08-19 15:17:03 +0100321static void doExports (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100322{
323 int fd ;
324 int i, l, first ;
325 char fName [128] ;
326 char buf [16] ;
327
Gordon Hendersonda384432013-05-13 19:43:26 +0100328 for (first = 0, i = 0 ; i < 64 ; ++i) // Crude, but effective
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100329 {
330
331// Try to read the direction
332
333 sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
334 if ((fd = open (fName, O_RDONLY)) == -1)
335 continue ;
336
337 if (first == 0)
338 {
339 ++first ;
340 printf ("GPIO Pins exported:\n") ;
341 }
342
343 printf ("%4d: ", i) ;
344
345 if ((l = read (fd, buf, 16)) == 0)
346 sprintf (buf, "%s", "?") ;
347
348 buf [l] = 0 ;
349 if ((buf [strlen (buf) - 1]) == '\n')
350 buf [strlen (buf) - 1] = 0 ;
351
352 printf ("%-3s", buf) ;
353
354 close (fd) ;
355
356// Try to Read the value
357
358 sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
359 if ((fd = open (fName, O_RDONLY)) == -1)
360 {
361 printf ("No Value file (huh?)\n") ;
362 continue ;
363 }
364
365 if ((l = read (fd, buf, 16)) == 0)
366 sprintf (buf, "%s", "?") ;
367
368 buf [l] = 0 ;
369 if ((buf [strlen (buf) - 1]) == '\n')
370 buf [strlen (buf) - 1] = 0 ;
371
372 printf (" %s", buf) ;
373
374// Read any edge trigger file
375
376 sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ;
377 if ((fd = open (fName, O_RDONLY)) == -1)
378 {
379 printf ("\n") ;
380 continue ;
381 }
382
383 if ((l = read (fd, buf, 16)) == 0)
384 sprintf (buf, "%s", "?") ;
385
386 buf [l] = 0 ;
387 if ((buf [strlen (buf) - 1]) == '\n')
388 buf [strlen (buf) - 1] = 0 ;
389
390 printf (" %-8s\n", buf) ;
391
392 close (fd) ;
393 }
394}
395
396
397/*
398 * doExport:
399 * gpio export pin mode
400 * This uses the /sys/class/gpio device interface.
401 *********************************************************************************
402 */
403
404void doExport (int argc, char *argv [])
405{
406 FILE *fd ;
407 int pin ;
408 char *mode ;
409 char fName [128] ;
410
411 if (argc != 4)
412 {
413 fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
414 exit (1) ;
415 }
416
417 pin = atoi (argv [2]) ;
418
419 mode = argv [3] ;
420
421 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
422 {
423 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
424 exit (1) ;
425 }
426
427 fprintf (fd, "%d\n", pin) ;
428 fclose (fd) ;
429
430 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
431 if ((fd = fopen (fName, "w")) == NULL)
432 {
433 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
434 exit (1) ;
435 }
436
437 /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
438 fprintf (fd, "in\n") ;
439 else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
440 fprintf (fd, "out\n") ;
441 else
442 {
443 fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ;
444 exit (1) ;
445 }
446
447 fclose (fd) ;
448
449// Change ownership so the current user can actually use it!
450
451 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
452 changeOwner (argv [0], fName) ;
453
454 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
455 changeOwner (argv [0], fName) ;
456
457}
458
459
460/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100461 * doWfi:
462 * gpio wfi pin mode
463 * Wait for Interrupt on a given pin.
464 * Slight cheat here - it's easier to actually use ISR now (which calls
465 * gpio to set the pin modes!) then we simply sleep, and expect the thread
466 * to exit the program. Crude but effective.
467 *********************************************************************************
468 */
469
470static void wfi (void)
471 { exit (0) ; }
472
473void doWfi (int argc, char *argv [])
474{
475 int pin, mode ;
476
477 if (argc != 4)
478 {
479 fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ;
480 exit (1) ;
481 }
482
483 pin = atoi (argv [2]) ;
484
485 /**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ;
486 else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
487 else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ;
488 else
489 {
490 fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ;
491 exit (1) ;
492 }
493
494 if (wiringPiISR (pin, mode, &wfi) < 0)
495 {
496 fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
497 exit (1) ;
498 }
499
500 for (;;)
501 delay (9999) ;
502}
503
504
505
506/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100507 * doEdge:
508 * gpio edge pin mode
509 * Easy access to changing the edge trigger on a GPIO pin
510 * This uses the /sys/class/gpio device interface.
511 *********************************************************************************
512 */
513
514void doEdge (int argc, char *argv [])
515{
516 FILE *fd ;
517 int pin ;
518 char *mode ;
519 char fName [128] ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100520
521 if (argc != 4)
522 {
523 fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
524 exit (1) ;
525 }
526
Gordon Henderson178ea082012-08-19 15:17:03 +0100527 pin = atoi (argv [2]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100528 mode = argv [3] ;
529
530// Export the pin and set direction to input
531
532 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
533 {
534 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
535 exit (1) ;
536 }
537
538 fprintf (fd, "%d\n", pin) ;
539 fclose (fd) ;
540
541 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
542 if ((fd = fopen (fName, "w")) == NULL)
543 {
544 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
545 exit (1) ;
546 }
547
548 fprintf (fd, "in\n") ;
549 fclose (fd) ;
550
551 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
552 if ((fd = fopen (fName, "w")) == NULL)
553 {
554 fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
555 exit (1) ;
556 }
557
Gordon Henderson178ea082012-08-19 15:17:03 +0100558 /**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
559 else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
560 else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
561 else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100562 else
563 {
564 fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
565 exit (1) ;
566 }
567
Gordon Henderson178ea082012-08-19 15:17:03 +0100568// Change ownership of the value and edge files, so the current user can actually use it!
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100569
570 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100571 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100572
573 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100574 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100575
576 fclose (fd) ;
577}
578
579
580/*
581 * doUnexport:
582 * gpio unexport pin
583 * This uses the /sys/class/gpio device interface.
584 *********************************************************************************
585 */
586
587void doUnexport (int argc, char *argv [])
588{
589 FILE *fd ;
590 int pin ;
591
592 if (argc != 3)
593 {
594 fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
595 exit (1) ;
596 }
597
598 pin = atoi (argv [2]) ;
599
600 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
601 {
602 fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
603 exit (1) ;
604 }
605
606 fprintf (fd, "%d\n", pin) ;
607 fclose (fd) ;
608}
609
610
611/*
612 * doUnexportAll:
613 * gpio unexportall
614 * Un-Export all the GPIO pins.
615 * This uses the /sys/class/gpio device interface.
616 *********************************************************************************
617 */
618
Gordon Hendersonda384432013-05-13 19:43:26 +0100619void doUnexportall (char *progName)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100620{
621 FILE *fd ;
622 int pin ;
623
624 for (pin = 0 ; pin < 63 ; ++pin)
625 {
626 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
627 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100628 fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100629 exit (1) ;
630 }
631 fprintf (fd, "%d\n", pin) ;
632 fclose (fd) ;
633 }
634}
635
636
637/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100638 * doReset:
639 * Reset the GPIO pins - as much as we can do
640 *********************************************************************************
641 */
642
643static void doReset (char *progName)
644{
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000645 printf ("GPIO Reset is dangerous and has been removed from the gpio command.\n") ;
646 printf (" - Please write a shell-script to reset the GPIO pins into the state\n") ;
647 printf (" that you need them in for your applications.\n") ;
Gordon Hendersonda384432013-05-13 19:43:26 +0100648}
649
650
651/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100652 * doMode:
653 * gpio mode pin mode ...
654 *********************************************************************************
655 */
656
657void doMode (int argc, char *argv [])
658{
659 int pin ;
660 char *mode ;
661
662 if (argc != 4)
663 {
664 fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
665 exit (1) ;
666 }
667
668 pin = atoi (argv [2]) ;
669
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100670 mode = argv [3] ;
671
Gordon Hendersondca8a192014-07-14 08:39:38 +0100672 /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
673 else if (strcasecmp (mode, "input") == 0) pinMode (pin, INPUT) ;
674 else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
675 else if (strcasecmp (mode, "output") == 0) pinMode (pin, OUTPUT) ;
676 else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
677 else if (strcasecmp (mode, "pwmTone") == 0) pinMode (pin, PWM_TONE_OUTPUT) ;
678 else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ;
679 else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
680 else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
681 else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
682 else if (strcasecmp (mode, "off") == 0) pullUpDnControl (pin, PUD_OFF) ;
Gordon Hendersonf18c8f72013-08-03 23:53:35 +0100683 else if (strcasecmp (mode, "alt0") == 0) pinModeAlt (pin, 0b100) ;
684 else if (strcasecmp (mode, "alt1") == 0) pinModeAlt (pin, 0b101) ;
685 else if (strcasecmp (mode, "alt2") == 0) pinModeAlt (pin, 0b110) ;
686 else if (strcasecmp (mode, "alt3") == 0) pinModeAlt (pin, 0b111) ;
687 else if (strcasecmp (mode, "alt4") == 0) pinModeAlt (pin, 0b011) ;
688 else if (strcasecmp (mode, "alt5") == 0) pinModeAlt (pin, 0b010) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100689 else
690 {
Gordon Henderson56c77b52013-02-01 20:19:22 +0000691 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 +0100692 exit (1) ;
693 }
694}
695
696
697/*
698 * doPadDrive:
699 * gpio drive group value
700 *********************************************************************************
701 */
702
Gordon Henderson1bb49892012-08-19 15:33:26 +0100703static void doPadDrive (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100704{
705 int group, val ;
706
707 if (argc != 4)
708 {
709 fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
710 exit (1) ;
711 }
712
713 group = atoi (argv [2]) ;
714 val = atoi (argv [3]) ;
715
716 if ((group < 0) || (group > 2))
717 {
718 fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
719 exit (1) ;
720 }
721
722 if ((val < 0) || (val > 7))
723 {
724 fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
725 exit (1) ;
726 }
727
728 setPadDrive (group, val) ;
729}
730
731
732/*
Gordon Hendersondf453882014-07-17 22:23:57 +0100733 * doUsbP:
734 * Control USB Power - High (1.2A) or Low (600mA)
735 * gpio usbp high/low
736 *********************************************************************************
737 */
738
739static void doUsbP (int argc, char *argv [])
740{
741 int model, rev, mem, maker, overVolted ;
742
743 if (argc != 3)
744 {
745 fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
746 exit (1) ;
747 }
748
749// Make sure we're on a B+
750
751 piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
752
753 if (model != PI_MODEL_BP)
754 {
755 fprintf (stderr, "USB power contol is applicable to B+ boards only.\n") ;
756 exit (1) ;
757 }
758
759// Need to force BCM_GPIO mode:
760
761 wiringPiSetupGpio () ;
762
763 if ((strcasecmp (argv [2], "high") == 0) || (strcasecmp (argv [2], "hi") == 0))
764 {
765 digitalWrite (PI_USB_POWER_CONTROL, 1) ;
766 pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
767 printf ("Switched to HIGH current USB (1.2A)\n") ;
768 return ;
769 }
770
771 if ((strcasecmp (argv [2], "low") == 0) || (strcasecmp (argv [2], "lo") == 0))
772 {
773 digitalWrite (PI_USB_POWER_CONTROL, 0) ;
774 pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
775 printf ("Switched to LOW current USB (600mA)\n") ;
776 return ;
777 }
778
779 fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
780 exit (1) ;
781}
782
783
784/*
Gordon Henderson99095e32012-08-27 20:56:14 +0100785 * doGbw:
786 * gpio gbw channel value
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000787 * Gertboard Write - To the Analog output
Gordon Henderson99095e32012-08-27 20:56:14 +0100788 *********************************************************************************
789 */
790
791static void doGbw (int argc, char *argv [])
792{
793 int channel, value ;
794
795 if (argc != 4)
796 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100797 fprintf (stderr, "Usage: %s gbw <channel> <value>\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100798 exit (1) ;
799 }
800
801 channel = atoi (argv [2]) ;
802 value = atoi (argv [3]) ;
803
804 if ((channel < 0) || (channel > 1))
805 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100806 fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100807 exit (1) ;
808 }
809
Gordon Hendersondca8a192014-07-14 08:39:38 +0100810 if ((value < 0) || (value > 255))
Gordon Henderson99095e32012-08-27 20:56:14 +0100811 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100812 fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100813 exit (1) ;
814 }
815
Gordon Hendersonda384432013-05-13 19:43:26 +0100816 if (gertboardAnalogSetup (64) < 0)
Gordon Henderson99095e32012-08-27 20:56:14 +0100817 {
818 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
819 exit (1) ;
820 }
821
Gordon Hendersonda384432013-05-13 19:43:26 +0100822 analogWrite (64 + channel, value) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100823}
824
825
826/*
827 * doGbr:
828 * gpio gbr channel
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000829 * From the analog input
Gordon Henderson99095e32012-08-27 20:56:14 +0100830 *********************************************************************************
831 */
832
833static void doGbr (int argc, char *argv [])
834{
835 int channel ;
836
837 if (argc != 3)
838 {
839 fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
840 exit (1) ;
841 }
842
843 channel = atoi (argv [2]) ;
844
845 if ((channel < 0) || (channel > 1))
846 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100847 fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100848 exit (1) ;
849 }
850
Gordon Hendersonda384432013-05-13 19:43:26 +0100851 if (gertboardAnalogSetup (64) < 0)
Gordon Henderson99095e32012-08-27 20:56:14 +0100852 {
853 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
854 exit (1) ;
855 }
856
Gordon Hendersonda384432013-05-13 19:43:26 +0100857 printf ("%d\n", analogRead (64 + channel)) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100858}
859
860
Gordon Henderson99095e32012-08-27 20:56:14 +0100861/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100862 * doWrite:
863 * gpio write pin value
864 *********************************************************************************
865 */
866
Gordon Henderson1bb49892012-08-19 15:33:26 +0100867static void doWrite (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100868{
869 int pin, val ;
870
871 if (argc != 4)
872 {
873 fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
874 exit (1) ;
875 }
876
877 pin = atoi (argv [2]) ;
878
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000879 /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
880 val = 1 ;
881 else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
882 val = 0 ;
883 else
884 val = atoi (argv [3]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100885
886 /**/ if (val == 0)
887 digitalWrite (pin, LOW) ;
888 else
889 digitalWrite (pin, HIGH) ;
890}
891
Gordon Hendersonda384432013-05-13 19:43:26 +0100892
893/*
894 * doAwriterite:
895 * gpio awrite pin value
896 *********************************************************************************
897 */
898
899static void doAwrite (int argc, char *argv [])
900{
901 int pin, val ;
902
903 if (argc != 4)
904 {
905 fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
906 exit (1) ;
907 }
908
909 pin = atoi (argv [2]) ;
910
911 val = atoi (argv [3]) ;
912
913 analogWrite (pin, val) ;
914}
915
916
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000917/*
918 * doWriteByte:
919 * gpio write value
920 *********************************************************************************
921 */
922
923static void doWriteByte (int argc, char *argv [])
924{
925 int val ;
926
927 if (argc != 3)
928 {
929 fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
930 exit (1) ;
931 }
932
933 val = (int)strtol (argv [2], NULL, 0) ;
934
935 digitalWriteByte (val) ;
936}
937
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100938
939/*
940 * doRead:
941 * Read a pin and return the value
942 *********************************************************************************
943 */
944
945void doRead (int argc, char *argv [])
946{
947 int pin, val ;
948
949 if (argc != 3)
950 {
951 fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
952 exit (1) ;
953 }
954
955 pin = atoi (argv [2]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100956 val = digitalRead (pin) ;
957
958 printf ("%s\n", val == 0 ? "0" : "1") ;
959}
960
961
962/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100963 * doAread:
964 * Read an analog pin and return the value
965 *********************************************************************************
966 */
967
968void doAread (int argc, char *argv [])
969{
Gordon Hendersonda384432013-05-13 19:43:26 +0100970 if (argc != 3)
971 {
972 fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
973 exit (1) ;
974 }
975
Gordon Hendersonbfaf2662013-05-20 21:13:44 +0100976 printf ("%d\n", analogRead (atoi (argv [2]))) ;
Gordon Hendersonda384432013-05-13 19:43:26 +0100977}
978
979
980/*
981 * doToggle:
982 * Toggle an IO pin
983 *********************************************************************************
984 */
985
986void doToggle (int argc, char *argv [])
987{
988 int pin ;
989
990 if (argc != 3)
991 {
992 fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
993 exit (1) ;
994 }
995
996 pin = atoi (argv [2]) ;
997
998 digitalWrite (pin, !digitalRead (pin)) ;
999}
1000
Gordon Hendersondca8a192014-07-14 08:39:38 +01001001
1002/*
1003 * doPwmTone:
1004 * Output a tone in a PWM pin
1005 *********************************************************************************
1006 */
1007
1008void doPwmTone (int argc, char *argv [])
1009{
1010 int pin, freq ;
1011
1012 if (argc != 4)
1013 {
1014 fprintf (stderr, "Usage: %s pwmTone <pin> <freq>\n", argv [0]) ;
1015 exit (1) ;
1016 }
1017
1018 pin = atoi (argv [2]) ;
1019 freq = atoi (argv [3]) ;
1020
1021 pwmToneWrite (pin, freq) ;
1022}
1023
1024
Gordon Hendersonda384432013-05-13 19:43:26 +01001025/*
Gordon Henderson56c77b52013-02-01 20:19:22 +00001026 * doClock:
1027 * Output a clock on a pin
1028 *********************************************************************************
1029 */
1030
1031void doClock (int argc, char *argv [])
1032{
1033 int pin, freq ;
1034
1035 if (argc != 4)
1036 {
1037 fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
1038 exit (1) ;
1039 }
1040
1041 pin = atoi (argv [2]) ;
1042
Gordon Henderson56c77b52013-02-01 20:19:22 +00001043 freq = atoi (argv [3]) ;
1044
1045 gpioClockSet (pin, freq) ;
1046}
1047
1048
1049/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001050 * doPwm:
1051 * Output a PWM value on a pin
1052 *********************************************************************************
1053 */
1054
1055void doPwm (int argc, char *argv [])
1056{
1057 int pin, val ;
1058
1059 if (argc != 4)
1060 {
1061 fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
1062 exit (1) ;
1063 }
1064
1065 pin = atoi (argv [2]) ;
1066
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001067 val = atoi (argv [3]) ;
1068
1069 pwmWrite (pin, val) ;
1070}
1071
1072
1073/*
Gordon Henderson8cb49392012-09-16 10:15:32 +01001074 * doPwmMode: doPwmRange: doPwmClock:
1075 * Change the PWM mode, range and clock divider values
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001076 *********************************************************************************
1077 */
1078
1079static void doPwmMode (int mode)
1080{
1081 pwmSetMode (mode) ;
1082}
1083
1084static void doPwmRange (int argc, char *argv [])
1085{
1086 unsigned int range ;
1087
1088 if (argc != 3)
1089 {
1090 fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
1091 exit (1) ;
1092 }
1093
1094 range = (unsigned int)strtoul (argv [2], NULL, 10) ;
1095
1096 if (range == 0)
1097 {
1098 fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
1099 exit (1) ;
1100 }
1101
1102 pwmSetRange (range) ;
1103}
1104
Gordon Henderson8cb49392012-09-16 10:15:32 +01001105static void doPwmClock (int argc, char *argv [])
1106{
1107 unsigned int clock ;
1108
1109 if (argc != 3)
1110 {
1111 fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
1112 exit (1) ;
1113 }
1114
1115 clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
1116
1117 if ((clock < 1) || (clock > 4095))
1118 {
1119 fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
1120 exit (1) ;
1121 }
1122
1123 pwmSetClock (clock) ;
1124}
1125
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001126
1127/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001128 * main:
1129 * Start here
1130 *********************************************************************************
1131 */
1132
1133int main (int argc, char *argv [])
1134{
1135 int i ;
Gordon Hendersondf453882014-07-17 22:23:57 +01001136 int model, rev, mem, maker, overVolted ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001137
Gordon Henderson13bbba72013-01-14 11:31:56 +00001138 if (getenv ("WIRINGPI_DEBUG") != NULL)
1139 {
1140 printf ("gpio: wiringPi debug mode enabled\n") ;
1141 wiringPiDebug = TRUE ;
1142 }
1143
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001144 if (argc == 1)
1145 {
Gordon Henderson86a5c682012-10-02 14:32:12 +01001146 fprintf (stderr, "%s\n", usage) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001147 return 1 ;
1148 }
1149
Gordon Hendersonda384432013-05-13 19:43:26 +01001150// Help
1151
Gordon Henderson178ea082012-08-19 15:17:03 +01001152 if (strcasecmp (argv [1], "-h") == 0)
1153 {
1154 printf ("%s: %s\n", argv [0], usage) ;
1155 return 0 ;
1156 }
1157
Gordon Hendersonda384432013-05-13 19:43:26 +01001158// Sort of a special:
1159
1160 if (strcmp (argv [1], "-R") == 0)
1161 {
1162 printf ("%d\n", piBoardRev ()) ;
1163 return 0 ;
1164 }
1165
1166// Version & Warranty
1167
1168 if (strcmp (argv [1], "-V") == 0)
1169 {
1170 printf ("%d\n", piBoardRev ()) ;
1171 return 0 ;
1172 }
1173
1174 if (strcmp (argv [1], "-v") == 0)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001175 {
1176 printf ("gpio version: %s\n", VERSION) ;
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +00001177 printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001178 printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
1179 printf ("For details type: %s -warranty\n", argv [0]) ;
Gordon Henderson86a5c682012-10-02 14:32:12 +01001180 printf ("\n") ;
Gordon Hendersondf453882014-07-17 22:23:57 +01001181 piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
1182 if (model == PI_MODEL_UNKNOWN)
1183 {
1184 printf ("Your Raspberry Pi has an unknown model type. Please report this to\n") ;
1185 printf (" projects@drogon.net\n") ;
1186 printf ("with a copy of your /proc/cpuinfo if possible\n") ;
1187 }
1188 else
1189 {
1190 printf ("Raspberry Pi Details:\n") ;
1191 printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n",
1192 piModelNames [model], piRevisionNames [rev], mem, piMakerNames [maker], overVolted ? "[OV]" : "") ;
1193 }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001194 return 0 ;
1195 }
1196
1197 if (strcasecmp (argv [1], "-warranty") == 0)
1198 {
1199 printf ("gpio version: %s\n", VERSION) ;
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +00001200 printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001201 printf ("\n") ;
1202 printf (" This program is free software; you can redistribute it and/or modify\n") ;
1203 printf (" it under the terms of the GNU Leser General Public License as published\n") ;
1204 printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
1205 printf (" (at your option) any later version.\n") ;
1206 printf ("\n") ;
1207 printf (" This program is distributed in the hope that it will be useful,\n") ;
1208 printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
1209 printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
1210 printf (" GNU Lesser General Public License for more details.\n") ;
1211 printf ("\n") ;
1212 printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
1213 printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
1214 printf ("\n") ;
1215 return 0 ;
1216 }
1217
1218 if (geteuid () != 0)
1219 {
1220 fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
1221 return 1 ;
1222 }
1223
1224// Initial test for /sys/class/gpio operations:
1225
Gordon Henderson178ea082012-08-19 15:17:03 +01001226 /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
1227 else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
1228 else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
Gordon Henderson178ea082012-08-19 15:17:03 +01001229 else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
Gordon Hendersonda384432013-05-13 19:43:26 +01001230 else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; }
Gordon Henderson178ea082012-08-19 15:17:03 +01001231
Gordon Henderson86a5c682012-10-02 14:32:12 +01001232// Check for load command:
Gordon Henderson178ea082012-08-19 15:17:03 +01001233
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +00001234 if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
1235 if (strcasecmp (argv [1], "unload" ) == 0) { doUnLoad (argc, argv) ; return 0 ; }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001236
Gordon Henderson99095e32012-08-27 20:56:14 +01001237// Gertboard commands
1238
1239 if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
1240 if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
1241
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001242// Check for -g argument
1243
Gordon Hendersonda384432013-05-13 19:43:26 +01001244 /**/ if (strcasecmp (argv [1], "-g") == 0)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001245 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001246 wiringPiSetupGpio () ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001247
1248 for (i = 2 ; i < argc ; ++i)
1249 argv [i - 1] = argv [i] ;
1250 --argc ;
1251 wpMode = WPI_MODE_GPIO ;
1252 }
1253
Gordon Hendersonda384432013-05-13 19:43:26 +01001254// Check for -1 argument
1255
1256 else if (strcasecmp (argv [1], "-1") == 0)
1257 {
1258 wiringPiSetupPhys () ;
1259
1260 for (i = 2 ; i < argc ; ++i)
1261 argv [i - 1] = argv [i] ;
1262 --argc ;
1263 wpMode = WPI_MODE_PHYS ;
1264 }
1265
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001266// Check for -p argument for PiFace
1267
1268 else if (strcasecmp (argv [1], "-p") == 0)
1269 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001270 piFaceSetup (200) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001271
1272 for (i = 2 ; i < argc ; ++i)
1273 argv [i - 1] = argv [i] ;
1274 --argc ;
1275 wpMode = WPI_MODE_PIFACE ;
1276 }
1277
1278// Default to wiringPi mode
1279
1280 else
1281 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001282 wiringPiSetup () ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001283 wpMode = WPI_MODE_PINS ;
1284 }
1285
Gordon Hendersonda384432013-05-13 19:43:26 +01001286// Check for -x argument to load in a new extension
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001287
Gordon Hendersonda384432013-05-13 19:43:26 +01001288 if (strcasecmp (argv [1], "-x") == 0)
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001289 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001290 if (argc < 3)
1291 {
1292 fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ;
1293 exit (EXIT_FAILURE) ;
1294 }
1295
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +00001296 if (!loadWPiExtension (argv [0], argv [2], TRUE)) // Prints its own error messages
Gordon Hendersonda384432013-05-13 19:43:26 +01001297 exit (EXIT_FAILURE) ;
1298
1299 for (i = 3 ; i < argc ; ++i)
1300 argv [i - 2] = argv [i] ;
1301 argc -= 2 ;
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001302 }
1303
Gordon Hendersonda384432013-05-13 19:43:26 +01001304 if (argc <= 1)
1305 {
1306 fprintf (stderr, "%s: no command given\n", argv [0]) ;
1307 exit (EXIT_FAILURE) ;
1308 }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001309
Gordon Hendersonda384432013-05-13 19:43:26 +01001310// Core wiringPi functions
1311
1312 /**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
1313 else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
1314 else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ;
1315 else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
1316 else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite (argc, argv) ;
1317 else if (strcasecmp (argv [1], "aread" ) == 0) doAread (argc, argv) ;
1318
1319// GPIO Nicies
1320
1321 else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ;
1322
1323// Pi Specifics
1324
Gordon Henderson27698762013-06-27 21:51:55 +01001325 else if (strcasecmp (argv [1], "pwm-bal" ) == 0) doPwmMode (PWM_MODE_BAL) ;
1326 else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ;
1327 else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ;
1328 else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ;
Gordon Hendersondca8a192014-07-14 08:39:38 +01001329 else if (strcasecmp (argv [1], "pwmTone" ) == 0) doPwmTone (argc, argv) ;
Gordon Henderson27698762013-06-27 21:51:55 +01001330 else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
Gordon Hendersondf453882014-07-17 22:23:57 +01001331 else if (strcasecmp (argv [1], "usbp" ) == 0) doUsbP (argc, argv) ;
1332 else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
Gordon Henderson8c8578a2013-07-23 09:19:34 +01001333 else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ;
Gordon Henderson05e2f672014-05-20 11:43:07 +01001334 else if (strcasecmp (argv [1], "pins" ) == 0) doPins () ;
Gordon Henderson27698762013-06-27 21:51:55 +01001335 else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
1336 else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ;
1337 else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
1338 else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
1339 else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
1340 else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001341 else
1342 {
Gordon Henderson178ea082012-08-19 15:17:03 +01001343 fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
Gordon Hendersonda384432013-05-13 19:43:26 +01001344 exit (EXIT_FAILURE) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001345 }
1346 return 0 ;
1347}