Statistics
| Branch: | Revision:

ddr4s / fw / wiringPi / gpio / gpio.c @ 32:cadb9025f1e0

History | View | Annotate | Download (36.5 KB)

1
/*
2
 * gpio.c:
3
 *        Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
4
 *        Pi's GPIO.
5
 *        Copyright (c) 2012-2018 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

    
25

    
26
#include <stdio.h>
27
#include <stdlib.h>
28
#include <stdint.h>
29
#include <ctype.h>
30
#include <string.h>
31
#include <unistd.h>
32
#include <errno.h>
33
#include <fcntl.h>
34
#include <sys/types.h>
35
#include <sys/stat.h>
36

    
37
#include <wiringPi.h>
38
#include <wpiExtensions.h>
39

    
40
#include <gertboard.h>
41
#include <piFace.h>
42

    
43
#include "../version.h"
44

    
45
extern int wiringPiDebug ;
46

    
47
// External functions I can't be bothered creating a separate .h file for:
48

    
49
extern void doReadall    (void) ;
50
extern void doAllReadall (void) ;
51
extern void doQmode      (int argc, char *argv []) ;
52

    
53
#ifndef TRUE
54
#  define        TRUE        (1==1)
55
#  define        FALSE        (1==2)
56
#endif
57

    
58
#define        PI_USB_POWER_CONTROL        38
59
#define        I2CDETECT                "i2cdetect"
60
#define        MODPROBE                "modprobe"
61
#define        RMMOD                        "rmmod"
62

    
63
int wpMode ;
64

    
65
char *usage = "Usage: gpio -v\n"
66
              "       gpio -h\n"
67
              "       gpio [-g|-1] ...\n"
68
              "       gpio [-d] ...\n"
69
              "       [-x extension:params] [[ -x ...]] ...\n"
70
              "       gpio [-p] <read/write/wb> ...\n"
71
              "       gpio <mode/read/write/aread/awritewb/pwm/pwmTone/clock> ...\n"
72
              "       gpio <toggle/blink> <pin>\n"
73
              "       gpio readall\n"
74
              "       gpio unexportall/exports\n"
75
              "       gpio export/edge/unexport ...\n"
76
              "       gpio wfi <pin> <mode>\n"
77
              "       gpio drive <group> <value>\n"
78
              "       gpio pwm-bal/pwm-ms \n"
79
              "       gpio pwmr <range> \n"
80
              "       gpio pwmc <divider> \n"
81
              "       gpio load spi/i2c\n"
82
              "       gpio unload spi/i2c\n"
83
              "       gpio i2cd/i2cdetect\n"
84
              "       gpio rbx/rbd\n"
85
              "       gpio wb <value>\n"
86
              "       gpio usbp high/low\n"
87
              "       gpio gbr <channel>\n"
88
              "       gpio gbw <channel> <value>" ;        // No trailing newline needed here.
89

    
90

    
91
#ifdef        NOT_FOR_NOW
92
/*
93
 * decodePin:
94
 *        Decode a pin "number" which can actually be a pin name to represent
95
 *        one of the Pi's on-board pins.
96
 *********************************************************************************
97
 */
98

    
99
static int decodePin (const char *str)
100
{
101

    
102
// The first case - see if it's a number:
103

    
104
  if (isdigit (str [0]))
105
    return atoi (str) ;
106

    
107
  return 0 ;
108
}
109
#endif
110

    
111

    
112
/*
113
 * findExecutable:
114
 *        Code to locate the path to the given executable. We have a fixed list
115
 *        of locations to try which completely overrides any $PATH environment.
116
 *        This may be detrimental, however it avoids the reliance on $PATH
117
 *        which may be a security issue when this program is run a set-uid-root.
118
 *********************************************************************************
119
 */
120

    
121
static const char *searchPath [] =
122
{
123
  "/sbin",
124
  "/usr/sbin",
125
  "/bin",
126
  "/usr/bin",
127
  NULL,
128
} ;
129

    
130
static char *findExecutable (const char *progName)
131
{
132
  static char *path = NULL ;
133
  int len = strlen (progName) ;
134
  int i = 0 ;
135
  struct stat statBuf ;
136

    
137
  for (i = 0 ; searchPath [i] != NULL ; ++i)
138
  {
139
    path = malloc (strlen (searchPath [i]) + len + 2) ;
140
    sprintf (path, "%s/%s", searchPath [i], progName) ;
141

    
142
    if (stat (path, &statBuf) == 0)
143
      return path ;
144
    free (path) ;
145
  }
146

    
147
  return NULL ;
148
}
149

    
150

    
151
/*
152
 * changeOwner:
153
 *        Change the ownership of the file to the real userId of the calling
154
 *        program so we can access it.
155
 *********************************************************************************
156
 */
157

    
158
static void changeOwner (char *cmd, char *file)
159
{
160
  uid_t uid = getuid () ;
161
  uid_t gid = getgid () ;
162

    
163
  if (chown (file, uid, gid) != 0)
164
  {
165

    
166
// Removed (ignoring) the check for not existing as I'm fed-up with morons telling me that
167
//        the warning message is an error.
168

    
169
    if (errno != ENOENT)
170
      fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
171
  }
172
}
173

    
174

    
175
/*
176
 * moduleLoaded:
177
 *        Return true/false if the supplied module is loaded
178
 *********************************************************************************
179
 */
180

    
181
static int moduleLoaded (char *modName)
182
{
183
  int len   = strlen (modName) ;
184
  int found = FALSE ;
185
  FILE *fd = fopen ("/proc/modules", "r") ;
186
  char line [80] ;
187

    
188
  if (fd == NULL)
189
  {
190
    fprintf (stderr, "gpio: Unable to check /proc/modules: %s\n", strerror (errno)) ;
191
    exit (1) ;
192
  }
193

    
194
  while (fgets (line, 80, fd) != NULL)
195
  {
196
    if (strncmp (line, modName, len) != 0)
197
      continue ;
198

    
199
    found = TRUE ;
200
    break ;
201
  }
202

    
203
  fclose (fd) ;
204

    
205
  return found ;
206
}
207

    
208

    
209
/*
210
 * doLoad:
211
 *        Load either the spi or i2c modules and change device ownerships, etc.
212
 *********************************************************************************
213
 */
