blob: f019c1ff9765166793c06ec6618a3d5fb63222e2 [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 Hendersonbf0ad862012-08-16 15:04:43 +01005 * Copyright (c) 2012 Gordon Henderson
6 ***********************************************************************
7 * This file is part of wiringPi:
8 * https://projects.drogon.net/raspberry-pi/wiringpi/
9 *
10 * wiringPi is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * wiringPi is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
22 ***********************************************************************
23 */
24
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010025
26#include <stdio.h>
27#include <stdlib.h>
28#include <stdint.h>
29#include <string.h>
30#include <unistd.h>
31#include <errno.h>
32#include <sys/types.h>
33#include <fcntl.h>
34
Gordon Henderson99095e32012-08-27 20:56:14 +010035#include <wiringPi.h>
36#include <gertboard.h>
37
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010038#ifndef TRUE
39# define TRUE (1==1)
40# define FALSE (1==2)
41#endif
42
Gordon Henderson183c5a62012-10-21 15:25:16 +010043#define VERSION "1.4"
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010044
45static int wpMode ;
46
47char *usage = "Usage: gpio -v\n"
Gordon Henderson178ea082012-08-19 15:17:03 +010048 " gpio -h\n"
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010049 " gpio [-g] <read/write/pwm/mode> ...\n"
50 " gpio [-p] <read/write/mode> ...\n"
Gordon Henderson183c5a62012-10-21 15:25:16 +010051 " gpio readall\n"
52 " gpio unexportall/exports ...\n"
53 " gpio export/edge/unexport ...\n"
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010054 " gpio drive <group> <value>\n"
Gordon Hendersonf99ffed2012-08-19 15:12:45 +010055 " gpio pwm-bal/pwm-ms \n"
56 " gpio pwmr <range> \n"
Gordon Henderson8cb49392012-09-16 10:15:32 +010057 " gpio pwmc <divider> \n"
Gordon Henderson99095e32012-08-27 20:56:14 +010058 " gpio load spi/i2c\n"
59 " gpio gbr <channel>\n"
Gordon Henderson8cb49392012-09-16 10:15:32 +010060 " gpio gbw <channel> <value>" ; // No trailing newline needed here.
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010061
62
Gordon Hendersonbf0ad862012-08-16 15:04:43 +010063/*
64 * changeOwner:
65 * Change the ownership of the file to the real userId of the calling
66 * program so we can access it.
67 *********************************************************************************
68 */
69
70static void changeOwner (char *cmd, char *file)
71{
72 uid_t uid = getuid () ;
73 uid_t gid = getgid () ;
74
75 if (chown (file, uid, gid) != 0)
76 {
77 if (errno == ENOENT) // Warn that it's not there
78 fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ;
79 else
80 {
81 fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
82 exit (1) ;
83 }
84 }
85}
86
87
88/*
89 * moduleLoaded:
90 * Return true/false if the supplied module is loaded
91 *********************************************************************************
92 */
93
94static int moduleLoaded (char *modName)
95{
96 int len = strlen (modName) ;
97 int found = FALSE ;
98 FILE *fd = fopen ("/proc/modules", "r") ;
99 char line [80] ;
100
101 if (fd == NULL)
102 {
103 fprintf (stderr, "gpio: Unable to check modules: %s\n", strerror (errno)) ;
104 exit (1) ;
105 }
106
107 while (fgets (line, 80, fd) != NULL)
108 {
109 if (strncmp (line, modName, len) != 0)
110 continue ;
111
112 found = TRUE ;
113 break ;
114 }
115
116 fclose (fd) ;
117
118 return found ;
119}
120
121
122/*
123 * doLoad:
124 * Load either the spi or i2c modules and change device ownerships, etc.
125 *********************************************************************************
126 */
127
128static void _doLoadUsage (char *argv [])
129{
130 fprintf (stderr, "Usage: %s load <spi/i2c>\n", argv [0]) ;
131 exit (1) ;
132}
133
134static void doLoad (int argc, char *argv [])
135{
136 char *module ;
137 char cmd [80] ;
138 char *file1, *file2 ;
139
140 if (argc != 3)
141 _doLoadUsage (argv) ;
142
143 /**/ if (strcasecmp (argv [2], "spi") == 0)
144 {
145 module = "spi_bcm2708" ;
146 file1 = "/dev/spidev0.0" ;
147 file2 = "/dev/spidev0.1" ;
148 }
149 else if (strcasecmp (argv [2], "i2c") == 0)
150 {
151 module = "i2c_bcm2708" ;
152 file1 = "/dev/i2c-0" ;
153 file2 = "/dev/i2c-1" ;
154 }
155 else
156 _doLoadUsage (argv) ;
157
158 if (!moduleLoaded (module))
159 {
160 sprintf (cmd, "modprobe %s", module) ;
161 system (cmd) ;
162 }
163
164 if (!moduleLoaded (module))
165 {
166 fprintf (stderr, "%s: Unable to load %s\n", argv [0], module) ;
167 exit (1) ;
168 }
169
170 sleep (1) ; // To let things get settled
171
172 changeOwner (argv [0], file1) ;
173 changeOwner (argv [0], file2) ;
174}
175
176
Gordon Henderson183c5a62012-10-21 15:25:16 +0100177/*
178 * doReadall:
179 * Read all the GPIO pins
180 *********************************************************************************
181 */
182
183static char *pinNames [] =
184{
185 "GPIO 0",
186 "GPIO 1",
187 "GPIO 2",
188 "GPIO 3",
189 "GPIO 4",
190 "GPIO 5",
191 "GPIO 6",
192 "GPIO 7",
193 "SDA ",
194 "SCL ",
195 "CE0 ",
196 "CE1 ",
197 "MOSI ",
198 "MISO ",
199 "SCLK ",
200 "TxD ",
201 "RxD ",
202 "GPIO 8",
203 "GPIO 9",
204 "GPIO10",
205 "GPIO11",
206} ;
207
208static void doReadall (void)
209{
210 int pin ;
211
212 printf ("+----------+------+--------+-------+\n") ;
213 printf ("| wiringPi | GPIO | Name | Value |\n") ;
214 printf ("+----------+------+--------+-------+\n") ;
215
216 for (pin = 0 ; pin < NUM_PINS ; ++pin)
217 printf ("| %6d | %3d | %s | %s |\n",
218 pin, wpiPinToGpio (pin),
219 pinNames [pin],
220 digitalRead (pin) == HIGH ? "High" : "Low ") ;
221
222 printf ("+----------+------+--------+-------+\n") ;
223
224 if (piBoardRev () == 1)
225 return ;
226
227 for (pin = 17 ; pin <= 20 ; ++pin)
228 printf ("| %6d | %3d | %s | %s |\n",
229 pin, wpiPinToGpio (pin),
230 pinNames [pin],
231 digitalRead (pin) == HIGH ? "High" : "Low ") ;
232
233 printf ("+----------+------+--------+-------+\n") ;
234}
235
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100236
237/*
238 * doExports:
239 * List all GPIO exports
240 *********************************************************************************
241 */
242
Gordon Henderson178ea082012-08-19 15:17:03 +0100243static void doExports (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100244{
245 int fd ;
246 int i, l, first ;
247 char fName [128] ;
248 char buf [16] ;
249
250// Rather crude, but who knows what others are up to...
251
252 for (first = 0, i = 0 ; i < 64 ; ++i)
253 {
254
255// Try to read the direction
256
257 sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
258 if ((fd = open (fName, O_RDONLY)) == -1)
259 continue ;
260
261 if (first == 0)
262 {
263 ++first ;
264 printf ("GPIO Pins exported:\n") ;
265 }
266
267 printf ("%4d: ", i) ;
268
269 if ((l = read (fd, buf, 16)) == 0)
270 sprintf (buf, "%s", "?") ;
271
272 buf [l] = 0 ;
273 if ((buf [strlen (buf) - 1]) == '\n')
274 buf [strlen (buf) - 1] = 0 ;
275
276 printf ("%-3s", buf) ;
277
278 close (fd) ;
279
280// Try to Read the value
281
282 sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
283 if ((fd = open (fName, O_RDONLY)) == -1)
284 {
285 printf ("No Value file (huh?)\n") ;
286 continue ;
287 }
288
289 if ((l = read (fd, buf, 16)) == 0)
290 sprintf (buf, "%s", "?") ;
291
292 buf [l] = 0 ;
293 if ((buf [strlen (buf) - 1]) == '\n')
294 buf [strlen (buf) - 1] = 0 ;
295
296 printf (" %s", buf) ;
297
298// Read any edge trigger file
299
300 sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ;
301 if ((fd = open (fName, O_RDONLY)) == -1)
302 {
303 printf ("\n") ;
304 continue ;
305 }
306
307 if ((l = read (fd, buf, 16)) == 0)
308 sprintf (buf, "%s", "?") ;
309
310 buf [l] = 0 ;
311 if ((buf [strlen (buf) - 1]) == '\n')
312 buf [strlen (buf) - 1] = 0 ;
313
314 printf (" %-8s\n", buf) ;
315
316 close (fd) ;
317 }
318}
319
320
321/*
322 * doExport:
323 * gpio export pin mode
324 * This uses the /sys/class/gpio device interface.
325 *********************************************************************************
326 */
327
328void doExport (int argc, char *argv [])
329{
330 FILE *fd ;
331 int pin ;
332 char *mode ;
333 char fName [128] ;
334
335 if (argc != 4)
336 {
337 fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
338 exit (1) ;
339 }
340
341 pin = atoi (argv [2]) ;
342
343 mode = argv [3] ;
344
345 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
346 {
347 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
348 exit (1) ;
349 }
350
351 fprintf (fd, "%d\n", pin) ;
352 fclose (fd) ;
353
354 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
355 if ((fd = fopen (fName, "w")) == NULL)
356 {
357 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
358 exit (1) ;
359 }
360
361 /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
362 fprintf (fd, "in\n") ;
363 else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
364 fprintf (fd, "out\n") ;
365 else
366 {
367 fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ;
368 exit (1) ;
369 }
370
371 fclose (fd) ;
372
373// Change ownership so the current user can actually use it!
374
375 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
376 changeOwner (argv [0], fName) ;
377
378 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
379 changeOwner (argv [0], fName) ;
380
381}
382
383
384/*
385 * doEdge:
386 * gpio edge pin mode
387 * Easy access to changing the edge trigger on a GPIO pin
388 * This uses the /sys/class/gpio device interface.
389 *********************************************************************************
390 */
391
392void doEdge (int argc, char *argv [])
393{
394 FILE *fd ;
395 int pin ;
396 char *mode ;
397 char fName [128] ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100398
399 if (argc != 4)
400 {
401 fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
402 exit (1) ;
403 }
404
Gordon Henderson178ea082012-08-19 15:17:03 +0100405 pin = atoi (argv [2]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100406 mode = argv [3] ;
407
408// Export the pin and set direction to input
409
410 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
411 {
412 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
413 exit (1) ;
414 }
415
416 fprintf (fd, "%d\n", pin) ;
417 fclose (fd) ;
418
419 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
420 if ((fd = fopen (fName, "w")) == NULL)
421 {
422 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
423 exit (1) ;
424 }
425
426 fprintf (fd, "in\n") ;
427 fclose (fd) ;
428
429 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
430 if ((fd = fopen (fName, "w")) == NULL)
431 {
432 fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
433 exit (1) ;
434 }
435
Gordon Henderson178ea082012-08-19 15:17:03 +0100436 /**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
437 else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
438 else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
439 else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100440 else
441 {
442 fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
443 exit (1) ;
444 }
445
Gordon Henderson178ea082012-08-19 15:17:03 +0100446// Change ownership of the value and edge files, so the current user can actually use it!
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100447
448 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100449 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100450
451 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
Gordon Henderson178ea082012-08-19 15:17:03 +0100452 changeOwner (argv [0], fName) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100453
454 fclose (fd) ;
455}
456
457
458/*
459 * doUnexport:
460 * gpio unexport pin
461 * This uses the /sys/class/gpio device interface.
462 *********************************************************************************
463 */
464
465void doUnexport (int argc, char *argv [])
466{
467 FILE *fd ;
468 int pin ;
469
470 if (argc != 3)
471 {
472 fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
473 exit (1) ;
474 }
475
476 pin = atoi (argv [2]) ;
477
478 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
479 {
480 fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
481 exit (1) ;
482 }
483
484 fprintf (fd, "%d\n", pin) ;
485 fclose (fd) ;
486}
487
488
489/*
490 * doUnexportAll:
491 * gpio unexportall
492 * Un-Export all the GPIO pins.
493 * This uses the /sys/class/gpio device interface.
494 *********************************************************************************
495 */
496
497void doUnexportall (int argc, char *argv [])
498{
499 FILE *fd ;
500 int pin ;
501
502 for (pin = 0 ; pin < 63 ; ++pin)
503 {
504 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
505 {
506 fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
507 exit (1) ;
508 }
509 fprintf (fd, "%d\n", pin) ;
510 fclose (fd) ;
511 }
512}
513
514
515/*
516 * doMode:
517 * gpio mode pin mode ...
518 *********************************************************************************
519 */
520
521void doMode (int argc, char *argv [])
522{
523 int pin ;
524 char *mode ;
525
526 if (argc != 4)
527 {
528 fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
529 exit (1) ;
530 }
531
532 pin = atoi (argv [2]) ;
533
534 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
535 return ;
536
537 mode = argv [3] ;
538
Gordon Henderson178ea082012-08-19 15:17:03 +0100539 /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
540 else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
541 else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
542 else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
543 else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
544 else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100545 else
546 {
547 fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/up/down/tri\n", argv [1], mode) ;
548 exit (1) ;
549 }
550}
551
552
553/*
554 * doPadDrive:
555 * gpio drive group value
556 *********************************************************************************
557 */
558
Gordon Henderson1bb49892012-08-19 15:33:26 +0100559static void doPadDrive (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100560{
561 int group, val ;
562
563 if (argc != 4)
564 {
565 fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
566 exit (1) ;
567 }
568
569 group = atoi (argv [2]) ;
570 val = atoi (argv [3]) ;
571
572 if ((group < 0) || (group > 2))
573 {
574 fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
575 exit (1) ;
576 }
577
578 if ((val < 0) || (val > 7))
579 {
580 fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
581 exit (1) ;
582 }
583
584 setPadDrive (group, val) ;
585}
586
587
588/*
Gordon Henderson99095e32012-08-27 20:56:14 +0100589 * doGbw:
590 * gpio gbw channel value
591 *********************************************************************************
592 */
593
594static void doGbw (int argc, char *argv [])
595{
596 int channel, value ;
597
598 if (argc != 4)
599 {
600 fprintf (stderr, "Usage: %s gbr <channel> <value>\n", argv [0]) ;
601 exit (1) ;
602 }
603
604 channel = atoi (argv [2]) ;
605 value = atoi (argv [3]) ;
606
607 if ((channel < 0) || (channel > 1))
608 {
609 fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
610 exit (1) ;
611 }
612
613 if ((value < 0) || (value > 1023))
614 {
615 fprintf (stderr, "%s: value must be from 0 to 255\n", argv [0]) ;
616 exit (1) ;
617 }
618
619 if (gertboardSPISetup () == -1)
620 {
621 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
622 exit (1) ;
623 }
624
625 gertboardAnalogWrite (channel, value) ;
626}
627
628
629/*
630 * doGbr:
631 * gpio gbr channel
632 *********************************************************************************
633 */
634
635static void doGbr (int argc, char *argv [])
636{
637 int channel ;
638
639 if (argc != 3)
640 {
641 fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
642 exit (1) ;
643 }
644
645 channel = atoi (argv [2]) ;
646
647 if ((channel < 0) || (channel > 1))
648 {
649 fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
650 exit (1) ;
651 }
652
653 if (gertboardSPISetup () == -1)
654 {
655 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
656 exit (1) ;
657 }
658
659 printf ("%d\n",gertboardAnalogRead (channel)) ;
660}
661
662
663
664/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100665 * doWrite:
666 * gpio write pin value
667 *********************************************************************************
668 */
669
Gordon Henderson1bb49892012-08-19 15:33:26 +0100670static void doWrite (int argc, char *argv [])
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100671{
672 int pin, val ;
673
674 if (argc != 4)
675 {
676 fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
677 exit (1) ;
678 }
679
680 pin = atoi (argv [2]) ;
681
682 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
683 return ;
684
685 val = atoi (argv [3]) ;
686
687 /**/ if (val == 0)
688 digitalWrite (pin, LOW) ;
689 else
690 digitalWrite (pin, HIGH) ;
691}
692
693
694/*
695 * doRead:
696 * Read a pin and return the value
697 *********************************************************************************
698 */
699
700void doRead (int argc, char *argv [])
701{
702 int pin, val ;
703
704 if (argc != 3)
705 {
706 fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
707 exit (1) ;
708 }
709
710 pin = atoi (argv [2]) ;
711
712 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
713 {
714 printf ("0\n") ;
715 return ;
716 }
717
718 val = digitalRead (pin) ;
719
720 printf ("%s\n", val == 0 ? "0" : "1") ;
721}
722
723
724/*
725 * doPwm:
726 * Output a PWM value on a pin
727 *********************************************************************************
728 */
729
730void doPwm (int argc, char *argv [])
731{
732 int pin, val ;
733
734 if (argc != 4)
735 {
736 fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
737 exit (1) ;
738 }
739
740 pin = atoi (argv [2]) ;
741
742 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
743 return ;
744
745 val = atoi (argv [3]) ;
746
747 pwmWrite (pin, val) ;
748}
749
750
751/*
Gordon Henderson8cb49392012-09-16 10:15:32 +0100752 * doPwmMode: doPwmRange: doPwmClock:
753 * Change the PWM mode, range and clock divider values
Gordon Hendersonf99ffed2012-08-19 15:12:45 +0100754 *********************************************************************************
755 */
756
757static void doPwmMode (int mode)
758{
759 pwmSetMode (mode) ;
760}
761
762static void doPwmRange (int argc, char *argv [])
763{
764 unsigned int range ;
765
766 if (argc != 3)
767 {
768 fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
769 exit (1) ;
770 }
771
772 range = (unsigned int)strtoul (argv [2], NULL, 10) ;
773
774 if (range == 0)
775 {
776 fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
777 exit (1) ;
778 }
779
780 pwmSetRange (range) ;
781}
782
Gordon Henderson8cb49392012-09-16 10:15:32 +0100783static void doPwmClock (int argc, char *argv [])
784{
785 unsigned int clock ;
786
787 if (argc != 3)
788 {
789 fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
790 exit (1) ;
791 }
792
793 clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
794
795 if ((clock < 1) || (clock > 4095))
796 {
797 fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
798 exit (1) ;
799 }
800
801 pwmSetClock (clock) ;
802}
803
Gordon Hendersonf99ffed2012-08-19 15:12:45 +0100804
805/*
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100806 * main:
807 * Start here
808 *********************************************************************************
809 */
810
811int main (int argc, char *argv [])
812{
813 int i ;
814
815 if (argc == 1)
816 {
Gordon Henderson86a5c682012-10-02 14:32:12 +0100817 fprintf (stderr, "%s\n", usage) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100818 return 1 ;
819 }
820
Gordon Henderson178ea082012-08-19 15:17:03 +0100821 if (strcasecmp (argv [1], "-h") == 0)
822 {
823 printf ("%s: %s\n", argv [0], usage) ;
824 return 0 ;
825 }
826
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100827 if (strcasecmp (argv [1], "-v") == 0)
828 {
829 printf ("gpio version: %s\n", VERSION) ;
830 printf ("Copyright (c) 2012 Gordon Henderson\n") ;
831 printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
832 printf ("For details type: %s -warranty\n", argv [0]) ;
Gordon Henderson86a5c682012-10-02 14:32:12 +0100833 printf ("\n") ;
834 printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100835 return 0 ;
836 }
837
838 if (strcasecmp (argv [1], "-warranty") == 0)
839 {
840 printf ("gpio version: %s\n", VERSION) ;
841 printf ("Copyright (c) 2012 Gordon Henderson\n") ;
842 printf ("\n") ;
843 printf (" This program is free software; you can redistribute it and/or modify\n") ;
844 printf (" it under the terms of the GNU Leser General Public License as published\n") ;
845 printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
846 printf (" (at your option) any later version.\n") ;
847 printf ("\n") ;
848 printf (" This program is distributed in the hope that it will be useful,\n") ;
849 printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
850 printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
851 printf (" GNU Lesser General Public License for more details.\n") ;
852 printf ("\n") ;
853 printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
854 printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
855 printf ("\n") ;
856 return 0 ;
857 }
858
859 if (geteuid () != 0)
860 {
861 fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
862 return 1 ;
863 }
864
865// Initial test for /sys/class/gpio operations:
866
Gordon Henderson178ea082012-08-19 15:17:03 +0100867 /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
868 else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
869 else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100870 else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; }
Gordon Henderson178ea082012-08-19 15:17:03 +0100871 else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
872
Gordon Henderson86a5c682012-10-02 14:32:12 +0100873// Check for load command:
Gordon Henderson178ea082012-08-19 15:17:03 +0100874
Gordon Henderson178ea082012-08-19 15:17:03 +0100875 if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100876
Gordon Henderson99095e32012-08-27 20:56:14 +0100877// Gertboard commands
878
879 if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
880 if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
881
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100882// Check for -g argument
883
884 if (strcasecmp (argv [1], "-g") == 0)
885 {
886 if (wiringPiSetupGpio () == -1)
887 {
Gordon Henderson178ea082012-08-19 15:17:03 +0100888 fprintf (stderr, "%s: Unable to initialise GPIO mode.\n", argv [0]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100889 exit (1) ;
890 }
891
892 for (i = 2 ; i < argc ; ++i)
893 argv [i - 1] = argv [i] ;
894 --argc ;
895 wpMode = WPI_MODE_GPIO ;
896 }
897
898// Check for -p argument for PiFace
899
900 else if (strcasecmp (argv [1], "-p") == 0)
901 {
902 if (wiringPiSetupPiFaceForGpioProg () == -1)
903 {
904 fprintf (stderr, "%s: Unable to initialise PiFace.\n", argv [0]) ;
905 exit (1) ;
906 }
907
908 for (i = 2 ; i < argc ; ++i)
909 argv [i - 1] = argv [i] ;
910 --argc ;
911 wpMode = WPI_MODE_PIFACE ;
912 }
913
914// Default to wiringPi mode
915
916 else
917 {
918 if (wiringPiSetup () == -1)
919 {
Gordon Henderson178ea082012-08-19 15:17:03 +0100920 fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100921 exit (1) ;
922 }
923 wpMode = WPI_MODE_PINS ;
924 }
925
Gordon Henderson86a5c682012-10-02 14:32:12 +0100926// Check for PWM or Pad Drive operations
Gordon Hendersonf99ffed2012-08-19 15:12:45 +0100927
928 if (wpMode != WPI_MODE_PIFACE)
929 {
Gordon Henderson86a5c682012-10-02 14:32:12 +0100930 if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode (PWM_MODE_BAL) ; return 0 ; }
931 if (strcasecmp (argv [1], "pwm-ms") == 0) { doPwmMode (PWM_MODE_MS) ; return 0 ; }
932 if (strcasecmp (argv [1], "pwmr") == 0) { doPwmRange (argc, argv) ; return 0 ; }
933 if (strcasecmp (argv [1], "pwmc") == 0) { doPwmClock (argc, argv) ; return 0 ; }
934 if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; }
Gordon Hendersonf99ffed2012-08-19 15:12:45 +0100935 }
936
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100937// Check for wiring commands
938
Gordon Henderson183c5a62012-10-21 15:25:16 +0100939 /**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
940 else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
941 else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ;
942 else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
943 else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100944 else
945 {
Gordon Henderson178ea082012-08-19 15:17:03 +0100946 fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
Gordon Hendersonbf0ad862012-08-16 15:04:43 +0100947 exit (1) ;
948 }
949 return 0 ;
950}