wiringpi 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +7 -0
  2. data/ext/wiringpi/WiringPi/devLib/ds1302.c +240 -0
  3. data/ext/wiringpi/WiringPi/devLib/ds1302.h +44 -0
  4. data/ext/wiringpi/WiringPi/devLib/font.h +2577 -0
  5. data/ext/wiringpi/WiringPi/devLib/gertboard.c +164 -0
  6. data/ext/wiringpi/WiringPi/devLib/gertboard.h +45 -0
  7. data/ext/wiringpi/WiringPi/devLib/lcd.c +495 -0
  8. data/ext/wiringpi/WiringPi/devLib/lcd.h +52 -0
  9. data/ext/wiringpi/WiringPi/devLib/lcd128x64.c +673 -0
  10. data/ext/wiringpi/WiringPi/devLib/lcd128x64.h +39 -0
  11. data/ext/wiringpi/WiringPi/devLib/maxdetect.c +165 -0
  12. data/ext/wiringpi/{serial.h → WiringPi/devLib/maxdetect.h} +14 -15
  13. data/ext/wiringpi/WiringPi/devLib/piFace.c +112 -0
  14. data/ext/wiringpi/WiringPi/devLib/piFace.h +32 -0
  15. data/ext/wiringpi/WiringPi/devLib/piFaceOld.c +178 -0
  16. data/ext/wiringpi/WiringPi/devLib/piGlow.c +118 -0
  17. data/ext/wiringpi/WiringPi/devLib/piGlow.h +45 -0
  18. data/ext/wiringpi/WiringPi/devLib/piNes.c +113 -0
  19. data/ext/wiringpi/WiringPi/devLib/piNes.h +45 -0
  20. data/ext/wiringpi/WiringPi/examples/Gertboard/7segments.c +221 -0
  21. data/ext/wiringpi/WiringPi/examples/Gertboard/buttons.c +83 -0
  22. data/ext/wiringpi/WiringPi/examples/Gertboard/gertboard.c +96 -0
  23. data/ext/wiringpi/WiringPi/examples/Gertboard/record.c +60 -0
  24. data/ext/wiringpi/WiringPi/examples/Gertboard/temperature.c +78 -0
  25. data/ext/wiringpi/WiringPi/examples/Gertboard/voltmeter.c +73 -0
  26. data/ext/wiringpi/WiringPi/examples/Gertboard/vumeter.c +152 -0
  27. data/ext/wiringpi/WiringPi/examples/PiFace/blink.c +59 -0
  28. data/ext/wiringpi/WiringPi/examples/PiFace/buttons.c +103 -0
  29. data/ext/wiringpi/WiringPi/examples/PiFace/ladder.c +337 -0
  30. data/ext/wiringpi/WiringPi/examples/PiFace/metro.c +111 -0
  31. data/ext/wiringpi/WiringPi/examples/PiFace/motor.c +120 -0
  32. data/ext/wiringpi/WiringPi/examples/PiFace/reaction.c +194 -0
  33. data/ext/wiringpi/WiringPi/examples/PiGlow/piGlow0.c +51 -0
  34. data/ext/wiringpi/WiringPi/examples/PiGlow/piGlow1.c +258 -0
  35. data/ext/wiringpi/WiringPi/examples/PiGlow/piglow.c +176 -0
  36. data/ext/wiringpi/WiringPi/examples/blink.c +48 -0
  37. data/ext/wiringpi/WiringPi/examples/blink12.c +111 -0
  38. data/ext/wiringpi/WiringPi/examples/blink12drcs.c +125 -0
  39. data/ext/wiringpi/WiringPi/examples/blink6drcs.c +115 -0
  40. data/ext/wiringpi/WiringPi/examples/blink8.c +57 -0
  41. data/ext/wiringpi/WiringPi/examples/clock.c +201 -0
  42. data/ext/wiringpi/WiringPi/examples/delayTest.c +107 -0
  43. data/ext/wiringpi/WiringPi/examples/ds1302.c +238 -0
  44. data/ext/wiringpi/WiringPi/examples/header.h +23 -0
  45. data/ext/wiringpi/WiringPi/examples/isr-osc.c +118 -0
  46. data/ext/wiringpi/WiringPi/examples/isr.c +110 -0
  47. data/ext/wiringpi/WiringPi/examples/lcd-adafruit.c +347 -0
  48. data/ext/wiringpi/WiringPi/examples/lcd.c +286 -0
  49. data/ext/wiringpi/WiringPi/examples/lowPower.c +68 -0
  50. data/ext/wiringpi/WiringPi/examples/nes.c +67 -0
  51. data/ext/wiringpi/WiringPi/examples/okLed.c +82 -0
  52. data/ext/wiringpi/WiringPi/examples/pwm.c +58 -0
  53. data/ext/wiringpi/WiringPi/examples/q2w/binary.c +79 -0
  54. data/ext/wiringpi/WiringPi/examples/q2w/blink-io.c +61 -0
  55. data/ext/wiringpi/WiringPi/examples/q2w/blink.c +50 -0
  56. data/ext/wiringpi/WiringPi/examples/q2w/bright.c +59 -0
  57. data/ext/wiringpi/WiringPi/examples/q2w/button.c +63 -0
  58. data/ext/wiringpi/WiringPi/examples/q2w/volts.c +62 -0
  59. data/ext/wiringpi/WiringPi/examples/rht03.c +69 -0
  60. data/ext/wiringpi/WiringPi/examples/serialRead.c +48 -0
  61. data/ext/wiringpi/WiringPi/examples/serialTest.c +75 -0
  62. data/ext/wiringpi/WiringPi/examples/servo.c +57 -0
  63. data/ext/wiringpi/WiringPi/examples/softPwm.c +89 -0
  64. data/ext/wiringpi/WiringPi/examples/softTone.c +54 -0
  65. data/ext/wiringpi/WiringPi/examples/speed.c +95 -0
  66. data/ext/wiringpi/WiringPi/examples/spiSpeed.c +118 -0
  67. data/ext/wiringpi/WiringPi/examples/wfi.c +161 -0
  68. data/ext/wiringpi/WiringPi/gpio/gpio.c +1351 -0
  69. data/ext/wiringpi/WiringPi/gpio/pins.c +33 -0
  70. data/ext/wiringpi/WiringPi/gpio/readall.c +334 -0
  71. data/ext/wiringpi/WiringPi/gpio/version.h +1 -0
  72. data/ext/wiringpi/WiringPi/wiringPi/drcSerial.c +201 -0
  73. data/ext/wiringpi/WiringPi/wiringPi/drcSerial.h +33 -0
  74. data/ext/wiringpi/WiringPi/wiringPi/max31855.c +81 -0
  75. data/ext/wiringpi/WiringPi/wiringPi/max31855.h +33 -0
  76. data/ext/wiringpi/WiringPi/wiringPi/max5322.c +84 -0
  77. data/ext/wiringpi/WiringPi/wiringPi/max5322.h +33 -0
  78. data/ext/wiringpi/WiringPi/wiringPi/mcp23008.c +149 -0
  79. data/ext/wiringpi/WiringPi/wiringPi/mcp23008.h +33 -0
  80. data/ext/wiringpi/WiringPi/wiringPi/mcp23016.c +164 -0
  81. data/ext/wiringpi/WiringPi/wiringPi/mcp23016.h +33 -0
  82. data/ext/wiringpi/WiringPi/wiringPi/mcp23016reg.h +48 -0
  83. data/ext/wiringpi/WiringPi/wiringPi/mcp23017.c +195 -0
  84. data/ext/wiringpi/WiringPi/wiringPi/mcp23017.h +33 -0
  85. data/ext/wiringpi/WiringPi/wiringPi/mcp23s08.c +189 -0
  86. data/ext/wiringpi/WiringPi/wiringPi/mcp23s08.h +33 -0
  87. data/ext/wiringpi/WiringPi/wiringPi/mcp23s17.c +236 -0
  88. data/ext/wiringpi/WiringPi/wiringPi/mcp23s17.h +33 -0
  89. data/ext/wiringpi/WiringPi/wiringPi/mcp23x08.h +73 -0
  90. data/ext/wiringpi/WiringPi/wiringPi/mcp23x0817.h +87 -0
  91. data/ext/wiringpi/WiringPi/wiringPi/mcp3002.c +76 -0
  92. data/ext/wiringpi/WiringPi/wiringPi/mcp3002.h +33 -0
  93. data/ext/wiringpi/WiringPi/wiringPi/mcp3004.c +76 -0
  94. data/ext/wiringpi/WiringPi/wiringPi/mcp3004.h +33 -0
  95. data/ext/wiringpi/WiringPi/wiringPi/mcp3422.c +110 -0
  96. data/ext/wiringpi/WiringPi/wiringPi/mcp3422.h +43 -0
  97. data/ext/wiringpi/WiringPi/wiringPi/mcp4802.c +76 -0
  98. data/ext/wiringpi/WiringPi/wiringPi/mcp4802.h +33 -0
  99. data/ext/wiringpi/WiringPi/wiringPi/pcf8574.c +126 -0
  100. data/ext/wiringpi/WiringPi/wiringPi/pcf8574.h +33 -0
  101. data/ext/wiringpi/WiringPi/wiringPi/pcf8591.c +90 -0
  102. data/ext/wiringpi/WiringPi/wiringPi/pcf8591.h +33 -0
  103. data/ext/wiringpi/WiringPi/wiringPi/piHiPri.c +51 -0
  104. data/ext/wiringpi/WiringPi/wiringPi/piThread.c +63 -0
  105. data/ext/wiringpi/WiringPi/wiringPi/sn3218.c +75 -0
  106. data/ext/wiringpi/WiringPi/wiringPi/sn3218.h +33 -0
  107. data/ext/wiringpi/WiringPi/wiringPi/softPwm.c +166 -0
  108. data/ext/wiringpi/WiringPi/wiringPi/softPwm.h +35 -0
  109. data/ext/wiringpi/WiringPi/wiringPi/softServo.c +211 -0
  110. data/ext/wiringpi/WiringPi/wiringPi/softServo.h +35 -0
  111. data/ext/wiringpi/WiringPi/wiringPi/softTone.c +150 -0
  112. data/ext/wiringpi/WiringPi/wiringPi/softTone.h +39 -0
  113. data/ext/wiringpi/WiringPi/wiringPi/sr595.c +109 -0
  114. data/ext/wiringpi/WiringPi/wiringPi/sr595.h +34 -0
  115. data/ext/wiringpi/WiringPi/wiringPi/wiringPi.c +2007 -0
  116. data/ext/wiringpi/WiringPi/wiringPi/wiringPi.h +224 -0
  117. data/ext/wiringpi/WiringPi/wiringPi/wiringPiI2C.c +232 -0
  118. data/ext/wiringpi/WiringPi/wiringPi/wiringPiI2C.h +42 -0
  119. data/ext/wiringpi/WiringPi/wiringPi/wiringPiSPI.c +136 -0
  120. data/ext/wiringpi/WiringPi/wiringPi/wiringPiSPI.h +36 -0
  121. data/ext/wiringpi/{serial.c → WiringPi/wiringPi/wiringSerial.c} +38 -29
  122. data/ext/wiringpi/WiringPi/wiringPi/wiringSerial.h +38 -0
  123. data/ext/wiringpi/{wiringShift.c → WiringPi/wiringPi/wiringShift.c} +3 -4
  124. data/ext/wiringpi/{wiringShift.h → WiringPi/wiringPi/wiringShift.h} +5 -5
  125. data/ext/wiringpi/WiringPi/wiringPi/wpiExtensions.c +731 -0
  126. data/ext/wiringpi/WiringPi/wiringPi/wpiExtensions.h +26 -0
  127. data/ext/wiringpi/extconf.rb +7 -1
  128. data/ext/wiringpi/wiringpi_wrap.c +1741 -218
  129. data/lib/wiringpi.rb +24 -222
  130. data/lib/wiringpi/event.rb +21 -0
  131. data/lib/wiringpi/gpio.rb +139 -0
  132. data/lib/wiringpi/i2c.rb +26 -0
  133. data/lib/wiringpi/mcp23x17.rb +31 -0
  134. data/lib/wiringpi/serial.rb +49 -0
  135. data/lib/wiringpi/spi.rb +15 -0
  136. metadata +146 -22
  137. data/ext/wiringpi/wiringPi.c +0 -729
  138. data/ext/wiringpi/wiringPi.h +0 -69