214

    
215
static void checkDevTree (char *argv [])
216
{
217
  struct stat statBuf ;
218

    
219
  if (stat ("/proc/device-tree", &statBuf) == 0)        // We're on a devtree system ...
220
  {
221
    fprintf (stderr,
222
"%s: Unable to load/unload modules as this Pi has the device tree enabled.\n"
223
"  You need to run the raspi-config program (as root) and select the\n"
224
"  modules (SPI or I2C) that you wish to load/unload there and reboot.\n", argv [0]) ;
225
    exit (1) ;
226
  }
227
}
228

    
229
static void _doLoadUsage (char *argv [])
230
{
231
  fprintf (stderr, "Usage: %s load <spi/i2c> [I2C baudrate in Kb/sec]\n", argv [0]) ;
232
  exit (1) ;
233
}
234

    
235
static void doLoad (int argc, char *argv [])
236
{
237
  char *module1, *module2 ;
238
  char cmd [80] ;
239
  char *file1, *file2 ;
240
  char args1 [32], args2 [32] ;
241

    
242
  checkDevTree (argv) ;
243

    
244
  if (argc < 3)
245
    _doLoadUsage (argv) ;
246

    
247
  args1 [0] = args2 [0] = 0 ;
248

    
249
  /**/ if (strcasecmp (argv [2], "spi") == 0)
250
  {
251
    module1 = "spidev" ;
252
    module2 = "spi_bcm2708" ;
253
    file1  = "/dev/spidev0.0" ;
254
    file2  = "/dev/spidev0.1" ;
255
    if (argc == 4)
256
    {
257
      fprintf (stderr, "%s: Unable to set the buffer size now. Load aborted. Please see the man page.\n", argv [0]) ;
258
      exit (1) ;
259
    }
260
    else if (argc > 4)
261
      _doLoadUsage (argv) ;
262
  }
263
  else if (strcasecmp (argv [2], "i2c") == 0)
264
  {
265
    module1 = "i2c_dev" ;
266
    module2 = "i2c_bcm2708" ;
267
    file1  = "/dev/i2c-0" ;
268
    file2  = "/dev/i2c-1" ;
269
    if (argc == 4)
270
      sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ;
271
    else if (argc > 4)
272
      _doLoadUsage (argv) ;
273
  }
274
  else
275
    _doLoadUsage (argv) ;
276

    
277
  if (findExecutable ("modprobe") == NULL)
278
    printf ("No found\n") ;
279

    
280
  if (!moduleLoaded (module1))
281
  {
282
    sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ;
283
    system (cmd) ;
284
  }
285

    
286
  if (!moduleLoaded (module2))
287
  {
288
    sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ;
289
    system (cmd) ;
290
  }
291

    
292
  if (!moduleLoaded (module2))
293
  {
294
    fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ;
295
    exit (1) ;
296
  }
297

    
298
  sleep (1) ;        // To let things get settled
299

    
300
  changeOwner (argv [0], file1) ;
301
  changeOwner (argv [0], file2) ;
302
}
303

    
304

    
305
/*
306
 * doUnLoad:
307
 *        Un-Load either the spi or i2c modules and change device ownerships, etc.
308
 *********************************************************************************
309
 */
310

    
311
static void _doUnLoadUsage (char *argv [])
312
{
313
  fprintf (stderr, "Usage: %s unload <spi/i2c>\n", argv [0]) ;
314
  exit (1) ;
315
}
316

    
317
static void doUnLoad (int argc, char *argv [])
318
{
319
  char *module1, *module2 ;
320
  char cmd [80] ;
321

    
322
  checkDevTree (argv) ;
323

    
324
  if (argc != 3)
325
    _doUnLoadUsage (argv) ;
326

    
327
  /**/ if (strcasecmp (argv [2], "spi") == 0)
328
  {
329
    module1 = "spidev" ;
330
    module2 = "spi_bcm2708" ;
331
  }
332
  else if (strcasecmp (argv [2], "i2c") == 0)
333
  {
334
    module1 = "i2c_dev" ;
335
    module2 = "i2c_bcm2708" ;
336
  }
337
  else
338
    _doUnLoadUsage (argv) ;
339

    
340
  if (moduleLoaded (module1))
341
  {
342
    sprintf (cmd, "%s %s", findExecutable (RMMOD), module1) ;
343
    system (cmd) ;
344
  }
345

    
346
  if (moduleLoaded (module2))
347
  {
348
    sprintf (cmd, "%s %s", findExecutable (RMMOD), module2) ;
349
    system (cmd) ;
350
  }
351
}
352

    
353

    
354
/*
355
 * doI2Cdetect:
356
 *        Run the i2cdetect command with the right runes for this Pi revision
357
 *********************************************************************************
358
 */
359

    
360
static void doI2Cdetect (UNU int argc, char *argv [])
361
{
362
  int port = piGpioLayout () == 1 ? 0 : 1 ;
363
  char *c, *command ;
364

    
365
  if ((c = findExecutable (I2CDETECT)) == NULL)
366
  {
367
    fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
368
    return ;
369
  }
370

    
371
  if (!moduleLoaded ("i2c_dev"))
372
  {
373
    fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ;
374
    return ;
375
  }
376

    
377
  command = malloc (strlen (c) + 16) ;
378
  sprintf (command, "%s -y %d", c, port) ;
379
  if (system (command) < 0)
380
    fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;
381

    
382
}
383

    
384

    
385
/*
386
 * doExports:
387
 *        List all GPIO exports
388
 *********************************************************************************
389
 */
390

    
391
static void doExports (UNU int argc, UNU char *argv [])
392
{
393
  int fd ;
394
  int i, l, first ;
395
  char fName [128] ;
396
  char buf [16] ;
397

    
398
  for (first = 0, i = 0 ; i < 64 ; ++i)        // Crude, but effective
399
  {
400

    
401
// Try to read the direction
402

    
403
    sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
404
    if ((fd = open (fName, O_RDONLY)) == -1)
405
      continue ;
406

    
407
    if (first == 0)
408
    {
409
      ++first ;
410
      printf ("GPIO Pins exported:\n") ;
411
    }
412

    
413
    printf ("%4d: ", i) ;
414

    
415
    if ((l = read (fd, buf, 16)) == 0)
416
      sprintf (buf, "%s", "?") ;
417
 
418
    buf [l] = 0 ;
419
    if ((buf [strlen (buf) - 1]) == '\n')
420
      buf [strlen (buf) - 1] = 0 ;
421

    
422
    printf ("%-3s", buf) ;
423

    
424
    close (fd) ;
425

    
426
// Try to Read the value
427

    
428
    sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
429
    if ((fd = open (fName, O_RDONLY)) == -1)
430
    {
431
      printf ("No Value file (huh?)\n") ;
432
      continue ;
433
    }
434

    
435
    if ((l = read (fd, buf, 16)) == 0)
436
      sprintf (buf, "%s", "?") ;
437

    
438
    buf [l] = 0 ;
439
    if ((buf [strlen (buf) - 1]) == '\n')
440
      buf [strlen (buf) - 1] = 0 ;
441

    
442
    printf ("  %s", buf) ;
443

    
444
// Read any edge trigger file
445

    
446
    sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ;
447
    if ((fd = open (fName, O_RDONLY)) == -1)
448
    {
449
      printf ("\n") ;
450
      continue ;
451
    }
452

    
453
    if ((l = read (fd, buf, 16)) == 0)
454
      sprintf (buf, "%s", "?") ;
455

    
456
    buf [l] = 0 ;
457
    if ((buf [strlen (buf) - 1]) == '\n')
458
      buf [strlen (buf) - 1] = 0 ;
459

    
460
    printf ("  %-8s\n", buf) ;
461

    
462
    close (fd) ;
463
  }
464
}
465

    
466

    
467
/*
468
 * doExport:
469
 *        gpio export pin mode
470
 *        This uses the /sys/class/gpio device interface.
471
 *********************************************************************************
472
 */
473

    
474
void doExport (int argc, char *argv [])
475
{
476
  FILE *fd ;
477
  int pin ;
478
  char *mode ;
479
  char fName [128] ;
480

    
481
  if (argc != 4)
482
  {
483
    fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
484
    exit (1) ;
485
  }
486

    
487
  pin = atoi (argv [2]) ;
488

    
489
  mode = argv [3] ;
490

    
491
  if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
492
  {
493
    fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
494
    exit (1) ;
495
  }
496

    
497
  fprintf (fd, "%d\n", pin) ;
498
  fclose (fd) ;
499

    
500
  sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
501
  if ((fd = fopen (fName, "w")) == NULL)
502
  {
503
    fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
504
    exit (1) ;
505
  }
506

    
507
  /**/ if ((strcasecmp (mode, "in")   == 0) || (strcasecmp (mode, "input")  == 0))
508
    fprintf (fd, "in\n") ;
509
  else if ((strcasecmp (mode, "out")  == 0) || (strcasecmp (mode, "output") == 0))
510
    fprintf (fd, "out\n") ;
511
  else if ((strcasecmp (mode, "high") == 0) || (strcasecmp (mode, "up")     == 0))
512
    fprintf (fd, "high\n") ;
513
  else if ((strcasecmp (mode, "low")  == 0) || (strcasecmp (mode, "down")   == 0))
514
    fprintf (fd, "low\n") ;
515
  else
516
  {
517
    fprintf (stderr, "%s: Invalid mode: %s. Should be in, out, high or low\n", argv [1], mode) ;
518
    exit (1) ;
519
  }
520

    
521
  fclose (fd) ;
522

    
523
// Change ownership so the current user can actually use it
524

    
525
  sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
526
  changeOwner (argv [0], fName) ;
527

    
528
  sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
529
  changeOwner (argv [0], fName) ;
530

    
531
}
532

    
533

    
534
/*
535
 * doWfi:
536
 *        gpio wfi pin mode
537
 *        Wait for Interrupt on a given pin.
538
 *        Slight cheat here - it's easier to actually use ISR now (which calls
539
 *        gpio to set the pin modes!) then we simply sleep, and expect the thread
540
 *        to exit the program. Crude but effective.
541
 *********************************************************************************
542
 */
543

    
544
static void wfi (void)
545
  { exit (0) ; }
546

    
547
void doWfi (int argc, char *argv [])
548
{
549
  int pin, mode ;
550

    
551
  if (argc != 4)
552
  {
553
    fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ;
554
    exit (1) ;
555
  }
556

    
557
  pin  = atoi (argv [2]) ;
558

    
559
  /**/ if (strcasecmp (argv [3], "rising")  == 0) mode = INT_EDGE_RISING ;
560
  else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
561
  else if (strcasecmp (argv [3], "both")    == 0) mode = INT_EDGE_BOTH ;
562
  else
563
  {
564
    fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ;
565
    exit (1) ;
566
  }
567

    
568
  if (wiringPiISR (pin, mode, &wfi) < 0)
569
  {
570
    fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
571
    exit (1) ;
572
  }
573

    
574
  for (;;)
575
    delay (9999) ;
576
}
577

    
578

    
579

    
580
/*
581
 * doEdge:
582
 *        gpio edge pin mode
583
 *        Easy access to changing the edge trigger on a GPIO pin
584
 *        This uses the /sys/class/gpio device interface.
585
 *********************************************************************************
586
 */
