rpi_gpio 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,9 +1,9 @@
1
1
  /*
2
2
  Original code by Ben Croston modified for Ruby by Nick Lowery
3
3
  (github.com/clockvapor)
4
- Copyright (c) 2014-2015 Nick Lowery
4
+ Copyright (c) 2014-2020 Nick Lowery
5
5
 
6
- Copyright (c) 2013-2014 Ben Croston
6
+ Copyright (c) 2013-2018 Ben Croston
7
7
 
8
8
  Permission is hereby granted, free of charge, to any person obtaining a copy of
9
9
  this software and associated documentation files (the "Software"), to deal in
@@ -54,13 +54,14 @@ void remove_pwm(unsigned int gpio)
54
54
  {
55
55
  if (p->gpio == gpio)
56
56
  {
57
- if (prev == NULL)
57
+ if (prev == NULL) {
58
58
  pwm_list = p->next;
59
- else
59
+ } else {
60
60
  prev->next = p->next;
61
+ }
61
62
  temp = p;
62
63
  p = p->next;
63
- free(temp);
64
+ temp->running = 0; // signal the thread to stop. The thread will free() the pwm struct when it's done with it.
64
65
  } else {
65
66
  prev = p;
66
67
  p = p->next;
@@ -113,7 +114,7 @@ void *pwm_thread(void *threadarg)
113
114
 
114
115
  // clean up
115
116
  output_gpio(p->gpio, 0);
116
- remove_pwm(p->gpio);
117
+ free(p);
117
118
  pthread_exit(NULL);
118
119
  }
119
120
 
@@ -135,6 +136,7 @@ struct pwm *add_new_pwm(unsigned int gpio)
135
136
  }
136
137
 
137
138
  struct pwm *find_pwm(unsigned int gpio)
139
+ /* Return the pwm record for gpio, creating it if it does not exist */
138
140
  {
139
141
  struct pwm *p = pwm_list;
140
142
 
@@ -207,12 +209,27 @@ void pwm_start(unsigned int gpio)
207
209
  p->running = 0;
208
210
  return;
209
211
  }
212
+ pthread_detach(threads);
210
213
  }
211
214
 
212
215
  void pwm_stop(unsigned int gpio)
213
216
  {
214
- struct pwm *p;
217
+ remove_pwm(gpio);
218
+ }
215
219
 
216
- if ((p = find_pwm(gpio)) != NULL)
217
- p->running = 0;
220
+ // returns 1 if there is a PWM for this gpio, 0 otherwise
221
+ int pwm_exists(unsigned int gpio)
222
+ {
223
+ struct pwm *p = pwm_list;
224
+
225
+ while (p != NULL)
226
+ {
227
+ if (p->gpio == gpio)
228
+ {
229
+ return 1;
230
+ } else {
231
+ p = p->next;
232
+ }
233
+ }
234
+ return 0;
218
235
  }
@@ -1,9 +1,9 @@
1
1
  /*
2
2
  Original code by Ben Croston modified for Ruby by Nick Lowery
3
3
  (github.com/clockvapor)
4
- Copyright (c) 2014-2015 Nick Lowery
4
+ Copyright (c) 2014-2020 Nick Lowery
5
5
 
6
- Copyright (c) 2013-2014 Ben Croston
6
+ Copyright (c) 2013-2018 Ben Croston
7
7
 
8
8
  Permission is hereby granted, free of charge, to any person obtaining a copy of
9
9
  this software and associated documentation files (the "Software"), to deal in
@@ -30,3 +30,4 @@ void pwm_set_duty_cycle(unsigned int gpio, float dutycycle);
30
30
  void pwm_set_frequency(unsigned int gpio, float freq);
31
31
  void pwm_start(unsigned int gpio);
32
32
  void pwm_stop(unsigned int gpio);
33
+ int pwm_exists(unsigned int gpio);
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rpi_gpio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Lowery
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-18 00:00:00.000000000 Z
11
+ date: 2020-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -50,21 +50,6 @@ files:
50
50
  - LICENSE
51
51
  - README.md
52
52
  - Rakefile
53
- - ext/new/c_gpio.c
54
- - ext/new/c_gpio.h
55
- - ext/new/common.c
56
- - ext/new/common.h
57
- - ext/new/constants.c
58
- - ext/new/constants.h
59
- - ext/new/cpuinfo.c
60
- - ext/new/cpuinfo.h
61
- - ext/new/event_gpio.c
62
- - ext/new/event_gpio.h
63
- - ext/new/py_gpio.c
64
- - ext/new/py_pwm.c
65
- - ext/new/py_pwm.h
66
- - ext/new/soft_pwm.c
67
- - ext/new/soft_pwm.h
68
53
  - ext/rpi_gpio/c_gpio.c
69
54
  - ext/rpi_gpio/c_gpio.h
70
55
  - ext/rpi_gpio/common.c
@@ -82,7 +67,6 @@ files:
82
67
  - ext/rpi_gpio/rpi_gpio.h
83
68
  - ext/rpi_gpio/soft_pwm.c
84
69
  - ext/rpi_gpio/soft_pwm.h
85
- - lib/rpi_gpio.so
86
70
  homepage: https://github.com/ClockVapor/rpi_gpio
87
71
  licenses:
88
72
  - MIT
@@ -102,8 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
86
  - !ruby/object:Gem::Version
103
87
  version: '0'
104
88
  requirements: []
105
- rubyforge_project:
106
- rubygems_version: 2.4.8
89
+ rubygems_version: 3.1.2
107
90
  signing_key:
108
91
  specification_version: 4
109
92
  summary: Ruby conversion of RPi.GPIO Python module
@@ -1,237 +0,0 @@
1
- /*
2
- Copyright (c) 2012-2015 Ben Croston
3
-
4
- Permission is hereby granted, free of charge, to any person obtaining a copy of
5
- this software and associated documentation files (the "Software"), to deal in
6
- the Software without restriction, including without limitation the rights to
7
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8
- of the Software, and to permit persons to whom the Software is furnished to do
9
- so, subject to the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be included in all
12
- copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- SOFTWARE.
21
- */
22
-
23
- #include <stdio.h>
24
- #include <stdint.h>
25
- #include <stdlib.h>
26
- #include <fcntl.h>
27
- #include <sys/mman.h>
28
- #include "c_gpio.h"
29
-
30
- #define BCM2708_PERI_BASE_DEFAULT 0x20000000
31
- #define GPIO_BASE_OFFSET 0x200000
32
- #define FSEL_OFFSET 0 // 0x0000
33
- #define SET_OFFSET 7 // 0x001c / 4
34
- #define CLR_OFFSET 10 // 0x0028 / 4
35
- #define PINLEVEL_OFFSET 13 // 0x0034 / 4
36
- #define EVENT_DETECT_OFFSET 16 // 0x0040 / 4
37
- #define RISING_ED_OFFSET 19 // 0x004c / 4
38
- #define FALLING_ED_OFFSET 22 // 0x0058 / 4
39
- #define HIGH_DETECT_OFFSET 25 // 0x0064 / 4
40
- #define LOW_DETECT_OFFSET 28 // 0x0070 / 4
41
- #define PULLUPDN_OFFSET 37 // 0x0094 / 4
42
- #define PULLUPDNCLK_OFFSET 38 // 0x0098 / 4
43
-
44
- #define PAGE_SIZE (4*1024)
45
- #define BLOCK_SIZE (4*1024)
46
-
47
- static volatile uint32_t *gpio_map;
48
-
49
- void short_wait(void)
50
- {
51
- int i;
52
-
53
- for (i=0; i<150; i++) { // wait 150 cycles
54
- asm volatile("nop");
55
- }
56
- }
57
-
58
- int setup(void)
59
- {
60
- int mem_fd;
61
- uint8_t *gpio_mem;
62
- uint32_t peri_base = BCM2708_PERI_BASE_DEFAULT;
63
- uint32_t gpio_base;
64
- unsigned char buf[4];
65
- FILE *fp;
66
-
67
- // get peri base from device tree
68
- if ((fp = fopen("/proc/device-tree/soc/ranges", "rb")) != NULL) {
69
- fseek(fp, 4, SEEK_SET);
70
- if (fread(buf, 1, sizeof buf, fp) == sizeof buf) {
71
- peri_base = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3] << 0;
72
- }
73
- fclose(fp);
74
- }
75
-
76
- gpio_base = peri_base + GPIO_BASE_OFFSET;
77
-
78
- // mmap the GPIO memory registers
79
- if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0)
80
- return SETUP_DEVMEM_FAIL;
81
-
82
- if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
83
- return SETUP_MALLOC_FAIL;
84
-
85
- if ((uint32_t)gpio_mem % PAGE_SIZE)
86
- gpio_mem += PAGE_SIZE - ((uint32_t)gpio_mem % PAGE_SIZE);
87
-
88
- gpio_map = (uint32_t *)mmap( (caddr_t)gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, gpio_base);
89
-
90
- if ((uint32_t)gpio_map < 0)
91
- return SETUP_MMAP_FAIL;
92
-
93
- return SETUP_OK;
94
- }
95
-
96
- void clear_event_detect(int gpio)
97
- {
98
- int offset = EVENT_DETECT_OFFSET + (gpio/32);
99
- int shift = (gpio%32);
100
-
101
- *(gpio_map+offset) |= (1 << shift);
102
- short_wait();
103
- *(gpio_map+offset) = 0;
104
- }
105
-
106
- int eventdetected(int gpio)
107
- {
108
- int offset, value, bit;
109
-
110
- offset = EVENT_DETECT_OFFSET + (gpio/32);
111
- bit = (1 << (gpio%32));
112
- value = *(gpio_map+offset) & bit;
113
- if (value)
114
- clear_event_detect(gpio);
115
- return value;
116
- }
117
-
118
- void set_rising_event(int gpio, int enable)
119
- {
120
- int offset = RISING_ED_OFFSET + (gpio/32);
121
- int shift = (gpio%32);
122
-
123
- if (enable)
124
- *(gpio_map+offset) |= 1 << shift;
125
- else
126
- *(gpio_map+offset) &= ~(1 << shift);
127
- clear_event_detect(gpio);
128
- }
129
-
130
- void set_falling_event(int gpio, int enable)
131
- {
132
- int offset = FALLING_ED_OFFSET + (gpio/32);
133
- int shift = (gpio%32);
134
-
135
- if (enable) {
136
- *(gpio_map+offset) |= (1 << shift);
137
- *(gpio_map+offset) = (1 << shift);
138
- } else {
139
- *(gpio_map+offset) &= ~(1 << shift);
140
- }
141
- clear_event_detect(gpio);
142
- }
143
-
144
- void set_high_event(int gpio, int enable)
145
- {
146
- int offset = HIGH_DETECT_OFFSET + (gpio/32);
147
- int shift = (gpio%32);
148
-
149
- if (enable)
150
- *(gpio_map+offset) |= (1 << shift);
151
- else
152
- *(gpio_map+offset) &= ~(1 << shift);
153
- clear_event_detect(gpio);
154
- }
155
-
156
- void set_low_event(int gpio, int enable)
157
- {
158
- int offset = LOW_DETECT_OFFSET + (gpio/32);
159
- int shift = (gpio%32);
160
-
161
- if (enable)
162
- *(gpio_map+offset) |= 1 << shift;
163
- else
164
- *(gpio_map+offset) &= ~(1 << shift);
165
- clear_event_detect(gpio);
166
- }
167
-
168
- void set_pullupdn(int gpio, int pud)
169
- {
170
- int clk_offset = PULLUPDNCLK_OFFSET + (gpio/32);
171
- int shift = (gpio%32);
172
-
173
- if (pud == PUD_DOWN)
174
- *(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_DOWN;
175
- else if (pud == PUD_UP)
176
- *(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_UP;
177
- else // pud == PUD_OFF
178
- *(gpio_map+PULLUPDN_OFFSET) &= ~3;
179
-
180
- short_wait();
181
- *(gpio_map+clk_offset) = 1 << shift;
182
- short_wait();
183
- *(gpio_map+PULLUPDN_OFFSET) &= ~3;
184
- *(gpio_map+clk_offset) = 0;
185
- }
186
-
187
- void setup_gpio(int gpio, int direction, int pud)
188
- {
189
- int offset = FSEL_OFFSET + (gpio/10);
190
- int shift = (gpio%10)*3;
191
-
192
- set_pullupdn(gpio, pud);
193
- if (direction == OUTPUT)
194
- *(gpio_map+offset) = (*(gpio_map+offset) & ~(7<<shift)) | (1<<shift);
195
- else // direction == INPUT
196
- *(gpio_map+offset) = (*(gpio_map+offset) & ~(7<<shift));
197
- }
198
-
199
- // Contribution by Eric Ptak <trouch@trouch.com>
200
- int gpio_function(int gpio)
201
- {
202
- int offset = FSEL_OFFSET + (gpio/10);
203
- int shift = (gpio%10)*3;
204
- int value = *(gpio_map+offset);
205
- value >>= shift;
206
- value &= 7;
207
- return value; // 0=input, 1=output, 4=alt0
208
- }
209
-
210
- void output_gpio(int gpio, int value)
211
- {
212
- int offset, shift;
213
-
214
- if (value) // value == HIGH
215
- offset = SET_OFFSET + (gpio/32);
216
- else // value == LOW
217
- offset = CLR_OFFSET + (gpio/32);
218
-
219
- shift = (gpio%32);
220
-
221
- *(gpio_map+offset) = 1 << shift;
222
- }
223
-
224
- int input_gpio(int gpio)
225
- {
226
- int offset, value, mask;
227
-
228
- offset = PINLEVEL_OFFSET + (gpio/32);
229
- mask = (1 << gpio%32);
230
- value = *(gpio_map+offset) & mask;
231
- return value;
232
- }
233
-
234
- void cleanup(void)
235
- {
236
- munmap((caddr_t)gpio_map, BLOCK_SIZE);
237
- }
@@ -1,49 +0,0 @@
1
- /*
2
- Copyright (c) 2012-2013 Ben Croston
3
-
4
- Permission is hereby granted, free of charge, to any person obtaining a copy of
5
- this software and associated documentation files (the "Software"), to deal in
6
- the Software without restriction, including without limitation the rights to
7
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8
- of the Software, and to permit persons to whom the Software is furnished to do
9
- so, subject to the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be included in all
12
- copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- SOFTWARE.
21
- */
22
-
23
- int setup(void);
24
- void setup_gpio(int gpio, int direction, int pud);
25
- int gpio_function(int gpio);
26
- void output_gpio(int gpio, int value);
27
- int input_gpio(int gpio);
28
- void set_rising_event(int gpio, int enable);
29
- void set_falling_event(int gpio, int enable);
30
- void set_high_event(int gpio, int enable);
31
- void set_low_event(int gpio, int enable);
32
- int eventdetected(int gpio);
33
- void cleanup(void);
34
-
35
- #define SETUP_OK 0
36
- #define SETUP_DEVMEM_FAIL 1
37
- #define SETUP_MALLOC_FAIL 2
38
- #define SETUP_MMAP_FAIL 3
39
-
40
- #define INPUT 1 // is really 0 for control register!
41
- #define OUTPUT 0 // is really 1 for control register!
42
- #define ALT0 4
43
-
44
- #define HIGH 1
45
- #define LOW 0
46
-
47
- #define PUD_OFF 0
48
- #define PUD_DOWN 1
49
- #define PUD_UP 2
@@ -1,87 +0,0 @@
1
- /*
2
- Copyright (c) 2013-2014 Ben Croston
3
-
4
- Permission is hereby granted, free of charge, to any person obtaining a copy of
5
- this software and associated documentation files (the "Software"), to deal in
6
- the Software without restriction, including without limitation the rights to
7
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8
- of the Software, and to permit persons to whom the Software is furnished to do
9
- so, subject to the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be included in all
12
- copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- SOFTWARE.
21
- */
22
-
23
- #include "Python.h"
24
- #include "c_gpio.h"
25
- #include "common.h"
26
-
27
- int gpio_mode = MODE_UNKNOWN;
28
- 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 };
29
- 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 };
30
- 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 };
31
- int setup_error = 0;
32
- int module_setup = 0;
33
-
34
- int check_gpio_priv(void)
35
- {
36
- // check module has been imported cleanly
37
- if (setup_error)
38
- {
39
- PyErr_SetString(PyExc_RuntimeError, "Module not imported correctly!");
40
- return 1;
41
- }
42
-
43
- // check mmap setup has worked
44
- if (!module_setup)
45
- {
46
- PyErr_SetString(PyExc_RuntimeError, "No access to /dev/mem. Try running as root!");
47
- return 2;
48
- }
49
- return 0;
50
- }
51
-
52
- int get_gpio_number(int channel, unsigned int *gpio)
53
- {
54
- // check setmode() has been run
55
- if (gpio_mode != BOARD && gpio_mode != BCM)
56
- {
57
- PyErr_SetString(PyExc_RuntimeError, "Please set pin numbering mode using GPIO.setmode(GPIO.BOARD) or GPIO.setmode(GPIO.BCM)");
58
- return 3;
59
- }
60
-
61
- // check channel number is in range
62
- if ( (gpio_mode == BCM && (channel < 0 || channel > 53))
63
- || (gpio_mode == BOARD && (channel < 1 || channel > 26) && rpiinfo.p1_revision != 3)
64
- || (gpio_mode == BOARD && (channel < 1 || channel > 40) && rpiinfo.p1_revision == 3) )
65
- {
66
- PyErr_SetString(PyExc_ValueError, "The channel sent is invalid on a Raspberry Pi");
67
- return 4;
68
- }
69
-
70
- // convert channel to gpio
71
- if (gpio_mode == BOARD)
72
- {
73
- if (*(*pin_to_gpio+channel) == -1)
74
- {
75
- PyErr_SetString(PyExc_ValueError, "The channel sent is invalid on a Raspberry Pi");
76
- return 5;
77
- } else {
78
- *gpio = *(*pin_to_gpio+channel);
79
- }
80
- }
81
- else // gpio_mode == BCM
82
- {
83
- *gpio = channel;
84
- }
85
-
86
- return 0;
87
- }