@@ -0,0 +1,35 @@
1
+ /*
2
+ * softServo.h:
3
+ * Provide N channels of software driven PWM suitable for RC
4
+ * servo motors.
5
+ * Copyright (c) 2012 Gordon Henderson
6
+ ***********************************************************************
7
+ * This file is part of wiringPi:
8
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
9
+ *
10
+ * wiringPi is free software: you can redistribute it and/or modify
11
+ * it under the terms of the GNU Lesser General Public License as
12
+ * published by the Free Software Foundation, either version 3 of the
13
+ * License, or (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
21
+ * License along with wiringPi.
22
+ * If not, see <http://www.gnu.org/licenses/>.
23
+ ***********************************************************************
24
+ */
25
+
26
+ #ifdef __cplusplus
27
+ extern "C" {
28
+ #endif
29
+
30
+ extern void softServoWrite (int pin, int value) ;
31
+ extern int softServoSetup (int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7) ;
32
+
33
+ #ifdef __cplusplus
34
+ }
35
+ #endif
@@ -0,0 +1,150 @@
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
+ #include <stdio.h>
30
+ #include <pthread.h>
31
+
32
+ #include "wiringPi.h"
33
+ #include "softTone.h"
34
+
35
+ #define MAX_PINS 64
36
+
37
+ #define PULSE_TIME 100
38
+
39
+ static int freqs [MAX_PINS] ;
40
+ static pthread_t threads [MAX_PINS] ;
41
+
42
+ static int newPin = -1 ;
43
+
44
+
45
+ /*
46
+ * softToneThread:
47
+ * Thread to do the actual PWM output
48
+ *********************************************************************************
49
+ */
50
+
51
+ static PI_THREAD (softToneThread)
52
+ {
53
+ int pin, freq, halfPeriod ;
54
+ struct sched_param param ;
55
+
56
+ param.sched_priority = sched_get_priority_max (SCHED_RR) ;
57
+ pthread_setschedparam (pthread_self (), SCHED_RR, &param) ;
58
+
59
+ pin = newPin ;
60
+ newPin = -1 ;
61
+
62
+ piHiPri (50) ;
63
+
64
+ for (;;)
65
+ {
66
+ freq = freqs [pin] ;
67
+ if (freq == 0)
68
+ delay (1) ;
69
+ else
70
+ {
71
+ halfPeriod = 500000 / freq ;
72
+
73
+ digitalWrite (pin, HIGH) ;
74
+ delayMicroseconds (halfPeriod) ;
75
+
76
+ digitalWrite (pin, LOW) ;
77
+ delayMicroseconds (halfPeriod) ;
78
+ }
79
+ }
80
+
81
+ return NULL ;
82
+ }
83
+
84
+
85
+ /*
86
+ * softToneWrite:
87
+ * Write a frequency value to the given pin
88
+ *********************************************************************************
89
+ */
90
+
91
+ void softToneWrite (int pin, int freq)
92
+ {
93
+ pin &= 63 ;
94
+
95
+ /**/ if (freq < 0)
96
+ freq = 0 ;
97
+ else if (freq > 5000) // Max 5KHz
98
+ freq = 5000 ;
99
+
100
+ freqs [pin] = freq ;
101
+ }
102
+
103
+
104
+ /*
105
+ * softToneCreate:
106
+ * Create a new tone thread.
107
+ *********************************************************************************
108
+ */
109
+
110
+ int softToneCreate (int pin)
111
+ {
112
+ int res ;
113
+ pthread_t myThread ;
114
+
115
+ pinMode (pin, OUTPUT) ;
116
+ digitalWrite (pin, LOW) ;
117
+
118
+ if (threads [pin] != 0)
119
+ return -1 ;
120
+
121
+ freqs [pin] = 0 ;
122
+
123
+ newPin = pin ;
124
+ res = pthread_create (&myThread, NULL, softToneThread, NULL) ;
125
+
126
+ while (newPin != -1)
127
+ delay (1) ;
128
+
129
+ threads [pin] = myThread ;
130
+
131
+ return res ;
132
+ }
133
+
134
+
135
+ /*
136
+ * softToneStop:
137
+ * Stop an existing softTone thread
138
+ *********************************************************************************
139
+ */
140
+
141
+ void softToneStop (int pin)
142
+ {
143
+ if (threads [pin] != 0)
144
+ {
145
+ pthread_cancel (threads [pin]) ;
146
+ pthread_join (threads [pin], NULL) ;
147
+ threads [pin] = 0 ;
148
+ digitalWrite (pin, LOW) ;
149
+ }
150
+ }
@@ -0,0 +1,39 @@
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 softToneStop (int pin) ;
35
+ extern void softToneWrite (int pin, int freq) ;
36
+
37
+ #ifdef __cplusplus
38
+ }
39
+ #endif
@@ -0,0 +1,109 @@
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 (const int pinBase, const int numPins,
86
+ const int dataPin, const int clockPin, const int latchPin)
87
+ {
88
+ struct wiringPiNodeStruct *node ;
89
+
90
+ node = wiringPiNewNode (pinBase, numPins) ;
91
+
92
+ node->data0 = dataPin ;
93
+ node->data1 = clockPin ;
94
+ node->data2 = latchPin ;
95
+ node->data3 = 0 ; // Output register
96
+ node->digitalWrite = myDigitalWrite ;
97
+
98
+ // Initialise the underlying hardware
99
+
100
+ digitalWrite (dataPin, LOW) ;
101
+ digitalWrite (clockPin, LOW) ;
102
+ digitalWrite (latchPin, HIGH) ;
103
+
104
+ pinMode (dataPin, OUTPUT) ;
105
+ pinMode (clockPin, OUTPUT) ;
106
+ pinMode (latchPin, OUTPUT) ;
107
+
108
+ return 0 ;
109
+ }
@@ -0,0 +1,34 @@
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 (const int pinBase, const int numPins,
30
+ const int dataPin, const int clockPin, const int latchPin) ;
31
+
32
+ #ifdef __cplusplus
33
+ }
34
+ #endif
@@ -0,0 +1,2007 @@
1
+ /*
2
+ * wiringPi:
3
+ * Arduino look-a-like Wiring library for the Raspberry Pi
4
+ * Copyright (c) 2012-2015 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 "softPwm.h"
74
+ #include "softTone.h"
75
+
76
+ #include "wiringPi.h"
77
+
78
+ #ifndef TRUE
79
+ #define TRUE (1==1)
80
+ #define FALSE (1==2)
81
+ #endif
82
+
83
+ // Environment Variables
84
+
85
+ #define ENV_DEBUG "WIRINGPI_DEBUG"
86
+ #define ENV_CODES "WIRINGPI_CODES"
87
+
88
+
89
+ // Mask for the bottom 64 pins which belong to the Raspberry Pi
90
+ // The others are available for the other devices
91
+
92
+ #define PI_GPIO_MASK (0xFFFFFFC0)
93
+
94
+ struct wiringPiNodeStruct *wiringPiNodes = NULL ;
95
+
96
+ // BCM Magic
97
+
98
+ #define BCM_PASSWORD 0x5A000000
99
+
100
+
101
+ // The BCM2835 has 54 GPIO pins.
102
+ // BCM2835 data sheet, Page 90 onwards.
103
+ // There are 6 control registers, each control the functions of a block
104
+ // of 10 pins.
105
+ // Each control register has 10 sets of 3 bits per GPIO pin - the ALT values
106
+ //
107
+ // 000 = GPIO Pin X is an input
108
+ // 001 = GPIO Pin X is an output
109
+ // 100 = GPIO Pin X takes alternate function 0
110
+ // 101 = GPIO Pin X takes alternate function 1
111
+ // 110 = GPIO Pin X takes alternate function 2
112
+ // 111 = GPIO Pin X takes alternate function 3
113
+ // 011 = GPIO Pin X takes alternate function 4
114
+ // 010 = GPIO Pin X takes alternate function 5
115
+ //
116
+ // So the 3 bits for port X are:
117
+ // X / 10 + ((X % 10) * 3)
118
+
119
+ // Port function select bits
120
+
121
+ #define FSEL_INPT 0b000
122
+ #define FSEL_OUTP 0b001
123
+ #define FSEL_ALT0 0b100
124
+ #define FSEL_ALT1 0b101
125
+ #define FSEL_ALT2 0b110
126
+ #define FSEL_ALT3 0b111
127
+ #define FSEL_ALT4 0b011
128
+ #define FSEL_ALT5 0b010
129
+
130
+ // Access from ARM Running Linux
131
+ // Taken from Gert/Doms code. Some of this is not in the manual
132
+ // that I can find )-:
133
+
134
+ static volatile unsigned int BCM2708_PERI_BASE = 0x20000000 ; // Variable for Pi2
135
+ #define GPIO_PADS (BCM2708_PERI_BASE + 0x00100000)
136
+ #define CLOCK_BASE (BCM2708_PERI_BASE + 0x00101000)
137
+ #define GPIO_BASE (BCM2708_PERI_BASE + 0x00200000)
138
+ #define GPIO_TIMER (BCM2708_PERI_BASE + 0x0000B000)
139
+ #define GPIO_PWM (BCM2708_PERI_BASE + 0x0020C000)
140
+
141
+ #define PAGE_SIZE (4*1024)
142
+ #define BLOCK_SIZE (4*1024)
143
+
144
+ // PWM
145
+ // Word offsets into the PWM control region
146
+
147
+ #define PWM_CONTROL 0
148
+ #define PWM_STATUS 1
149
+ #define PWM0_RANGE 4
150
+ #define PWM0_DATA 5
151
+ #define PWM1_RANGE 8
152
+ #define PWM1_DATA 9
153
+
154
+ // Clock regsiter offsets
155
+
156
+ #define PWMCLK_CNTL 40
157
+ #define PWMCLK_DIV 41
158
+
159
+ #define PWM0_MS_MODE 0x0080 // Run in MS mode
160
+ #define PWM0_USEFIFO 0x0020 // Data from FIFO
161
+ #define PWM0_REVPOLAR 0x0010 // Reverse polarity
162
+ #define PWM0_OFFSTATE 0x0008 // Ouput Off state
163
+ #define PWM0_REPEATFF 0x0004 // Repeat last value if FIFO empty
164
+ #define PWM0_SERIAL 0x0002 // Run in serial mode
165
+ #define PWM0_ENABLE 0x0001 // Channel Enable
166
+
167
+ #define PWM1_MS_MODE 0x8000 // Run in MS mode
168
+ #define PWM1_USEFIFO 0x2000 // Data from FIFO
169
+ #define PWM1_REVPOLAR 0x1000 // Reverse polarity
170
+ #define PWM1_OFFSTATE 0x0800 // Ouput Off state
171
+ #define PWM1_REPEATFF 0x0400 // Repeat last value if FIFO empty
172
+ #define PWM1_SERIAL 0x0200 // Run in serial mode
173
+ #define PWM1_ENABLE 0x0100 // Channel Enable
174
+
175
+ // Timer
176
+ // Word offsets
177
+
178
+ #define TIMER_LOAD (0x400 >> 2)
179
+ #define TIMER_VALUE (0x404 >> 2)
180
+ #define TIMER_CONTROL (0x408 >> 2)
181
+ #define TIMER_IRQ_CLR (0x40C >> 2)
182
+ #define TIMER_IRQ_RAW (0x410 >> 2)
183
+ #define TIMER_IRQ_MASK (0x414 >> 2)
184
+ #define TIMER_RELOAD (0x418 >> 2)
185
+ #define TIMER_PRE_DIV (0x41C >> 2)
186
+ #define TIMER_COUNTER (0x420 >> 2)
187
+
188
+ // Locals to hold pointers to the hardware
189
+
190
+ static volatile uint32_t *gpio ;
191
+ static volatile uint32_t *pwm ;
192
+ static volatile uint32_t *clk ;
193
+ static volatile uint32_t *pads ;
194
+
195
+ #ifdef USE_TIMER
196
+ static volatile uint32_t *timer ;
197
+ static volatile uint32_t *timerIrqRaw ;
198
+ #endif
199
+
200
+
201
+ // Data for use with the boardId functions.
202
+ // The order of entries here to correspond with the PI_MODEL_X
203
+ // and PI_VERSION_X defines in wiringPi.h
204
+ // Only intended for the gpio command - use at your own risk!
205
+
206
+ static int piModel2 = FALSE ;
207
+
208
+ const char *piModelNames [7] =
209
+ {
210
+ "Unknown",
211
+ "Model A",
212
+ "Model B",
213
+ "Model B+",
214
+ "Compute Module",
215
+ "Model A+",
216
+ "Model 2", // Quad Core
217
+ } ;
218
+
219
+ const char *piRevisionNames [5] =
220
+ {
221
+ "Unknown",
222
+ "1",
223
+ "1.1",
224
+ "1.2",
225
+ "2",
226
+ } ;
227
+
228
+ const char *piMakerNames [5] =
229
+ {
230
+ "Unknown",
231
+ "Egoman",
232
+ "Sony",
233
+ "Qusda",
234
+ "MBest",
235
+ } ;
236
+
237
+
238
+ // Time for easy calculations
239
+
240
+ static uint64_t epochMilli, epochMicro ;
241
+
242
+ // Misc
243
+
244
+ static int wiringPiMode = WPI_MODE_UNINITIALISED ;
245
+ static volatile int pinPass = -1 ;
246
+ static pthread_mutex_t pinMutex ;
247
+
248
+ // Debugging & Return codes
249
+
250
+ int wiringPiDebug = FALSE ;
251
+ int wiringPiReturnCodes = FALSE ;
252
+
253
+ // sysFds:
254
+ // Map a file descriptor from the /sys/class/gpio/gpioX/value
255
+
256
+ static int sysFds [64] =
257
+ {
258
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
259
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
260
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
261
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
262
+ } ;
263
+
264
+ // ISR Data
265
+
266
+ static void (*isrFunctions [64])(void) ;
267
+
268
+
269
+ // Doing it the Arduino way with lookup tables...
270
+ // Yes, it's probably more innefficient than all the bit-twidling, but it
271
+ // does tend to make it all a bit clearer. At least to me!
272
+
273
+ // pinToGpio:
274
+ // Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin
275
+ // Cope for 3 different board revisions here.
276
+
277
+ static int *pinToGpio ;
278
+
279
+ // Revision 1, 1.1:
280
+
281
+ static int pinToGpioR1 [64] =
282
+ {
283
+ 17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7
284
+ 0, 1, // I2C - SDA1, SCL1 wpi 8 - 9
285
+ 8, 7, // SPI - CE1, CE0 wpi 10 - 11
286
+ 10, 9, 11, // SPI - MOSI, MISO, SCLK wpi 12 - 14
287
+ 14, 15, // UART - Tx, Rx wpi 15 - 16
288
+
289
+ // Padding:
290
+
291
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31
292
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47
293
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63
294
+ } ;
295
+
296
+ // Revision 2:
297
+
298
+ static int pinToGpioR2 [64] =
299
+ {
300
+ 17, 18, 27, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7
301
+ 2, 3, // I2C - SDA0, SCL0 wpi 8 - 9
302
+ 8, 7, // SPI - CE1, CE0 wpi 10 - 11
303
+ 10, 9, 11, // SPI - MOSI, MISO, SCLK wpi 12 - 14
304
+ 14, 15, // UART - Tx, Rx wpi 15 - 16
305
+ 28, 29, 30, 31, // Rev 2: New GPIOs 8 though 11 wpi 17 - 20
306
+ 5, 6, 13, 19, 26, // B+ wpi 21, 22, 23, 24, 25
307
+ 12, 16, 20, 21, // B+ wpi 26, 27, 28, 29
308
+ 0, 1, // B+ wpi 30, 31
309
+
310
+ // Padding:
311
+
312
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47
313
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63
314
+ } ;
315
+
316
+
317
+ // physToGpio:
318
+ // Take a physical pin (1 through 26) and re-map it to the BCM_GPIO pin
319
+ // Cope for 2 different board revisions here.
320
+ // Also add in the P5 connector, so the P5 pins are 3,4,5,6, so 53,54,55,56
321
+
322
+ static int *physToGpio ;
323
+
324
+ static int physToGpioR1 [64] =
325
+ {
326
+ -1, // 0
327
+ -1, -1, // 1, 2
328
+ 0, -1,
329
+ 1, -1,
330
+ 4, 14,
331
+ -1, 15,
332
+ 17, 18,
333
+ 21, -1,
334
+ 22, 23,
335
+ -1, 24,
336
+ 10, -1,
337
+ 9, 25,
338
+ 11, 8,
339
+ -1, 7, // 25, 26
340
+
341
+ -1, -1, -1, -1, -1, // ... 31
342
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47
343
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63
344
+ } ;
345
+
346
+ static int physToGpioR2 [64] =
347
+ {
348
+ -1, // 0
349
+ -1, -1, // 1, 2
350
+ 2, -1,
351
+ 3, -1,
352
+ 4, 14,
353
+ -1, 15,
354
+ 17, 18,
355
+ 27, -1,
356
+ 22, 23,
357
+ -1, 24,
358
+ 10, -1,
359
+ 9, 25,
360
+ 11, 8,
361
+ -1, 7, // 25, 26
362
+
363
+ // B+
364
+
365
+ 0, 1,
366
+ 5, -1,
367
+ 6, 12,
368
+ 13, -1,
369
+ 19, 16,
370
+ 26, 20,
371
+ -1, 21,
372
+
373
+ // the P5 connector on the Rev 2 boards:
374
+
375
+ -1, -1,
376
+ -1, -1,
377
+ -1, -1,
378
+ -1, -1,
379
+ -1, -1,
380
+ 28, 29,
381
+ 30, 31,
382
+ -1, -1,
383
+ -1, -1,
384
+ -1, -1,
385
+ -1, -1,
386
+ } ;
387
+
388
+ // gpioToGPFSEL:
389
+ // Map a BCM_GPIO pin to it's Function Selection
390
+ // control port. (GPFSEL 0-5)
391
+ // Groups of 10 - 3 bits per Function - 30 bits per port
392
+
393
+ static uint8_t gpioToGPFSEL [] =
394
+ {
395
+ 0,0,0,0,0,0,0,0,0,0,
396
+ 1,1,1,1,1,1,1,1,1,1,
397
+ 2,2,2,2,2,2,2,2,2,2,
398
+ 3,3,3,3,3,3,3,3,3,3,
399
+ 4,4,4,4,4,4,4,4,4,4,
400
+ 5,5,5,5,5,5,5,5,5,5,
401
+ } ;
402
+
403
+
404
+ // gpioToShift
405
+ // Define the shift up for the 3 bits per pin in each GPFSEL port
406
+
407
+ static uint8_t gpioToShift [] =
408
+ {
409
+ 0,3,6,9,12,15,18,21,24,27,
410
+ 0,3,6,9,12,15,18,21,24,27,
411
+ 0,3,6,9,12,15,18,21,24,27,
412
+ 0,3,6,9,12,15,18,21,24,27,
413
+ 0,3,6,9,12,15,18,21,24,27,
414
+ } ;
415
+
416
+
417
+ // gpioToGPSET:
418
+ // (Word) offset to the GPIO Set registers for each GPIO pin
419
+
420
+ static uint8_t gpioToGPSET [] =
421
+ {
422
+ 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,
423
+ 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,
424
+ } ;
425
+
426
+ // gpioToGPCLR:
427
+ // (Word) offset to the GPIO Clear registers for each GPIO pin
428
+
429
+ static uint8_t gpioToGPCLR [] =
430
+ {
431
+ 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,
432
+ 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,
433
+ } ;
434
+
435
+
436
+ // gpioToGPLEV:
437
+ // (Word) offset to the GPIO Input level registers for each GPIO pin
438
+
439
+ static uint8_t gpioToGPLEV [] =
440
+ {
441
+ 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,
442
+ 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,
443
+ } ;
444
+
445
+
446
+ #ifdef notYetReady
447
+ // gpioToEDS
448
+ // (Word) offset to the Event Detect Status
449
+
450
+ static uint8_t gpioToEDS [] =
451
+ {
452
+ 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,
453
+ 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,
454
+ } ;
455
+
456
+ // gpioToREN
457
+ // (Word) offset to the Rising edge ENable register
458
+
459
+ static uint8_t gpioToREN [] =
460
+ {
461
+ 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,
462
+ 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,
463
+ } ;
464
+
465
+ // gpioToFEN
466
+ // (Word) offset to the Falling edgde ENable register
467
+
468
+ static uint8_t gpioToFEN [] =
469
+ {
470
+ 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,
471
+ 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,
472
+ } ;
473
+ #endif
474
+
475
+
476
+ // GPPUD:
477
+ // GPIO Pin pull up/down register
478
+
479
+ #define GPPUD 37
480
+
481
+ // gpioToPUDCLK
482
+ // (Word) offset to the Pull Up Down Clock regsiter
483
+
484
+ static uint8_t gpioToPUDCLK [] =
485
+ {
486
+ 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,
487
+ 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,
488
+ } ;
489
+
490
+
491
+ // gpioToPwmALT
492
+ // the ALT value to put a GPIO pin into PWM mode
493
+
494
+ static uint8_t gpioToPwmALT [] =
495
+ {
496
+ 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7
497
+ 0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, 0, 0, // 8 -> 15
498
+ 0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, 0, 0, // 16 -> 23
499
+ 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
500
+ 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39
501
+ FSEL_ALT0, FSEL_ALT0, 0, 0, 0, FSEL_ALT0, 0, 0, // 40 -> 47
502
+ 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55
503
+ 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63
504
+ } ;
505
+
506
+
507
+ // gpioToPwmPort
508
+ // The port value to put a GPIO pin into PWM mode
509
+
510
+ static uint8_t gpioToPwmPort [] =
511
+ {
512
+ 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7
513
+ 0, 0, 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, // 8 -> 15
514
+ 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, 0, 0, // 16 -> 23
515
+ 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
516
+ 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39
517
+ PWM0_DATA, PWM1_DATA, 0, 0, 0, PWM1_DATA, 0, 0, // 40 -> 47
518
+ 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55
519
+ 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63
520
+
521
+ } ;
522
+
523
+ // gpioToGpClkALT:
524
+ // ALT value to put a GPIO pin into GP Clock mode.
525
+ // On the Pi we can really only use BCM_GPIO_4 and BCM_GPIO_21
526
+ // for clocks 0 and 1 respectively, however I'll include the full
527
+ // list for completeness - maybe one day...
528
+
529
+ #define GPIO_CLOCK_SOURCE 1
530
+
531
+ // gpioToGpClkALT0:
532
+
533
+ static uint8_t gpioToGpClkALT0 [] =
534
+ {
535
+ 0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, FSEL_ALT0, 0, // 0 -> 7
536
+ 0, 0, 0, 0, 0, 0, 0, 0, // 8 -> 15
537
+ 0, 0, 0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, // 16 -> 23
538
+ 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
539
+ FSEL_ALT0, 0, FSEL_ALT0, 0, 0, 0, 0, 0, // 32 -> 39
540
+ 0, 0, FSEL_ALT0, FSEL_ALT0, FSEL_ALT0, 0, 0, 0, // 40 -> 47
541
+ 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55
542
+ 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63
543
+ } ;
544
+
545
+ // gpioToClk:
546
+ // (word) Offsets to the clock Control and Divisor register
547
+
548
+ static uint8_t gpioToClkCon [] =
549
+ {
550
+ -1, -1, -1, -1, 28, 30, 32, -1, // 0 -> 7
551
+ -1, -1, -1, -1, -1, -1, -1, -1, // 8 -> 15
552
+ -1, -1, -1, -1, 28, 30, -1, -1, // 16 -> 23
553
+ -1, -1, -1, -1, -1, -1, -1, -1, // 24 -> 31
554
+ 28, -1, 28, -1, -1, -1, -1, -1, // 32 -> 39
555
+ -1, -1, 28, 30, 28, -1, -1, -1, // 40 -> 47
556
+ -1, -1, -1, -1, -1, -1, -1, -1, // 48 -> 55
557
+ -1, -1, -1, -1, -1, -1, -1, -1, // 56 -> 63
558
+ } ;
559
+
560
+ static uint8_t gpioToClkDiv [] =
561
+ {
562
+ -1, -1, -1, -1, 29, 31, 33, -1, // 0 -> 7
563
+ -1, -1, -1, -1, -1, -1, -1, -1, // 8 -> 15
564
+ -1, -1, -1, -1, 29, 31, -1, -1, // 16 -> 23
565
+ -1, -1, -1, -1, -1, -1, -1, -1, // 24 -> 31
566
+ 29, -1, 29, -1, -1, -1, -1, -1, // 32 -> 39
567
+ -1, -1, 29, 31, 29, -1, -1, -1, // 40 -> 47
568
+ -1, -1, -1, -1, -1, -1, -1, -1, // 48 -> 55
569
+ -1, -1, -1, -1, -1, -1, -1, -1, // 56 -> 63
570
+ } ;
571
+
572
+
573
+ /*
574
+ * Functions
575
+ *********************************************************************************
576
+ */
577
+
578
+
579
+ /*
580
+ * wiringPiFailure:
581
+ * Fail. Or not.
582
+ *********************************************************************************
583
+ */
584
+
585
+ int wiringPiFailure (int fatal, const char *message, ...)
586
+ {
587
+ va_list argp ;
588
+ char buffer [1024] ;
589
+
590
+ if (!fatal && wiringPiReturnCodes)
591
+ return -1 ;
592
+
593
+ va_start (argp, message) ;
594
+ vsnprintf (buffer, 1023, message, argp) ;
595
+ va_end (argp) ;
596
+
597
+ fprintf (stderr, "%s", buffer) ;
598
+ exit (EXIT_FAILURE) ;
599
+
600
+ return 0 ;
601
+ }
602
+
603
+
604
+ /*
605
+ * piBoardRev:
606
+ * Return a number representing the hardware revision of the board.
607
+ *
608
+ * Revision 1 really means the early Model B's.
609
+ * Revision 2 is everything else - it covers the B, B+ and CM.
610
+ * ... and the Pi 2 - which is a B+ ++ ...
611
+ *
612
+ * Seems there are some boards with 0000 in them (mistake in manufacture)
613
+ * So the distinction between boards that I can see is:
614
+ * 0000 - Error
615
+ * 0001 - Not used
616
+ * 0002 - Model B, Rev 1, 256MB, Egoman
617
+ * 0003 - Model B, Rev 1.1, 256MB, Egoman, Fuses/D14 removed.
618
+ * 0004 - Model B, Rev 2, 256MB, Sony
619
+ * 0005 - Model B, Rev 2, 256MB, Qisda
620
+ * 0006 - Model B, Rev 2, 256MB, Egoman
621
+ * 0007 - Model A, Rev 2, 256MB, Egoman
622
+ * 0008 - Model A, Rev 2, 256MB, Sony
623
+ * 0009 - Model A, Rev 2, 256MB, Qisda
624
+ * 000d - Model B, Rev 2, 512MB, Egoman
625
+ * 000e - Model B, Rev 2, 512MB, Sony
626
+ * 000f - Model B, Rev 2, 512MB, Qisda
627
+ * 0010 - Model B+, Rev 1.2, 512MB, Sony
628
+ * 0011 - Pi CM, Rev 1.2, 512MB, Sony
629
+ * 0012 - Model A+ Rev 1.2, 256MB, Sony
630
+ * 0014 - Pi CM, Rev 1.1, 512MB, Sony (Actual Revision might be different)
631
+ *
632
+ * For the Pi 2:
633
+ * 0010 - Model 2, Rev 1.1, Quad Core, 1GB, Sony
634
+ *
635
+ * A small thorn is the olde style overvolting - that will add in
636
+ * 1000000
637
+ *
638
+ * The Pi compute module has an revision of 0011 - since we only check the
639
+ * last digit, then it's 1, therefore it'll default to not 2 or 3 for a
640
+ * Rev 1, so will appear as a Rev 2. This is fine for the most part, but
641
+ * we'll properly detect the Compute Module later and adjust accordingly.
642
+ * And the next rev of the CN is 0014 ...
643
+ *
644
+ *********************************************************************************
645
+ */
646
+
647
+ static void piBoardRevOops (const char *why)
648
+ {
649
+ fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
650
+ fprintf (stderr, " -> %s\n", why) ;
651
+ fprintf (stderr, " -> You may want to check:\n") ;
652
+ fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ;
653
+ exit (EXIT_FAILURE) ;
654
+ }
655
+
656
+ int piBoardRev (void)
657
+ {
658
+ FILE *cpuFd ;
659
+ char line [120] ;
660
+ char *c ;
661
+ static int boardRev = -1 ;
662
+
663
+ if (boardRev != -1) // No point checking twice
664
+ return boardRev ;
665
+
666
+ if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
667
+ piBoardRevOops ("Unable to open /proc/cpuinfo") ;
668
+
669
+ // Start by looking for the Architecture, then we can look for a B2 revision....
670
+
671
+ while (fgets (line, 120, cpuFd) != NULL)
672
+ if (strncmp (line, "Hardware", 8) == 0)
673
+ break ;
674
+
675
+ if (strncmp (line, "Hardware", 8) != 0)
676
+ piBoardRevOops ("No \"Hardware\" line") ;
677
+
678
+ if (wiringPiDebug)
679
+ printf ("piboardRev: Hardware: %s\n", line) ;
680
+
681
+ // See if it's BCM2708 or BCM2709
682
+
683
+ if (strstr (line, "BCM2709") != NULL)
684
+ piModel2 = TRUE ;
685
+ else if (strstr (line, "BCM2708") == NULL)
686
+ {
687
+ fprintf (stderr, "Unable to determine hardware version. I see: %s,\n", line) ;
688
+ fprintf (stderr, " - expecting BCM2708 or BCM2709. Please report this to projects@drogon.net\n") ;
689
+ exit (EXIT_FAILURE) ;
690
+ }
691
+
692
+ // Now do the rest of it as before
693
+
694
+ rewind (cpuFd) ;
695
+
696
+ while (fgets (line, 120, cpuFd) != NULL)
697
+ if (strncmp (line, "Revision", 8) == 0)
698
+ break ;
699
+
700
+ fclose (cpuFd) ;
701
+
702
+ if (strncmp (line, "Revision", 8) != 0)
703
+ piBoardRevOops ("No \"Revision\" line") ;
704
+
705
+ // Chomp trailing CR/NL
706
+
707
+ for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c)
708
+ *c = 0 ;
709
+
710
+ if (wiringPiDebug)
711
+ printf ("piboardRev: Revision string: %s\n", line) ;
712
+
713
+ // Scan to first digit
714
+
715
+ for (c = line ; *c ; ++c)
716
+ if (isdigit (*c))
717
+ break ;
718
+
719
+ if (!isdigit (*c))
720
+ piBoardRevOops ("No numeric revision string") ;
721
+
722
+ // Make sure its long enough
723
+
724
+ if (strlen (c) < 4)
725
+ piBoardRevOops ("Bogus \"Revision\" line (too small)") ;
726
+
727
+ // If you have overvolted the Pi, then it appears that the revision
728
+ // has 100000 added to it!
729
+ // The actual condition for it being set is:
730
+ // (force_turbo || current_limit_override || temp_limit>85) && over_voltage>0
731
+
732
+ if (wiringPiDebug)
733
+ if (strlen (c) != 4)
734
+ printf ("piboardRev: This Pi has/is (force_turbo || current_limit_override || temp_limit>85) && over_voltage>0\n") ;
735
+
736
+ // Isolate last 4 characters:
737
+
738
+ c = c + strlen (c) - 4 ;
739
+
740
+ if (wiringPiDebug)
741
+ printf ("piboardRev: last4Chars are: \"%s\"\n", c) ;
742
+
743
+ if ( (strcmp (c, "0002") == 0) || (strcmp (c, "0003") == 0))
744
+ boardRev = 1 ;
745
+ else
746
+ boardRev = 2 ; // Covers everything else from the B revision 2 to the B+, the Pi v2 and CM's.
747
+
748
+ if (wiringPiDebug)
749
+ printf ("piBoardRev: Returning revision: %d\n", boardRev) ;
750
+
751
+ return boardRev ;
752
+ }
753
+
754
+
755
+ /*
756
+ * piBoardId:
757
+ * Do more digging into the board revision string as above, but return
758
+ * as much details as we can.
759
+ * This is undocumented and really only intended for the GPIO command.
760
+ * Use at your own risk!
761
+ *
762
+ * for Pi v2:
763
+ * [USER:8] [NEW:1] [MEMSIZE:3] [MANUFACTURER:4] [PROCESSOR:4] [TYPE:8] [REV:4]
764
+ * NEW 23: will be 1 for the new scheme, 0 for the old scheme
765
+ * MEMSIZE 20: 0=256M 1=512M 2=1G
766
+ * MANUFACTURER 16: 0=SONY 1=EGOMAN 2=EMBEST
767
+ * PROCESSOR 12: 0=2835 1=2836
768
+ * TYPE 04: 0=MODELA 1=MODELB 2=MODELA+ 3=MODELB+ 4=Pi2 MODEL B 5=ALPHA 6=CM
769
+ * REV 00: 0=REV0 1=REV1 2=REV2
770
+ *********************************************************************************
771
+ */
772
+
773
+ void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted)
774
+ {
775
+ FILE *cpuFd ;
776
+ char line [120] ;
777
+ char *c ;
778
+
779
+ // Will deal with the properly later on - for now, lets just get it going...
780
+ // unsigned int modelNum ;
781
+
782
+ (void)piBoardRev () ; // Call this first to make sure all's OK. Don't care about the result.
783
+
784
+ if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
785
+ piBoardRevOops ("Unable to open /proc/cpuinfo") ;
786
+
787
+ while (fgets (line, 120, cpuFd) != NULL)
788
+ if (strncmp (line, "Revision", 8) == 0)
789
+ break ;
790
+
791
+ fclose (cpuFd) ;
792
+
793
+ if (strncmp (line, "Revision", 8) != 0)
794
+ piBoardRevOops ("No \"Revision\" line") ;
795
+
796
+ // Chomp trailing CR/NL
797
+
798
+ for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c)
799
+ *c = 0 ;
800
+
801
+ if (wiringPiDebug)
802
+ printf ("piboardId: Revision string: %s\n", line) ;
803
+
804
+ if (piModel2)
805
+ {
806
+
807
+ // Scan to the colon
808
+
809
+ for (c = line ; *c ; ++c)
810
+ if (*c == ':')
811
+ break ;
812
+
813
+ if (*c != ':')
814
+ piBoardRevOops ("Bogus \"Revision\" line (no colon)") ;
815
+
816
+ // modelNum = (unsigned int)strtol (++c, NULL, 16) ; // Hex number with no leading 0x
817
+
818
+ *model = PI_MODEL_2 ;
819
+ *rev = PI_VERSION_1_1 ;
820
+ *mem = 1024 ;
821
+ *maker = PI_MAKER_SONY ;
822
+ }
823
+ else
824
+ {
825
+
826
+ // Scan to first digit
827
+
828
+ for (c = line ; *c ; ++c)
829
+ if (isdigit (*c))
830
+ break ;
831
+
832
+ // Make sure its long enough
833
+
834
+ if (strlen (c) < 4)
835
+ piBoardRevOops ("Bogus \"Revision\" line (not long enough)") ;
836
+
837
+ // If longer than 4, we'll assume it's been overvolted
838
+
839
+ *overVolted = strlen (c) > 4 ;
840
+
841
+ // Extract last 4 characters:
842
+
843
+ c = c + strlen (c) - 4 ;
844
+
845
+ // Fill out the replys as appropriate
846
+
847
+ /**/ if (strcmp (c, "0002") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1 ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
848
+ else if (strcmp (c, "0003") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_1 ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
849
+ else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 256 ; *maker = PI_MAKER_SONY ; }
850
+ else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 256 ; *maker = PI_MAKER_QISDA ; }
851
+ else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
852
+ else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_2 ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
853
+ else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_2 ; *mem = 256 ; *maker = PI_MAKER_SONY ; ; }
854
+ else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 256 ; *maker = PI_MAKER_QISDA ; }
855
+ else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 512 ; *maker = PI_MAKER_EGOMAN ; }
856
+ else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 512 ; *maker = PI_MAKER_SONY ; }
857
+ else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 512 ; *maker = PI_MAKER_EGOMAN ; }
858
+ else if (strcmp (c, "0010") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_SONY ; }
859
+ else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_SONY ; }
860
+ else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_2 ; *mem = 256 ; *maker = PI_MAKER_SONY ; }
861
+ else if (strcmp (c, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_MBEST ; }
862
+ else if (strcmp (c, "0014") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_SONY ; }
863
+ else { *model = 0 ; *rev = 0 ; *mem = 0 ; *maker = 0 ; }
864
+ }
865
+ }
866
+
867
+
868
+
869
+ /*
870
+ * wpiPinToGpio:
871
+ * Translate a wiringPi Pin number to native GPIO pin number.
872
+ * Provided for external support.
873
+ *********************************************************************************
874
+ */
875
+
876
+ int wpiPinToGpio (int wpiPin)
877
+ {
878
+ return pinToGpio [wpiPin & 63] ;
879
+ }
880
+
881
+
882
+ /*
883
+ * physPinToGpio:
884
+ * Translate a physical Pin number to native GPIO pin number.
885
+ * Provided for external support.
886
+ *********************************************************************************
887
+ */
888
+
889
+ int physPinToGpio (int physPin)
890
+ {
891
+ return physToGpio [physPin & 63] ;
892
+ }
893
+
894
+
895
+ /*
896
+ * setPadDrive:
897
+ * Set the PAD driver value
898
+ *********************************************************************************
899
+ */
900
+
901
+ void setPadDrive (int group, int value)
902
+ {
903
+ uint32_t wrVal ;
904
+
905
+ if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
906
+ {
907
+ if ((group < 0) || (group > 2))
908
+ return ;
909
+
910
+ wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
911
+ *(pads + group + 11) = wrVal ;
912
+
913
+ if (wiringPiDebug)
914
+ {
915
+ printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
916
+ printf ("Read : %08X\n", *(pads + group + 11)) ;
917
+ }
918
+ }
919
+ }
920
+
921
+
922
+ /*
923
+ * getAlt:
924
+ * Returns the ALT bits for a given port. Only really of-use
925
+ * for the gpio readall command (I think)
926
+ *********************************************************************************
927
+ */
928
+
929
+ int getAlt (int pin)
930
+ {
931
+ int fSel, shift, alt ;
932
+
933
+ pin &= 63 ;
934
+
935
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
936
+ pin = pinToGpio [pin] ;
937
+ else if (wiringPiMode == WPI_MODE_PHYS)
938
+ pin = physToGpio [pin] ;
939
+ else if (wiringPiMode != WPI_MODE_GPIO)
940
+ return 0 ;
941
+
942
+ fSel = gpioToGPFSEL [pin] ;
943
+ shift = gpioToShift [pin] ;
944
+
945
+ alt = (*(gpio + fSel) >> shift) & 7 ;
946
+
947
+ return alt ;
948
+ }
949
+
950
+
951
+ /*
952
+ * pwmSetMode:
953
+ * Select the native "balanced" mode, or standard mark:space mode
954
+ *********************************************************************************
955
+ */
956
+
957
+ void pwmSetMode (int mode)
958
+ {
959
+ if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
960
+ {
961
+ if (mode == PWM_MODE_MS)
962
+ *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ;
963
+ else
964
+ *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
965
+ }
966
+ }
967
+
968
+
969
+ /*
970
+ * pwmSetRange:
971
+ * Set the PWM range register. We set both range registers to the same
972
+ * value. If you want different in your own code, then write your own.
973
+ *********************************************************************************
974
+ */
975
+
976
+ void pwmSetRange (unsigned int range)
977
+ {
978
+ if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
979
+ {
980
+ *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
981
+ *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
982
+ }
983
+ }
984
+
985
+
986
+ /*
987
+ * pwmSetClock:
988
+ * Set/Change the PWM clock. Originally my code, but changed
989
+ * (for the better!) by Chris Hall, <chris@kchall.plus.com>
990
+ * after further study of the manual and testing with a 'scope
991
+ *********************************************************************************
992
+ */
993
+
994
+ void pwmSetClock (int divisor)
995
+ {
996
+ uint32_t pwm_control ;
997
+ divisor &= 4095 ;
998
+
999
+ if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
1000
+ {
1001
+ if (wiringPiDebug)
1002
+ printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
1003
+
1004
+ pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL
1005
+
1006
+ // We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY
1007
+ // stays high.
1008
+
1009
+ *(pwm + PWM_CONTROL) = 0 ; // Stop PWM
1010
+
1011
+ // Stop PWM clock before changing divisor. The delay after this does need to
1012
+ // this big (95uS occasionally fails, 100uS OK), it's almost as though the BUSY
1013
+ // flag is not working properly in balanced mode. Without the delay when DIV is
1014
+ // adjusted the clock sometimes switches to very slow, once slow further DIV
1015
+ // adjustments do nothing and it's difficult to get out of this mode.
1016
+
1017
+ *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
1018
+ delayMicroseconds (110) ; // prevents clock going sloooow
1019
+
1020
+ while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY
1021
+ delayMicroseconds (1) ;
1022
+
1023
+ *(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ;
1024
+
1025
+ *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock
1026
+ *(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL
1027
+
1028
+ if (wiringPiDebug)
1029
+ printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
1030
+ }
1031
+ }
1032
+
1033
+
1034
+ /*
1035
+ * gpioClockSet:
1036
+ * Set the freuency on a GPIO clock pin
1037
+ *********************************************************************************
1038
+ */
1039
+
1040
+ void gpioClockSet (int pin, int freq)
1041
+ {
1042
+ int divi, divr, divf ;
1043
+
1044
+ pin &= 63 ;
1045
+
1046
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
1047
+ pin = pinToGpio [pin] ;
1048
+ else if (wiringPiMode == WPI_MODE_PHYS)
1049
+ pin = physToGpio [pin] ;
1050
+ else if (wiringPiMode != WPI_MODE_GPIO)
1051
+ return ;
1052
+
1053
+ divi = 19200000 / freq ;
1054
+ divr = 19200000 % freq ;
1055
+ divf = (int)((double)divr * 4096.0 / 19200000.0) ;
1056
+
1057
+ if (divi > 4095)
1058
+ divi = 4095 ;
1059
+
1060
+ *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ; // Stop GPIO Clock
1061
+ while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0) // ... and wait
1062
+ ;
1063
+
1064
+ *(clk + gpioToClkDiv [pin]) = BCM_PASSWORD | (divi << 12) | divf ; // Set dividers
1065
+ *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | 0x10 | GPIO_CLOCK_SOURCE ; // Start Clock
1066
+ }
1067
+
1068
+
1069
+ /*
1070
+ * wiringPiFindNode:
1071
+ * Locate our device node
1072
+ *********************************************************************************
1073
+ */
1074
+
1075
+ struct wiringPiNodeStruct *wiringPiFindNode (int pin)
1076
+ {
1077
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
1078
+
1079
+ while (node != NULL)
1080
+ if ((pin >= node->pinBase) && (pin <= node->pinMax))
1081
+ return node ;
1082
+ else
1083
+ node = node->next ;
1084
+
1085
+ return NULL ;
1086
+ }
1087
+
1088
+
1089
+ /*
1090
+ * wiringPiNewNode:
1091
+ * Create a new GPIO node into the wiringPi handling system
1092
+ *********************************************************************************
1093
+ */
1094
+
1095
+ static void pinModeDummy (struct wiringPiNodeStruct *node, int pin, int mode) { return ; }
1096
+ static void pullUpDnControlDummy (struct wiringPiNodeStruct *node, int pin, int pud) { return ; }
1097
+ static int digitalReadDummy (struct wiringPiNodeStruct *node, int pin) { return LOW ; }
1098
+ static void digitalWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
1099
+ static void pwmWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
1100
+ static int analogReadDummy (struct wiringPiNodeStruct *node, int pin) { return 0 ; }
1101
+ static void analogWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
1102
+
1103
+ struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins)
1104
+ {
1105
+ int pin ;
1106
+ struct wiringPiNodeStruct *node ;
1107
+
1108
+ // Minimum pin base is 64
1109
+
1110
+ if (pinBase < 64)
1111
+ (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: pinBase of %d is < 64\n", pinBase) ;
1112
+
1113
+ // Check all pins in-case there is overlap:
1114
+
1115
+ for (pin = pinBase ; pin < (pinBase + numPins) ; ++pin)
1116
+ if (wiringPiFindNode (pin) != NULL)
1117
+ (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Pin %d overlaps with existing definition\n", pin) ;
1118
+
1119
+ node = (struct wiringPiNodeStruct *)calloc (sizeof (struct wiringPiNodeStruct), 1) ; // calloc zeros
1120
+ if (node == NULL)
1121
+ (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Unable to allocate memory: %s\n", strerror (errno)) ;
1122
+
1123
+ node->pinBase = pinBase ;
1124
+ node->pinMax = pinBase + numPins - 1 ;
1125
+ node->pinMode = pinModeDummy ;
1126
+ node->pullUpDnControl = pullUpDnControlDummy ;
1127
+ node->digitalRead = digitalReadDummy ;
1128
+ node->digitalWrite = digitalWriteDummy ;
1129
+ node->pwmWrite = pwmWriteDummy ;
1130
+ node->analogRead = analogReadDummy ;
1131
+ node->analogWrite = analogWriteDummy ;
1132
+ node->next = wiringPiNodes ;
1133
+ wiringPiNodes = node ;
1134
+
1135
+ return node ;
1136
+ }
1137
+
1138
+
1139
+ #ifdef notYetReady
1140
+ /*
1141
+ * pinED01:
1142
+ * pinED10:
1143
+ * Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0
1144
+ * Pin must already be in input mode with appropriate pull up/downs set.
1145
+ *********************************************************************************
1146
+ */
1147
+
1148
+ void pinEnableED01Pi (int pin)
1149
+ {
1150
+ pin = pinToGpio [pin & 63] ;
1151
+ }
1152
+ #endif
1153
+
1154
+
1155
+ /*
1156
+ *********************************************************************************
1157
+ * Core Functions
1158
+ *********************************************************************************
1159
+ */
1160
+
1161
+ /*
1162
+ * pinModeAlt:
1163
+ * This is an un-documented special to let you set any pin to any mode
1164
+ *********************************************************************************
1165
+ */
1166
+
1167
+ void pinModeAlt (int pin, int mode)
1168
+ {
1169
+ int fSel, shift ;
1170
+
1171
+ if ((pin & PI_GPIO_MASK) == 0) // On-board pin
1172
+ {
1173
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
1174
+ pin = pinToGpio [pin] ;
1175
+ else if (wiringPiMode == WPI_MODE_PHYS)
1176
+ pin = physToGpio [pin] ;
1177
+ else if (wiringPiMode != WPI_MODE_GPIO)
1178
+ return ;
1179
+
1180
+ fSel = gpioToGPFSEL [pin] ;
1181
+ shift = gpioToShift [pin] ;
1182
+
1183
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ;
1184
+ }
1185
+ }
1186
+
1187
+
1188
+ /*
1189
+ * pinMode:
1190
+ * Sets the mode of a pin to be input, output or PWM output
1191
+ *********************************************************************************
1192
+ */
1193
+
1194
+ void pinMode (int pin, int mode)
1195
+ {
1196
+ int fSel, shift, alt ;
1197
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
1198
+ int origPin = pin ;
1199
+
1200
+ if ((pin & PI_GPIO_MASK) == 0) // On-board pin
1201
+ {
1202
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
1203
+ pin = pinToGpio [pin] ;
1204
+ else if (wiringPiMode == WPI_MODE_PHYS)
1205
+ pin = physToGpio [pin] ;
1206
+ else if (wiringPiMode != WPI_MODE_GPIO)
1207
+ return ;
1208
+
1209
+ softPwmStop (origPin) ;
1210
+ softToneStop (origPin) ;
1211
+
1212
+ fSel = gpioToGPFSEL [pin] ;
1213
+ shift = gpioToShift [pin] ;
1214
+
1215
+ /**/ if (mode == INPUT)
1216
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
1217
+ else if (mode == OUTPUT)
1218
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
1219
+ else if (mode == SOFT_PWM_OUTPUT)
1220
+ softPwmCreate (origPin, 0, 100) ;
1221
+ else if (mode == SOFT_TONE_OUTPUT)
1222
+ softToneCreate (origPin) ;
1223
+ else if (mode == PWM_TONE_OUTPUT)
1224
+ {
1225
+ pinMode (origPin, PWM_OUTPUT) ; // Call myself to enable PWM mode
1226
+ pwmSetMode (PWM_MODE_MS) ;
1227
+ }
1228
+ else if (mode == PWM_OUTPUT)
1229
+ {
1230
+ if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin
1231
+ return ;
1232
+
1233
+ // Set pin to PWM mode
1234
+
1235
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
1236
+ delayMicroseconds (110) ; // See comments in pwmSetClockWPi
1237
+
1238
+ pwmSetMode (PWM_MODE_BAL) ; // Pi default mode
1239
+ pwmSetRange (1024) ; // Default range of 1024
1240
+ pwmSetClock (32) ; // 19.2 / 32 = 600KHz - Also starts the PWM
1241
+ }
1242
+ else if (mode == GPIO_CLOCK)
1243
+ {
1244
+ if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin
1245
+ return ;
1246
+
1247
+ // Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz
1248
+
1249
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
1250
+ delayMicroseconds (110) ;
1251
+ gpioClockSet (pin, 100000) ;
1252
+ }
1253
+ }
1254
+ else
1255
+ {
1256
+ if ((node = wiringPiFindNode (pin)) != NULL)
1257
+ node->pinMode (node, pin, mode) ;
1258
+ return ;
1259
+ }
1260
+ }
1261
+
1262
+
1263
+ /*
1264
+ * pullUpDownCtrl:
1265
+ * Control the internal pull-up/down resistors on a GPIO pin
1266
+ * The Arduino only has pull-ups and these are enabled by writing 1
1267
+ * to a port when in input mode - this paradigm doesn't quite apply
1268
+ * here though.
1269
+ *********************************************************************************
1270
+ */
1271
+
1272
+ void pullUpDnControl (int pin, int pud)
1273
+ {
1274
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
1275
+
1276
+ if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
1277
+ {
1278
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
1279
+ pin = pinToGpio [pin] ;
1280
+ else if (wiringPiMode == WPI_MODE_PHYS)
1281
+ pin = physToGpio [pin] ;
1282
+ else if (wiringPiMode != WPI_MODE_GPIO)
1283
+ return ;
1284
+
1285
+ *(gpio + GPPUD) = pud & 3 ; delayMicroseconds (5) ;
1286
+ *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ;
1287
+
1288
+ *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ;
1289
+ *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ;
1290
+ }
1291
+ else // Extension module
1292
+ {
1293
+ if ((node = wiringPiFindNode (pin)) != NULL)
1294
+ node->pullUpDnControl (node, pin, pud) ;
1295
+ return ;
1296
+ }
1297
+ }
1298
+
1299
+
1300
+ /*
1301
+ * digitalRead:
1302
+ * Read the value of a given Pin, returning HIGH or LOW
1303
+ *********************************************************************************
1304
+ */
1305
+
1306
+ int digitalRead (int pin)
1307
+ {
1308
+ char c ;
1309
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
1310
+
1311
+ if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
1312
+ {
1313
+ /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode
1314
+ {
1315
+ if (sysFds [pin] == -1)
1316
+ return LOW ;
1317
+
1318
+ lseek (sysFds [pin], 0L, SEEK_SET) ;
1319
+ read (sysFds [pin], &c, 1) ;
1320
+ return (c == '0') ? LOW : HIGH ;
1321
+ }
1322
+ else if (wiringPiMode == WPI_MODE_PINS)
1323
+ pin = pinToGpio [pin] ;
1324
+ else if (wiringPiMode == WPI_MODE_PHYS)
1325
+ pin = physToGpio [pin] ;
1326
+ else if (wiringPiMode != WPI_MODE_GPIO)
1327
+ return LOW ;
1328
+
1329
+ if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
1330
+ return HIGH ;
1331
+ else
1332
+ return LOW ;
1333
+ }
1334
+ else
1335
+ {
1336
+ if ((node = wiringPiFindNode (pin)) == NULL)
1337
+ return LOW ;
1338
+ return node->digitalRead (node, pin) ;
1339
+ }
1340
+ }
1341
+
1342
+
1343
+ /*
1344
+ * digitalWrite:
1345
+ * Set an output bit
1346
+ *********************************************************************************
1347
+ */
1348
+
1349
+ void digitalWrite (int pin, int value)
1350
+ {
1351
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
1352
+
1353
+ if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
1354
+ {
1355
+ /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode
1356
+ {
1357
+ if (sysFds [pin] != -1)
1358
+ {
1359
+ if (value == LOW)
1360
+ write (sysFds [pin], "0\n", 2) ;
1361
+ else
1362
+ write (sysFds [pin], "1\n", 2) ;
1363
+ }
1364
+ return ;
1365
+ }
1366
+ else if (wiringPiMode == WPI_MODE_PINS)
1367
+ pin = pinToGpio [pin] ;
1368
+ else if (wiringPiMode == WPI_MODE_PHYS)
1369
+ pin = physToGpio [pin] ;
1370
+ else if (wiringPiMode != WPI_MODE_GPIO)
1371
+ return ;
1372
+
1373
+ if (value == LOW)
1374
+ *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
1375
+ else
1376
+ *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
1377
+ }
1378
+ else
1379
+ {
1380
+ if ((node = wiringPiFindNode (pin)) != NULL)
1381
+ node->digitalWrite (node, pin, value) ;
1382
+ }
1383
+ }
1384
+
1385
+
1386
+ /*
1387
+ * pwmWrite:
1388
+ * Set an output PWM value
1389
+ *********************************************************************************
1390
+ */
1391
+
1392
+ void pwmWrite (int pin, int value)
1393
+ {
1394
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
1395
+
1396
+ if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
1397
+ {
1398
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
1399
+ pin = pinToGpio [pin] ;
1400
+ else if (wiringPiMode == WPI_MODE_PHYS)
1401
+ pin = physToGpio [pin] ;
1402
+ else if (wiringPiMode != WPI_MODE_GPIO)
1403
+ return ;
1404
+
1405
+ *(pwm + gpioToPwmPort [pin]) = value ;
1406
+ }
1407
+ else
1408
+ {
1409
+ if ((node = wiringPiFindNode (pin)) != NULL)
1410
+ node->pwmWrite (node, pin, value) ;
1411
+ }
1412
+ }
1413
+
1414
+
1415
+ /*
1416
+ * analogRead:
1417
+ * Read the analog value of a given Pin.
1418
+ * There is no on-board Pi analog hardware,
1419
+ * so this needs to go to a new node.
1420
+ *********************************************************************************
1421
+ */
1422
+
1423
+ int analogRead (int pin)
1424
+ {
1425
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
1426
+
1427
+ if ((node = wiringPiFindNode (pin)) == NULL)
1428
+ return 0 ;
1429
+ else
1430
+ return node->analogRead (node, pin) ;
1431
+ }
1432
+
1433
+
1434
+ /*
1435
+ * analogWrite:
1436
+ * Write the analog value to the given Pin.
1437
+ * There is no on-board Pi analog hardware,
1438
+ * so this needs to go to a new node.
1439
+ *********************************************************************************
1440
+ */
1441
+
1442
+ void analogWrite (int pin, int value)
1443
+ {
1444
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
1445
+
1446
+ if ((node = wiringPiFindNode (pin)) == NULL)
1447
+ return ;
1448
+
1449
+ node->analogWrite (node, pin, value) ;
1450
+ }
1451
+
1452
+
1453
+ /*
1454
+ * pwmToneWrite:
1455
+ * Pi Specific.
1456
+ * Output the given frequency on the Pi's PWM pin
1457
+ *********************************************************************************
1458
+ */
1459
+
1460
+ void pwmToneWrite (int pin, int freq)
1461
+ {
1462
+ int range ;
1463
+
1464
+ if (freq == 0)
1465
+ pwmWrite (pin, 0) ; // Off
1466
+ else
1467
+ {
1468
+ range = 600000 / freq ;
1469
+ pwmSetRange (range) ;
1470
+ pwmWrite (pin, freq / 2) ;
1471
+ }
1472
+ }
1473
+
1474
+
1475
+
1476
+ /*
1477
+ * digitalWriteByte:
1478
+ * Pi Specific
1479
+ * Write an 8-bit byte to the first 8 GPIO pins - try to do it as
1480
+ * fast as possible.
1481
+ * However it still needs 2 operations to set the bits, so any external
1482
+ * hardware must not rely on seeing a change as there will be a change
1483
+ * to set the outputs bits to zero, then another change to set the 1's
1484
+ *********************************************************************************
1485
+ */
1486
+
1487
+ void digitalWriteByte (int value)
1488
+ {
1489
+ uint32_t pinSet = 0 ;
1490
+ uint32_t pinClr = 0 ;
1491
+ int mask = 1 ;
1492
+ int pin ;
1493
+
1494
+ /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS)
1495
+ {
1496
+ for (pin = 0 ; pin < 8 ; ++pin)
1497
+ {
1498
+ digitalWrite (pin, value & mask) ;
1499
+ mask <<= 1 ;
1500
+ }
1501
+ return ;
1502
+ }
1503
+ else
1504
+ {
1505
+ for (pin = 0 ; pin < 8 ; ++pin)
1506
+ {
1507
+ if ((value & mask) == 0)
1508
+ pinClr |= (1 << pinToGpio [pin]) ;
1509
+ else
1510
+ pinSet |= (1 << pinToGpio [pin]) ;
1511
+
1512
+ mask <<= 1 ;
1513
+ }
1514
+
1515
+ *(gpio + gpioToGPCLR [0]) = pinClr ;
1516
+ *(gpio + gpioToGPSET [0]) = pinSet ;
1517
+ }
1518
+ }
1519
+
1520
+
1521
+ /*
1522
+ * waitForInterrupt:
1523
+ * Pi Specific.
1524
+ * Wait for Interrupt on a GPIO pin.
1525
+ * This is actually done via the /sys/class/gpio interface regardless of
1526
+ * the wiringPi access mode in-use. Maybe sometime it might get a better
1527
+ * way for a bit more efficiency.
1528
+ *********************************************************************************
1529
+ */
1530
+
1531
+ int waitForInterrupt (int pin, int mS)
1532
+ {
1533
+ int fd, x ;
1534
+ uint8_t c ;
1535
+ struct pollfd polls ;
1536
+
1537
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
1538
+ pin = pinToGpio [pin] ;
1539
+ else if (wiringPiMode == WPI_MODE_PHYS)
1540
+ pin = physToGpio [pin] ;
1541
+
1542
+ if ((fd = sysFds [pin]) == -1)
1543
+ return -2 ;
1544
+
1545
+ // Setup poll structure
1546
+
1547
+ polls.fd = fd ;
1548
+ polls.events = POLLPRI ; // Urgent data!
1549
+
1550
+ // Wait for it ...
1551
+
1552
+ x = poll (&polls, 1, mS) ;
1553
+
1554
+ // Do a dummy read to clear the interrupt
1555
+ // A one character read appars to be enough.
1556
+ // Followed by a seek to reset it.
1557
+
1558
+ (void)read (fd, &c, 1) ;
1559
+ lseek (fd, 0, SEEK_SET) ;
1560
+
1561
+ return x ;
1562
+ }
1563
+
1564
+
1565
+ /*
1566
+ * interruptHandler:
1567
+ * This is a thread and gets started to wait for the interrupt we're
1568
+ * hoping to catch. It will call the user-function when the interrupt
1569
+ * fires.
1570
+ *********************************************************************************
1571
+ */
1572
+
1573
+ static void *interruptHandler (void *arg)
1574
+ {
1575
+ int myPin ;
1576
+
1577
+ (void)piHiPri (55) ; // Only effective if we run as root
1578
+
1579
+ myPin = pinPass ;
1580
+ pinPass = -1 ;
1581
+
1582
+ for (;;)
1583
+ if (waitForInterrupt (myPin, -1) > 0)
1584
+ isrFunctions [myPin] () ;
1585
+
1586
+ return NULL ;
1587
+ }
1588
+
1589
+
1590
+ /*
1591
+ * wiringPiISR:
1592
+ * Pi Specific.
1593
+ * Take the details and create an interrupt handler that will do a call-
1594
+ * back to the user supplied function.
1595
+ *********************************************************************************
1596
+ */
1597
+
1598
+ int wiringPiISR (int pin, int mode, void (*function)(void))
1599
+ {
1600
+ pthread_t threadId ;
1601
+ const char *modeS ;
1602
+ char fName [64] ;
1603
+ char pinS [8] ;
1604
+ pid_t pid ;
1605
+ int count, i ;
1606
+ char c ;
1607
+ int bcmGpioPin ;
1608
+
1609
+ if ((pin < 0) || (pin > 63))
1610
+ return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-63 (%d)\n", pin) ;
1611
+
1612
+ /**/ if (wiringPiMode == WPI_MODE_UNINITIALISED)
1613
+ return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ;
1614
+ else if (wiringPiMode == WPI_MODE_PINS)
1615
+ bcmGpioPin = pinToGpio [pin] ;
1616
+ else if (wiringPiMode == WPI_MODE_PHYS)
1617
+ bcmGpioPin = physToGpio [pin] ;
1618
+ else
1619
+ bcmGpioPin = pin ;
1620
+
1621
+ // Now export the pin and set the right edge
1622
+ // We're going to use the gpio program to do this, so it assumes
1623
+ // a full installation of wiringPi. It's a bit 'clunky', but it
1624
+ // is a way that will work when we're running in "Sys" mode, as
1625
+ // a non-root user. (without sudo)
1626
+
1627
+ if (mode != INT_EDGE_SETUP)
1628
+ {
1629
+ /**/ if (mode == INT_EDGE_FALLING)
1630
+ modeS = "falling" ;
1631
+ else if (mode == INT_EDGE_RISING)
1632
+ modeS = "rising" ;
1633
+ else
1634
+ modeS = "both" ;
1635
+
1636
+ sprintf (pinS, "%d", bcmGpioPin) ;
1637
+
1638
+ if ((pid = fork ()) < 0) // Fail
1639
+ return wiringPiFailure (WPI_FATAL, "wiringPiISR: fork failed: %s\n", strerror (errno)) ;
1640
+
1641
+ if (pid == 0) // Child, exec
1642
+ {
1643
+ /**/ if (access ("/usr/local/bin/gpio", X_OK) == 0)
1644
+ {
1645
+ execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ;
1646
+ return wiringPiFailure (WPI_FATAL, "wiringPiISR: execl failed: %s\n", strerror (errno)) ;
1647
+ }
1648
+ else if (access ("/usr/bin/gpio", X_OK) == 0)
1649
+ {
1650
+ execl ("/usr/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ;
1651
+ return wiringPiFailure (WPI_FATAL, "wiringPiISR: execl failed: %s\n", strerror (errno)) ;
1652
+ }
1653
+ else
1654
+ return wiringPiFailure (WPI_FATAL, "wiringPiISR: Can't find gpio program\n") ;
1655
+ }
1656
+ else // Parent, wait
1657
+ wait (NULL) ;
1658
+ }
1659
+
1660
+ // Now pre-open the /sys/class node - but it may already be open if
1661
+ // we are in Sys mode...
1662
+
1663
+ if (sysFds [bcmGpioPin] == -1)
1664
+ {
1665
+ sprintf (fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin) ;
1666
+ if ((sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0)
1667
+ return wiringPiFailure (WPI_FATAL, "wiringPiISR: unable to open %s: %s\n", fName, strerror (errno)) ;
1668
+ }
1669
+
1670
+ // Clear any initial pending interrupt
1671
+
1672
+ ioctl (sysFds [bcmGpioPin], FIONREAD, &count) ;
1673
+ for (i = 0 ; i < count ; ++i)
1674
+ read (sysFds [bcmGpioPin], &c, 1) ;
1675
+
1676
+ isrFunctions [pin] = function ;
1677
+
1678
+ pthread_mutex_lock (&pinMutex) ;
1679
+ pinPass = pin ;
1680
+ pthread_create (&threadId, NULL, interruptHandler, NULL) ;
1681
+ while (pinPass != -1)
1682
+ delay (1) ;
1683
+ pthread_mutex_unlock (&pinMutex) ;
1684
+
1685
+ return 0 ;
1686
+ }
1687
+
1688
+
1689
+ /*
1690
+ * initialiseEpoch:
1691
+ * Initialise our start-of-time variable to be the current unix
1692
+ * time in milliseconds and microseconds.
1693
+ *********************************************************************************
1694
+ */
1695
+
1696
+ static void initialiseEpoch (void)
1697
+ {
1698
+ struct timeval tv ;
1699
+
1700
+ gettimeofday (&tv, NULL) ;
1701
+ epochMilli = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ;
1702
+ epochMicro = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)(tv.tv_usec) ;
1703
+ }
1704
+
1705
+
1706
+ /*
1707
+ * delay:
1708
+ * Wait for some number of milliseconds
1709
+ *********************************************************************************
1710
+ */
1711
+
1712
+ void delay (unsigned int howLong)
1713
+ {
1714
+ struct timespec sleeper, dummy ;
1715
+
1716
+ sleeper.tv_sec = (time_t)(howLong / 1000) ;
1717
+ sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;
1718
+
1719
+ nanosleep (&sleeper, &dummy) ;
1720
+ }
1721
+
1722
+
1723
+ /*
1724
+ * delayMicroseconds:
1725
+ * This is somewhat intersting. It seems that on the Pi, a single call
1726
+ * to nanosleep takes some 80 to 130 microseconds anyway, so while
1727
+ * obeying the standards (may take longer), it's not always what we
1728
+ * want!
1729
+ *
1730
+ * So what I'll do now is if the delay is less than 100uS we'll do it
1731
+ * in a hard loop, watching a built-in counter on the ARM chip. This is
1732
+ * somewhat sub-optimal in that it uses 100% CPU, something not an issue
1733
+ * in a microcontroller, but under a multi-tasking, multi-user OS, it's
1734
+ * wastefull, however we've no real choice )-:
1735
+ *
1736
+ * Plan B: It seems all might not be well with that plan, so changing it
1737
+ * to use gettimeofday () and poll on that instead...
1738
+ *********************************************************************************
1739
+ */
1740
+
1741
+ void delayMicrosecondsHard (unsigned int howLong)
1742
+ {
1743
+ struct timeval tNow, tLong, tEnd ;
1744
+
1745
+ gettimeofday (&tNow, NULL) ;
1746
+ tLong.tv_sec = howLong / 1000000 ;
1747
+ tLong.tv_usec = howLong % 1000000 ;
1748
+ timeradd (&tNow, &tLong, &tEnd) ;
1749
+
1750
+ while (timercmp (&tNow, &tEnd, <))
1751
+ gettimeofday (&tNow, NULL) ;
1752
+ }
1753
+
1754
+ void delayMicroseconds (unsigned int howLong)
1755
+ {
1756
+ struct timespec sleeper ;
1757
+ unsigned int uSecs = howLong % 1000000 ;
1758
+ unsigned int wSecs = howLong / 1000000 ;
1759
+
1760
+ /**/ if (howLong == 0)
1761
+ return ;
1762
+ else if (howLong < 100)
1763
+ delayMicrosecondsHard (howLong) ;
1764
+ else
1765
+ {
1766
+ sleeper.tv_sec = wSecs ;
1767
+ sleeper.tv_nsec = (long)(uSecs * 1000L) ;
1768
+ nanosleep (&sleeper, NULL) ;
1769
+ }
1770
+ }
1771
+
1772
+
1773
+ /*
1774
+ * millis:
1775
+ * Return a number of milliseconds as an unsigned int.
1776
+ *********************************************************************************
1777
+ */
1778
+
1779
+ unsigned int millis (void)
1780
+ {
1781
+ struct timeval tv ;
1782
+ uint64_t now ;
1783
+
1784
+ gettimeofday (&tv, NULL) ;
1785
+ now = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ;
1786
+
1787
+ return (uint32_t)(now - epochMilli) ;
1788
+ }
1789
+
1790
+
1791
+ /*
1792
+ * micros:
1793
+ * Return a number of microseconds as an unsigned int.
1794
+ *********************************************************************************
1795
+ */
1796
+
1797
+ unsigned int micros (void)
1798
+ {
1799
+ struct timeval tv ;
1800
+ uint64_t now ;
1801
+
1802
+ gettimeofday (&tv, NULL) ;
1803
+ now = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)tv.tv_usec ;
1804
+
1805
+ return (uint32_t)(now - epochMicro) ;
1806
+ }
1807
+
1808
+
1809
+ /*
1810
+ * wiringPiSetup:
1811
+ * Must be called once at the start of your program execution.
1812
+ *
1813
+ * Default setup: Initialises the system into wiringPi Pin mode and uses the
1814
+ * memory mapped hardware directly.
1815
+ *
1816
+ * Changed now to revert to "gpio" mode if we're running on a Compute Module.
1817
+ *********************************************************************************
1818
+ */
1819
+
1820
+ int wiringPiSetup (void)
1821
+ {
1822
+ int fd ;
1823
+ int boardRev ;
1824
+ int model, rev, mem, maker, overVolted ;
1825
+
1826
+ if (getenv (ENV_DEBUG) != NULL)
1827
+ wiringPiDebug = TRUE ;
1828
+
1829
+ if (getenv (ENV_CODES) != NULL)
1830
+ wiringPiReturnCodes = TRUE ;
1831
+
1832
+ if (geteuid () != 0)
1833
+ (void)wiringPiFailure (WPI_FATAL, "wiringPiSetup: Must be root. (Did you forget sudo?)\n") ;
1834
+
1835
+ if (wiringPiDebug)
1836
+ printf ("wiringPi: wiringPiSetup called\n") ;
1837
+
1838
+ boardRev = piBoardRev () ;
1839
+
1840
+ /**/ if (boardRev == 1) // A, B, Rev 1, 1.1
1841
+ {
1842
+ pinToGpio = pinToGpioR1 ;
1843
+ physToGpio = physToGpioR1 ;
1844
+ }
1845
+ else // A, B, Rev 2, B+, CM, Pi2
1846
+ {
1847
+ if (piModel2)
1848
+ BCM2708_PERI_BASE = 0x3F000000 ;
1849
+ pinToGpio = pinToGpioR2 ;
1850
+ physToGpio = physToGpioR2 ;
1851
+ }
1852
+
1853
+ // Open the master /dev/memory device
1854
+
1855
+ if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0)
1856
+ return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
1857
+
1858
+ // GPIO:
1859
+
1860
+ gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ;
1861
+ if ((int32_t)gpio == -1)
1862
+ return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ;
1863
+
1864
+ // PWM
1865
+
1866
+ pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ;
1867
+ if ((int32_t)pwm == -1)
1868
+ return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ;
1869
+
1870
+ // Clock control (needed for PWM)
1871
+
1872
+ clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CLOCK_BASE) ;
1873
+ if ((int32_t)clk == -1)
1874
+ return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ;
1875
+
1876
+ // The drive pads
1877
+
1878
+ pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ;
1879
+ if ((int32_t)pads == -1)
1880
+ return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ;
1881
+
1882
+ #ifdef USE_TIMER
1883
+ // The system timer
1884
+
1885
+ timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ;
1886
+ if ((int32_t)timer == -1)
1887
+ return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (TIMER) failed: %s\n", strerror (errno)) ;
1888
+
1889
+ // Set the timer to free-running, 1MHz.
1890
+ // 0xF9 is 249, the timer divide is base clock / (divide+1)
1891
+ // so base clock is 250MHz / 250 = 1MHz.
1892
+
1893
+ *(timer + TIMER_CONTROL) = 0x0000280 ;
1894
+ *(timer + TIMER_PRE_DIV) = 0x00000F9 ;
1895
+ timerIrqRaw = timer + TIMER_IRQ_RAW ;
1896
+ #endif
1897
+
1898
+ initialiseEpoch () ;
1899
+
1900
+ // If we're running on a compute module, then wiringPi pin numbers don't really many anything...
1901
+
1902
+ piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
1903
+ if (model == PI_MODEL_CM)
1904
+ wiringPiMode = WPI_MODE_GPIO ;
1905
+ else
1906
+ wiringPiMode = WPI_MODE_PINS ;
1907
+
1908
+ return 0 ;
1909
+ }
1910
+
1911
+
1912
+ /*
1913
+ * wiringPiSetupGpio:
1914
+ * Must be called once at the start of your program execution.
1915
+ *
1916
+ * GPIO setup: Initialises the system into GPIO Pin mode and uses the
1917
+ * memory mapped hardware directly.
1918
+ *********************************************************************************
1919
+ */
1920
+
1921
+ int wiringPiSetupGpio (void)
1922
+ {
1923
+ (void)wiringPiSetup () ;
1924
+
1925
+ if (wiringPiDebug)
1926
+ printf ("wiringPi: wiringPiSetupGpio called\n") ;
1927
+
1928
+ wiringPiMode = WPI_MODE_GPIO ;
1929
+
1930
+ return 0 ;
1931
+ }
1932
+
1933
+
1934
+ /*
1935
+ * wiringPiSetupPhys:
1936
+ * Must be called once at the start of your program execution.
1937
+ *
1938
+ * Phys setup: Initialises the system into Physical Pin mode and uses the
1939
+ * memory mapped hardware directly.
1940
+ *********************************************************************************
1941
+ */
1942
+
1943
+ int wiringPiSetupPhys (void)
1944
+ {
1945
+ (void)wiringPiSetup () ;
1946
+
1947
+ if (wiringPiDebug)
1948
+ printf ("wiringPi: wiringPiSetupPhys called\n") ;
1949
+
1950
+ wiringPiMode = WPI_MODE_PHYS ;
1951
+
1952
+ return 0 ;
1953
+ }
1954
+
1955
+
1956
+ /*
1957
+ * wiringPiSetupSys:
1958
+ * Must be called once at the start of your program execution.
1959
+ *
1960
+ * Initialisation (again), however this time we are using the /sys/class/gpio
1961
+ * interface to the GPIO systems - slightly slower, but always usable as
1962
+ * a non-root user, assuming the devices are already exported and setup correctly.
1963
+ */
1964
+
1965
+ int wiringPiSetupSys (void)
1966
+ {
1967
+ int boardRev ;
1968
+ int pin ;
1969
+ char fName [128] ;
1970
+
1971
+ if (getenv (ENV_DEBUG) != NULL)
1972
+ wiringPiDebug = TRUE ;
1973
+
1974
+ if (getenv (ENV_CODES) != NULL)
1975
+ wiringPiReturnCodes = TRUE ;
1976
+
1977
+ if (wiringPiDebug)
1978
+ printf ("wiringPi: wiringPiSetupSys called\n") ;
1979
+
1980
+ boardRev = piBoardRev () ;
1981
+
1982
+ if (boardRev == 1)
1983
+ {
1984
+ pinToGpio = pinToGpioR1 ;
1985
+ physToGpio = physToGpioR1 ;
1986
+ }
1987
+ else
1988
+ {
1989
+ pinToGpio = pinToGpioR2 ;
1990
+ physToGpio = physToGpioR2 ;
1991
+ }
1992
+
1993
+ // Open and scan the directory, looking for exported GPIOs, and pre-open
1994
+ // the 'value' interface to speed things up for later
1995
+
1996
+ for (pin = 0 ; pin < 64 ; ++pin)
1997
+ {
1998
+ sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
1999
+ sysFds [pin] = open (fName, O_RDWR) ;
2000
+ }
2001
+
2002
+ initialiseEpoch () ;
2003
+
2004
+ wiringPiMode = WPI_MODE_GPIO_SYS ;
2005
+
2006
+ return 0 ;
2007
+ }