wiringpi2 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/ext/wiringpi/WiringPi/examples/blink.c +50 -0
  2. data/ext/wiringpi/WiringPi/examples/delayTest.c +107 -0
  3. data/ext/wiringpi/WiringPi/examples/ds1302.c +238 -0
  4. data/ext/wiringpi/WiringPi/examples/gertboard.c +94 -0
  5. data/ext/wiringpi/WiringPi/examples/header.h +23 -0
  6. data/ext/wiringpi/WiringPi/examples/isr-osc.c +118 -0
  7. data/ext/wiringpi/WiringPi/examples/isr.c +99 -0
  8. data/ext/wiringpi/WiringPi/examples/lcd.c +129 -0
  9. data/ext/wiringpi/WiringPi/examples/nes.c +67 -0
  10. data/ext/wiringpi/WiringPi/examples/okLed.c +83 -0
  11. data/ext/wiringpi/WiringPi/examples/piface.c +74 -0
  12. data/ext/wiringpi/WiringPi/examples/pwm.c +93 -0
  13. data/ext/wiringpi/WiringPi/examples/serialRead.c +48 -0
  14. data/ext/wiringpi/WiringPi/examples/serialTest.c +75 -0
  15. data/ext/wiringpi/WiringPi/examples/servo.c +57 -0
  16. data/ext/wiringpi/WiringPi/examples/speed.c +123 -0
  17. data/ext/wiringpi/WiringPi/examples/test1.c +111 -0
  18. data/ext/wiringpi/WiringPi/examples/test2.c +58 -0
  19. data/ext/wiringpi/WiringPi/examples/tone.c +59 -0
  20. data/ext/wiringpi/WiringPi/examples/wfi.c +161 -0
  21. data/ext/wiringpi/WiringPi/gpio/gpio.c +1371 -0
  22. data/ext/wiringpi/WiringPi/wiringPi/ds1302.c +239 -0
  23. data/ext/wiringpi/WiringPi/wiringPi/ds1302.h +44 -0
  24. data/ext/wiringpi/WiringPi/wiringPi/gertboard.c +166 -0
  25. data/ext/wiringpi/WiringPi/wiringPi/gertboard.h +40 -0
  26. data/ext/wiringpi/WiringPi/wiringPi/lcd.c +380 -0
  27. data/ext/wiringpi/WiringPi/wiringPi/lcd.h +46 -0
  28. data/ext/wiringpi/WiringPi/wiringPi/mcp23008.c +155 -0
  29. data/ext/wiringpi/WiringPi/wiringPi/mcp23008.h +33 -0
  30. data/ext/wiringpi/WiringPi/wiringPi/mcp23017.c +195 -0
  31. data/ext/wiringpi/WiringPi/wiringPi/mcp23017.h +33 -0
  32. data/ext/wiringpi/WiringPi/wiringPi/mcp23s08.c +195 -0
  33. data/ext/wiringpi/WiringPi/wiringPi/mcp23s08.h +33 -0
  34. data/ext/wiringpi/WiringPi/wiringPi/mcp23s17.c +236 -0
  35. data/ext/wiringpi/WiringPi/wiringPi/mcp23s17.h +33 -0
  36. data/ext/wiringpi/WiringPi/wiringPi/mcp23x08.h +73 -0
  37. data/ext/wiringpi/WiringPi/wiringPi/mcp23x0817.h +87 -0
  38. data/ext/wiringpi/WiringPi/wiringPi/piFace.c +179 -0
  39. data/ext/wiringpi/WiringPi/wiringPi/piFace.h +32 -0
  40. data/ext/wiringpi/WiringPi/wiringPi/piHiPri.c +50 -0
  41. data/ext/wiringpi/WiringPi/wiringPi/piNes.c +113 -0
  42. data/ext/wiringpi/WiringPi/wiringPi/piNes.h +45 -0
  43. data/ext/wiringpi/WiringPi/wiringPi/piThread.c +63 -0
  44. data/ext/wiringpi/WiringPi/wiringPi/softPwm.c +130 -0
  45. data/ext/wiringpi/WiringPi/wiringPi/softPwm.h +34 -0
  46. data/ext/wiringpi/WiringPi/wiringPi/softServo.c +211 -0
  47. data/ext/wiringpi/WiringPi/wiringPi/softServo.h +35 -0
  48. data/ext/wiringpi/WiringPi/wiringPi/softTone.c +121 -0
  49. data/ext/wiringpi/WiringPi/wiringPi/softTone.h +38 -0
  50. data/ext/wiringpi/WiringPi/wiringPi/sr595.c +108 -0
  51. data/ext/wiringpi/WiringPi/wiringPi/sr595.h +33 -0
  52. data/ext/wiringpi/WiringPi/wiringPi/wiringPi.c +1664 -0
  53. data/ext/wiringpi/WiringPi/wiringPi/wiringPi.h +168 -0
  54. data/ext/wiringpi/WiringPi/wiringPi/wiringPiI2C.c +227 -0
  55. data/ext/wiringpi/WiringPi/wiringPi/wiringPiI2C.h +42 -0
  56. data/ext/wiringpi/WiringPi/wiringPi/wiringPiSPI.c +119 -0
  57. data/ext/wiringpi/WiringPi/wiringPi/wiringPiSPI.h +35 -0
  58. data/ext/wiringpi/WiringPi/wiringPi/wiringSerial.c +213 -0
  59. data/ext/wiringpi/WiringPi/wiringPi/wiringSerial.h +38 -0
  60. data/ext/wiringpi/WiringPi/wiringPi/wiringShift.c +83 -0
  61. data/ext/wiringpi/WiringPi/wiringPi/wiringShift.h +41 -0
  62. data/ext/wiringpi/extconf.rb +8 -0
  63. data/ext/wiringpi/wiringpi_wrap.c +4378 -0
  64. data/lib/wiringpi/event.rb +21 -0
  65. data/lib/wiringpi/gpio.rb +131 -0
  66. data/lib/wiringpi/i2c.rb +26 -0
  67. data/lib/wiringpi/mcp23x17.rb +31 -0
  68. data/lib/wiringpi/serial.rb +49 -0
  69. data/lib/wiringpi/spi.rb +15 -0
  70. data/lib/wiringpi2.rb +42 -0
  71. metadata +122 -0
