rpi_gpio 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,36 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- rpi_gpio (0.4.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- diff-lcs (1.4.4)
10
- rake (13.0.1)
11
- rake-compiler (1.1.1)
12
- rake
13
- rspec (3.9.0)
14
- rspec-core (~> 3.9.0)
15
- rspec-expectations (~> 3.9.0)
16
- rspec-mocks (~> 3.9.0)
17
- rspec-core (3.9.2)
18
- rspec-support (~> 3.9.3)
19
- rspec-expectations (3.9.2)
20
- diff-lcs (>= 1.2.0, < 2.0)
21
- rspec-support (~> 3.9.0)
22
- rspec-mocks (3.9.1)
23
- diff-lcs (>= 1.2.0, < 2.0)
24
- rspec-support (~> 3.9.0)
25
- rspec-support (3.9.3)
26
-
27
- PLATFORMS
28
- ruby
29
-
30
- DEPENDENCIES
31
- rake-compiler
32
- rpi_gpio!
33
- rspec
34
-
35
- BUNDLED WITH
36
- 2.1.4
@@ -1,305 +0,0 @@
1
- /*
2
- Original code by Ben Croston modified for Ruby by Nick Lowery
3
- (github.com/clockvapor)
4
- Copyright (c) 2014-2020 Nick Lowery
5
-
6
- Copyright (c) 2012-2019 Ben Croston
7
-
8
- Permission is hereby granted, free of charge, to any person obtaining a copy of
9
- this software and associated documentation files (the "Software"), to deal in
10
- the Software without restriction, including without limitation the rights to
11
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12
- of the Software, and to permit persons to whom the Software is furnished to do
13
- so, subject to the following conditions:
14
-
15
- The above copyright notice and this permission notice shall be included in all
16
- copies or substantial portions of the Software.
17
-
18
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
- SOFTWARE.
25
- */
26
-
27
- #include <stdio.h>
28
- #include <stdint.h>
29
- #include <stdlib.h>
30
- #include <fcntl.h>
31
- #include <sys/mman.h>
32
- #include <string.h>
33
- #include "c_gpio.h"
34
-
35
- #define BCM2708_PERI_BASE_DEFAULT 0x20000000
36
- #define BCM2709_PERI_BASE_DEFAULT 0x3f000000
37
- #define GPIO_BASE_OFFSET 0x200000
38
- #define FSEL_OFFSET 0 // 0x0000
39
- #define SET_OFFSET 7 // 0x001c / 4
40
- #define CLR_OFFSET 10 // 0x0028 / 4
41
- #define PINLEVEL_OFFSET 13 // 0x0034 / 4
42
- #define EVENT_DETECT_OFFSET 16 // 0x0040 / 4
43
- #define RISING_ED_OFFSET 19 // 0x004c / 4
44
- #define FALLING_ED_OFFSET 22 // 0x0058 / 4
45
- #define HIGH_DETECT_OFFSET 25 // 0x0064 / 4
46
- #define LOW_DETECT_OFFSET 28 // 0x0070 / 4
47
- #define PULLUPDN_OFFSET 37 // 0x0094 / 4
48
- #define PULLUPDNCLK_OFFSET 38 // 0x0098 / 4
49
-
50
- #define PULLUPDN_OFFSET_2711_0 57
51
- #define PULLUPDN_OFFSET_2711_1 58
52
- #define PULLUPDN_OFFSET_2711_2 59
53
- #define PULLUPDN_OFFSET_2711_3 60
54
-
55
- #define PAGE_SIZE (4*1024)
56
- #define BLOCK_SIZE (4*1024)
57
-
58
- static volatile uint32_t *gpio_map;
59
-
60
- void short_wait(void)
61
- {
62
- int i;
63
-
64
- for (i=0; i<150; i++) { // wait 150 cycles
65
- asm volatile("nop");
66
- }
67
- }
68
-
69
- int setup(void)
70
- {
71
- int mem_fd;
72
- uint8_t *gpio_mem;
73
- uint32_t peri_base = 0;
74
- uint32_t gpio_base;
75
- unsigned char buf[4];
76
- FILE *fp;
77
- char buffer[1024];
78
- char hardware[1024];
79
- int found = 0;
80
-
81
- // try /dev/gpiomem first - this does not require root privs
82
- if ((mem_fd = open("/dev/gpiomem", O_RDWR|O_SYNC)) > 0)
83
- {
84
- if ((gpio_map = (uint32_t *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0)) == MAP_FAILED) {
85
- return SETUP_MMAP_FAIL;
86
- } else {
87
- return SETUP_OK;
88
- }
89
- }
90
-
91
- // revert to /dev/mem method - requires root
92
-
93
- // determine peri_base
94
- if ((fp = fopen("/proc/device-tree/soc/ranges", "rb")) != NULL) {
95
- // get peri base from device tree
96
- fseek(fp, 4, SEEK_SET);
97
- if (fread(buf, 1, sizeof buf, fp) == sizeof buf) {
98
- peri_base = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3] << 0;
99
- }
100
- fclose(fp);
101
- } else {
102
- // guess peri base based on /proc/cpuinfo hardware field
103
- if ((fp = fopen("/proc/cpuinfo", "r")) == NULL)
104
- return SETUP_CPUINFO_FAIL;
105
-
106
- while(!feof(fp) && !found && fgets(buffer, sizeof(buffer), fp)) {
107
- sscanf(buffer, "Hardware : %s", hardware);
108
- if (strcmp(hardware, "BCM2708") == 0 || strcmp(hardware, "BCM2835") == 0) {
109
- // pi 1 hardware
110
- peri_base = BCM2708_PERI_BASE_DEFAULT;
111
- found = 1;
112
- } else if (strcmp(hardware, "BCM2709") == 0 || strcmp(hardware, "BCM2836") == 0) {
113
- // pi 2 hardware
114
- peri_base = BCM2709_PERI_BASE_DEFAULT;
115
- found = 1;
116
- }
117
- }
118
- fclose(fp);
119
- if (!found)
120
- return SETUP_NOT_RPI_FAIL;
121
- }
122
-
123
- if (!peri_base)
124
- return SETUP_NOT_RPI_FAIL;
125
- gpio_base = peri_base + GPIO_BASE_OFFSET;
126
-
127
- // mmap the GPIO memory registers
128
- if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0)
129
- return SETUP_DEVMEM_FAIL;
130
-
131
- if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
132
- return SETUP_MALLOC_FAIL;
133
-
134
- if ((uint32_t)gpio_mem % PAGE_SIZE)
135
- gpio_mem += PAGE_SIZE - ((uint32_t)gpio_mem % PAGE_SIZE);
136
-
137
- if ((gpio_map = (uint32_t *)mmap( (void *)gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, gpio_base)) == MAP_FAILED)
138
- return SETUP_MMAP_FAIL;
139
-
140
- return SETUP_OK;
141
- }
142
-
143
- void clear_event_detect(int gpio)
144
- {
145
- int offset = EVENT_DETECT_OFFSET + (gpio/32);
146
- int shift = (gpio%32);
147
-
148
- *(gpio_map+offset) |= (1 << shift);
149
- short_wait();
150
- *(gpio_map+offset) = 0;
151
- }
152
-
153
- int eventdetected(int gpio)
154
- {
155
- int offset, value, bit;
156
-
157
- offset = EVENT_DETECT_OFFSET + (gpio/32);
158
- bit = (1 << (gpio%32));
159
- value = *(gpio_map+offset) & bit;
160
- if (value)
161
- clear_event_detect(gpio);
162
- return value;
163
- }
164
-
165
- void set_rising_event(int gpio, int enable)
166
- {
167
- int offset = RISING_ED_OFFSET + (gpio/32);
168
- int shift = (gpio%32);
169
-
170
- if (enable)
171
- *(gpio_map+offset) |= 1 << shift;
172
- else
173
- *(gpio_map+offset) &= ~(1 << shift);
174
- clear_event_detect(gpio);
175
- }
176
-
177
- void set_falling_event(int gpio, int enable)
178
- {
179
- int offset = FALLING_ED_OFFSET + (gpio/32);
180
- int shift = (gpio%32);
181
-
182
- if (enable) {
183
- *(gpio_map+offset) |= (1 << shift);
184
- *(gpio_map+offset) = (1 << shift);
185
- } else {
186
- *(gpio_map+offset) &= ~(1 << shift);
187
- }
188
- clear_event_detect(gpio);
189
- }
190
-
191
- void set_high_event(int gpio, int enable)
192
- {
193
- int offset = HIGH_DETECT_OFFSET + (gpio/32);
194
- int shift = (gpio%32);
195
-
196
- if (enable)
197
- *(gpio_map+offset) |= (1 << shift);
198
- else
199
- *(gpio_map+offset) &= ~(1 << shift);
200
- clear_event_detect(gpio);
201
- }
202
-
203
- void set_low_event(int gpio, int enable)
204
- {
205
- int offset = LOW_DETECT_OFFSET + (gpio/32);
206
- int shift = (gpio%32);
207
-
208
- if (enable)
209
- *(gpio_map+offset) |= 1 << shift;
210
- else
211
- *(gpio_map+offset) &= ~(1 << shift);
212
- clear_event_detect(gpio);
213
- }
214
-
215
- void set_pullupdn(int gpio, int pud)
216
- {
217
- // Check GPIO register
218
- int is2711 = *(gpio_map+PULLUPDN_OFFSET_2711_3) != 0x6770696f;
219
- if (is2711) {
220
- // Pi 4 Pull-up/down method
221
- int pullreg = PULLUPDN_OFFSET_2711_0 + (gpio >> 4);
222
- int pullshift = (gpio & 0xf) << 1;
223
- unsigned int pullbits;
224
- unsigned int pull = 0;
225
- switch (pud) {
226
- case PUD_OFF: pull = 0; break;
227
- case PUD_UP: pull = 1; break;
228
- case PUD_DOWN: pull = 2; break;
229
- default: pull = 0; // switch PUD to OFF for other values
230
- }
231
- pullbits = *(gpio_map + pullreg);
232
- pullbits &= ~(3 << pullshift);
233
- pullbits |= (pull << pullshift);
234
- *(gpio_map + pullreg) = pullbits;
235
- } else {
236
- // Legacy Pull-up/down method
237
- int clk_offset = PULLUPDNCLK_OFFSET + (gpio/32);
238
- int shift = (gpio%32);
239
-
240
- if (pud == PUD_DOWN) {
241
- *(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_DOWN;
242
- } else if (pud == PUD_UP) {
243
- *(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_UP;
244
- } else { // pud == PUD_OFF
245
- *(gpio_map+PULLUPDN_OFFSET) &= ~3;
246
- }
247
- short_wait();
248
- *(gpio_map+clk_offset) = 1 << shift;
249
- short_wait();
250
- *(gpio_map+PULLUPDN_OFFSET) &= ~3;
251
- *(gpio_map+clk_offset) = 0;
252
- }
253
- }
254
-
255
- void setup_gpio(int gpio, int direction, int pud)
256
- {
257
- int offset = FSEL_OFFSET + (gpio/10);
258
- int shift = (gpio%10)*3;
259
-
260
- set_pullupdn(gpio, pud);
261
- if (direction == OUTPUT)
262
- *(gpio_map+offset) = (*(gpio_map+offset) & ~(7<<shift)) | (1<<shift);
263
- else // direction == INPUT
264
- *(gpio_map+offset) = (*(gpio_map+offset) & ~(7<<shift));
265
- }
266
-
267
- // Contribution by Eric Ptak <trouch@trouch.com>
268
- int gpio_function(int gpio)
269
- {
270
- int offset = FSEL_OFFSET + (gpio/10);
271
- int shift = (gpio%10)*3;
272
- int value = *(gpio_map+offset);
273
- value >>= shift;
274
- value &= 7;
275
- return value; // 0=input, 1=output, 4=alt0
276
- }
277
-
278
- void output_gpio(int gpio, int value)
279
- {
280
- int offset, shift;
281
-
282
- if (value) // value == HIGH
283
- offset = SET_OFFSET + (gpio/32);
284
- else // value == LOW
285
- offset = CLR_OFFSET + (gpio/32);
286
-
287
- shift = (gpio%32);
288
-
289
- *(gpio_map+offset) = 1 << shift;
290
- }
291
-
292
- int input_gpio(int gpio)
293
- {
294
- int offset, value, mask;
295
-
296
- offset = PINLEVEL_OFFSET + (gpio/32);
297
- mask = (1 << gpio%32);
298
- value = *(gpio_map+offset) & mask;
299
- return value;
300
- }
301
-
302
- void cleanup(void)
303
- {
304
- munmap((void *)gpio_map, BLOCK_SIZE);
305
- }
@@ -1,55 +0,0 @@
1
- /*
2
- Original code by Ben Croston modified for Ruby by Nick Lowery
3
- (github.com/clockvapor)
4
- Copyright (c) 2014-2020 Nick Lowery
5
-
6
- Copyright (c) 2013-2015 Ben Croston
7
-
8
- Permission is hereby granted, free of charge, to any person obtaining a copy of
9
- this software and associated documentation files (the "Software"), to deal in
10
- the Software without restriction, including without limitation the rights to
11
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12
- of the Software, and to permit persons to whom the Software is furnished to do
13
- so, subject to the following conditions:
14
-
15
- The above copyright notice and this permission notice shall be included in all
16
- copies or substantial portions of the Software.
17
-
18
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
- SOFTWARE.
25
- */
26
-
27
- int setup(void);
28
- void setup_gpio(int gpio, int direction, int pud);
29
- int gpio_function(int gpio);
30
- void output_gpio(int gpio, int value);
31
- int input_gpio(int gpio);
32
- void set_rising_event(int gpio, int enable);
33
- void set_falling_event(int gpio, int enable);
34
- void set_high_event(int gpio, int enable);
35
- void set_low_event(int gpio, int enable);
36
- int eventdetected(int gpio);
37
- void cleanup(void);
38
-
39
- #define SETUP_OK 0
40
- #define SETUP_DEVMEM_FAIL 1
41
- #define SETUP_MALLOC_FAIL 2
42
- #define SETUP_MMAP_FAIL 3
43
- #define SETUP_CPUINFO_FAIL 4
44
- #define SETUP_NOT_RPI_FAIL 5
45
-
46
- #define INPUT 1 // is really 0 for control register!
47
- #define OUTPUT 0 // is really 1 for control register!
48
- #define ALT0 4
49
-
50
- #define HIGH 1
51
- #define LOW 0
52
-
53
- #define PUD_OFF 0
54
- #define PUD_DOWN 1
55
- #define PUD_UP 2
@@ -1,93 +0,0 @@
1
- /*
2
- Original code by Ben Croston modified for Ruby by Nick Lowery
3
- (github.com/clockvapor)
4
- Copyright (c) 2014-2020 Nick Lowery
5
-
6
- Copyright (c) 2013-2014 Ben Croston
7
-
8
- Permission is hereby granted, free of charge, to any person obtaining a copy of
9
- this software and associated documentation files (the "Software"), to deal in
10
- the Software without restriction, including without limitation the rights to
11
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12
- of the Software, and to permit persons to whom the Software is furnished to do
13
- so, subject to the following conditions:
14
-
15
- The above copyright notice and this permission notice shall be included in all
16
- copies or substantial portions of the Software.
17
-
18
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
- SOFTWARE.
25
- */
26
-
27
- #include "ruby.h"
28
- #include "c_gpio.h"
29
- #include "common.h"
30
-
31
- int gpio_mode = MODE_UNKNOWN;
32
- const int pin_to_gpio_rev1[41] = {-1, -1, -1, 0, -1, 1, -1, 4, 14, -1, 15, 17, 18, 21, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
33
- const int pin_to_gpio_rev2[41] = {-1, -1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17, 18, 27, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
34
- const int pin_to_gpio_rev3[41] = {-1, -1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17, 18, 27, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, 5, -1, 6, 12, 13, -1, 19, 16, 26, 20, -1, 21 };
35
- int setup_error = 0;
36
- int module_setup = 0;
37
-
38
- int check_gpio_priv(void)
39
- {
40
- // check module has been imported cleanly
41
- if (setup_error)
42
- {
43
- rb_raise(rb_eRuntimeError, "gem not imported correctly!");
44
- return 1;
45
- }
46
-
47
- // check mmap setup has worked
48
- if (!module_setup)
49
- {
50
- rb_raise(rb_eRuntimeError, "no access to /dev/mem. Try running as root!");
51
- return 2;
52
- }
53
- return 0;
54
- }
55
-
56
- int get_gpio_number(int channel, unsigned int *gpio)
57
- {
58
- // check setmode() has been run
59
- if (gpio_mode != BOARD && gpio_mode != BCM)
60
- {
61
- rb_raise(rb_eRuntimeError, "please set pin numbering mode "
62
- "using RPi::GPIO.set_numbering :board or "
63
- "RPi::GPIO.set_numbering :bcm");
64
- return 3;
65
- }
66
-
67
- // check channel number is in range
68
- if ( (gpio_mode == BCM && (channel < 0 || channel > 53))
69
- || (gpio_mode == BOARD && (channel < 1 || channel > 26) && rpiinfo.p1_revision != 3)
70
- || (gpio_mode == BOARD && (channel < 1 || channel > 40) && rpiinfo.p1_revision == 3) )
71
- {
72
- rb_raise(rb_eArgError, "the channel sent is invalid on a Raspberry Pi");
73
- return 4;
74
- }
75
-
76
- // convert channel to gpio
77
- if (gpio_mode == BOARD)
78
- {
79
- if (*(*pin_to_gpio+channel) == -1)
80
- {
81
- rb_raise(rb_eArgError, "the channel sent is invalid on a Raspberry Pi");
82
- return 5;
83
- } else {
84
- *gpio = *(*pin_to_gpio+channel);
85
- }
86
- }
87
- else // gpio_mode == BCM
88
- {
89
- *gpio = channel;
90
- }
91
-
92
- return 0;
93
- }