587

    
588
void doEdge (int argc, char *argv [])
589
{
590
  FILE *fd ;
591
  int pin ;
592
  char *mode ;
593
  char fName [128] ;
594

    
595
  if (argc != 4)
596
  {
597
    fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
598
    exit (1) ;
599
  }
600

    
601
  pin  = atoi (argv [2]) ;
602
  mode = argv [3] ;
603

    
604
// Export the pin and set direction to input
605

    
606
  if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
607
  {
608
    fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
609
    exit (1) ;
610
  }
611

    
612
  fprintf (fd, "%d\n", pin) ;
613
  fclose (fd) ;
614

    
615
  sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
616
  if ((fd = fopen (fName, "w")) == NULL)
617
  {
618
    fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
619
    exit (1) ;
620
  }
621

    
622
  fprintf (fd, "in\n") ;
623
  fclose (fd) ;
624

    
625
  sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
626
  if ((fd = fopen (fName, "w")) == NULL)
627
  {
628
    fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
629
    exit (1) ;
630
  }
631

    
632
  /**/ if (strcasecmp (mode, "none")    == 0) fprintf (fd, "none\n") ;
633
  else if (strcasecmp (mode, "rising")  == 0) fprintf (fd, "rising\n") ;
634
  else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
635
  else if (strcasecmp (mode, "both")    == 0) fprintf (fd, "both\n") ;
636
  else
637
  {
638
    fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
639
    exit (1) ;
640
  }
641

    
642
// Change ownership of the value and edge files, so the current user can actually use it!
643

    
644
  sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
645
  changeOwner (argv [0], fName) ;
646

    
647
  sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
648
  changeOwner (argv [0], fName) ;
649

    
650
  fclose (fd) ;
651
}
652

    
653

    
654
/*
655
 * doUnexport:
656
 *        gpio unexport pin
657
 *        This uses the /sys/class/gpio device interface.
658
 *********************************************************************************
659
 */
660

    
661
void doUnexport (int argc, char *argv [])
662
{
663
  FILE *fd ;
664
  int pin ;
665

    
666
  if (argc != 3)
667
  {
668
    fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
669
    exit (1) ;
670
  }
671

    
672
  pin = atoi (argv [2]) ;
673

    
674
  if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
675
  {
676
    fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
677
    exit (1) ;
678
  }
679

    
680
  fprintf (fd, "%d\n", pin) ;
681
  fclose (fd) ;
682
}
683

    
684

    
685
/*
686
 * doUnexportAll:
687
 *        gpio unexportall
688
 *        Un-Export all the GPIO pins.
689
 *        This uses the /sys/class/gpio device interface.
690
 *********************************************************************************
691
 */
692

    
693
void doUnexportall (char *progName)
694
{
695
  FILE *fd ;
696
  int pin ;
697

    
698
  for (pin = 0 ; pin < 63 ; ++pin)
699
  {
700
    if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
701
    {
702
      fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
703
      exit (1) ;
704
    }
705
    fprintf (fd, "%d\n", pin) ;
706
    fclose (fd) ;
707
  }
708
}
709

    
710

    
711
/*
712
 * doReset:
713
 *        Reset the GPIO pins - as much as we can do
714
 *********************************************************************************
715
 */
716

    
717
static void doReset (UNU char *progName)
718
{
719
  printf ("GPIO Reset is dangerous and has been removed from the gpio command.\n") ;
720
  printf (" - Please write a shell-script to reset the GPIO pins into the state\n") ;
721
  printf ("   that you need them in for your applications.\n") ;
722
}
723

    
724

    
725
/*
726
 * doMode:
727
 *        gpio mode pin mode ...
728
 *********************************************************************************
729
 */
730

    
731
void doMode (int argc, char *argv [])
732
{
733
  int pin ;
734
  char *mode ;
735

    
736
  if (argc != 4)
737
  {
738
    fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
739
    exit (1) ;
740
  }
741

    
742
  pin = atoi (argv [2]) ;
743

    
744
  mode = argv [3] ;
745

    
746
  /**/ if (strcasecmp (mode, "in")      == 0) pinMode         (pin, INPUT) ;
747
  else if (strcasecmp (mode, "input")   == 0) pinMode         (pin, INPUT) ;
748
  else if (strcasecmp (mode, "out")     == 0) pinMode         (pin, OUTPUT) ;
749
  else if (strcasecmp (mode, "output")  == 0) pinMode         (pin, OUTPUT) ;
750
  else if (strcasecmp (mode, "pwm")     == 0) pinMode         (pin, PWM_OUTPUT) ;
751
  else if (strcasecmp (mode, "pwmTone") == 0) pinMode         (pin, PWM_TONE_OUTPUT) ;
752
  else if (strcasecmp (mode, "clock")   == 0) pinMode         (pin, GPIO_CLOCK) ;
753
  else if (strcasecmp (mode, "up")      == 0) pullUpDnControl (pin, PUD_UP) ;
754
  else if (strcasecmp (mode, "down")    == 0) pullUpDnControl (pin, PUD_DOWN) ;
755
  else if (strcasecmp (mode, "tri")     == 0) pullUpDnControl (pin, PUD_OFF) ;
756
  else if (strcasecmp (mode, "off")     == 0) pullUpDnControl (pin, PUD_OFF) ;
757
  else if (strcasecmp (mode, "alt0")    == 0) pinModeAlt (pin, 0b100) ;
758
  else if (strcasecmp (mode, "alt1")    == 0) pinModeAlt (pin, 0b101) ;
759
  else if (strcasecmp (mode, "alt2")    == 0) pinModeAlt (pin, 0b110) ;
760
  else if (strcasecmp (mode, "alt3")    == 0) pinModeAlt (pin, 0b111) ;
761
  else if (strcasecmp (mode, "alt4")    == 0) pinModeAlt (pin, 0b011) ;
762
  else if (strcasecmp (mode, "alt5")    == 0) pinModeAlt (pin, 0b010) ;
763
  else
764
  {
765
    fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ;
766
    exit (1) ;
767
  }
768
}
769

    
770

    
771
/*
772
 * doPadDrive:
773
 *        gpio drive group value
774
 *********************************************************************************
775
 */
776

    
777
static void doPadDrive (int argc, char *argv [])
778
{
779
  int group, val ;
780

    
781
  if (argc != 4)
782
  {
783
    fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
784
    exit (1) ;
785
  }
786

    
787
  group = atoi (argv [2]) ;
788
  val   = atoi (argv [3]) ;
789

    
790
  if ((group < 0) || (group > 2))
791
  {
792
    fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
793
    exit (1) ;
794
  }
795

    
796
  if ((val < 0) || (val > 7))
797
  {
798
    fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
799
    exit (1) ;
800
  }
801

    
802
  setPadDrive (group, val) ;
803
}
804

    
805

    
806
/*
807
 * doUsbP:
808
 *        Control USB Power - High (1.2A) or Low (600mA)
809
 *        gpio usbp high/low
810
 *********************************************************************************
811
 */