@@ -0,0 +1,111 @@
1
+ /*
2
+ * test1.c:
3
+ * Simple test program to test the wiringPi functions
4
+ * This is a sequencer to make a patter appear on 8 LEDs
5
+ * connected to the GPIO pins.
6
+ *
7
+ * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
8
+ ***********************************************************************
9
+ * This file is part of wiringPi:
10
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
11
+ *
12
+ * wiringPi is free software: you can redistribute it and/or modify
13
+ * it under the terms of the GNU Lesser General Public License as published by
14
+ * the Free Software Foundation, either version 3 of the License, or
15
+ * (at your option) any later version.
16
+ *
17
+ * wiringPi is distributed in the hope that it will be useful,
18
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ * GNU Lesser General Public License for more details.
21
+ *
22
+ * You should have received a copy of the GNU Lesser General Public License
23
+ * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
24
+ ***********************************************************************
25
+ */
26
+
27
+ #include <wiringPi.h>
28
+
29
+ #include <stdio.h>
30
+ #include <stdlib.h>
31
+ #include <stdint.h>
32
+
33
+
34
+ // Simple sequencer data
35
+ // Triplets of LED, On/Off and delay
36
+
37
+ uint8_t data [] =
38
+ {
39
+ 0, 1, 1,
40
+ 1, 1, 1,
41
+ 0, 0, 0, 2, 1, 1,
42
+ 1, 0, 0, 3, 1, 1,
43
+ 2, 0, 0, 4, 1, 1,
44
+ 3, 0, 0, 5, 1, 1,
45
+ 4, 0, 0, 6, 1, 1,
46
+ 5, 0, 0, 7, 1, 1,
47
+ 6, 0, 1,
48
+ 7, 0, 1,
49
+
50
+ 0, 0, 1, // Extra delay
51
+
52
+ // Back again
53
+
54
+ 7, 1, 1,
55
+ 6, 1, 1,
56
+ 7, 0, 0, 5, 1, 1,
57
+ 6, 0, 0, 4, 1, 1,
58
+ 5, 0, 0, 3, 1, 1,
59
+ 4, 0, 0, 2, 1, 1,
60
+ 3, 0, 0, 1, 1, 1,
61
+ 2, 0, 0, 0, 1, 1,
62
+ 1, 0, 1,
63
+ 0, 0, 1,
64
+
65
+ 0, 0, 1, // Extra delay
66
+
67
+ 9, 9, 9, // End marker
68
+
69
+ } ;
70
+
71
+
72
+ int main (void)
73
+ {
74
+ int pin ;
75
+ int dataPtr ;
76
+ int l, s, d ;
77
+
78
+ printf ("Raspberry Pi wiringPi test program\n") ;
79
+
80
+ if (wiringPiSetup () == -1)
81
+ exit (1) ;
82
+
83
+ for (pin = 0 ; pin < 8 ; ++pin)
84
+ pinMode (pin, OUTPUT) ;
85
+
86
+ pinMode (8, INPUT) ; // Pin 8 SDA0 - Has on-board 2k2 pull-up resistor
87
+
88
+ dataPtr = 0 ;
89
+
90
+ for (;;)
91
+ {
92
+ l = data [dataPtr++] ; // LED
93
+ s = data [dataPtr++] ; // State
94
+ d = data [dataPtr++] ; // Duration (10ths)
95
+
96
+ if ((l + s + d) == 27)
97
+ {
98
+ dataPtr = 0 ;
99
+ continue ;
100
+ }
101
+
102
+ digitalWrite (l, s) ;
103
+
104
+ if (digitalRead (8) == 0) // Pressed as our switch shorts to ground
105
+ delay (d * 10) ; // Faster!
106
+ else
107
+ delay (d * 100) ;
108
+ }
109
+
110
+ return 0 ;
111
+ }
@@ -0,0 +1,58 @@
1
+ /*
2
+ * test2.c:
3
+ * This tests the hardware PWM channel.
4
+ *
5
+ * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
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
+ #include <wiringPi.h>
26
+
27
+ #include <stdio.h>
28
+ #include <stdlib.h>
29
+ #include <stdint.h>
30
+
31
+ int main (void)
32
+ {
33
+ int bright ;
34
+
35
+ printf ("Raspberry Pi wiringPi PWM test program\n") ;
36
+
37
+ if (wiringPiSetup () == -1)
38
+ exit (1) ;
39
+
40
+ pinMode (1, PWM_OUTPUT) ;
41
+
42
+ for (;;)
43
+ {
44
+ for (bright = 0 ; bright < 1024 ; ++bright)
45
+ {
46
+ pwmWrite (1, bright) ;
47
+ delay (1) ;
48
+ }
49
+
50
+ for (bright = 1023 ; bright >= 0 ; --bright)
51
+ {
52
+ pwmWrite (1, bright) ;
53
+ delay (1) ;
54
+ }
55
+ }
56
+
57
+ return 0 ;
58
+ }
@@ -0,0 +1,59 @@
1
+ /*
2
+ * tone.c:
3
+ * Test of the softTone module in wiringPi
4
+ * Plays a scale out on pin 3 - connect pizeo disc to pin 3 & 0v
5
+ *
6
+ * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
7
+ ***********************************************************************
8
+ * This file is part of wiringPi:
9
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
10
+ *
11
+ * wiringPi is free software: you can redistribute it and/or modify
12
+ * it under the terms of the GNU Lesser General Public License as published by
13
+ * the Free Software Foundation, either version 3 of the License, or
14
+ * (at your option) any later version.
15
+ *
16
+ * wiringPi is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ * GNU Lesser General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU Lesser General Public License
22
+ * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
23
+ ***********************************************************************
24
+ */
25
+
26
+ #include <stdio.h>
27
+ #include <errno.h>
28
+ #include <string.h>
29
+
30
+ #include <wiringPi.h>
31
+ #include <softTone.h>
32
+
33
+ #define PIN 3
34
+
35
+ int scale [8] = { 262, 294, 330, 349, 392, 440, 494, 525 } ;
36
+
37
+ int main ()
38
+ {
39
+ int i ;
40
+
41
+ if (wiringPiSetup () == -1)
42
+ {
43
+ fprintf (stdout, "oops: %s\n", strerror (errno)) ;
44
+ return 1 ;
45
+ }
46
+
47
+ softToneCreate (PIN) ;
48
+
49
+ for (;;)
50
+ {
51
+ for (i = 0 ; i < 8 ; ++i)
52
+ {
53
+ printf ("%3d\n", i) ;
54
+ softToneWrite (PIN, scale [i]) ;
55
+ delay (500) ;
56
+ }
57
+ }
58
+
59
+ }
@@ -0,0 +1,161 @@
1
+ /*
2
+ * wfi.c:
3
+ * Wait for Interrupt test program
4
+ *
5
+ * This program demonstrates the use of the waitForInterrupt()
6
+ * function in wiringPi. It listens to a button input on
7
+ * BCM_GPIO pin 17 (wiringPi pin 0)
8
+ *
9
+ * The biggest issue with this method is that it really only works
10
+ * well in Sys mode.
11
+ *
12
+ * Jan 2013: This way of doing things is sort of deprecated now, see
13
+ * the wiringPiISR() function instead and the isr.c test program here.
14
+ *
15
+ * Copyright (c) 2012-2013 Gordon Henderson.
16
+ ***********************************************************************
17
+ * This file is part of wiringPi:
18
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
19
+ *
20
+ * wiringPi is free software: you can redistribute it and/or modify
21
+ * it under the terms of the GNU Lesser General Public License as published by
22
+ * the Free Software Foundation, either version 3 of the License, or
23
+ * (at your option) any later version.
24
+ *
25
+ * wiringPi is distributed in the hope that it will be useful,
26
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28
+ * GNU Lesser General Public License for more details.
29
+ *
30
+ * You should have received a copy of the GNU Lesser General Public License
31
+ * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
32
+ ***********************************************************************
33
+ */
34
+
35
+ #include <stdio.h>
36
+ #include <stdlib.h>
37
+ #include <wiringPi.h>
38
+
39
+ // A 'key' which we can lock and unlock - values are 0 through 3
40
+ // This is interpreted internally as a pthread_mutex by wiringPi
41
+ // which is hiding some of that to make life simple.
42
+
43
+ #define COUNT_KEY 0
44
+
45
+ // What BCM_GPIO input are we using?
46
+
47
+ #define BUTTON_PIN 17
48
+
49
+ // Debounce time in mS
50
+
51
+ #define DEBOUNCE_TIME 100
52
+
53
+
54
+ // globalCounter:
55
+ // Global variable to count interrupts
56
+ // Should be declared volatile to make sure the compiler doesn't cache it.
57
+
58
+ static volatile int globalCounter = 0 ;
59
+
60
+
61
+ /*
62
+ * waitForIt:
63
+ * This is a thread created using the wiringPi simplified threading
64
+ * mechanism. It will wait on an interrupt on the button and increment
65
+ * a counter.
66
+ *********************************************************************************
67
+ */
68
+
69
+ PI_THREAD (waitForIt)
70
+ {
71
+ int state = 0 ;
72
+ int debounceTime = 0 ;
73
+
74
+ (void)piHiPri (10) ; // Set this thread to be high priority
75
+
76
+ for (;;)
77
+ {
78
+ if (waitForInterrupt (BUTTON_PIN, -1) > 0) // Got it
79
+ {
80
+ // Bouncing?
81
+
82
+ if (millis () < debounceTime)
83
+ {
84
+ debounceTime = millis () + DEBOUNCE_TIME ;
85
+ continue ;
86
+ }
87
+
88
+ // We have a valid one
89
+
90
+ state ^= 1 ;
91
+
92
+ piLock (COUNT_KEY) ;
93
+ ++globalCounter ;
94
+ piUnlock (COUNT_KEY) ;
95
+
96
+ // Wait for key to be released
97
+
98
+ while (digitalRead (BUTTON_PIN) == LOW)
99
+ delay (1) ;
100
+
101
+ debounceTime = millis () + DEBOUNCE_TIME ;
102
+ }
103
+ }
104
+ }
105
+
106
+
107
+ /*
108
+ * setup:
109
+ * Demo a crude but effective way to initialise the hardware
110
+ *********************************************************************************
111
+ */
112
+
113
+ void setup (void)
114
+ {
115
+
116
+ // Use the gpio program to initialise the hardware
117
+ // (This is the crude, but effective)
118
+
119
+ system ("gpio edge 17 falling") ;
120
+
121
+ // Setup wiringPi
122
+
123
+ wiringPiSetupSys () ;
124
+
125
+ // Fire off our interrupt handler
126
+
127
+ piThreadCreate (waitForIt) ;
128
+
129
+ }
130
+
131
+
132
+ /*
133
+ * main
134
+ *********************************************************************************
135
+ */
136
+
137
+ int main (void)
138
+ {
139
+ int lastCounter = 0 ;
140
+ int myCounter = 0 ;
141
+
142
+ setup () ;
143
+
144
+ for (;;)
145
+ {
146
+ printf ("Waiting ... ") ; fflush (stdout) ;
147
+
148
+ while (myCounter == lastCounter)
149
+ {
150
+ piLock (COUNT_KEY) ;
151
+ myCounter = globalCounter ;
152
+ piUnlock (COUNT_KEY) ;
153
+ delay (500) ;
154
+ }
155
+
156
+ printf (" Done. myCounter: %5d\n", myCounter) ;
157
+ lastCounter = myCounter ;
158
+ }
159
+
160
+ return 0 ;
161
+ }
@@ -0,0 +1,1371 @@
1
+ /*
2
+ * gpio.c:
3
+ * Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
4
+ * Pi's GPIO.
5
+ * Copyright (c) 2012-2013 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 <sys/types.h>
34
+ #include <fcntl.h>
35
+
36
+ #include <wiringPi.h>
37
+
38
+ #include <gertboard.h>
39
+ #include <piFace.h>
40
+ #include <sr595.h>
41
+ #include <mcp23008.h>
42
+ #include <mcp23017.h>
43
+ #include <mcp23s08.h>
44
+ #include <mcp23s17.h>
45
+
46
+ extern int wiringPiDebug ;
47
+
48
+ #ifndef TRUE
49
+ # define TRUE (1==1)
50
+ # define FALSE (1==2)
51
+ #endif
52
+
53
+ #define VERSION "2.00"
54
+
55
+ static int wpMode ;
56
+
57
+ char *usage = "Usage: gpio -v\n"
58
+ " gpio -h\n"
59
+ " gpio [-g|-1] [-x module:params] ...\n"
60
+ " gpio [-p] <read/write/wb> ...\n"
61
+ " gpio <read/write/aread/awritewb/pwm/clock/mode> ...\n"
62
+ " gpio readall/reset\n"
63
+ " gpio unexportall/exports\n"
64
+ " gpio export/edge/unexport ...\n"
65
+ " gpio drive <group> <value>\n"
66
+ " gpio pwm-bal/pwm-ms \n"
67
+ " gpio pwmr <range> \n"
68
+ " gpio pwmc <divider> \n"
69
+ " gpio load spi/i2c\n"
70
+ " gpio gbr <channel>\n"
71
+ " gpio gbw <channel> <value>" ; // No trailing newline needed here.
72
+
73
+ struct moduleFunctionStruct
74
+ {
75
+ const char *name ;
76
+ int (*function)(char *progName, int pinBase, char *params) ;
77
+ } ;
78
+
79
+ static int doModuleMcp23008 (char *progName, int pinBase, char *params)
80
+ {
81
+ int i2c ;
82
+
83
+ // Extract the I2C address:
84
+
85
+ if (*params != ':')
86
+ {
87
+ fprintf (stderr, "%s: colon expected after pin-base number\n", progName) ;
88
+ return FALSE ;
89
+ }
90
+
91
+ ++params ;
92
+ if (!isdigit (*params))
93
+ {
94
+ fprintf (stderr, "%s: digit expected after pin-base number\n", progName) ;
95
+ return FALSE ;
96
+ }
97
+
98
+ i2c = strtol (params, NULL, 0) ;
99
+ if ((i2c < 0x03) || (i2c > 0x77))
100
+ {
101
+ fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
102
+ return FALSE ;
103
+ }
104
+
105
+ mcp23008Setup (pinBase, i2c) ;
106
+
107
+ return TRUE ;
108
+ }
109
+
110
+ static int doModuleMcp23017 (char *progName, int pinBase, char *params)
111
+ {
112
+ int i2c ;
113
+
114
+ // Extract the I2C address:
115
+
116
+ if (*params != ':')
117
+ {
118
+ fprintf (stderr, "%s: colon expected after pin-base number\n", progName) ;
119
+ return FALSE ;
120
+ }
121
+
122
+ ++params ;
123
+ if (!isdigit (*params))
124
+ {
125
+ fprintf (stderr, "%s: digit expected after pin-base number\n", progName) ;
126
+ return FALSE ;
127
+ }
128
+
129
+ i2c = strtol (params, NULL, 0) ;
130
+ if ((i2c < 0x03) || (i2c > 0x77))
131
+ {
132
+ fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
133
+ return FALSE ;
134
+ }
135
+
136
+ mcp23017Setup (pinBase, i2c) ;
137
+
138
+ return TRUE ;
139
+ }
140
+
141
+ static int doModuleMcp23s08 (char *progName, int pinBase, char *params)
142
+ {
143
+ int spi, port ;
144
+
145
+ // Extract the SPI address:
146
+
147
+ if (*params != ':')
148
+ {
149
+ fprintf (stderr, "%s: colon expected after pin-base number\n", progName) ;
150
+ return FALSE ;
151
+ }
152
+
153
+ ++params ;
154
+ if (!isdigit (*params))
155
+ {
156
+ fprintf (stderr, "%s: digit expected after pin-base number\n", progName) ;
157
+ return FALSE ;
158
+ }
159
+
160
+ spi = *params - '0' ;
161
+ if ((spi < 0) || (spi > 1))
162
+ {
163
+ fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
164
+ return FALSE ;
165
+ }
166
+
167
+ // Extract the port:
168
+
169
+ if (*++params != ':')
170
+ {
171
+ fprintf (stderr, "%s: colon expected after SPI address\n", progName) ;
172
+ return FALSE ;
173
+ }
174
+
175
+ ++params ;
176
+ if (!isdigit (*params))
177
+ {
178
+ fprintf (stderr, "%s: digit expected after SPI address\n", progName) ;
179
+ return FALSE ;
180
+ }
181
+
182
+ port = strtol (params, NULL, 0) ;
183
+ if ((port < 0) || (port > 7))
184
+ {
185
+ fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
186
+ return FALSE ;
187
+ }
188
+
189
+ mcp23s08Setup (pinBase, spi, port) ;
190
+
191
+ return TRUE ;
192
+ }
193
+
194
+ static int doModuleMcp23s17 (char *progName, int pinBase, char *params)
195
+ {
196
+ int spi, port ;
197
+
198
+ // Extract the SPI address:
199
+
200
+ if (*params != ':')
201
+ {
202
+ fprintf (stderr, "%s: colon expected after pin-base number\n", progName) ;
203
+ return FALSE ;
204
+ }
205
+
206
+ ++params ;
207
+ if (!isdigit (*params))
208
+ {
209
+ fprintf (stderr, "%s: digit expected after pin-base number\n", progName) ;
210
+ return FALSE ;
211
+ }
212
+
213
+ spi = *params - '0' ;
214
+ if ((spi < 0) || (spi > 1))
215
+ {
216
+ fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
217
+ return FALSE ;
218
+ }
219
+
220
+ // Extract the port:
221
+
222
+ if (*++params != ':')
223
+ {
224
+ fprintf (stderr, "%s: colon expected after SPI address\n", progName) ;
225
+ return FALSE ;
226
+ }
227
+
228
+ ++params ;
229
+ if (!isdigit (*params))
230
+ {
231
+ fprintf (stderr, "%s: digit expected after SPI address\n", progName) ;
232
+ return FALSE ;
233
+ }
234
+
235
+ port = strtol (params, NULL, 0) ;
236
+ if ((port < 0) || (port > 7))
237
+ {
238
+ fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
239
+ return FALSE ;
240
+ }
241
+
242
+ mcp23s17Setup (pinBase, spi, port) ;
243
+
244
+ return TRUE ;
245
+ }
246
+
247
+
248
+ struct moduleFunctionStruct moduleFunctions [] =
249
+ {
250
+ { "mcp23008", &doModuleMcp23008 },
251
+ { "mcp23017", &doModuleMcp23017 },
252
+ { "mcp23s08", &doModuleMcp23s08 },
253
+ { "mcp23s17", &doModuleMcp23s17 },
254
+ { NULL, NULL },
255
+ } ;
256
+
257
+
258
+
259
+
260
+
261
+ /*
262
+ * changeOwner:
263
+ * Change the ownership of the file to the real userId of the calling
264
+ * program so we can access it.
265
+ *********************************************************************************
266
+ */
267
+
268
+ static void changeOwner (char *cmd, char *file)
269
+ {
270
+ uid_t uid = getuid () ;
271
+ uid_t gid = getgid () ;
272
+
273
+ if (chown (file, uid, gid) != 0)
274
+ {
275
+ if (errno == ENOENT) // Warn that it's not there
276
+ fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ;
277
+ else
278
+ {
279
+ fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
280
+ exit (1) ;
281
+ }
282
+ }
283
+ }
284
+
285
+
286
+ /*
287
+ * moduleLoaded:
288
+ * Return true/false if the supplied module is loaded
289
+ *********************************************************************************
290
+ */
291
+
292
+ static int moduleLoaded (char *modName)
293
+ {
294
+ int len = strlen (modName) ;
295
+ int found = FALSE ;
296
+ FILE *fd = fopen ("/proc/modules", "r") ;
297
+ char line [80] ;
298
+
299
+ if (fd == NULL)
300
+ {
301
+ fprintf (stderr, "gpio: Unable to check modules: %s\n", strerror (errno)) ;
302
+ exit (1) ;
303
+ }
304
+
305
+ while (fgets (line, 80, fd) != NULL)
306
+ {
307
+ if (strncmp (line, modName, len) != 0)
308
+ continue ;
309
+
310
+ found = TRUE ;
311
+ break ;
312
+ }
313
+
314
+ fclose (fd) ;
315
+
316
+ return found ;
317
+ }
318
+
319
+
320
+ /*
321
+ * doLoad:
322
+ * Load either the spi or i2c modules and change device ownerships, etc.
323
+ *********************************************************************************
324
+ */
325
+
326
+ static void _doLoadUsage (char *argv [])
327
+ {
328
+ fprintf (stderr, "Usage: %s load <spi/i2c> [SPI bufferSize in KB | I2C baudrate in Kb/sec]\n", argv [0]) ;
329
+ exit (1) ;
330
+ }
331
+
332
+ static void doLoad (int argc, char *argv [])
333
+ {
334
+ char *module1, *module2 ;
335
+ char cmd [80] ;
336
+ char *file1, *file2 ;
337
+ char args1 [32], args2 [32] ;
338
+
339
+ if (argc < 3)
340
+ _doLoadUsage (argv) ;
341
+
342
+ args1 [0] = args2 [0] = 0 ;
343
+
344
+ /**/ if (strcasecmp (argv [2], "spi") == 0)
345
+ {
346
+ module1 = "spidev" ;
347
+ module2 = "spi_bcm2708" ;
348
+ file1 = "/dev/spidev0.0" ;
349
+ file2 = "/dev/spidev0.1" ;
350
+ if (argc == 4)
351
+ sprintf (args1, " bufsiz=%d", atoi (argv [3]) * 1024) ;
352
+ else if (argc > 4)
353
+ _doLoadUsage (argv) ;
354
+ }
355
+ else if (strcasecmp (argv [2], "i2c") == 0)
356
+ {
357
+ module1 = "i2c_dev" ;
358
+ module2 = "i2c_bcm2708" ;
359
+ file1 = "/dev/i2c-0" ;
360
+ file2 = "/dev/i2c-1" ;
361
+ if (argc == 4)
362
+ sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ;
363
+ else if (argc > 4)
364
+ _doLoadUsage (argv) ;
365
+ }
366
+ else
367
+ _doLoadUsage (argv) ;
368
+
369
+ if (!moduleLoaded (module1))
370
+ {
371
+ sprintf (cmd, "modprobe %s%s", module1, args1) ;
372
+ system (cmd) ;
373
+ }
374
+
375
+ if (!moduleLoaded (module2))
376
+ {
377
+ sprintf (cmd, "modprobe %s%s", module2, args2) ;
378
+ system (cmd) ;
379
+ }
380
+
381
+ if (!moduleLoaded (module2))
382
+ {
383
+ fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ;
384
+ exit (1) ;
385
+ }
386
+
387
+ sleep (1) ; // To let things get settled
388
+
389
+ changeOwner (argv [0], file1) ;
390
+ changeOwner (argv [0], file2) ;
391
+ }
392
+
393
+
394
+ /*
395
+ * doReadall:
396
+ * Read all the GPIO pins
397
+ *********************************************************************************
398
+ */
399
+
400
+ static char *pinNames [] =
401
+ {
402
+ "GPIO 0", "GPIO 1", "GPIO 2", "GPIO 3", "GPIO 4", "GPIO 5", "GPIO 6", "GPIO 7",
403
+ "SDA ", "SCL ",
404
+ "CE0 ", "CE1 ", "MOSI ", "MISO ", "SCLK ",
405
+ "TxD ", "RxD ",
406
+ "GPIO 8", "GPIO 9", "GPIO10", "GPIO11",
407
+ } ;
408
+
409
+ static char *alts [] =
410
+ {
411
+ "IN ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3"
412
+ } ;
413
+
414
+ static int wpiToPhys [64] =
415
+ {
416
+ 11, 12, 13, 15, 16, 18, 22, 7, // 0...7
417
+ 3, 5, // 8...9
418
+ 24, 26, 19, 21, 23, // 10..14
419
+ 8, 10, // 15..16
420
+ 3, 4, 5, 6, // 17..20
421
+ 0,0,0,0,0,0,0,0,0,0,0, // 20..31
422
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 32..47
423
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 47..63
424
+ } ;
425
+
426
+ static void doReadall (void)
427
+ {
428
+ int pin ;
429
+
430
+ printf ("+----------+-Rev%d-+------+--------+------+-------+\n", piBoardRev ()) ;
431
+ printf ("| wiringPi | GPIO | Phys | Name | Mode | Value |\n") ;
432
+ printf ("+----------+------+------+--------+------+-------+\n") ;
433
+
434
+ for (pin = 0 ; pin < 64 ; ++pin)
435
+ {
436
+ if (wpiPinToGpio (pin) == -1)
437
+ continue ;
438
+
439
+ printf ("| %6d | %3d | %3d | %s | %s | %s |\n",
440
+ pin, wpiPinToGpio (pin), wpiToPhys [pin],
441
+ pinNames [pin],
442
+ alts [getAlt (pin)],
443
+ digitalRead (pin) == HIGH ? "High" : "Low ") ;
444
+ }
445
+
446
+ printf ("+----------+------+------+--------+------+-------+\n") ;
447
+ }
448
+
449
+
450
+ /*
451
+ * doExports:
452
+ * List all GPIO exports
453
+ *********************************************************************************
454
+ */
455
+
456
+ static void doExports (int argc, char *argv [])
457
+ {
458
+ int fd ;
459
+ int i, l, first ;
460
+ char fName [128] ;
461
+ char buf [16] ;
462
+
463
+ // Rather crude, but who knows what others are up to...
464
+
465
+ for (first = 0, i = 0 ; i < 64 ; ++i)
466
+ {
467
+
468
+ // Try to read the direction
469
+
470
+ sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
471
+ if ((fd = open (fName, O_RDONLY)) == -1)
472
+ continue ;
473
+
474
+ if (first == 0)
475
+ {
476
+ ++first ;
477
+ printf ("GPIO Pins exported:\n") ;
478
+ }
479
+
480
+ printf ("%4d: ", i) ;
481
+
482
+ if ((l = read (fd, buf, 16)) == 0)
483
+ sprintf (buf, "%s", "?") ;
484
+
485
+ buf [l] = 0 ;
486
+ if ((buf [strlen (buf) - 1]) == '\n')
487
+ buf [strlen (buf) - 1] = 0 ;
488
+
489
+ printf ("%-3s", buf) ;
490
+
491
+ close (fd) ;
492
+
493
+ // Try to Read the value
494
+
495
+ sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
496
+ if ((fd = open (fName, O_RDONLY)) == -1)
497
+ {
498
+ printf ("No Value file (huh?)\n") ;
499
+ continue ;
500
+ }
501
+
502
+ if ((l = read (fd, buf, 16)) == 0)
503
+ sprintf (buf, "%s", "?") ;
504
+
505
+ buf [l] = 0 ;
506
+ if ((buf [strlen (buf) - 1]) == '\n')
507
+ buf [strlen (buf) - 1] = 0 ;
508
+
509
+ printf (" %s", buf) ;
510
+
511
+ // Read any edge trigger file
512
+
513
+ sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ;
514
+ if ((fd = open (fName, O_RDONLY)) == -1)
515
+ {
516
+ printf ("\n") ;
517
+ continue ;
518
+ }
519
+
520
+ if ((l = read (fd, buf, 16)) == 0)
521
+ sprintf (buf, "%s", "?") ;
522
+
523
+ buf [l] = 0 ;
524
+ if ((buf [strlen (buf) - 1]) == '\n')
525
+ buf [strlen (buf) - 1] = 0 ;
526
+
527
+ printf (" %-8s\n", buf) ;
528
+
529
+ close (fd) ;
530
+ }
531
+ }
532
+
533
+
534
+ /*
535
+ * doExport:
536
+ * gpio export pin mode
537
+ * This uses the /sys/class/gpio device interface.
538
+ *********************************************************************************
539
+ */
540
+
541
+ void doExport (int argc, char *argv [])
542
+ {
543
+ FILE *fd ;
544
+ int pin ;
545
+ char *mode ;
546
+ char fName [128] ;
547
+
548
+ if (argc != 4)
549
+ {
550
+ fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
551
+ exit (1) ;
552
+ }
553
+
554
+ pin = atoi (argv [2]) ;
555
+
556
+ mode = argv [3] ;
557
+
558
+ if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
559
+ {
560
+ fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
561
+ exit (1) ;
562
+ }
563
+
564
+ fprintf (fd, "%d\n", pin) ;
565
+ fclose (fd) ;
566
+
567
+ sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
568
+ if ((fd = fopen (fName, "w")) == NULL)
569
+ {
570
+ fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
571
+ exit (1) ;
572
+ }
573
+
574
+ /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
575
+ fprintf (fd, "in\n") ;
576
+ else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
577
+ fprintf (fd, "out\n") ;
578
+ else
579
+ {
580
+ fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ;
581
+ exit (1) ;
582
+ }
583
+
584
+ fclose (fd) ;
585
+
586
+ // Change ownership so the current user can actually use it!
587
+
588
+ sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
589
+ changeOwner (argv [0], fName) ;
590
+
591
+ sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
592
+ changeOwner (argv [0], fName) ;
593
+
594
+ }
595
+
596
+
597
+ /*
598
+ * doEdge:
599
+ * gpio edge pin mode
600
+ * Easy access to changing the edge trigger on a GPIO pin
601
+ * This uses the /sys/class/gpio device interface.
602
+ *********************************************************************************
603
+ */
604
+
605
+ void doEdge (int argc, char *argv [])
606
+ {
607
+ FILE *fd ;
608
+ int pin ;
609
+ char *mode ;
610
+ char fName [128] ;
611
+
612
+ if (argc != 4)
613
+ {
614
+ fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
615
+ exit (1) ;
616
+ }
617
+
618
+ pin = atoi (argv [2]) ;
619
+ mode = argv [3] ;
620
+
621
+ // Export the pin and set direction to input
622
+
623
+ if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
624
+ {
625
+ fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
626
+ exit (1) ;
627
+ }
628
+
629
+ fprintf (fd, "%d\n", pin) ;
630
+ fclose (fd) ;
631
+
632
+ sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
633
+ if ((fd = fopen (fName, "w")) == NULL)
634
+ {
635
+ fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
636
+ exit (1) ;
637
+ }
638
+
639
+ fprintf (fd, "in\n") ;
640
+ fclose (fd) ;
641
+
642
+ sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
643
+ if ((fd = fopen (fName, "w")) == NULL)
644
+ {
645
+ fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
646
+ exit (1) ;
647
+ }
648
+
649
+ /**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
650
+ else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
651
+ else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
652
+ else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
653
+ else
654
+ {
655
+ fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
656
+ exit (1) ;
657
+ }
658
+
659
+ // Change ownership of the value and edge files, so the current user can actually use it!
660
+
661
+ sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
662
+ changeOwner (argv [0], fName) ;
663
+
664
+ sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
665
+ changeOwner (argv [0], fName) ;
666
+
667
+ fclose (fd) ;
668
+ }
669
+
670
+
671
+ /*
672
+ * doUnexport:
673
+ * gpio unexport pin
674
+ * This uses the /sys/class/gpio device interface.
675
+ *********************************************************************************
676
+ */
677
+
678
+ void doUnexport (int argc, char *argv [])
679
+ {
680
+ FILE *fd ;
681
+ int pin ;
682
+
683
+ if (argc != 3)
684
+ {
685
+ fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
686
+ exit (1) ;
687
+ }
688
+
689
+ pin = atoi (argv [2]) ;
690
+
691
+ if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
692
+ {
693
+ fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
694
+ exit (1) ;
695
+ }
696
+
697
+ fprintf (fd, "%d\n", pin) ;
698
+ fclose (fd) ;
699
+ }
700
+
701
+
702
+ /*
703
+ * doUnexportAll:
704
+ * gpio unexportall
705
+ * Un-Export all the GPIO pins.
706
+ * This uses the /sys/class/gpio device interface.
707
+ *********************************************************************************
708
+ */
709
+
710
+ void doUnexportall (char *progName)
711
+ {
712
+ FILE *fd ;
713
+ int pin ;
714
+
715
+ for (pin = 0 ; pin < 63 ; ++pin)
716
+ {
717
+ if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
718
+ {
719
+ fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
720
+ exit (1) ;
721
+ }
722
+ fprintf (fd, "%d\n", pin) ;
723
+ fclose (fd) ;
724
+ }
725
+ }
726
+
727
+
728
+ /*
729
+ * doReset:
730
+ * Reset the GPIO pins - as much as we can do
731
+ *********************************************************************************
732
+ */
733
+
734
+ static void doReset (char *progName)
735
+ {
736
+ int pin ;
737
+
738
+ doUnexportall (progName) ;
739
+
740
+ for (pin = 0 ; pin < 64 ; ++pin)
741
+ {
742
+ if (wpiPinToGpio (pin) == -1)
743
+ continue ;
744
+
745
+ digitalWrite (pin, LOW) ;
746
+ pinMode (pin, INPUT) ;
747
+ pullUpDnControl (pin, PUD_OFF) ;
748
+ }
749
+ }
750
+
751
+
752
+ /*
753
+ * doMode:
754
+ * gpio mode pin mode ...
755
+ *********************************************************************************
756
+ */
757
+
758
+ void doMode (int argc, char *argv [])
759
+ {
760
+ int pin ;
761
+ char *mode ;
762
+
763
+ if (argc != 4)
764
+ {
765
+ fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
766
+ exit (1) ;
767
+ }
768
+
769
+ pin = atoi (argv [2]) ;
770
+
771
+ mode = argv [3] ;
772
+
773
+ /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
774
+ else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
775
+ else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
776
+ else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ;
777
+ else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
778
+ else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
779
+ else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
780
+ else
781
+ {
782
+ fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ;
783
+ exit (1) ;
784
+ }
785
+ }
786
+
787
+
788
+ /*
789
+ * doPadDrive:
790
+ * gpio drive group value
791
+ *********************************************************************************
792
+ */
793
+
794
+ static void doPadDrive (int argc, char *argv [])
795
+ {
796
+ int group, val ;
797
+
798
+ if (argc != 4)
799
+ {
800
+ fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
801
+ exit (1) ;
802
+ }
803
+
804
+ group = atoi (argv [2]) ;
805
+ val = atoi (argv [3]) ;
806
+
807
+ if ((group < 0) || (group > 2))
808
+ {
809
+ fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
810
+ exit (1) ;
811
+ }
812
+
813
+ if ((val < 0) || (val > 7))
814
+ {
815
+ fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
816
+ exit (1) ;
817
+ }
818
+
819
+ setPadDrive (group, val) ;
820
+ }
821
+
822
+
823
+ /*
824
+ * doGbw:
825
+ * gpio gbw channel value
826
+ * Gertboard Write - To the Analog output
827
+ *********************************************************************************
828
+ */
829
+
830
+ static void doGbw (int argc, char *argv [])
831
+ {
832
+ int channel, value ;
833
+
834
+ if (argc != 4)
835
+ {
836
+ fprintf (stderr, "Usage: %s gbr <channel> <value>\n", argv [0]) ;
837
+ exit (1) ;
838
+ }
839
+
840
+ channel = atoi (argv [2]) ;
841
+ value = atoi (argv [3]) ;
842
+
843
+ if ((channel < 0) || (channel > 1))
844
+ {
845
+ fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
846
+ exit (1) ;
847
+ }
848
+
849
+ if ((value < 0) || (value > 1023))
850
+ {
851
+ fprintf (stderr, "%s: value must be from 0 to 255\n", argv [0]) ;
852
+ exit (1) ;
853
+ }
854
+
855
+ if (gertboardAnalogSetup (64) < 0)
856
+ {
857
+ fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
858
+ exit (1) ;
859
+ }
860
+
861
+ analogWrite (64 + channel, value) ;
862
+ }
863
+
864
+
865
+ /*
866
+ * doGbr:
867
+ * gpio gbr channel
868
+ * From the analog input
869
+ *********************************************************************************
870
+ */
871
+
872
+ static void doGbr (int argc, char *argv [])
873
+ {
874
+ int channel ;
875
+
876
+ if (argc != 3)
877
+ {
878
+ fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
879
+ exit (1) ;
880
+ }
881
+
882
+ channel = atoi (argv [2]) ;
883
+
884
+ if ((channel < 0) || (channel > 1))
885
+ {
886
+ fprintf (stderr, "%s: channel must be 0 or 1\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
+ printf ("%d\n", analogRead (64 + channel)) ;
897
+ }
898
+
899
+
900
+ /*
901
+ * doWrite:
902
+ * gpio write pin value
903
+ *********************************************************************************
904
+ */
905
+
906
+ static void doWrite (int argc, char *argv [])
907
+ {
908
+ int pin, val ;
909
+
910
+ if (argc != 4)
911
+ {
912
+ fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
913
+ exit (1) ;
914
+ }
915
+
916
+ pin = atoi (argv [2]) ;
917
+
918
+ /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
919
+ val = 1 ;
920
+ else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
921
+ val = 0 ;
922
+ else
923
+ val = atoi (argv [3]) ;
924
+
925
+ /**/ if (val == 0)
926
+ digitalWrite (pin, LOW) ;
927
+ else
928
+ digitalWrite (pin, HIGH) ;
929
+ }
930
+
931
+
932
+ /*
933
+ * doAwriterite:
934
+ * gpio awrite pin value
935
+ *********************************************************************************
936
+ */
937
+
938
+ static void doAwrite (int argc, char *argv [])
939
+ {
940
+ int pin, val ;
941
+
942
+ if (argc != 4)
943
+ {
944
+ fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
945
+ exit (1) ;
946
+ }
947
+
948
+ pin = atoi (argv [2]) ;
949
+
950
+ val = atoi (argv [3]) ;
951
+
952
+ analogWrite (pin, val) ;
953
+ }
954
+
955
+
956
+ /*
957
+ * doWriteByte:
958
+ * gpio write value
959
+ *********************************************************************************
960
+ */
961
+
962
+ static void doWriteByte (int argc, char *argv [])
963
+ {
964
+ int val ;
965
+
966
+ if (argc != 3)
967
+ {
968
+ fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
969
+ exit (1) ;
970
+ }
971
+
972
+ val = (int)strtol (argv [2], NULL, 0) ;
973
+
974
+ digitalWriteByte (val) ;
975
+ }
976
+
977
+
978
+ /*
979
+ * doRead:
980
+ * Read a pin and return the value
981
+ *********************************************************************************
982
+ */
983
+
984
+ void doRead (int argc, char *argv [])
985
+ {
986
+ int pin, val ;
987
+
988
+ if (argc != 3)
989
+ {
990
+ fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
991
+ exit (1) ;
992
+ }
993
+
994
+ pin = atoi (argv [2]) ;
995
+
996
+ val = digitalRead (pin) ;
997
+
998
+ printf ("%s\n", val == 0 ? "0" : "1") ;
999
+ }
1000
+
1001
+
1002
+ /*
1003
+ * doAread:
1004
+ * Read an analog pin and return the value
1005
+ *********************************************************************************
1006
+ */
1007
+
1008
+ void doAread (int argc, char *argv [])
1009
+ {
1010
+ int pin, val ;
1011
+
1012
+ if (argc != 3)
1013
+ {
1014
+ fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
1015
+ exit (1) ;
1016
+ }
1017
+
1018
+ pin = atoi (argv [2]) ;
1019
+
1020
+ val = analogRead (pin) ;
1021
+
1022
+ printf ("%s\n", val == 0 ? "0" : "1") ;
1023
+ }
1024
+
1025
+
1026
+ /*
1027
+ * doClock:
1028
+ * Output a clock on a pin
1029
+ *********************************************************************************
1030
+ */
1031
+
1032
+ void doClock (int argc, char *argv [])
1033
+ {
1034
+ int pin, freq ;
1035
+
1036
+ if (argc != 4)
1037
+ {
1038
+ fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
1039
+ exit (1) ;
1040
+ }
1041
+
1042
+ pin = atoi (argv [2]) ;
1043
+
1044
+ freq = atoi (argv [3]) ;
1045
+
1046
+ gpioClockSet (pin, freq) ;
1047
+ }
1048
+
1049
+
1050
+ /*
1051
+ * doPwm:
1052
+ * Output a PWM value on a pin
1053
+ *********************************************************************************
1054
+ */
1055
+
1056
+ void doPwm (int argc, char *argv [])
1057
+ {
1058
+ int pin, val ;
1059
+
1060
+ if (argc != 4)
1061
+ {
1062
+ fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
1063
+ exit (1) ;
1064
+ }
1065
+
1066
+ pin = atoi (argv [2]) ;
1067
+
1068
+ val = atoi (argv [3]) ;
1069
+
1070
+ pwmWrite (pin, val) ;
1071
+ }
1072
+
1073
+
1074
+ /*
1075
+ * doPwmMode: doPwmRange: doPwmClock:
1076
+ * Change the PWM mode, range and clock divider values
1077
+ *********************************************************************************
1078
+ */
1079
+
1080
+ static void doPwmMode (int mode)
1081
+ {
1082
+ pwmSetMode (mode) ;
1083
+ }
1084
+
1085
+ static void doPwmRange (int argc, char *argv [])
1086
+ {
1087
+ unsigned int range ;
1088
+
1089
+ if (argc != 3)
1090
+ {
1091
+ fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
1092
+ exit (1) ;
1093
+ }
1094
+
1095
+ range = (unsigned int)strtoul (argv [2], NULL, 10) ;
1096
+
1097
+ if (range == 0)
1098
+ {
1099
+ fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
1100
+ exit (1) ;
1101
+ }
1102
+
1103
+ pwmSetRange (range) ;
1104
+ }
1105
+
1106
+ static void doPwmClock (int argc, char *argv [])
1107
+ {
1108
+ unsigned int clock ;
1109
+
1110
+ if (argc != 3)
1111
+ {
1112
+ fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
1113
+ exit (1) ;
1114
+ }
1115
+
1116
+ clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
1117
+
1118
+ if ((clock < 1) || (clock > 4095))
1119
+ {
1120
+ fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
1121
+ exit (1) ;
1122
+ }
1123
+
1124
+ pwmSetClock (clock) ;
1125
+ }
1126
+
1127
+
1128
+ /*
1129
+ * doModule:
1130
+ * Load in a wiringPi extension module
1131
+ *********************************************************************************
1132
+ */
1133
+
1134
+ static int doModule (char *progName, char *moduleData)
1135
+ {
1136
+ char *p ;
1137
+ char *module = moduleData ;
1138
+ struct moduleFunctionStruct *modFn ;
1139
+ int pinBase = 0 ;
1140
+
1141
+ // Get the module name by finding the first :
1142
+
1143
+ p = module ;
1144
+ while (*p != ':')
1145
+ {
1146
+ if (!*p) // ran out of characters
1147
+ {
1148
+ fprintf (stderr, "%s: module name not terminated by a colon\n", progName) ;
1149
+ return FALSE ;
1150
+ }
1151
+ ++p ;
1152
+ }
1153
+
1154
+ *p++ = 0 ;
1155
+
1156
+ if (!isdigit (*p))
1157
+ {
1158
+ fprintf (stderr, "%s: pinBase number expected after module name\n", progName) ;
1159
+ return FALSE ;
1160
+ }
1161
+
1162
+ while (isdigit (*p))
1163
+ {
1164
+ if (pinBase > 1000000000)
1165
+ {
1166
+ fprintf (stderr, "%s: pinBase too large\n", progName) ;
1167
+ return FALSE ;
1168
+ }
1169
+
1170
+ pinBase = pinBase * 10 + (*p - '0') ;
1171
+ ++p ;
1172
+ }
1173
+
1174
+ if (pinBase < 64)
1175
+ {
1176
+ fprintf (stderr, "%s: pinBase (%d) too small. Minimum is 64.\n", progName, pinBase) ;
1177
+ return FALSE ;
1178
+ }
1179
+
1180
+ // Search for modules:
1181
+
1182
+ for (modFn = moduleFunctions ; modFn->name != NULL ; ++modFn)
1183
+ {
1184
+ if (strcmp (modFn->name, module) == 0)
1185
+ return modFn->function (progName, pinBase, p) ;
1186
+ }
1187
+
1188
+ fprintf (stderr, "%s: module %s not found\n", progName, module) ;
1189
+ return FALSE ;
1190
+ }
1191
+
1192
+
1193
+
1194
+ /*
1195
+ * main:
1196
+ * Start here
1197
+ *********************************************************************************
1198
+ */
1199
+
1200
+ int main (int argc, char *argv [])
1201
+ {
1202
+ int i ;
1203
+
1204
+ if (getenv ("WIRINGPI_DEBUG") != NULL)
1205
+ {
1206
+ printf ("gpio: wiringPi debug mode enabled\n") ;
1207
+ wiringPiDebug = TRUE ;
1208
+ }
1209
+
1210
+ if (argc == 1)
1211
+ {
1212
+ fprintf (stderr, "%s\n", usage) ;
1213
+ return 1 ;
1214
+ }
1215
+
1216
+ if (strcasecmp (argv [1], "-h") == 0)
1217
+ {
1218
+ printf ("%s: %s\n", argv [0], usage) ;
1219
+ return 0 ;
1220
+ }
1221
+
1222
+ if (strcasecmp (argv [1], "-v") == 0)
1223
+ {
1224
+ printf ("gpio version: %s\n", VERSION) ;
1225
+ printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
1226
+ printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
1227
+ printf ("For details type: %s -warranty\n", argv [0]) ;
1228
+ printf ("\n") ;
1229
+ printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ;
1230
+ return 0 ;
1231
+ }
1232
+
1233
+ if (strcasecmp (argv [1], "-warranty") == 0)
1234
+ {
1235
+ printf ("gpio version: %s\n", VERSION) ;
1236
+ printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
1237
+ printf ("\n") ;
1238
+ printf (" This program is free software; you can redistribute it and/or modify\n") ;
1239
+ printf (" it under the terms of the GNU Leser General Public License as published\n") ;
1240
+ printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
1241
+ printf (" (at your option) any later version.\n") ;
1242
+ printf ("\n") ;
1243
+ printf (" This program is distributed in the hope that it will be useful,\n") ;
1244
+ printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
1245
+ printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
1246
+ printf (" GNU Lesser General Public License for more details.\n") ;
1247
+ printf ("\n") ;
1248
+ printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
1249
+ printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
1250
+ printf ("\n") ;
1251
+ return 0 ;
1252
+ }
1253
+
1254
+ if (geteuid () != 0)
1255
+ {
1256
+ fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
1257
+ return 1 ;
1258
+ }
1259
+
1260
+ // Initial test for /sys/class/gpio operations:
1261
+
1262
+ /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
1263
+ else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
1264
+ else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
1265
+ else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
1266
+ else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; }
1267
+
1268
+ // Check for load command:
1269
+
1270
+ if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
1271
+
1272
+ // Gertboard commands
1273
+
1274
+ if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
1275
+ if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
1276
+
1277
+ // Check for -g argument
1278
+
1279
+ /**/ if (strcasecmp (argv [1], "-g") == 0)
1280
+ {
1281
+ wiringPiSetupGpio () ;
1282
+
1283
+ for (i = 2 ; i < argc ; ++i)
1284
+ argv [i - 1] = argv [i] ;
1285
+ --argc ;
1286
+ wpMode = WPI_MODE_GPIO ;
1287
+ }
1288
+
1289
+ // Check for -1 argument
1290
+
1291
+ else if (strcasecmp (argv [1], "-1") == 0)
1292
+ {
1293
+ wiringPiSetupPhys () ;
1294
+
1295
+ for (i = 2 ; i < argc ; ++i)
1296
+ argv [i - 1] = argv [i] ;
1297
+ --argc ;
1298
+ wpMode = WPI_MODE_PHYS ;
1299
+ }
1300
+
1301
+ // Check for -p argument for PiFace
1302
+
1303
+ else if (strcasecmp (argv [1], "-p") == 0)
1304
+ {
1305
+ piFaceSetup (200) ;
1306
+
1307
+ for (i = 2 ; i < argc ; ++i)
1308
+ argv [i - 1] = argv [i] ;
1309
+ --argc ;
1310
+ wpMode = WPI_MODE_PIFACE ;
1311
+ }
1312
+
1313
+ // Default to wiringPi mode
1314
+
1315
+ else
1316
+ {
1317
+ wiringPiSetup () ;
1318
+ wpMode = WPI_MODE_PINS ;
1319
+ }
1320
+
1321
+ // Check for -x argument to load in a new module
1322
+
1323
+ if (strcasecmp (argv [1], "-x") == 0)
1324
+ {
1325
+ if (argc < 3)
1326
+ {
1327
+ fprintf (stderr, "%s: -x missing module specification.\n", argv [0]) ;
1328
+ exit (EXIT_FAILURE) ;
1329
+ }
1330
+
1331
+ if (!doModule (argv [0], argv [2])) // Prints its own error messages
1332
+ exit (EXIT_FAILURE) ;
1333
+
1334
+ for (i = 3 ; i < argc ; ++i)
1335
+ argv [i - 2] = argv [i] ;
1336
+ argc -= 2 ;
1337
+ }
1338
+
1339
+ if (argc <= 1)
1340
+ {
1341
+ fprintf (stderr, "%s: no command given\n", argv [0]) ;
1342
+ exit (EXIT_FAILURE) ;
1343
+ }
1344
+
1345
+ // Core wiringPi functions
1346
+
1347
+ /**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
1348
+ else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
1349
+ else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ;
1350
+ else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
1351
+ else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite (argc, argv) ;
1352
+ else if (strcasecmp (argv [1], "aread" ) == 0) doAread (argc, argv) ;
1353
+
1354
+ // Pi Specifics
1355
+
1356
+ else if (strcasecmp (argv [1], "pwm-bal") == 0) doPwmMode (PWM_MODE_BAL) ;
1357
+ else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ;
1358
+ else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ;
1359
+ else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ;
1360
+ else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
1361
+ else if (strcasecmp (argv [1], "readall") == 0) doReadall () ;
1362
+ else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
1363
+ else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
1364
+ else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
1365
+ else
1366
+ {
1367
+ fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
1368
+ exit (EXIT_FAILURE) ;
1369
+ }
1370
+ return 0 ;
1371
+ }