blob: 6dc6113af67794ee2adc362d0a4796fe7d860f02 [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
Gordon Henderson72b2af22015-02-03 14:53:32 +0000437 /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100438 fprintf (fd, "in\n") ;
Gordon Henderson72b2af22015-02-03 14:53:32 +0000439 else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100440 fprintf (fd, "out\n") ;
Gordon Henderson72b2af22015-02-03 14:53:32 +0000441 else if ((strcasecmp (mode, "high") == 0) || (strcasecmp (mode, "up") == 0))
442 fprintf (fd, "high\n") ;
443 else if ((strcasecmp (mode, "low") == 0) || (strcasecmp (mode, "down") == 0))
444 fprintf (fd, "low\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100445 else
446 {
Gordon Henderson72b2af22015-02-03 14:53:32 +0000447 fprintf (stderr, "%s: Invalid mode: %s. Should be in, out, high or low\n", argv [1], mode) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100448 exit (1) ;
449 }
450
451 fclose (fd) ;
452
Gordon Henderson72b2af22015-02-03 14:53:32 +0000453// Change ownership so the current user can actually use it
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100454
455 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
456 changeOwner (argv [0], fName) ;
457
458 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
459 changeOwner (argv [0], fName) ;
460
461}
462
463
464/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100465 * doWfi:
466 * gpio wfi pin mode
467 * Wait for Interrupt on a given pin.
468 * Slight cheat here - it's easier to actually use ISR now (which calls
469 * gpio to set the pin modes!) then we simply sleep, and expect the thread
470 * to exit the program. Crude but effective.
471 *********************************************************************************
472 */
473
474static void wfi (void)
475 { exit (0) ; }
476
477void doWfi (int argc, char *argv [])
478{
479 int pin, mode ;
480
481 if (argc != 4)
482 {
483 fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ;
484 exit (1) ;
485 }
486
487 pin = atoi (argv [2]) ;
488
489 /**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ;
490 else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
491 else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ;
492 else
493 {
494 fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ;
495 exit (1) ;
496 }
497
498 if (wiringPiISR (pin, mode, &wfi) < 0)
499 {
500 fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
501 exit (1) ;
502 }
503
504 for (;;)
505 delay (9999) ;
506}
507
508
509
510/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100511 * doEdge:
512 * gpio edge pin mode
513 * Easy access to changing the edge trigger on a GPIO pin
514 * This uses the /sys/class/gpio device interface.
515 *********************************************************************************
516 */
517
518void doEdge (int argc, char *argv [])
519{
520 FILE *fd ;
521 int pin ;
522 char *mode ;
523 char fName [128] ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100524
525 if (argc != 4)
526 {
527 fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
528 exit (1) ;
529 }
530
Gordon Henderson178ea082012-08-19 15:17:03 +0100531 pin = atoi (argv [2]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100532 mode = argv [3] ;
533
534// Export the pin and set direction to input
535
536 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
537 {
538 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
539 exit (1) ;
540 }
541
542 fprintf (fd, "%d\n", pin) ;
543 fclose (fd) ;
544
545 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
546 if ((fd = fopen (fName, "w")) == NULL)
547 {
548 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
549 exit (1) ;
550 }
551
552 fprintf (fd, "in\n") ;
553 fclose (fd) ;
554
555 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
556 if ((fd = fopen (fName, "w")) == NULL)
557 {
558 fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
559 exit (1) ;
560 }
561
Gordon Henderson178ea082012-08-19 15:17:03 +0100562 /**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
563 else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
564 else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
565 else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100566 else
567 {
568 fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
569 exit (1) ;
570 }
571
Gordon Henderson178ea082012-08-19 15:17:03 +0100572// Change ownership of the value and edge files, so the current user can actually use it!
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100573
574 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100575 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100576
577 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100578 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100579
580 fclose (fd) ;
581}
582
583
584/*
585 * doUnexport:
586 * gpio unexport pin
587 * This uses the /sys/class/gpio device interface.
588 *********************************************************************************
589 */
590
591void doUnexport (int argc, char *argv [])
592{
593 FILE *fd ;
594 int pin ;
595
596 if (argc != 3)
597 {
598 fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
599 exit (1) ;
600 }
601
602 pin = atoi (argv [2]) ;
603
604 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
605 {
606 fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
607 exit (1) ;
608 }
609
610 fprintf (fd, "%d\n", pin) ;
611 fclose (fd) ;
612}
613
614
615/*
616 * doUnexportAll:
617 * gpio unexportall
618 * Un-Export all the GPIO pins.
619 * This uses the /sys/class/gpio device interface.
620 *********************************************************************************
621 */
622
Gordon Hendersonda384432013-05-13 19:43:26 +0100623void doUnexportall (char *progName)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100624{
625 FILE *fd ;
626 int pin ;
627
628 for (pin = 0 ; pin < 63 ; ++pin)
629 {
630 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
631 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100632 fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100633 exit (1) ;
634 }
635 fprintf (fd, "%d\n", pin) ;
636 fclose (fd) ;
637 }
638}
639
640
641/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100642 * doReset:
643 * Reset the GPIO pins - as much as we can do
644 *********************************************************************************
645 */
646
647static void doReset (char *progName)
648{
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +0000649 printf ("GPIO Reset is dangerous and has been removed from the gpio command.\n") ;
650 printf (" - Please write a shell-script to reset the GPIO pins into the state\n") ;
651 printf (" that you need them in for your applications.\n") ;
Gordon Hendersonda384432013-05-13 19:43:26 +0100652}
653
654
655/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100656 * doMode:
657 * gpio mode pin mode ...
658 *********************************************************************************
659 */
660
661void doMode (int argc, char *argv [])
662{
663 int pin ;
664 char *mode ;
665
666 if (argc != 4)
667 {
668 fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
669 exit (1) ;
670 }
671
672 pin = atoi (argv [2]) ;
673
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100674 mode = argv [3] ;
675
Gordon Hendersondca8a192014-07-14 08:39:38 +0100676 /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
677 else if (strcasecmp (mode, "input") == 0) pinMode (pin, INPUT) ;
678 else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
679 else if (strcasecmp (mode, "output") == 0) pinMode (pin, OUTPUT) ;
680 else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
681 else if (strcasecmp (mode, "pwmTone") == 0) pinMode (pin, PWM_TONE_OUTPUT) ;
682 else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ;
683 else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
684 else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
685 else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
686 else if (strcasecmp (mode, "off") == 0) pullUpDnControl (pin, PUD_OFF) ;
Gordon Hendersonf18c8f72013-08-03 23:53:35 +0100687 else if (strcasecmp (mode, "alt0") == 0) pinModeAlt (pin, 0b100) ;
688 else if (strcasecmp (mode, "alt1") == 0) pinModeAlt (pin, 0b101) ;
689 else if (strcasecmp (mode, "alt2") == 0) pinModeAlt (pin, 0b110) ;
690 else if (strcasecmp (mode, "alt3") == 0) pinModeAlt (pin, 0b111) ;
691 else if (strcasecmp (mode, "alt4") == 0) pinModeAlt (pin, 0b011) ;
692 else if (strcasecmp (mode, "alt5") == 0) pinModeAlt (pin, 0b010) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100693 else
694 {
Gordon Henderson56c77b52013-02-01 20:19:22 +0000695 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 +0100696 exit (1) ;
697 }
698}
699
700
701/*
702 * doPadDrive:
703 * gpio drive group value
704 *********************************************************************************
705 */
706
Gordon Henderson1bb49892012-08-19 15:33:26 +0100707static void doPadDrive (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100708{
709 int group, val ;
710
711 if (argc != 4)
712 {
713 fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
714 exit (1) ;
715 }
716
717 group = atoi (argv [2]) ;
718 val = atoi (argv [3]) ;
719
720 if ((group < 0) || (group > 2))
721 {
722 fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
723 exit (1) ;
724 }
725
726 if ((val < 0) || (val > 7))
727 {
728 fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
729 exit (1) ;
730 }
731
732 setPadDrive (group, val) ;
733}
734
735
736/*
Gordon Hendersondf453882014-07-17 22:23:57 +0100737 * doUsbP:
738 * Control USB Power - High (1.2A) or Low (600mA)
739 * gpio usbp high/low
740 *********************************************************************************
741 */
742
743static void doUsbP (int argc, char *argv [])
744{
745 int model, rev, mem, maker, overVolted ;
746
747 if (argc != 3)
748 {
749 fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
750 exit (1) ;
751 }
752
753// Make sure we're on a B+
754
755 piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
756
757 if (model != PI_MODEL_BP)
758 {
759 fprintf (stderr, "USB power contol is applicable to B+ boards only.\n") ;
760 exit (1) ;
761 }
762
763// Need to force BCM_GPIO mode:
764
765 wiringPiSetupGpio () ;
766
767 if ((strcasecmp (argv [2], "high") == 0) || (strcasecmp (argv [2], "hi") == 0))
768 {
769 digitalWrite (PI_USB_POWER_CONTROL, 1) ;
770 pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
771 printf ("Switched to HIGH current USB (1.2A)\n") ;
772 return ;
773 }
774
775 if ((strcasecmp (argv [2], "low") == 0) || (strcasecmp (argv [2], "lo") == 0))
776 {
777 digitalWrite (PI_USB_POWER_CONTROL, 0) ;
778 pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
779 printf ("Switched to LOW current USB (600mA)\n") ;
780 return ;
781 }
782
783 fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
784 exit (1) ;
785}
786
787
788/*
Gordon Henderson99095e32012-08-27 20:56:14 +0100789 * doGbw:
790 * gpio gbw channel value
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000791 * Gertboard Write - To the Analog output
Gordon Henderson99095e32012-08-27 20:56:14 +0100792 *********************************************************************************
793 */
794
795static void doGbw (int argc, char *argv [])
796{
797 int channel, value ;
798
799 if (argc != 4)
800 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100801 fprintf (stderr, "Usage: %s gbw <channel> <value>\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100802 exit (1) ;
803 }
804
805 channel = atoi (argv [2]) ;
806 value = atoi (argv [3]) ;
807
808 if ((channel < 0) || (channel > 1))
809 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100810 fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100811 exit (1) ;
812 }
813
Gordon Hendersondca8a192014-07-14 08:39:38 +0100814 if ((value < 0) || (value > 255))
Gordon Henderson99095e32012-08-27 20:56:14 +0100815 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100816 fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100817 exit (1) ;
818 }
819
Gordon Hendersonda384432013-05-13 19:43:26 +0100820 if (gertboardAnalogSetup (64) < 0)
Gordon Henderson99095e32012-08-27 20:56:14 +0100821 {
822 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
823 exit (1) ;
824 }
825
Gordon Hendersonda384432013-05-13 19:43:26 +0100826 analogWrite (64 + channel, value) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100827}
828
829
830/*
831 * doGbr:
832 * gpio gbr channel
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000833 * From the analog input
Gordon Henderson99095e32012-08-27 20:56:14 +0100834 *********************************************************************************
835 */
836
837static void doGbr (int argc, char *argv [])
838{
839 int channel ;
840
841 if (argc != 3)
842 {
843 fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
844 exit (1) ;
845 }
846
847 channel = atoi (argv [2]) ;
848
849 if ((channel < 0) || (channel > 1))
850 {
Gordon Hendersonda384432013-05-13 19:43:26 +0100851 fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100852 exit (1) ;
853 }
854
Gordon Hendersonda384432013-05-13 19:43:26 +0100855 if (gertboardAnalogSetup (64) < 0)
Gordon Henderson99095e32012-08-27 20:56:14 +0100856 {
857 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
858 exit (1) ;
859 }
860
Gordon Hendersonda384432013-05-13 19:43:26 +0100861 printf ("%d\n", analogRead (64 + channel)) ;
Gordon Henderson99095e32012-08-27 20:56:14 +0100862}
863
864
Gordon Henderson99095e32012-08-27 20:56:14 +0100865/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100866 * doWrite:
867 * gpio write pin value
868 *********************************************************************************
869 */
870
Gordon Henderson1bb49892012-08-19 15:33:26 +0100871static void doWrite (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100872{
873 int pin, val ;
874
875 if (argc != 4)
876 {
877 fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
878 exit (1) ;
879 }
880
881 pin = atoi (argv [2]) ;
882
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000883 /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
884 val = 1 ;
885 else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
886 val = 0 ;
887 else
888 val = atoi (argv [3]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100889
890 /**/ if (val == 0)
891 digitalWrite (pin, LOW) ;
892 else
893 digitalWrite (pin, HIGH) ;
894}
895
Gordon Hendersonda384432013-05-13 19:43:26 +0100896
897/*
898 * doAwriterite:
899 * gpio awrite pin value
900 *********************************************************************************
901 */
902
903static void doAwrite (int argc, char *argv [])
904{
905 int pin, val ;
906
907 if (argc != 4)
908 {
909 fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
910 exit (1) ;
911 }
912
913 pin = atoi (argv [2]) ;
914
915 val = atoi (argv [3]) ;
916
917 analogWrite (pin, val) ;
918}
919
920
Gordon Henderson25e4ec52012-12-06 21:49:41 +0000921/*
922 * doWriteByte:
923 * gpio write value
924 *********************************************************************************
925 */
926
927static void doWriteByte (int argc, char *argv [])
928{
929 int val ;
930
931 if (argc != 3)
932 {
933 fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
934 exit (1) ;
935 }
936
937 val = (int)strtol (argv [2], NULL, 0) ;
938
939 digitalWriteByte (val) ;
940}
941
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100942
943/*
944 * doRead:
945 * Read a pin and return the value
946 *********************************************************************************
947 */
948
949void doRead (int argc, char *argv [])
950{
951 int pin, val ;
952
953 if (argc != 3)
954 {
955 fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
956 exit (1) ;
957 }
958
959 pin = atoi (argv [2]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100960 val = digitalRead (pin) ;
961
962 printf ("%s\n", val == 0 ? "0" : "1") ;
963}
964
965
966/*
Gordon Hendersonda384432013-05-13 19:43:26 +0100967 * doAread:
968 * Read an analog pin and return the value
969 *********************************************************************************
970 */
971
972void doAread (int argc, char *argv [])
973{
Gordon Hendersonda384432013-05-13 19:43:26 +0100974 if (argc != 3)
975 {
976 fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
977 exit (1) ;
978 }
979
Gordon Hendersonbfaf2662013-05-20 21:13:44 +0100980 printf ("%d\n", analogRead (atoi (argv [2]))) ;
Gordon Hendersonda384432013-05-13 19:43:26 +0100981}
982
983
984/*
985 * doToggle:
986 * Toggle an IO pin
987 *********************************************************************************
988 */
989
990void doToggle (int argc, char *argv [])
991{
992 int pin ;
993
994 if (argc != 3)
995 {
996 fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
997 exit (1) ;
998 }
999
1000 pin = atoi (argv [2]) ;
1001
1002 digitalWrite (pin, !digitalRead (pin)) ;
1003}
1004
Gordon Hendersondca8a192014-07-14 08:39:38 +01001005
1006/*
1007 * doPwmTone:
1008 * Output a tone in a PWM pin
1009 *********************************************************************************
1010 */
1011
1012void doPwmTone (int argc, char *argv [])
1013{
1014 int pin, freq ;
1015
1016 if (argc != 4)
1017 {
1018 fprintf (stderr, "Usage: %s pwmTone <pin> <freq>\n", argv [0]) ;
1019 exit (1) ;
1020 }
1021
1022 pin = atoi (argv [2]) ;
1023 freq = atoi (argv [3]) ;
1024
1025 pwmToneWrite (pin, freq) ;
1026}
1027
1028
Gordon Hendersonda384432013-05-13 19:43:26 +01001029/*
Gordon Henderson56c77b52013-02-01 20:19:22 +00001030 * doClock:
1031 * Output a clock on a pin
1032 *********************************************************************************
1033 */
1034
1035void doClock (int argc, char *argv [])
1036{
1037 int pin, freq ;
1038
1039 if (argc != 4)
1040 {
1041 fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
1042 exit (1) ;
1043 }
1044
1045 pin = atoi (argv [2]) ;
1046
Gordon Henderson56c77b52013-02-01 20:19:22 +00001047 freq = atoi (argv [3]) ;
1048
1049 gpioClockSet (pin, freq) ;
1050}
1051
1052
1053/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001054 * doPwm:
1055 * Output a PWM value on a pin
1056 *********************************************************************************
1057 */
1058
1059void doPwm (int argc, char *argv [])
1060{
1061 int pin, val ;
1062
1063 if (argc != 4)
1064 {
1065 fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
1066 exit (1) ;
1067 }
1068
1069 pin = atoi (argv [2]) ;
1070
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001071 val = atoi (argv [3]) ;
1072
1073 pwmWrite (pin, val) ;
1074}
1075
1076
1077/*
Gordon Henderson8cb49392012-09-16 10:15:32 +01001078 * doPwmMode: doPwmRange: doPwmClock:
1079 * Change the PWM mode, range and clock divider values
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001080 *********************************************************************************
1081 */
1082
1083static void doPwmMode (int mode)
1084{
1085 pwmSetMode (mode) ;
1086}
1087
1088static void doPwmRange (int argc, char *argv [])
1089{
1090 unsigned int range ;
1091
1092 if (argc != 3)
1093 {
1094 fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
1095 exit (1) ;
1096 }
1097
1098 range = (unsigned int)strtoul (argv [2], NULL, 10) ;
1099
1100 if (range == 0)
1101 {
1102 fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
1103 exit (1) ;
1104 }
1105
1106 pwmSetRange (range) ;
1107}
1108
Gordon Henderson8cb49392012-09-16 10:15:32 +01001109static void doPwmClock (int argc, char *argv [])
1110{
1111 unsigned int clock ;
1112
1113 if (argc != 3)
1114 {
1115 fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
1116 exit (1) ;
1117 }
1118
1119 clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
1120
1121 if ((clock < 1) || (clock > 4095))
1122 {
1123 fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
1124 exit (1) ;
1125 }
1126
1127 pwmSetClock (clock) ;
1128}
1129
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001130
1131/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001132 * main:
1133 * Start here
1134 *********************************************************************************
1135 */
1136
1137int main (int argc, char *argv [])
1138{
1139 int i ;
Gordon Hendersondf453882014-07-17 22:23:57 +01001140 int model, rev, mem, maker, overVolted ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001141
Gordon Henderson13bbba72013-01-14 11:31:56 +00001142 if (getenv ("WIRINGPI_DEBUG") != NULL)
1143 {
1144 printf ("gpio: wiringPi debug mode enabled\n") ;
1145 wiringPiDebug = TRUE ;
1146 }
1147
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001148 if (argc == 1)
1149 {
Gordon Henderson86a5c682012-10-02 14:32:12 +01001150 fprintf (stderr, "%s\n", usage) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001151 return 1 ;
1152 }
1153
Gordon Hendersonda384432013-05-13 19:43:26 +01001154// Help
1155
Gordon Henderson178ea082012-08-19 15:17:03 +01001156 if (strcasecmp (argv [1], "-h") == 0)
1157 {
1158 printf ("%s: %s\n", argv [0], usage) ;
1159 return 0 ;
1160 }
1161
Gordon Hendersonda384432013-05-13 19:43:26 +01001162// Sort of a special:
1163
1164 if (strcmp (argv [1], "-R") == 0)
1165 {
1166 printf ("%d\n", piBoardRev ()) ;
1167 return 0 ;
1168 }
1169
1170// Version & Warranty
1171
1172 if (strcmp (argv [1], "-V") == 0)
1173 {
1174 printf ("%d\n", piBoardRev ()) ;
1175 return 0 ;
1176 }
1177
1178 if (strcmp (argv [1], "-v") == 0)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001179 {
1180 printf ("gpio version: %s\n", VERSION) ;
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +00001181 printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001182 printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
1183 printf ("For details type: %s -warranty\n", argv [0]) ;
Gordon Henderson86a5c682012-10-02 14:32:12 +01001184 printf ("\n") ;
Gordon Hendersondf453882014-07-17 22:23:57 +01001185 piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
1186 if (model == PI_MODEL_UNKNOWN)
1187 {
1188 printf ("Your Raspberry Pi has an unknown model type. Please report this to\n") ;
1189 printf (" projects@drogon.net\n") ;
1190 printf ("with a copy of your /proc/cpuinfo if possible\n") ;
1191 }
1192 else
1193 {
1194 printf ("Raspberry Pi Details:\n") ;
1195 printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n",
1196 piModelNames [model], piRevisionNames [rev], mem, piMakerNames [maker], overVolted ? "[OV]" : "") ;
1197 }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001198 return 0 ;
1199 }
1200
1201 if (strcasecmp (argv [1], "-warranty") == 0)
1202 {
1203 printf ("gpio version: %s\n", VERSION) ;
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +00001204 printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001205 printf ("\n") ;
1206 printf (" This program is free software; you can redistribute it and/or modify\n") ;
1207 printf (" it under the terms of the GNU Leser General Public License as published\n") ;
1208 printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
1209 printf (" (at your option) any later version.\n") ;
1210 printf ("\n") ;
1211 printf (" This program is distributed in the hope that it will be useful,\n") ;
1212 printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
1213 printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
1214 printf (" GNU Lesser General Public License for more details.\n") ;
1215 printf ("\n") ;
1216 printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
1217 printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
1218 printf ("\n") ;
1219 return 0 ;
1220 }
1221
1222 if (geteuid () != 0)
1223 {
1224 fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
1225 return 1 ;
1226 }
1227
1228// Initial test for /sys/class/gpio operations:
1229
Gordon Henderson178ea082012-08-19 15:17:03 +01001230 /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
1231 else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
1232 else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
Gordon Henderson178ea082012-08-19 15:17:03 +01001233 else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
Gordon Hendersonda384432013-05-13 19:43:26 +01001234 else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; }
Gordon Henderson178ea082012-08-19 15:17:03 +01001235
Gordon Henderson86a5c682012-10-02 14:32:12 +01001236// Check for load command:
Gordon Henderson178ea082012-08-19 15:17:03 +01001237
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +00001238 if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
1239 if (strcasecmp (argv [1], "unload" ) == 0) { doUnLoad (argc, argv) ; return 0 ; }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001240
Gordon Henderson99095e32012-08-27 20:56:14 +01001241// Gertboard commands
1242
1243 if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
1244 if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
1245
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001246// Check for -g argument
1247
Gordon Hendersonda384432013-05-13 19:43:26 +01001248 /**/ if (strcasecmp (argv [1], "-g") == 0)
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001249 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001250 wiringPiSetupGpio () ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001251
1252 for (i = 2 ; i < argc ; ++i)
1253 argv [i - 1] = argv [i] ;
1254 --argc ;
1255 wpMode = WPI_MODE_GPIO ;
1256 }
1257
Gordon Hendersonda384432013-05-13 19:43:26 +01001258// Check for -1 argument
1259
1260 else if (strcasecmp (argv [1], "-1") == 0)
1261 {
1262 wiringPiSetupPhys () ;
1263
1264 for (i = 2 ; i < argc ; ++i)
1265 argv [i - 1] = argv [i] ;
1266 --argc ;
1267 wpMode = WPI_MODE_PHYS ;
1268 }
1269
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001270// Check for -p argument for PiFace
1271
1272 else if (strcasecmp (argv [1], "-p") == 0)
1273 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001274 piFaceSetup (200) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001275
1276 for (i = 2 ; i < argc ; ++i)
1277 argv [i - 1] = argv [i] ;
1278 --argc ;
1279 wpMode = WPI_MODE_PIFACE ;
1280 }
1281
1282// Default to wiringPi mode
1283
1284 else
1285 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001286 wiringPiSetup () ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001287 wpMode = WPI_MODE_PINS ;
1288 }
1289
Gordon Hendersonda384432013-05-13 19:43:26 +01001290// Check for -x argument to load in a new extension
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001291
Gordon Hendersonda384432013-05-13 19:43:26 +01001292 if (strcasecmp (argv [1], "-x") == 0)
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001293 {
Gordon Hendersonda384432013-05-13 19:43:26 +01001294 if (argc < 3)
1295 {
1296 fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ;
1297 exit (EXIT_FAILURE) ;
1298 }
1299
Gordon Hendersoneb1fc2c2015-01-30 18:14:49 +00001300 if (!loadWPiExtension (argv [0], argv [2], TRUE)) // Prints its own error messages
Gordon Hendersonda384432013-05-13 19:43:26 +01001301 exit (EXIT_FAILURE) ;
1302
1303 for (i = 3 ; i < argc ; ++i)
1304 argv [i - 2] = argv [i] ;
1305 argc -= 2 ;
Gordon Hendersonf99ffed2012-08-19 15:12:45 +01001306 }
1307
Gordon Hendersonda384432013-05-13 19:43:26 +01001308 if (argc <= 1)
1309 {
1310 fprintf (stderr, "%s: no command given\n", argv [0]) ;
1311 exit (EXIT_FAILURE) ;
1312 }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001313
Gordon Hendersonda384432013-05-13 19:43:26 +01001314// Core wiringPi functions
1315
1316 /**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
1317 else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
1318 else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ;
1319 else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
1320 else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite (argc, argv) ;
1321 else if (strcasecmp (argv [1], "aread" ) == 0) doAread (argc, argv) ;
1322
1323// GPIO Nicies
1324
1325 else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ;
1326
1327// Pi Specifics
1328
Gordon Henderson27698762013-06-27 21:51:55 +01001329 else if (strcasecmp (argv [1], "pwm-bal" ) == 0) doPwmMode (PWM_MODE_BAL) ;
1330 else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ;
1331 else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ;
1332 else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ;
Gordon Hendersondca8a192014-07-14 08:39:38 +01001333 else if (strcasecmp (argv [1], "pwmTone" ) == 0) doPwmTone (argc, argv) ;
Gordon Henderson27698762013-06-27 21:51:55 +01001334 else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
Gordon Hendersondf453882014-07-17 22:23:57 +01001335 else if (strcasecmp (argv [1], "usbp" ) == 0) doUsbP (argc, argv) ;
1336 else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
Gordon Henderson8c8578a2013-07-23 09:19:34 +01001337 else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ;
Gordon Henderson05e2f672014-05-20 11:43:07 +01001338 else if (strcasecmp (argv [1], "pins" ) == 0) doPins () ;
Gordon Henderson27698762013-06-27 21:51:55 +01001339 else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
1340 else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ;
1341 else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
1342 else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
1343 else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
1344 else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001345 else
1346 {
Gordon Henderson178ea082012-08-19 15:17:03 +01001347 fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
Gordon Hendersonda384432013-05-13 19:43:26 +01001348 exit (EXIT_FAILURE) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +01001349 }
1350 return 0 ;
1351}