wiringpi 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }