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,38 @@
1
+ /*
2
+ * softTone.c:
3
+ * For that authentic retro sound...
4
+ * Er... A little experiment to produce tones out of a Pi using
5
+ * one (or 2) GPIO pins and a piezeo "speaker" element.
6
+ * (Or a high impedance speaker, but don'y blame me if you blow-up
7
+ * the GPIO pins!)
8
+ * Copyright (c) 2012 Gordon Henderson
9
+ ***********************************************************************
10
+ * This file is part of wiringPi:
11
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
12
+ *
13
+ * wiringPi is free software: you can redistribute it and/or modify
14
+ * it under the terms of the GNU Lesser General Public License as
15
+ * published by the Free Software Foundation, either version 3 of the
16
+ * License, or (at your option) any later version.
17
+ *
18
+ * wiringPi is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
+ * GNU Lesser General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU Lesser General Public
24
+ * License along with wiringPi.
25
+ * If not, see <http://www.gnu.org/licenses/>.
26
+ ***********************************************************************
27
+ */
28
+
29
+ #ifdef __cplusplus
30
+ extern "C" {
31
+ #endif
32
+
33
+ extern int softToneCreate (int pin) ;
34
+ extern void softToneWrite (int pin, int freq) ;
35
+
36
+ #ifdef __cplusplus
37
+ }
38
+ #endif
@@ -0,0 +1,108 @@
1
+ /*
2
+ * sr595.c:
3
+ * Extend wiringPi with the 74x595 shift register as a GPIO
4
+ * expander chip.
5
+ * Note that the code can cope with a number of 595's
6
+ * daisy-chained together - up to 4 for now as we're storing
7
+ * the output "register" in a single unsigned int.
8
+ *
9
+ * Copyright (c) 2013 Gordon Henderson
10
+ ***********************************************************************
11
+ * This file is part of wiringPi:
12
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
13
+ *
14
+ * wiringPi is free software: you can redistribute it and/or modify
15
+ * it under the terms of the GNU Lesser General Public License as
16
+ * published by the Free Software Foundation, either version 3 of the
17
+ * License, or (at your option) any later version.
18
+ *
19
+ * wiringPi is distributed in the hope that it will be useful,
20
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
+ * GNU Lesser General Public License for more details.
23
+ *
24
+ * You should have received a copy of the GNU Lesser General Public
25
+ * License along with wiringPi.
26
+ * If not, see <http://www.gnu.org/licenses/>.
27
+ ***********************************************************************
28
+ */
29
+
30
+ #include <stdio.h>
31
+ #include <stdint.h>
32
+
33
+ #include "wiringPi.h"
34
+
35
+ #include "sr595.h"
36
+
37
+
38
+ /*
39
+ * myDigitalWrite:
40
+ *********************************************************************************
41
+ */
42
+
43
+ static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
44
+ {
45
+ unsigned int mask ;
46
+ int dataPin, clockPin, latchPin ;
47
+ int bit, bits, output ;
48
+
49
+ pin -= node->pinBase ; // Normalise pin number
50
+ bits = node->pinMax - node->pinBase + 1 ; // ie. number of clock pulses
51
+ dataPin = node->data0 ;
52
+ clockPin = node->data1 ;
53
+ latchPin = node->data2 ;
54
+ output = node->data3 ;
55
+
56
+ mask = 1 << pin ;
57
+
58
+ if (value == LOW)
59
+ output &= (~mask) ;
60
+ else
61
+ output |= mask ;
62
+
63
+ node->data3 = output ;
64
+
65
+ // A low -> high latch transition copies the latch to the output pins
66
+
67
+ digitalWrite (latchPin, LOW) ; delayMicroseconds (1) ;
68
+ for (bit = bits - 1 ; bit >= 0 ; --bit)
69
+ {
70
+ digitalWrite (dataPin, output & (1 << bit)) ;
71
+
72
+ digitalWrite (clockPin, HIGH) ; delayMicroseconds (1) ;
73
+ digitalWrite (clockPin, LOW) ; delayMicroseconds (1) ;
74
+ }
75
+ digitalWrite (latchPin, HIGH) ; delayMicroseconds (1) ;
76
+ }
77
+
78
+
79
+ /*
80
+ * sr595Setup:
81
+ * Create a new instance of a 74x595 shift register GPIO expander.
82
+ *********************************************************************************
83
+ */
84
+
85
+ int sr595Setup (int pinBase, int numPins, int dataPin, int clockPin, int latchPin)
86
+ {
87
+ struct wiringPiNodeStruct *node ;
88
+
89
+ node = wiringPiNewNode (pinBase, numPins) ;
90
+
91
+ node->data0 = dataPin ;
92
+ node->data1 = clockPin ;
93
+ node->data2 = latchPin ;
94
+ node->data3 = 0 ; // Output register
95
+ node->digitalWrite = myDigitalWrite ;
96
+
97
+ // Initialise the underlying hardware
98
+
99
+ digitalWrite (dataPin, LOW) ;
100
+ digitalWrite (clockPin, LOW) ;
101
+ digitalWrite (latchPin, HIGH) ;
102
+
103
+ pinMode (dataPin, OUTPUT) ;
104
+ pinMode (clockPin, OUTPUT) ;
105
+ pinMode (latchPin, OUTPUT) ;
106
+
107
+ return 0 ;
108
+ }
@@ -0,0 +1,33 @@
1
+ /*
2
+ * sr595.h:
3
+ * Extend wiringPi with the 74x595 shift registers.
4
+ * Copyright (c) 2013 Gordon Henderson
5
+ ***********************************************************************
6
+ * This file is part of wiringPi:
7
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
8
+ *
9
+ * wiringPi is free software: you can redistribute it and/or modify
10
+ * it under the terms of the GNU Lesser General Public License as
11
+ * published by the Free Software Foundation, either version 3 of the
12
+ * License, or (at your option) any later version.
13
+ *
14
+ * wiringPi is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ * GNU Lesser General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU Lesser General Public
20
+ * License along with wiringPi.
21
+ * If not, see <http://www.gnu.org/licenses/>.
22
+ ***********************************************************************
23
+ */
24
+
25
+ #ifdef __cplusplus
26
+ extern "C" {
27
+ #endif
28
+
29
+ extern int sr595Setup (int pinBase, int numPins, int dataPin, int clockPin, int latchPin) ;
30
+
31
+ #ifdef __cplusplus
32
+ }
33
+ #endif
@@ -0,0 +1,1664 @@
1
+ /*
2
+ * wiringPi:
3
+ * Arduino compatable (ish) Wiring library for the Raspberry Pi
4
+ * Copyright (c) 2012 Gordon Henderson
5
+ * Additional code for pwmSetClock by Chris Hall <chris@kchall.plus.com>
6
+ *
7
+ * Thanks to code samples from Gert Jan van Loo and the
8
+ * BCM2835 ARM Peripherals manual, however it's missing
9
+ * the clock section /grr/mutter/
10
+ ***********************************************************************
11
+ * This file is part of wiringPi:
12
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
13
+ *
14
+ * wiringPi is free software: you can redistribute it and/or modify
15
+ * it under the terms of the GNU Lesser General Public License as
16
+ * published by the Free Software Foundation, either version 3 of the
17
+ * License, or (at your option) any later version.
18
+ *
19
+ * wiringPi is distributed in the hope that it will be useful,
20
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
+ * GNU Lesser General Public License for more details.
23
+ *
24
+ * You should have received a copy of the GNU Lesser General Public
25
+ * License along with wiringPi.
26
+ * If not, see <http://www.gnu.org/licenses/>.
27
+ ***********************************************************************
28
+ */
29
+
30
+ // Revisions:
31
+ // 19 Jul 2012:
32
+ // Moved to the LGPL
33
+ // Added an abstraction layer to the main routines to save a tiny
34
+ // bit of run-time and make the clode a little cleaner (if a little
35
+ // larger)
36
+ // Added waitForInterrupt code
37
+ // Added piHiPri code
38
+ //
39
+ // 9 Jul 2012:
40
+ // Added in support to use the /sys/class/gpio interface.
41
+ // 2 Jul 2012:
42
+ // Fixed a few more bugs to do with range-checking when in GPIO mode.
43
+ // 11 Jun 2012:
44
+ // Fixed some typos.
45
+ // Added c++ support for the .h file
46
+ // Added a new function to allow for using my "pin" numbers, or native
47
+ // GPIO pin numbers.
48
+ // Removed my busy-loop delay and replaced it with a call to delayMicroseconds
49
+ //
50
+ // 02 May 2012:
51
+ // Added in the 2 UART pins
52
+ // Change maxPins to numPins to more accurately reflect purpose
53
+
54
+
55
+ #include <stdio.h>
56
+ #include <stdarg.h>
57
+ #include <stdint.h>
58
+ #include <stdlib.h>
59
+ #include <ctype.h>
60
+ #include <poll.h>
61
+ #include <unistd.h>
62
+ #include <errno.h>
63
+ #include <string.h>
64
+ #include <time.h>
65
+ #include <fcntl.h>
66
+ #include <pthread.h>
67
+ #include <sys/time.h>
68
+ #include <sys/mman.h>
69
+ #include <sys/stat.h>
70
+ #include <sys/wait.h>
71
+ #include <sys/ioctl.h>
72
+
73
+ #include "wiringPi.h"
74
+
75
+ #ifndef TRUE
76
+ #define TRUE (1==1)
77
+ #define FALSE (1==2)
78
+ #endif
79
+
80
+ // Environment Variables
81
+
82
+ #define ENV_DEBUG "WIRINGPI_DEBUG"
83
+ #define ENV_CODES "WIRINGPI_CODES"
84
+
85
+
86
+ // Mask for the bottom 64 pins which belong to the Raspberry Pi
87
+ // The others are available for the other devices
88
+
89
+ #define PI_GPIO_MASK (0xFFFFFFC0)
90
+
91
+ static struct wiringPiNodeStruct *wiringPiNodes = NULL ;
92
+
93
+ // BCM Magic
94
+
95
+ #define BCM_PASSWORD 0x5A000000
96
+
97
+
98
+ // The BCM2835 has 54 GPIO pins.
99
+ // BCM2835 data sheet, Page 90 onwards.
100
+ // There are 6 control registers, each control the functions of a block
101
+ // of 10 pins.
102
+ // Each control register has 10 sets of 3 bits per GPIO pin - the ALT values
103
+ //
104
+ // 000 = GPIO Pin X is an input
105
+ // 001 = GPIO Pin X is an output
106
+ // 100 = GPIO Pin X takes alternate function 0
107
+ // 101 = GPIO Pin X takes alternate function 1
108
+ // 110 = GPIO Pin X takes alternate function 2
109
+ // 111 = GPIO Pin X takes alternate function 3
110
+ // 011 = GPIO Pin X takes alternate function 4
111
+ // 010 = GPIO Pin X takes alternate function 5
112
+ //
113
+ // So the 3 bits for port X are:
114
+ // X / 10 + ((X % 10) * 3)
115
+
116
+ // Port function select bits
117
+
118
+ #define FSEL_INPT 0b000
119
+ #define FSEL_OUTP 0b001
120
+ #define FSEL_ALT0 0b100
121
+ #define FSEL_ALT0 0b100
122
+ #define FSEL_ALT1 0b101
123
+ #define FSEL_ALT2 0b110
124
+ #define FSEL_ALT3 0b111
125
+ #define FSEL_ALT4 0b011
126
+ #define FSEL_ALT5 0b010
127
+
128
+ // Access from ARM Running Linux
129
+ // Taken from Gert/Doms code. Some of this is not in the manual
130
+ // that I can find )-:
131
+
132
+ #define BCM2708_PERI_BASE 0x20000000
133
+ #define GPIO_PADS (BCM2708_PERI_BASE + 0x00100000)
134
+ #define CLOCK_BASE (BCM2708_PERI_BASE + 0x00101000)
135
+ #define GPIO_BASE (BCM2708_PERI_BASE + 0x00200000)
136
+ #define GPIO_TIMER (BCM2708_PERI_BASE + 0x0000B000)
137
+ #define GPIO_PWM (BCM2708_PERI_BASE + 0x0020C000)
138
+
139
+ #define PAGE_SIZE (4*1024)
140
+ #define BLOCK_SIZE (4*1024)
141
+
142
+ // PWM
143
+ // Word offsets into the PWM control region
144
+
145
+ #define PWM_CONTROL 0
146
+ #define PWM_STATUS 1
147
+ #define PWM0_RANGE 4
148
+ #define PWM0_DATA 5
149
+ #define PWM1_RANGE 8
150
+ #define PWM1_DATA 9
151
+
152
+ // Clock regsiter offsets
153
+
154
+ #define PWMCLK_CNTL 40
155
+ #define PWMCLK_DIV 41
156
+
157
+ #define PWM0_MS_MODE 0x0080 // Run in MS mode
158
+ #define PWM0_USEFIFO 0x0020 // Data from FIFO
159
+ #define PWM0_REVPOLAR 0x0010 // Reverse polarity
160
+ #define PWM0_OFFSTATE 0x0008 // Ouput Off state
161
+ #define PWM0_REPEATFF 0x0004 // Repeat last value if FIFO empty
162
+ #define PWM0_SERIAL 0x0002 // Run in serial mode
163
+ #define PWM0_ENABLE 0x0001 // Channel Enable
164
+
165
+ #define PWM1_MS_MODE 0x8000 // Run in MS mode
166
+ #define PWM1_USEFIFO 0x2000 // Data from FIFO
167
+ #define PWM1_REVPOLAR 0x1000 // Reverse polarity
168
+ #define PWM1_OFFSTATE 0x0800 // Ouput Off state
169
+ #define PWM1_REPEATFF 0x0400 // Repeat last value if FIFO empty
170
+ #define PWM1_SERIAL 0x0200 // Run in serial mode
171
+ #define PWM1_ENABLE 0x0100 // Channel Enable
172
+
173
+ // Timer
174
+ // Word offsets
175
+
176
+ #define TIMER_LOAD (0x400 >> 2)
177
+ #define TIMER_VALUE (0x404 >> 2)
178
+ #define TIMER_CONTROL (0x408 >> 2)
179
+ #define TIMER_IRQ_CLR (0x40C >> 2)
180
+ #define TIMER_IRQ_RAW (0x410 >> 2)
181
+ #define TIMER_IRQ_MASK (0x414 >> 2)
182
+ #define TIMER_RELOAD (0x418 >> 2)
183
+ #define TIMER_PRE_DIV (0x41C >> 2)
184
+ #define TIMER_COUNTER (0x420 >> 2)
185
+
186
+ // Locals to hold pointers to the hardware
187
+
188
+ static volatile uint32_t *gpio ;
189
+ static volatile uint32_t *pwm ;
190
+ static volatile uint32_t *clk ;
191
+ static volatile uint32_t *pads ;
192
+
193
+ #ifdef USE_TIMER
194
+ static volatile uint32_t *timer ;
195
+ static volatile uint32_t *timerIrqRaw ;
196
+ #endif
197
+
198
+ // Time for easy calculations
199
+
200
+ static uint64_t epochMilli, epochMicro ;
201
+
202
+ // Misc
203
+
204
+ static int wiringPiMode = WPI_MODE_UNINITIALISED ;
205
+
206
+ // Debugging & Return codes
207
+
208
+ int wiringPiDebug = FALSE ;
209
+ int wiringPiCodes = FALSE ;
210
+
211
+ // sysFds:
212
+ // Map a file descriptor from the /sys/class/gpio/gpioX/value
213
+
214
+ static int sysFds [64] ;
215
+
216
+ // ISR Data
217
+
218
+ static void (*isrFunctions [64])(void) ;
219
+
220
+
221
+ // Doing it the Arduino way with lookup tables...
222
+ // Yes, it's probably more innefficient than all the bit-twidling, but it
223
+ // does tend to make it all a bit clearer. At least to me!
224
+
225
+ // pinToGpio:
226
+ // Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin
227
+ // Cope for 2 different board revisions here.
228
+
229
+ static int *pinToGpio ;
230
+
231
+ static int pinToGpioR1 [64] =
232
+ {
233
+ 17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7
234
+ 0, 1, // I2C - SDA0, SCL0 wpi 8 - 9
235
+ 8, 7, // SPI - CE1, CE0 wpi 10 - 11
236
+ 10, 9, 11, // SPI - MOSI, MISO, SCLK wpi 12 - 14
237
+ 14, 15, // UART - Tx, Rx wpi 15 - 16
238
+
239
+ // Padding:
240
+
241
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31
242
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47
243
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63
244
+ } ;
245
+
246
+ static int pinToGpioR2 [64] =
247
+ {
248
+ 17, 18, 27, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7
249
+ 2, 3, // I2C - SDA0, SCL0 wpi 8 - 9
250
+ 8, 7, // SPI - CE1, CE0 wpi 10 - 11
251
+ 10, 9, 11, // SPI - MOSI, MISO, SCLK wpi 12 - 14
252
+ 14, 15, // UART - Tx, Rx wpi 15 - 16
253
+ 28, 29, 30, 31, // New GPIOs 8 though 11 wpi 17 - 20
254
+
255
+ // Padding:
256
+
257
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31
258
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47
259
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63
260
+ } ;
261
+
262
+
263
+ // physToGpio:
264
+ // Take a physical pin (1 through 26) and re-map it to the BCM_GPIO pin
265
+ // Cope for 2 different board revisions here.
266
+
267
+ static int *physToGpio ;
268
+
269
+ static int physToGpioR1 [64] =
270
+ {
271
+ -1, // 0
272
+ -1, -1, // 1, 2
273
+ 0, -1,
274
+ 1, -1,
275
+ 4, 14,
276
+ -1, 15,
277
+ 17, 18,
278
+ 21, -1,
279
+ 22, 23,
280
+ -1, 24,
281
+ 10, -1,
282
+ 9, 25,
283
+ 11, 8,
284
+ -1, 7, // 25, 26
285
+
286
+ // Padding:
287
+
288
+ -1, -1, -1, -1, -1, // ... 31
289
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47
290
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63
291
+ } ;
292
+
293
+ static int physToGpioR2 [64] =
294
+ {
295
+ -1, // 0
296
+ -1, -1, // 1, 2
297
+ 2, -1,
298
+ 3, -1,
299
+ 4, 14,
300
+ -1, 15,
301
+ 17, 18,
302
+ 27, -1,
303
+ 22, 23,
304
+ -1, 24,
305
+ 10, -1,
306
+ 9, 25,
307
+ 11, 8,
308
+ -1, 7, // 25, 26
309
+
310
+ // Padding:
311
+
312
+ -1, -1, -1, -1, -1, // ... 31
313
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47
314
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63
315
+ } ;
316
+
317
+
318
+ // gpioToGPFSEL:
319
+ // Map a BCM_GPIO pin to it's Function Selection
320
+ // control port. (GPFSEL 0-5)
321
+ // Groups of 10 - 3 bits per Function - 30 bits per port
322
+
323
+ static uint8_t gpioToGPFSEL [] =
324
+ {
325
+ 0,0,0,0,0,0,0,0,0,0,
326
+ 1,1,1,1,1,1,1,1,1,1,
327
+ 2,2,2,2,2,2,2,2,2,2,
328
+ 3,3,3,3,3,3,3,3,3,3,
329
+ 4,4,4,4,4,4,4,4,4,4,
330
+ 5,5,5,5,5,5,5,5,5,5,
331
+ } ;
332
+
333
+
334
+ // gpioToShift
335
+ // Define the shift up for the 3 bits per pin in each GPFSEL port
336
+
337
+ static uint8_t gpioToShift [] =
338
+ {
339
+ 0,3,6,9,12,15,18,21,24,27,
340
+ 0,3,6,9,12,15,18,21,24,27,
341
+ 0,3,6,9,12,15,18,21,24,27,
342
+ 0,3,6,9,12,15,18,21,24,27,
343
+ 0,3,6,9,12,15,18,21,24,27,
344
+ } ;
345
+
346
+
347
+ // gpioToGPSET:
348
+ // (Word) offset to the GPIO Set registers for each GPIO pin
349
+
350
+ static uint8_t gpioToGPSET [] =
351
+ {
352
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
353
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
354
+ } ;
355
+
356
+ // gpioToGPCLR:
357
+ // (Word) offset to the GPIO Clear registers for each GPIO pin
358
+
359
+ static uint8_t gpioToGPCLR [] =
360
+ {
361
+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
362
+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
363
+ } ;
364
+
365
+
366
+ // gpioToGPLEV:
367
+ // (Word) offset to the GPIO Input level registers for each GPIO pin
368
+
369
+ static uint8_t gpioToGPLEV [] =
370
+ {
371
+ 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
372
+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
373
+ } ;
374
+
375
+
376
+ #ifdef notYetReady
377
+ // gpioToEDS
378
+ // (Word) offset to the Event Detect Status
379
+
380
+ static uint8_t gpioToEDS [] =
381
+ {
382
+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
383
+ 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
384
+ } ;
385
+
386
+ // gpioToREN
387
+ // (Word) offset to the Rising edgde ENable register
388
+
389
+ static uint8_t gpioToREN [] =
390
+ {
391
+ 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
392
+ 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
393
+ } ;
394
+
395
+ // gpioToFEN
396
+ // (Word) offset to the Falling edgde ENable register
397
+
398
+ static uint8_t gpioToFEN [] =
399
+ {
400
+ 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
401
+ 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
402
+ } ;
403
+ #endif
404
+
405
+
406
+ // GPPUD:
407
+ // GPIO Pin pull up/down register
408
+
409
+ #define GPPUD 37
410
+
411
+ // gpioToPUDCLK
412
+ // (Word) offset to the Pull Up Down Clock regsiter
413
+
414
+ static uint8_t gpioToPUDCLK [] =
415
+ {
416
+ 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,
417
+ 39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
418
+ } ;
419
+
420
+
421
+ // gpioToPwmALT
422
+ // the ALT value to put a GPIO pin into PWM mode
423
+
424
+ static uint8_t gpioToPwmALT [] =
425
+ {
426
+ 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7
427
+ 0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, 0, 0, // 8 -> 15
428
+ 0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, 0, 0, // 16 -> 23
429
+ 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
430
+ 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39
431
+ FSEL_ALT0, FSEL_ALT0, 0, 0, 0, FSEL_ALT0, 0, 0, // 40 -> 47
432
+ 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55
433
+ 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63
434
+ } ;
435
+
436
+
437
+ // gpioToPwmPort
438
+ // The port value to put a GPIO pin into PWM mode
439
+
440
+ static uint8_t gpioToPwmPort [] =
441
+ {
442
+ 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7
443
+ 0, 0, 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, // 8 -> 15
444
+ 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, 0, 0, // 16 -> 23
445
+ 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
446
+ 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39
447
+ PWM0_DATA, PWM1_DATA, 0, 0, 0, PWM1_DATA, 0, 0, // 40 -> 47
448
+ 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55
449
+ 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63
450
+
451
+ } ;
452
+
453
+ // gpioToGpClkALT:
454
+ // ALT value to put a GPIO pin into GP Clock mode.
455
+ // On the Pi we can really only use BCM_GPIO_4 and BCM_GPIO_21
456
+ // for clocks 0 and 1 respectively, however I'll include the full
457
+ // list for completeness - maybe one day...
458
+
459
+ #define GPIO_CLOCK_SOURCE 1
460
+
461
+ // gpioToGpClkALT0:
462
+
463
+ static uint8_t gpioToGpClkALT0 [] =
464
+ {
465
+ 0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, FSEL_ALT0, 0, // 0 -> 7
466
+ 0, 0, 0, 0, 0, 0, 0, 0, // 8 -> 15
467
+ 0, 0, 0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, // 16 -> 23
468
+ 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
469
+ FSEL_ALT0, 0, FSEL_ALT0, 0, 0, 0, 0, 0, // 32 -> 39
470
+ 0, 0, FSEL_ALT0, FSEL_ALT0, FSEL_ALT0, 0, 0, 0, // 40 -> 47
471
+ 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55
472
+ 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63
473
+ } ;
474
+
475
+ // gpioToClk:
476
+ // (word) Offsets to the clock Control and Divisor register
477
+
478
+ static uint8_t gpioToClkCon [] =
479
+ {
480
+ -1, -1, -1, -1, 28, 30, 32, -1, // 0 -> 7
481
+ -1, -1, -1, -1, -1, -1, -1, -1, // 8 -> 15
482
+ -1, -1, -1, -1, 28, 30, -1, -1, // 16 -> 23
483
+ -1, -1, -1, -1, -1, -1, -1, -1, // 24 -> 31
484
+ 28, -1, 28, -1, -1, -1, -1, -1, // 32 -> 39
485
+ -1, -1, 28, 30, 28, -1, -1, -1, // 40 -> 47
486
+ -1, -1, -1, -1, -1, -1, -1, -1, // 48 -> 55
487
+ -1, -1, -1, -1, -1, -1, -1, -1, // 56 -> 63
488
+ } ;
489
+
490
+ static uint8_t gpioToClkDiv [] =
491
+ {
492
+ -1, -1, -1, -1, 29, 31, 33, -1, // 0 -> 7
493
+ -1, -1, -1, -1, -1, -1, -1, -1, // 8 -> 15
494
+ -1, -1, -1, -1, 29, 31, -1, -1, // 16 -> 23
495
+ -1, -1, -1, -1, -1, -1, -1, -1, // 24 -> 31
496
+ 29, -1, 29, -1, -1, -1, -1, -1, // 32 -> 39
497
+ -1, -1, 29, 31, 29, -1, -1, -1, // 40 -> 47
498
+ -1, -1, -1, -1, -1, -1, -1, -1, // 48 -> 55
499
+ -1, -1, -1, -1, -1, -1, -1, -1, // 56 -> 63
500
+ } ;
501
+
502
+
503
+ /*
504
+ * Functions
505
+ *********************************************************************************
506
+ */
507
+
508
+
509
+ /*
510
+ * wiringPiFailure:
511
+ * Fail. Or not.
512
+ *********************************************************************************
513
+ */
514
+
515
+ int wiringPiFailure (char *message, ...)
516
+ {
517
+ va_list argp ;
518
+ char buffer [1024] ;
519
+
520
+ va_start (argp, message) ;
521
+ vsnprintf (buffer, 1023, message, argp) ;
522
+ va_end (argp) ;
523
+
524
+ fprintf(stderr,"%s",buffer) ;
525
+ exit (EXIT_FAILURE) ;
526
+
527
+ return 0 ;
528
+ }
529
+
530
+
531
+ /*
532
+ * piBoardRev:
533
+ * Return a number representing the hardware revision of the board.
534
+ * Revision is currently 1 or 2. -1 is returned on error.
535
+ *
536
+ * Much confusion here )-:
537
+ * Seems there are some boards with 0000 in them (mistake in manufacture)
538
+ * and some board with 0005 in them (another mistake in manufacture?)
539
+ * So the distinction between boards that I can see is:
540
+ * 0000 - Error
541
+ * 0001 - Not used
542
+ * 0002 - Rev 1
543
+ * 0003 - Rev 1
544
+ * 0004 - Rev 2 (Early reports?
545
+ * 0005 - Rev 2 (but error?)
546
+ * 0006 - Rev 2
547
+ * 0008 - Rev 2 - Model A
548
+ * 000e - Rev 2 + 512MB
549
+ * 000f - Rev 2 + 512MB
550
+ *
551
+ * A small thorn is the olde style overvolting - that will add in
552
+ * 1000000
553
+ *
554
+ *********************************************************************************
555
+ */
556
+
557
+ static void piBoardRevOops (char *why)
558
+ {
559
+ fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
560
+ fprintf (stderr, " -> %s\n", why) ;
561
+ fprintf (stderr, " -> You may want to check:\n") ;
562
+ fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ;
563
+ exit (EXIT_FAILURE) ;
564
+ }
565
+
566
+ int piBoardRev (void)
567
+ {
568
+ FILE *cpuFd ;
569
+ char line [120] ;
570
+ char *c, lastChar ;
571
+ static int boardRev = -1 ;
572
+
573
+ if (boardRev != -1) // No point checking twice
574
+ return boardRev ;
575
+
576
+ if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
577
+ piBoardRevOops ("Unable to open /proc/cpuinfo") ;
578
+
579
+ while (fgets (line, 120, cpuFd) != NULL)
580
+ if (strncmp (line, "Revision", 8) == 0)
581
+ break ;
582
+
583
+ fclose (cpuFd) ;
584
+
585
+ if (strncmp (line, "Revision", 8) != 0)
586
+ piBoardRevOops ("No \"Revision\" line") ;
587
+
588
+ for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c)
589
+ *c = 0 ;
590
+
591
+ if (wiringPiDebug)
592
+ printf ("piboardRev: Revision string: %s\n", line) ;
593
+
594
+ for (c = line ; *c ; ++c)
595
+ if (isdigit (*c))
596
+ break ;
597
+
598
+ if (!isdigit (*c))
599
+ piBoardRevOops ("No numeric revision string") ;
600
+
601
+ // If you have overvolted the Pi, then it appears that the revision
602
+ // has 100000 added to it!
603
+
604
+ if (wiringPiDebug)
605
+ if (strlen (c) != 4)
606
+ printf ("piboardRev: This Pi has/is overvolted!\n") ;
607
+
608
+ lastChar = line [strlen (line) - 1] ;
609
+
610
+ if (wiringPiDebug)
611
+ printf ("piboardRev: lastChar is: '%c' (%d, 0x%02X)\n", lastChar, lastChar, lastChar) ;
612
+
613
+ /**/ if ((lastChar == '2') || (lastChar == '3'))
614
+ boardRev = 1 ;
615
+ else
616
+ boardRev = 2 ;
617
+
618
+ if (wiringPiDebug)
619
+ printf ("piBoardRev: Returning revision: %d\n", boardRev) ;
620
+
621
+ return boardRev ;
622
+ }
623
+
624
+
625
+ /*
626
+ * wpiPinToGpio:
627
+ * Translate a wiringPi Pin number to native GPIO pin number.
628
+ * Provided for external support.
629
+ *********************************************************************************
630
+ */
631
+
632
+ int wpiPinToGpio (int wpiPin)
633
+ {
634
+ return pinToGpio [wpiPin & 63] ;
635
+ }
636
+
637
+
638
+ /*
639
+ * physPinToGpio:
640
+ * Translate a physical Pin number to native GPIO pin number.
641
+ * Provided for external support.
642
+ *********************************************************************************
643
+ */
644
+
645
+ int physPinToGpio (int physPin)
646
+ {
647
+ return physToGpio [physPin & 63] ;
648
+ }
649
+
650
+
651
+ /*
652
+ * setPadDrive:
653
+ * Set the PAD driver value
654
+ *********************************************************************************
655
+ */
656
+
657
+ void setPadDrive (int group, int value)
658
+ {
659
+ uint32_t wrVal ;
660
+
661
+ if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_GPIO))
662
+ {
663
+ if ((group < 0) || (group > 2))
664
+ return ;
665
+
666
+ wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
667
+ *(pads + group + 11) = wrVal ;
668
+
669
+ if (wiringPiDebug)
670
+ {
671
+ printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
672
+ printf ("Read : %08X\n", *(pads + group + 11)) ;
673
+ }
674
+ }
675
+ }
676
+
677
+
678
+ /*
679
+ * getAlt:
680
+ * Returns the ALT bits for a given port. Only really of-use
681
+ * for the gpio readall command (I think)
682
+ *********************************************************************************
683
+ */
684
+
685
+ int getAlt (int pin)
686
+ {
687
+ int fSel, shift, alt ;
688
+
689
+ pin &= 63 ;
690
+
691
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
692
+ pin = pinToGpio [pin] ;
693
+ else if (wiringPiMode == WPI_MODE_PHYS)
694
+ pin = physToGpio [pin] ;
695
+ else if (wiringPiMode != WPI_MODE_GPIO)
696
+ return 0 ;
697
+
698
+ fSel = gpioToGPFSEL [pin] ;
699
+ shift = gpioToShift [pin] ;
700
+
701
+ alt = (*(gpio + fSel) >> shift) & 7 ;
702
+
703
+ return alt ;
704
+ }
705
+
706
+
707
+ /*
708
+ * pwmSetMode:
709
+ * Select the native "balanced" mode, or standard mark:space mode
710
+ *********************************************************************************
711
+ */
712
+
713
+ void pwmSetMode (int mode)
714
+ {
715
+ if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_GPIO) || (wiringPiMode == WPI_MODE_PHYS))
716
+ {
717
+ if (mode == PWM_MODE_MS)
718
+ *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ;
719
+ else
720
+ *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
721
+ }
722
+ }
723
+
724
+
725
+ /*
726
+ * pwmSetRange:
727
+ * Set the PWM range register. We set both range registers to the same
728
+ * value. If you want different in your own code, then write your own.
729
+ *********************************************************************************
730
+ */
731
+
732
+ void pwmSetRange (unsigned int range)
733
+ {
734
+ if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_GPIO) || (wiringPiMode == WPI_MODE_PHYS))
735
+ {
736
+ *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
737
+ *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
738
+ }
739
+ }
740
+
741
+
742
+ /*
743
+ * pwmSetClock:
744
+ * Set/Change the PWM clock. Originally my code, but changed
745
+ * (for the better!) by Chris Hall, <chris@kchall.plus.com>
746
+ * after further study of the manual and testing with a 'scope
747
+ *********************************************************************************
748
+ */
749
+
750
+ void pwmSetClock (int divisor)
751
+ {
752
+ uint32_t pwm_control ;
753
+ divisor &= 4095 ;
754
+
755
+ if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_GPIO) || (wiringPiMode == WPI_MODE_PHYS))
756
+ {
757
+ if (wiringPiDebug)
758
+ printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
759
+
760
+ pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL
761
+
762
+ // We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY
763
+ // stays high.
764
+
765
+ *(pwm + PWM_CONTROL) = 0 ; // Stop PWM
766
+
767
+ // Stop PWM clock before changing divisor. The delay after this does need to
768
+ // this big (95uS occasionally fails, 100uS OK), it's almost as though the BUSY
769
+ // flag is not working properly in balanced mode. Without the delay when DIV is
770
+ // adjusted the clock sometimes switches to very slow, once slow further DIV
771
+ // adjustments do nothing and it's difficult to get out of this mode.
772
+
773
+ *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
774
+ delayMicroseconds (110) ; // prevents clock going sloooow
775
+
776
+ while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY
777
+ delayMicroseconds (1) ;
778
+
779
+ *(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ;
780
+
781
+ *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock
782
+ *(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL
783
+
784
+ if (wiringPiDebug)
785
+ printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
786
+ }
787
+ }
788
+
789
+
790
+ /*
791
+ * gpioClockSet:
792
+ * Set the freuency on a GPIO clock pin
793
+ *********************************************************************************
794
+ */
795
+
796
+ void gpioClockSet (int pin, int freq)
797
+ {
798
+ int divi, divr, divf ;
799
+
800
+ pin &= 63 ;
801
+
802
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
803
+ pin = pinToGpio [pin] ;
804
+ else if (wiringPiMode == WPI_MODE_PHYS)
805
+ pin = physToGpio [pin] ;
806
+ else if (wiringPiMode != WPI_MODE_GPIO)
807
+ return ;
808
+
809
+ divi = 19200000 / freq ;
810
+ divr = 19200000 % freq ;
811
+ divf = (int)((double)divr * 4096.0 / 19200000.0) ;
812
+
813
+ if (divi > 4095)
814
+ divi = 4095 ;
815
+
816
+ *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ; // Stop GPIO Clock
817
+ while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0) // ... and wait
818
+ ;
819
+
820
+ *(clk + gpioToClkDiv [pin]) = BCM_PASSWORD | (divi << 12) | divf ; // Set dividers
821
+ *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | 0x10 | GPIO_CLOCK_SOURCE ; // Start Clock
822
+ }
823
+
824
+
825
+ /*
826
+ * wiringPiFindNode:
827
+ * Locate our device node
828
+ *********************************************************************************
829
+ */
830
+
831
+ static struct wiringPiNodeStruct *wiringPiFindNode (int pin)
832
+ {
833
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
834
+
835
+ while (node != NULL)
836
+ if ((pin >= node->pinBase) && (pin <= node->pinMax))
837
+ return node ;
838
+ else
839
+ node = node->next ;
840
+
841
+ return NULL ;
842
+ }
843
+
844
+
845
+ /*
846
+ * wiringPiNewNode:
847
+ * Create a new GPIO node into the wiringPi handling system
848
+ *********************************************************************************
849
+ */
850
+
851
+ static void pinModeDummy (struct wiringPiNodeStruct *node, int pin, int mode) { return ; }
852
+ static void pullUpDnControlDummy (struct wiringPiNodeStruct *node, int pin, int pud) { return ; }
853
+ static int digitalReadDummy (struct wiringPiNodeStruct *node, int pin) { return LOW ; }
854
+ static void digitalWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
855
+ static void pwmWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
856
+ static int analogReadDummy (struct wiringPiNodeStruct *node, int pin) { return 0 ; }
857
+ static void analogWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
858
+
859
+ struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins)
860
+ {
861
+ int pin ;
862
+ struct wiringPiNodeStruct *node ;
863
+
864
+ // Minimum pin base is 64
865
+
866
+ if (pinBase < 64)
867
+ (void)wiringPiFailure ("wiringPiNewNode: pinBase of %d is < 64\n", pinBase) ;
868
+
869
+ // Check all pins in-case there is overlap:
870
+
871
+ for (pin = pinBase ; pin < (pinBase + numPins) ; ++pin)
872
+ if (wiringPiFindNode (pin) != NULL)
873
+ (void)wiringPiFailure ("wiringPiNewNode: Pin %d overlaps with existing definition\n", pin) ;
874
+
875
+ node = calloc (sizeof (struct wiringPiNodeStruct), 1) ; // calloc zeros
876
+ if (node == NULL)
877
+ (void)wiringPiFailure ("wiringPiNewNode: Unable to allocate memory: %s\n", strerror (errno)) ;
878
+
879
+ node->pinBase = pinBase ;
880
+ node->pinMax = pinBase + numPins - 1 ;
881
+ node->pinMode = pinModeDummy ;
882
+ node->pullUpDnControl = pullUpDnControlDummy ;
883
+ node->digitalRead = digitalReadDummy ;
884
+ node->digitalWrite = digitalWriteDummy ;
885
+ node->pwmWrite = pwmWriteDummy ;
886
+ node->analogRead = analogReadDummy ;
887
+ node->analogWrite = analogWriteDummy ;
888
+ node->next = wiringPiNodes ;
889
+ wiringPiNodes = node ;
890
+
891
+ return node ;
892
+ }
893
+
894
+
895
+ #ifdef notYetReady
896
+ /*
897
+ * pinED01:
898
+ * pinED10:
899
+ * Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0
900
+ * Pin must already be in input mode with appropriate pull up/downs set.
901
+ *********************************************************************************
902
+ */
903
+
904
+ void pinEnableED01Pi (int pin)
905
+ {
906
+ pin = pinToGpio [pin & 63] ;
907
+ }
908
+ #endif
909
+
910
+
911
+ /*
912
+ *********************************************************************************
913
+ * Core Functions
914
+ *********************************************************************************
915
+ */
916
+
917
+
918
+ /*
919
+ * pinMode:
920
+ * Sets the mode of a pin to be input, output or PWM output
921
+ *********************************************************************************
922
+ */
923
+
924
+ void pinMode (int pin, int mode)
925
+ {
926
+ int fSel, shift, alt ;
927
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
928
+
929
+ if ((pin & PI_GPIO_MASK) == 0) // On-board pin
930
+ {
931
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
932
+ pin = pinToGpio [pin] ;
933
+ else if (wiringPiMode == WPI_MODE_PHYS)
934
+ pin = physToGpio [pin] ;
935
+ else if (wiringPiMode != WPI_MODE_GPIO)
936
+ return ;
937
+
938
+ fSel = gpioToGPFSEL [pin] ;
939
+ shift = gpioToShift [pin] ;
940
+
941
+ /**/ if (mode == INPUT)
942
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
943
+ else if (mode == OUTPUT)
944
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
945
+ else if (mode == PWM_OUTPUT)
946
+ {
947
+ if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin
948
+ return ;
949
+
950
+ // Set pin to PWM mode
951
+
952
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
953
+ delayMicroseconds (110) ; // See comments in pwmSetClockWPi
954
+
955
+ pwmSetMode (PWM_MODE_BAL) ; // Pi default mode
956
+ pwmSetRange (1024) ; // Default range of 1024
957
+ pwmSetClock (32) ; // 19.2 / 32 = 600KHz - Also starts the PWM
958
+ }
959
+ else if (mode == GPIO_CLOCK)
960
+ {
961
+ if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin
962
+ return ;
963
+
964
+ // Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz
965
+
966
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
967
+ delayMicroseconds (110) ;
968
+ gpioClockSet (pin, 100000) ;
969
+ }
970
+ }
971
+ else
972
+ {
973
+ if ((node = wiringPiFindNode (pin)) != NULL)
974
+ node->pinMode (node, pin, mode) ;
975
+ return ;
976
+ }
977
+ }
978
+
979
+
980
+ /*
981
+ * pullUpDownCtrl:
982
+ * Control the internal pull-up/down resistors on a GPIO pin
983
+ * The Arduino only has pull-ups and these are enabled by writing 1
984
+ * to a port when in input mode - this paradigm doesn't quite apply
985
+ * here though.
986
+ *********************************************************************************
987
+ */
988
+
989
+ void pullUpDnControl (int pin, int pud)
990
+ {
991
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
992
+
993
+ if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
994
+ {
995
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
996
+ pin = pinToGpio [pin] ;
997
+ else if (wiringPiMode == WPI_MODE_PHYS)
998
+ pin = physToGpio [pin] ;
999
+ else if (wiringPiMode != WPI_MODE_GPIO)
1000
+ return ;
1001
+
1002
+ pud &= 3 ;
1003
+
1004
+ *(gpio + GPPUD) = pud ; delayMicroseconds (5) ;
1005
+ *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ;
1006
+
1007
+ *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ;
1008
+ *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ;
1009
+ }
1010
+ else
1011
+ {
1012
+ if ((node = wiringPiFindNode (pin)) != NULL)
1013
+ node->pullUpDnControl (node, pin, pud) ;
1014
+ return ;
1015
+ }
1016
+ }
1017
+
1018
+
1019
+ /*
1020
+ * digitalRead:
1021
+ * Read the value of a given Pin, returning HIGH or LOW
1022
+ *********************************************************************************
1023
+ */
1024
+
1025
+ int digitalRead (int pin)
1026
+ {
1027
+ char c ;
1028
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
1029
+
1030
+ if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
1031
+ {
1032
+ /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode
1033
+ {
1034
+ if (sysFds [pin] == -1)
1035
+ return LOW ;
1036
+
1037
+ lseek (sysFds [pin], 0L, SEEK_SET) ;
1038
+ read (sysFds [pin], &c, 1) ;
1039
+ return (c == '0') ? LOW : HIGH ;
1040
+ }
1041
+ else if (wiringPiMode == WPI_MODE_PINS)
1042
+ pin = pinToGpio [pin] ;
1043
+ else if (wiringPiMode == WPI_MODE_PHYS)
1044
+ pin = physToGpio [pin] ;
1045
+ else if (wiringPiMode != WPI_MODE_GPIO)
1046
+ return LOW ;
1047
+
1048
+ if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
1049
+ return HIGH ;
1050
+ else
1051
+ return LOW ;
1052
+ }
1053
+ else
1054
+ {
1055
+ if ((node = wiringPiFindNode (pin)) == NULL)
1056
+ return LOW ;
1057
+ return node->digitalRead (node, pin) ;
1058
+ }
1059
+ }
1060
+
1061
+
1062
+ /*
1063
+ * digitalWrite:
1064
+ * Set an output bit
1065
+ *********************************************************************************
1066
+ */
1067
+
1068
+ void digitalWrite (int pin, int value)
1069
+ {
1070
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
1071
+
1072
+ if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
1073
+ {
1074
+ /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode
1075
+ {
1076
+ if (sysFds [pin] != -1)
1077
+ {
1078
+ if (value == LOW)
1079
+ write (sysFds [pin], "0\n", 2) ;
1080
+ else
1081
+ write (sysFds [pin], "1\n", 2) ;
1082
+ }
1083
+ }
1084
+ else if (wiringPiMode == WPI_MODE_PINS)
1085
+ pin = pinToGpio [pin] ;
1086
+ else if (wiringPiMode == WPI_MODE_GPIO)
1087
+ pin = physToGpio [pin] ;
1088
+ else if (wiringPiMode != WPI_MODE_GPIO)
1089
+ return ;
1090
+
1091
+ if (value == LOW)
1092
+ *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
1093
+ else
1094
+ *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
1095
+ }
1096
+ else
1097
+ {
1098
+ if ((node = wiringPiFindNode (pin)) != NULL)
1099
+ node->digitalWrite (node, pin, value) ;
1100
+ }
1101
+ }
1102
+
1103
+
1104
+ /*
1105
+ * pwmWrite:
1106
+ * Set an output PWM value
1107
+ *********************************************************************************
1108
+ */
1109
+
1110
+ void pwmWrite (int pin, int value)
1111
+ {
1112
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
1113
+
1114
+ if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
1115
+ {
1116
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
1117
+ pin = pinToGpio [pin] ;
1118
+ else if (wiringPiMode == WPI_MODE_PHYS)
1119
+ pin = physToGpio [pin] ;
1120
+ else if (wiringPiMode != WPI_MODE_GPIO)
1121
+ return ;
1122
+
1123
+ *(pwm + gpioToPwmPort [pin]) = value ;
1124
+ }
1125
+ else
1126
+ {
1127
+ if ((node = wiringPiFindNode (pin)) != NULL)
1128
+ node->pwmWrite (node, pin, value) ;
1129
+ }
1130
+ }
1131
+
1132
+
1133
+ /*
1134
+ * analogRead:
1135
+ * Read the analog value of a given Pin.
1136
+ * There is no on-board Pi analog hardware,
1137
+ * so this needs to go to a new node.
1138
+ *********************************************************************************
1139
+ */
1140
+
1141
+ int analogRead (int pin)
1142
+ {
1143
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
1144
+
1145
+ if ((node = wiringPiFindNode (pin)) == NULL)
1146
+ return 0 ;
1147
+ else
1148
+ return node->analogRead (node, pin) ;
1149
+ }
1150
+
1151
+
1152
+ /*
1153
+ * analogWrite:
1154
+ * Write the analog value to the given Pin.
1155
+ * There is no on-board Pi analog hardware,
1156
+ * so this needs to go to a new node.
1157
+ *********************************************************************************
1158
+ */
1159
+
1160
+ void analogWrite (int pin, int value)
1161
+ {
1162
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
1163
+
1164
+ if ((node = wiringPiFindNode (pin)) == NULL)
1165
+ return ;
1166
+
1167
+ node->analogWrite (node, pin, value) ;
1168
+ }
1169
+
1170
+
1171
+
1172
+ /*
1173
+ * digitalWriteByte:
1174
+ * Pi Specific
1175
+ * Write an 8-bit byte to the first 8 GPIO pins - try to do it as
1176
+ * fast as possible.
1177
+ * However it still needs 2 operations to set the bits, so any external
1178
+ * hardware must not rely on seeing a change as there will be a change
1179
+ * to set the outputs bits to zero, then another change to set the 1's
1180
+ *********************************************************************************
1181
+ */
1182
+
1183
+ void digitalWriteByte (int value)
1184
+ {
1185
+ uint32_t pinSet = 0 ;
1186
+ uint32_t pinClr = 0 ;
1187
+ int mask = 1 ;
1188
+ int pin ;
1189
+
1190
+ /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS)
1191
+ {
1192
+ for (pin = 0 ; pin < 8 ; ++pin)
1193
+ {
1194
+ digitalWrite (pin, value & mask) ;
1195
+ mask <<= 1 ;
1196
+ }
1197
+ }
1198
+ else
1199
+ {
1200
+ for (pin = 0 ; pin < 8 ; ++pin)
1201
+ {
1202
+ if ((value & mask) == 0)
1203
+ pinClr |= (1 << pinToGpio [pin]) ;
1204
+ else
1205
+ pinSet |= (1 << pinToGpio [pin]) ;
1206
+
1207
+ mask <<= 1 ;
1208
+ }
1209
+
1210
+ *(gpio + gpioToGPCLR [0]) = pinClr ;
1211
+ *(gpio + gpioToGPSET [0]) = pinSet ;
1212
+ }
1213
+ }
1214
+
1215
+
1216
+ /*
1217
+ * waitForInterrupt:
1218
+ * Pi Specific.
1219
+ * Wait for Interrupt on a GPIO pin.
1220
+ * This is actually done via the /sys/class/gpio interface regardless of
1221
+ * the wiringPi access mode in-use. Maybe sometime it might get a better
1222
+ * way for a bit more efficiency.
1223
+ *********************************************************************************
1224
+ */
1225
+
1226
+ int waitForInterrupt (int pin, int mS)
1227
+ {
1228
+ int fd, x ;
1229
+ uint8_t c ;
1230
+ struct pollfd polls ;
1231
+
1232
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
1233
+ pin = pinToGpio [pin] ;
1234
+ else if (wiringPiMode == WPI_MODE_PHYS)
1235
+ pin = physToGpio [pin] ;
1236
+
1237
+ if ((fd = sysFds [pin & 63]) == -1)
1238
+ return -2 ;
1239
+
1240
+ // Setup poll structure
1241
+
1242
+ polls.fd = fd ;
1243
+ polls.events = POLLPRI ; // Urgent data!
1244
+
1245
+ // Wait for it ...
1246
+
1247
+ x = poll (&polls, 1, mS) ;
1248
+
1249
+ // Do a dummy read to clear the interrupt
1250
+ // A one character read appars to be enough.
1251
+
1252
+ (void)read (fd, &c, 1) ;
1253
+
1254
+ return x ;
1255
+ }
1256
+
1257
+
1258
+ /*
1259
+ * interruptHandler:
1260
+ * This is a thread and gets started to wait for the interrupt we're
1261
+ * hoping to catch. It will call the user-function when the interrupt
1262
+ * fires.
1263
+ *********************************************************************************
1264
+ */
1265
+
1266
+ static void *interruptHandler (void *arg)
1267
+ {
1268
+ int myPin = *(int *)arg ;
1269
+
1270
+ (void)piHiPri (55) ; // Only effective if we run as root
1271
+
1272
+ for (;;)
1273
+ if (waitForInterrupt (myPin, -1) > 0)
1274
+ isrFunctions [myPin] () ;
1275
+
1276
+ return NULL ;
1277
+ }
1278
+
1279
+
1280
+ /*
1281
+ * wiringPiISR:
1282
+ * Pi Specific.
1283
+ * Take the details and create an interrupt handler that will do a call-
1284
+ * back to the user supplied function.
1285
+ *********************************************************************************
1286
+ */
1287
+
1288
+ int wiringPiISR (int pin, int mode, void (*function)(void))
1289
+ {
1290
+ pthread_t threadId ;
1291
+ char fName [64] ;
1292
+ char *modeS ;
1293
+ char pinS [8] ;
1294
+ pid_t pid ;
1295
+ int count, i ;
1296
+ uint8_t c ;
1297
+
1298
+ pin &= 63 ;
1299
+
1300
+ /**/ if (wiringPiMode == WPI_MODE_UNINITIALISED)
1301
+ (void)wiringPiFailure ("wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ;
1302
+ else if (wiringPiMode == WPI_MODE_PINS)
1303
+ pin = pinToGpio [pin] ;
1304
+ else if (wiringPiMode == WPI_MODE_PHYS)
1305
+ pin = physToGpio [pin] ;
1306
+
1307
+ // Now export the pin and set the right edge
1308
+ // We're going to use the gpio program to do this, so it assumes
1309
+ // a full installation of wiringPi. It's a bit 'clunky', but it
1310
+ // is a way that will work when we're running in "Sys" mode, as
1311
+ // a non-root user. (without sudo)
1312
+
1313
+ if (mode != INT_EDGE_SETUP)
1314
+ {
1315
+ /**/ if (mode == INT_EDGE_FALLING)
1316
+ modeS = "falling" ;
1317
+ else if (mode == INT_EDGE_RISING)
1318
+ modeS = "rising" ;
1319
+ else
1320
+ modeS = "both" ;
1321
+
1322
+ sprintf (pinS, "%d", pin) ;
1323
+
1324
+ if ((pid = fork ()) < 0) // Fail
1325
+ return pid ;
1326
+
1327
+ if (pid == 0) // Child, exec
1328
+ {
1329
+ execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ;
1330
+ return -1 ; // Failure ...
1331
+ }
1332
+ else // Parent, wait
1333
+ wait (NULL) ;
1334
+ }
1335
+
1336
+ // Now pre-open the /sys/class node - it may already be open if
1337
+ // we are in Sys mode, but this will do no harm.
1338
+
1339
+ sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
1340
+ if ((sysFds [pin] = open (fName, O_RDWR)) < 0)
1341
+ return -1 ;
1342
+
1343
+ // Clear any initial pending interrupt
1344
+
1345
+ ioctl (sysFds [pin], FIONREAD, &count) ;
1346
+ for (i = 0 ; i < count ; ++i)
1347
+ read (sysFds [pin], &c, 1) ;
1348
+
1349
+ isrFunctions [pin] = function ;
1350
+
1351
+ pthread_create (&threadId, NULL, interruptHandler, &pin) ;
1352
+
1353
+ delay (1) ;
1354
+
1355
+ return 0 ;
1356
+ }
1357
+
1358
+
1359
+ /*
1360
+ * initialiseEpoch:
1361
+ * Initialise our start-of-time variable to be the current unix
1362
+ * time in milliseconds and microseconds.
1363
+ *********************************************************************************
1364
+ */
1365
+
1366
+ static void initialiseEpoch (void)
1367
+ {
1368
+ struct timeval tv ;
1369
+
1370
+ gettimeofday (&tv, NULL) ;
1371
+ epochMilli = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ;
1372
+ epochMicro = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)(tv.tv_usec) ;
1373
+ }
1374
+
1375
+
1376
+ /*
1377
+ * delay:
1378
+ * Wait for some number of milliseconds
1379
+ *********************************************************************************
1380
+ */
1381
+
1382
+ void delay (unsigned int howLong)
1383
+ {
1384
+ struct timespec sleeper, dummy ;
1385
+
1386
+ sleeper.tv_sec = (time_t)(howLong / 1000) ;
1387
+ sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;
1388
+
1389
+ nanosleep (&sleeper, &dummy) ;
1390
+ }
1391
+
1392
+
1393
+ /*
1394
+ * delayMicroseconds:
1395
+ * This is somewhat intersting. It seems that on the Pi, a single call
1396
+ * to nanosleep takes some 80 to 130 microseconds anyway, so while
1397
+ * obeying the standards (may take longer), it's not always what we
1398
+ * want!
1399
+ *
1400
+ * So what I'll do now is if the delay is less than 100uS we'll do it
1401
+ * in a hard loop, watching a built-in counter on the ARM chip. This is
1402
+ * somewhat sub-optimal in that it uses 100% CPU, something not an issue
1403
+ * in a microcontroller, but under a multi-tasking, multi-user OS, it's
1404
+ * wastefull, however we've no real choice )-:
1405
+ *
1406
+ * Plan B: It seems all might not be well with that plan, so changing it
1407
+ * to use gettimeofday () and poll on that instead...
1408
+ *********************************************************************************
1409
+ */
1410
+
1411
+ void delayMicrosecondsHard (unsigned int howLong)
1412
+ {
1413
+ struct timeval tNow, tLong, tEnd ;
1414
+
1415
+ gettimeofday (&tNow, NULL) ;
1416
+ tLong.tv_sec = howLong / 1000000 ;
1417
+ tLong.tv_usec = howLong % 1000000 ;
1418
+ timeradd (&tNow, &tLong, &tEnd) ;
1419
+
1420
+ while (timercmp (&tNow, &tEnd, <))
1421
+ gettimeofday (&tNow, NULL) ;
1422
+ }
1423
+
1424
+ void delayMicroseconds (unsigned int howLong)
1425
+ {
1426
+ struct timespec sleeper ;
1427
+
1428
+ /**/ if (howLong == 0)
1429
+ return ;
1430
+ else if (howLong < 100)
1431
+ delayMicrosecondsHard (howLong) ;
1432
+ else
1433
+ {
1434
+ sleeper.tv_sec = 0 ;
1435
+ sleeper.tv_nsec = (long)(howLong * 1000) ;
1436
+ nanosleep (&sleeper, NULL) ;
1437
+ }
1438
+ }
1439
+
1440
+
1441
+ /*
1442
+ * millis:
1443
+ * Return a number of milliseconds as an unsigned int.
1444
+ *********************************************************************************
1445
+ */
1446
+
1447
+ unsigned int millis (void)
1448
+ {
1449
+ struct timeval tv ;
1450
+ uint64_t now ;
1451
+
1452
+ gettimeofday (&tv, NULL) ;
1453
+ now = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ;
1454
+
1455
+ return (uint32_t)(now - epochMilli) ;
1456
+ }
1457
+
1458
+
1459
+ /*
1460
+ * micros:
1461
+ * Return a number of microseconds as an unsigned int.
1462
+ *********************************************************************************
1463
+ */
1464
+
1465
+ unsigned int micros (void)
1466
+ {
1467
+ struct timeval tv ;
1468
+ uint64_t now ;
1469
+
1470
+ gettimeofday (&tv, NULL) ;
1471
+ now = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)tv.tv_usec ;
1472
+
1473
+ return (uint32_t)(now - epochMicro) ;
1474
+ }
1475
+
1476
+
1477
+ /*
1478
+ * wiringPiSetup:
1479
+ * Must be called once at the start of your program execution.
1480
+ *
1481
+ * Default setup: Initialises the system into wiringPi Pin mode and uses the
1482
+ * memory mapped hardware directly.
1483
+ *********************************************************************************
1484
+ */
1485
+
1486
+ int wiringPiSetup (void)
1487
+ {
1488
+ int fd ;
1489
+ int boardRev ;
1490
+
1491
+ if (getenv (ENV_DEBUG) != NULL)
1492
+ wiringPiDebug = TRUE ;
1493
+
1494
+ if (getenv (ENV_CODES) != NULL)
1495
+ wiringPiCodes = TRUE ;
1496
+
1497
+ if (geteuid () != 0)
1498
+ (void)wiringPiFailure ("wiringPiSetup: Must be root. (Did you forget sudo?)\n") ;
1499
+
1500
+ if (wiringPiDebug)
1501
+ printf ("wiringPi: wiringPiSetup called\n") ;
1502
+
1503
+ boardRev = piBoardRev () ;
1504
+
1505
+ if (boardRev == 1)
1506
+ {
1507
+ pinToGpio = pinToGpioR1 ;
1508
+ physToGpio = physToGpioR1 ;
1509
+ }
1510
+ else
1511
+ {
1512
+ pinToGpio = pinToGpioR2 ;
1513
+ physToGpio = physToGpioR2 ;
1514
+ }
1515
+
1516
+ // Open the master /dev/memory device
1517
+
1518
+ if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
1519
+ (void)wiringPiFailure ("wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
1520
+
1521
+ // GPIO:
1522
+
1523
+ gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ;
1524
+ if ((int32_t)gpio == -1)
1525
+ (void)wiringPiFailure ("wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ;
1526
+
1527
+ // PWM
1528
+
1529
+ pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ;
1530
+ if ((int32_t)pwm == -1)
1531
+ (void)wiringPiFailure ("wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ;
1532
+
1533
+ // Clock control (needed for PWM)
1534
+
1535
+ clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CLOCK_BASE) ;
1536
+ if ((int32_t)clk == -1)
1537
+ (void)wiringPiFailure ("wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ;
1538
+
1539
+ // The drive pads
1540
+
1541
+ pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ;
1542
+ if ((int32_t)pads == -1)
1543
+ (void)wiringPiFailure ("wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ;
1544
+
1545
+ #ifdef USE_TIMER
1546
+ // The system timer
1547
+
1548
+ timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ;
1549
+ if ((int32_t)timer == -1)
1550
+ (void)wiringPiFailure ("wiringPiSetup: mmap (TIMER) failed: %s\n", strerror (errno)) ;
1551
+
1552
+ // Set the timer to free-running, 1MHz.
1553
+ // 0xF9 is 249, the timer divide is base clock / (divide+1)
1554
+ // so base clock is 250MHz / 250 = 1MHz.
1555
+
1556
+ *(timer + TIMER_CONTROL) = 0x0000280 ;
1557
+ *(timer + TIMER_PRE_DIV) = 0x00000F9 ;
1558
+ timerIrqRaw = timer + TIMER_IRQ_RAW ;
1559
+ #endif
1560
+
1561
+ initialiseEpoch () ;
1562
+
1563
+ wiringPiMode = WPI_MODE_PINS ;
1564
+
1565
+ return 0 ;
1566
+ }
1567
+
1568
+
1569
+ /*
1570
+ * wiringPiSetupGpio:
1571
+ * Must be called once at the start of your program execution.
1572
+ *
1573
+ * GPIO setup: Initialises the system into GPIO Pin mode and uses the
1574
+ * memory mapped hardware directly.
1575
+ *********************************************************************************
1576
+ */
1577
+
1578
+ int wiringPiSetupGpio (void)
1579
+ {
1580
+ (void)wiringPiSetup () ;
1581
+
1582
+ if (wiringPiDebug)
1583
+ printf ("wiringPi: wiringPiSetupGpio called\n") ;
1584
+
1585
+ wiringPiMode = WPI_MODE_GPIO ;
1586
+
1587
+ return 0 ;
1588
+ }
1589
+
1590
+
1591
+ /*
1592
+ * wiringPiSetupPhys:
1593
+ * Must be called once at the start of your program execution.
1594
+ *
1595
+ * Phys setup: Initialises the system into Physical Pin mode and uses the
1596
+ * memory mapped hardware directly.
1597
+ *********************************************************************************
1598
+ */
1599
+
1600
+ int wiringPiSetupPhys (void)
1601
+ {
1602
+ (void)wiringPiSetup () ;
1603
+
1604
+ if (wiringPiDebug)
1605
+ printf ("wiringPi: wiringPiSetupPhys called\n") ;
1606
+
1607
+ wiringPiMode = WPI_MODE_PHYS ;
1608
+
1609
+ return 0 ;
1610
+ }
1611
+
1612
+
1613
+ /*
1614
+ * wiringPiSetupSys:
1615
+ * Must be called once at the start of your program execution.
1616
+ *
1617
+ * Initialisation (again), however this time we are using the /sys/class/gpio
1618
+ * interface to the GPIO systems - slightly slower, but always usable as
1619
+ * a non-root user, assuming the devices are already exported and setup correctly.
1620
+ */
1621
+
1622
+ int wiringPiSetupSys (void)
1623
+ {
1624
+ int boardRev ;
1625
+ int pin ;
1626
+ char fName [128] ;
1627
+
1628
+ if (getenv (ENV_DEBUG) != NULL)
1629
+ wiringPiDebug = TRUE ;
1630
+
1631
+ if (getenv (ENV_CODES) != NULL)
1632
+ wiringPiCodes = TRUE ;
1633
+
1634
+ if (wiringPiDebug)
1635
+ printf ("wiringPi: wiringPiSetupSys called\n") ;
1636
+
1637
+ boardRev = piBoardRev () ;
1638
+
1639
+ if (boardRev == 1)
1640
+ {
1641
+ pinToGpio = pinToGpioR1 ;
1642
+ physToGpio = physToGpioR1 ;
1643
+ }
1644
+ else
1645
+ {
1646
+ pinToGpio = pinToGpioR2 ;
1647
+ physToGpio = physToGpioR2 ;
1648
+ }
1649
+
1650
+ // Open and scan the directory, looking for exported GPIOs, and pre-open
1651
+ // the 'value' interface to speed things up for later
1652
+
1653
+ for (pin = 0 ; pin < 64 ; ++pin)
1654
+ {
1655
+ sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
1656
+ sysFds [pin] = open (fName, O_RDWR) ;
1657
+ }
1658
+
1659
+ initialiseEpoch () ;
1660
+
1661
+ wiringPiMode = WPI_MODE_GPIO_SYS ;
1662
+
1663
+ return 0 ;
1664
+ }