812

    
813
static void doUsbP (int argc, char *argv [])
814
{
815
  int model, rev, mem, maker, overVolted ;
816

    
817
  if (argc != 3)
818
  {
819
    fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
820
    exit (1) ;
821
  }
822

    
823
// Make sure we're on a B+
824

    
825
  piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
826

    
827
  if (!((model == PI_MODEL_BP) || (model == PI_MODEL_2)))
828
  {
829
    fprintf (stderr, "USB power contol is applicable to B+ and v2 boards only.\n") ;
830
    exit (1) ;
831
  }
832
    
833
// Make sure we start in BCM_GPIO mode
834

    
835
  wiringPiSetupGpio () ;
836

    
837
  if ((strcasecmp (argv [2], "high") == 0) || (strcasecmp (argv [2], "hi") == 0))
838
  {
839
    digitalWrite (PI_USB_POWER_CONTROL, 1) ;
840
    pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
841
    printf ("Switched to HIGH current USB (1.2A)\n") ;
842
    return ;
843
  }
844

    
845
  if ((strcasecmp (argv [2], "low") == 0) || (strcasecmp (argv [2], "lo") == 0))
846
  {
847
    digitalWrite (PI_USB_POWER_CONTROL, 0) ;
848
    pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
849
    printf ("Switched to LOW current USB (600mA)\n") ;
850
    return ;
851
  }
852

    
853
  fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
854
  exit (1) ;
855
}
856

    
857

    
858
/*
859
 * doGbw:
860
 *        gpio gbw channel value
861
 *        Gertboard Write - To the Analog output
862
 *********************************************************************************
863
 */
864

    
865
static void doGbw (int argc, char *argv [])
866
{
867
  int channel, value ;
868

    
869
  if (argc != 4)
870
  {
871
    fprintf (stderr, "Usage: %s gbw <channel> <value>\n", argv [0]) ;
872
    exit (1) ;
873
  }
874

    
875
  channel = atoi (argv [2]) ;
876
  value   = atoi (argv [3]) ;
877

    
878
  if ((channel < 0) || (channel > 1))
879
  {
880
    fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ;
881
    exit (1) ;
882
  }
883

    
884
  if ((value < 0) || (value > 255))
885
  {
886
    fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ;
887
    exit (1) ;
888
  }
889

    
890
  if (gertboardAnalogSetup (64) < 0)
891
  {
892
    fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
893
    exit (1) ;
894
  }
895

    
896
  analogWrite (64 + channel, value) ;
897
}
898

    
899

    
900
/*
901
 * doGbr:
902
 *        gpio gbr channel
903
 *        From the analog input
904
 *********************************************************************************
905
 */
906

    
907
static void doGbr (int argc, char *argv [])
908
{
909
  int channel ;
910

    
911
  if (argc != 3)
912
  {
913
    fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
914
    exit (1) ;
915
  }
916

    
917
  channel = atoi (argv [2]) ;
918

    
919
  if ((channel < 0) || (channel > 1))
920
  {
921
    fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ;
922
    exit (1) ;
923
  }
924

    
925
  if (gertboardAnalogSetup (64) < 0)
926
  {
927
    fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
928
    exit (1) ;
929
  }
930

    
931
  printf ("%d\n", analogRead (64 + channel)) ;
932
}
933

    
934

    
935
/*
936
 * doWrite:
937
 *        gpio write pin value
938
 *********************************************************************************
939
 */
940

    
941
static void doWrite (int argc, char *argv [])
942
{
943
  int pin, val ;
944

    
945
  if (argc != 4)
946
  {
947
    fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
948
    exit (1) ;
949
  }
950

    
951
  pin = atoi (argv [2]) ;
952

    
953
  /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
954
    val = 1 ;
955
  else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
956
    val = 0 ;
957
  else
958
    val = atoi (argv [3]) ;
959

    
960
  /**/ if (val == 0)
961
    digitalWrite (pin, LOW) ;
962
  else
963
    digitalWrite (pin, HIGH) ;
964
}
965

    
966

    
967
/*
968
 * doAwriterite:
969
 *        gpio awrite pin value
970
 *********************************************************************************
971
 */
972

    
973
static void doAwrite (int argc, char *argv [])
974
{
975
  int pin, val ;
976

    
977
  if (argc != 4)
978
  {
979
    fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
980
    exit (1) ;
981
  }
982

    
983
  pin = atoi (argv [2]) ;
984

    
985
  val = atoi (argv [3]) ;
986

    
987
  analogWrite (pin, val) ;
988
}
989

    
990

    
991
/*
992
 * doWriteByte:
993
 *        gpio wb value
994
 *********************************************************************************
995
 */
996

    
997
static void doWriteByte (int argc, char *argv [])
998
{
999
  int val ;
1000

    
1001
  if (argc != 3)
1002
  {
1003
    fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
1004
    exit (1) ;
1005
  }
1006

    
1007
  val = (int)strtol (argv [2], NULL, 0) ;
1008

    
1009
  digitalWriteByte (val) ;
1010
}
1011

    
1012

    
1013
/*
1014
 * doReadByte:
1015
 *        gpio rbx|rbd value
1016
 *********************************************************************************
1017
 */
1018

    
1019
static void doReadByte (int argc, char *argv [], int printHex)
1020
{
1021
  int val ;
1022

    
1023
  if (argc != 2)
1024
  {
1025
    fprintf (stderr, "Usage: %s rbx|rbd\n", argv [0]) ;
1026
    exit (1) ;
1027
  }
1028

    
1029
  val = digitalReadByte () ;
1030
  if (printHex)
1031
    printf ("%02X\n", val) ;
1032
  else
1033
    printf ("%d\n", val) ;
1034
}
1035

    
1036

    
1037
/*
1038
 * doRead:
1039
 *        Read a pin and return the value
1040
 *********************************************************************************
1041
 */
1042

    
1043
void doRead (int argc, char *argv []) 
1044
{
1045
  int pin, val ;
1046

    
1047
  if (argc != 3)
1048
  {
1049
    fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
1050
    exit (1) ;
1051
  }
1052

    
1053
  pin = atoi (argv [2]) ;
1054
  val = digitalRead (pin) ;
1055

    
1056
  printf ("%s\n", val == 0 ? "0" : "1") ;
1057
}
1058

    
1059

    
1060
/*
1061
 * doAread:
1062
 *        Read an analog pin and return the value
1063
 *********************************************************************************
1064
 */
1065

    
1066
void doAread (int argc, char *argv []) 
1067
{
1068
  if (argc != 3)
1069
  {
1070
    fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
1071
    exit (1) ;
1072
  }
1073

    
1074
  printf ("%d\n", analogRead (atoi (argv [2]))) ;
1075
}
1076

    
1077

    
1078
/*
1079
 * doToggle:
1080
 *        Toggle an IO pin
1081
 *********************************************************************************
1082
 */
1083

    
1084
void doToggle (int argc, char *argv [])
1085
{
1086
  int pin ;
1087

    
1088
  if (argc != 3)
1089
  {
1090
    fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
1091
    exit (1) ;
1092
  }
1093

    
1094
  pin = atoi (argv [2]) ;
1095

    
1096
  digitalWrite (pin, !digitalRead (pin)) ;
1097
}
1098

    
1099

    
1100
/*
1101
 * doBlink:
1102
 *        Blink an IO pin
1103
 *********************************************************************************
1104
 */
1105

    
1106
void doBlink (int argc, char *argv [])
1107
{
1108
  int pin ;
1109

    
1110
  if (argc != 3)
1111
  {
1112
    fprintf (stderr, "Usage: %s blink pin\n", argv [0]) ;
1113
    exit (1) ;
1114
  }
1115

    
1116
  pin = atoi (argv [2]) ;
1117

    
1118
  pinMode (pin, OUTPUT) ;
1119
  for (;;)
1120
  {
1121
    digitalWrite (pin, !digitalRead (pin)) ;
1122
    delay (500) ;
1123
  }
1124

    
1125
}
1126

    
1127

    
1128
/*
1129
 * doPwmTone:
1130
 *        Output a tone in a PWM pin
1131
 *********************************************************************************
1132
 */
1133

    
1134
void doPwmTone (int argc, char *argv [])
1135
{
1136
  int pin, freq ;
1137

    
1138
  if (argc != 4)
1139
  {
1140
    fprintf (stderr, "Usage: %s pwmTone <pin> <freq>\n", argv [0]) ;
1141
    exit (1) ;
1142
  }
1143

    
1144
  pin = atoi (argv [2]) ;
1145
  freq = atoi (argv [3]) ;
1146

    
1147
  pwmToneWrite (pin, freq) ;
1148
}
1149

    
1150

    
1151
/*
1152
 * doClock:
1153
 *        Output a clock on a pin
1154
 *********************************************************************************
1155
 */
1156

    
1157
void doClock (int argc, char *argv [])
1158
{
1159
  int pin, freq ;
1160

    
1161
  if (argc != 4)
1162
  {
1163
    fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
1164
    exit (1) ;
1165
  }
1166

    
1167
  pin = atoi (argv [2]) ;
1168

    
1169
  freq = atoi (argv [3]) ;
1170

    
1171
  gpioClockSet (pin, freq) ;
1172
}
1173

    
1174

    
1175
/*
1176
 * doPwm:
1177
 *        Output a PWM value on a pin
1178
 *********************************************************************************
1179
 */
1180

    
1181
void doPwm (int argc, char *argv [])
1182
{
1183
  int pin, val ;
1184

    
1185
  if (argc != 4)
1186
  {
1187
    fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
1188
    exit (1) ;
1189
  }
1190

    
1191
  pin = atoi (argv [2]) ;
1192

    
1193
  val = atoi (argv [3]) ;
1194

    
1195
  pwmWrite (pin, val) ;
1196
}
1197

    
1198

    
1199
/*
1200
 * doPwmMode: doPwmRange: doPwmClock:
1201
 *        Change the PWM mode, range and clock divider values
1202
 *********************************************************************************
1203
 */
1204

    
1205
static void doPwmMode (int mode)
1206
{
1207
  pwmSetMode (mode) ;
1208
}
1209

    
1210
static void doPwmRange (int argc, char *argv [])
1211
{
1212
  unsigned int range ;
1213

    
1214
  if (argc != 3)
1215
  {
1216
    fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
1217
    exit (1) ;
1218
  }
1219

    
1220
  range = (unsigned int)strtoul (argv [2], NULL, 10) ;
1221

    
1222
  if (range == 0)
1223
  {
1224
    fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
1225
    exit (1) ;
1226
  }
1227

    
1228
  pwmSetRange (range) ;
1229
}
1230

    
1231
static void doPwmClock (int argc, char *argv [])
1232
{
1233
  unsigned int clock ;
1234

    
1235
  if (argc != 3)
1236
  {
1237
    fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
1238
    exit (1) ;
1239
  }
1240

    
1241
  clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
1242

    
1243
  if ((clock < 1) || (clock > 4095))
1244
  {
1245
    fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
1246
    exit (1) ;
1247
  }
1248

    
1249
  pwmSetClock (clock) ;
1250
}
1251

    
1252

    
1253
/*
1254
 * doVersion:
1255
 *        Handle the ever more complicated version command and print out
1256
 *        some usefull information.
1257
 *********************************************************************************
1258
 */
1259

    
1260
static void doVersion (char *argv [])
1261
{
1262
  int model, rev, mem, maker, warranty ;
1263
  struct stat statBuf ;
1264
  char name [80] ;
1265
  FILE *fd ;
1266

    
1267
  int vMaj, vMin ;
1268

    
1269
  wiringPiVersion (&vMaj, &vMin) ;
1270
  printf ("gpio version: %d.%d\n", vMaj, vMin) ;
1271
  printf ("Copyright (c) 2012-2018 Gordon Henderson\n") ;
1272
  printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
1273
  printf ("For details type: %s -warranty\n", argv [0]) ;
1274
  printf ("\n") ;
1275
  piBoardId (&model, &rev, &mem, &maker, &warranty) ;
1276

    
1277
  printf ("Raspberry Pi Details:\n") ;
1278
  printf ("  Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n", 
1279
      piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ;
1280

    
1281
// Check for device tree
1282

    
1283
  if (stat ("/proc/device-tree", &statBuf) == 0)        // We're on a devtree system ...
1284
    printf ("  * Device tree is enabled.\n") ;
1285

    
1286
  if (stat ("/proc/device-tree/model", &statBuf) == 0)        // Output Kernel idea of board type
1287
  {
1288
    if ((fd = fopen ("/proc/device-tree/model", "r")) != NULL)
1289
    {
1290
      fgets (name, 80, fd) ;
1291
      fclose (fd) ;
1292
      printf ("  *--> %s\n", name) ;
1293
    }
1294
  }
1295

    
1296
  if (stat ("/dev/gpiomem", &statBuf) == 0)                // User level GPIO is GO
1297
    printf ("  * This Raspberry Pi supports user-level GPIO access.\n") ;
1298
  else
1299
    printf ("  * Root or sudo required for GPIO access.\n") ;
1300
}
1301

    
1302

    
1303
/*
1304
 * main:
1305
 *        Start here
1306
 *********************************************************************************
1307
 */
1308

    
1309
int main (int argc, char *argv [])
1310
{
1311
  int i ;
1312

    
1313
  if (getenv ("WIRINGPI_DEBUG") != NULL)
1314
  {
1315
    printf ("gpio: wiringPi debug mode enabled\n") ;
1316
    wiringPiDebug = TRUE ;
1317
  }
1318

    
1319
  if (argc == 1)
1320
  {
1321
    fprintf (stderr,
1322
"%s: At your service!\n"
1323
"  Type: gpio -h for full details and\n"
1324
"        gpio readall for a quick printout of your connector details\n", argv [0]) ;
1325
    exit (EXIT_FAILURE) ;
1326
  }
1327

    
1328
// Help
1329

    
1330
  if (strcasecmp (argv [1], "-h") == 0)
1331
  {
1332
    printf ("%s: %s\n", argv [0], usage) ;
1333
    exit (EXIT_SUCCESS) ;
1334
  }
1335

    
1336
// Version & Warranty
1337
//        Wish I could remember why I have both -R and -V ...
1338

    
1339
  if ((strcmp (argv [1], "-R") == 0) || (strcmp (argv [1], "-V") == 0))
1340
  {
1341
    printf ("%d\n", piGpioLayout ()) ;
1342
    exit (EXIT_SUCCESS) ;
1343
  }
1344

    
1345
// Version and information
1346

    
1347
  if (strcmp (argv [1], "-v") == 0)
1348
  {
1349
    doVersion (argv) ;
1350
    exit (EXIT_SUCCESS) ;
1351
  }
1352

    
1353
  if (strcasecmp (argv [1], "-warranty") == 0)
1354
  {
1355
    printf ("gpio version: %s\n", VERSION) ;
1356
    printf ("Copyright (c) 2012-2018 Gordon Henderson\n") ;
1357
    printf ("\n") ;
1358
    printf ("    This program is free software; you can redistribute it and/or modify\n") ;
1359
    printf ("    it under the terms of the GNU Leser General Public License as published\n") ;
1360
    printf ("    by the Free Software Foundation, either version 3 of the License, or\n") ;
1361
    printf ("    (at your option) any later version.\n") ;
1362
    printf ("\n") ;
1363
    printf ("    This program is distributed in the hope that it will be useful,\n") ;
1364
    printf ("    but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
1365
    printf ("    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n") ;
1366
    printf ("    GNU Lesser General Public License for more details.\n") ;
1367
    printf ("\n") ;
1368
    printf ("    You should have received a copy of the GNU Lesser General Public License\n") ;
1369
    printf ("    along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
1370
    printf ("\n") ;
1371
    exit (EXIT_SUCCESS) ;
1372
  }
1373

    
1374
  if (geteuid () != 0)
1375
  {
1376
    fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
1377
    exit (EXIT_FAILURE) ;
1378
  }
1379

    
1380
// Initial test for /sys/class/gpio operations:
1381

    
1382
  /**/ if (strcasecmp (argv [1], "exports"    ) == 0)        { doExports     (argc, argv) ;        return 0 ; }
1383
  else if (strcasecmp (argv [1], "export"     ) == 0)        { doExport      (argc, argv) ;        return 0 ; }
1384
  else if (strcasecmp (argv [1], "edge"       ) == 0)        { doEdge        (argc, argv) ;        return 0 ; }
1385
  else if (strcasecmp (argv [1], "unexport"   ) == 0)        { doUnexport    (argc, argv) ;        return 0 ; }
1386
  else if (strcasecmp (argv [1], "unexportall") == 0)        { doUnexportall (argv [0]) ;        return 0 ; }
1387

    
1388
// Check for load command:
1389

    
1390
  if (strcasecmp (argv [1], "load"   ) == 0)        { doLoad   (argc, argv) ; return 0 ; }
1391
  if (strcasecmp (argv [1], "unload" ) == 0)        { doUnLoad (argc, argv) ; return 0 ; }
1392

    
1393
// Check for usb power command
1394

    
1395
  if (strcasecmp (argv [1], "usbp"   ) == 0)        { doUsbP   (argc, argv) ; return 0 ; }
1396

    
1397
// Gertboard commands
1398

    
1399
  if (strcasecmp (argv [1], "gbr" ) == 0)        { doGbr (argc, argv) ; return 0 ; }
1400
  if (strcasecmp (argv [1], "gbw" ) == 0)        { doGbw (argc, argv) ; return 0 ; }
1401

    
1402
// Check for allreadall command, force Gpio mode
1403

    
1404
  if (strcasecmp (argv [1], "allreadall") == 0)
1405
  {
1406
    wiringPiSetupGpio () ;
1407
    doAllReadall      () ;
1408
    return 0 ;
1409
  }
1410

    
1411
// Check for -g argument
1412

    
1413
  /**/ if (strcasecmp (argv [1], "-g") == 0)
1414
  {
1415
    wiringPiSetupGpio () ;
1416

    
1417
    for (i = 2 ; i < argc ; ++i)
1418
      argv [i - 1] = argv [i] ;
1419
    --argc ;
1420
    wpMode = WPI_MODE_GPIO ;
1421
  }
1422

    
1423
// Check for -1 argument
1424

    
1425
  else if (strcasecmp (argv [1], "-1") == 0)
1426
  {
1427
    wiringPiSetupPhys () ;
1428

    
1429
    for (i = 2 ; i < argc ; ++i)
1430
      argv [i - 1] = argv [i] ;
1431
    --argc ;
1432
    wpMode = WPI_MODE_PHYS ;
1433
  }
1434

    
1435
// Check for -p argument for PiFace
1436

    
1437
  else if (strcasecmp (argv [1], "-p") == 0)
1438
  {
1439
    piFaceSetup (200) ;
1440

    
1441
    for (i = 2 ; i < argc ; ++i)
1442
      argv [i - 1] = argv [i] ;
1443
    --argc ;
1444
    wpMode = WPI_MODE_PIFACE ;
1445
  }
1446

    
1447
// Check for -z argument so we don't actually initialise wiringPi
1448

    
1449
  else if (strcasecmp (argv [1], "-z") == 0)
1450
  {
1451
    for (i = 2 ; i < argc ; ++i)
1452
      argv [i - 1] = argv [i] ;
1453
    --argc ;
1454
    wpMode = WPI_MODE_UNINITIALISED ;
1455
  }
1456

    
1457
// Default to wiringPi mode
1458

    
1459
  else
1460
  {
1461
    wiringPiSetup () ;
1462
    wpMode = WPI_MODE_PINS ;
1463
  }
1464

    
1465
// Check for -x argument to load in a new extension
1466
//        -x extension:base:args
1467
//        Can load many modules, but unless daemon mode we can only send one
1468
//        command at a time.
1469

    
1470
  while (strcasecmp (argv [1], "-x") == 0)
1471
  {
1472
    if (argc < 3)
1473
    {
1474
      fprintf (stderr, "%s: -x missing extension command.\n", argv [0]) ;
1475
      exit (EXIT_FAILURE) ;
1476
    }
1477

    
1478
    if (!loadWPiExtension (argv [0], argv [2], TRUE))
1479
    {
1480
      fprintf (stderr, "%s: Extension load failed: %s\n", argv [0], strerror (errno)) ;
1481
      exit (EXIT_FAILURE) ;
1482
    }
1483

    
1484
// Shift args down by 2
1485

    
1486
    for (i = 3 ; i < argc ; ++i)
1487
      argv [i - 2] = argv [i] ;
1488
    argc -= 2 ;
1489
  }
1490

    
1491
  if (argc <= 1)
1492
  {
1493
    fprintf (stderr, "%s: no command given\n", argv [0]) ;
1494
    exit (EXIT_FAILURE) ;
1495
  }
1496

    
1497
// Core wiringPi functions
1498

    
1499
  /**/ if (strcasecmp (argv [1], "mode"   ) == 0) doMode      (argc, argv) ;
1500
  else if (strcasecmp (argv [1], "read"   ) == 0) doRead      (argc, argv) ;
1501
  else if (strcasecmp (argv [1], "write"  ) == 0) doWrite     (argc, argv) ;
1502
  else if (strcasecmp (argv [1], "pwm"    ) == 0) doPwm       (argc, argv) ;
1503
  else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite    (argc, argv) ;
1504
  else if (strcasecmp (argv [1], "aread"  ) == 0) doAread     (argc, argv) ;
1505

    
1506
// GPIO Nicies
1507

    
1508
  else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle    (argc, argv) ;
1509
  else if (strcasecmp (argv [1], "blink"  ) == 0) doBlink     (argc, argv) ;
1510

    
1511
// Pi Specifics
1512

    
1513
  else if (strcasecmp (argv [1], "pwm-bal"  ) == 0) doPwmMode    (PWM_MODE_BAL) ;
1514
  else if (strcasecmp (argv [1], "pwm-ms"   ) == 0) doPwmMode    (PWM_MODE_MS) ;
1515
  else if (strcasecmp (argv [1], "pwmr"     ) == 0) doPwmRange   (argc, argv) ;
1516
  else if (strcasecmp (argv [1], "pwmc"     ) == 0) doPwmClock   (argc, argv) ;
1517
  else if (strcasecmp (argv [1], "pwmTone"  ) == 0) doPwmTone    (argc, argv) ;
1518
  else if (strcasecmp (argv [1], "drive"    ) == 0) doPadDrive   (argc, argv) ;
1519
  else if (strcasecmp (argv [1], "readall"  ) == 0) doReadall    () ;
1520
  else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall    () ;
1521
  else if (strcasecmp (argv [1], "pins"     ) == 0) doReadall    () ;
1522
  else if (strcasecmp (argv [1], "qmode"    ) == 0) doQmode      (argc, argv) ;
1523
  else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect  (argc, argv) ;
1524
  else if (strcasecmp (argv [1], "i2cd"     ) == 0) doI2Cdetect  (argc, argv) ;
1525
  else if (strcasecmp (argv [1], "reset"    ) == 0) doReset      (argv [0]) ;
1526
  else if (strcasecmp (argv [1], "wb"       ) == 0) doWriteByte  (argc, argv) ;
1527
  else if (strcasecmp (argv [1], "rbx"      ) == 0) doReadByte   (argc, argv, TRUE) ;
1528
  else if (strcasecmp (argv [1], "rbd"      ) == 0) doReadByte   (argc, argv, FALSE) ;
1529
  else if (strcasecmp (argv [1], "clock"    ) == 0) doClock      (argc, argv) ;
1530
  else if (strcasecmp (argv [1], "wfi"      ) == 0) doWfi        (argc, argv) ;
1531
  else
1532
  {
1533
    fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
1534
    exit (EXIT_FAILURE) ;
1535
  }
1536

    
1537
  return 0 ;
1538
}