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,47 +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 "event_gpio.h"
30
- #include "cpuinfo.h"
31
- #include "common.h"
32
- #include "rb_pwm.h"
33
-
34
- void define_gpio_module_stuff(void);
35
- int mmap_gpio_mem(void);
36
- int is_gpio_initialized(unsigned int gpio);
37
- int is_gpio_output(unsigned int gpio);
38
- int is_rpi(void);
39
- VALUE GPIO_clean_up(int argc, VALUE *argv, VALUE self);
40
- VALUE GPIO_reset(VALUE self);
41
- VALUE GPIO_setup(VALUE self, VALUE channel, VALUE hash);
42
- VALUE GPIO_set_numbering(VALUE self, VALUE mode);
43
- VALUE GPIO_set_high(VALUE self, VALUE channel);
44
- VALUE GPIO_set_low(VALUE self, VALUE channel);
45
- VALUE GPIO_test_high(VALUE self, VALUE channel);
46
- VALUE GPIO_test_low(VALUE self, VALUE channel);
47
- VALUE GPIO_set_warnings(VALUE self, VALUE setting);
@@ -1,148 +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-2018 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 "rb_pwm.h"
28
-
29
- extern VALUE m_GPIO;
30
- VALUE c_PWM = Qnil;
31
-
32
- void define_pwm_class_stuff(void)
33
- {
34
- c_PWM = rb_define_class_under(m_GPIO, "PWM", rb_cObject);
35
- rb_define_method(c_PWM, "initialize", PWM_initialize, 2);
36
- rb_define_method(c_PWM, "start", PWM_start, 1);
37
- rb_define_method(c_PWM, "gpio", PWM_get_gpio, 0);
38
- rb_define_method(c_PWM, "duty_cycle", PWM_get_duty_cycle, 0);
39
- rb_define_method(c_PWM, "duty_cycle=", PWM_set_duty_cycle, 1);
40
- rb_define_method(c_PWM, "frequency", PWM_get_frequency, 0);
41
- rb_define_method(c_PWM, "frequency=", PWM_set_frequency, 1);
42
- rb_define_method(c_PWM, "stop", PWM_stop, 0);
43
- rb_define_method(c_PWM, "running?", PWM_get_running, 0);
44
- }
45
-
46
- // RPi::GPIO::PWM#initialize
47
- VALUE PWM_initialize(VALUE self, VALUE channel, VALUE frequency)
48
- {
49
- int chan;
50
- unsigned int gpio;
51
-
52
- chan = NUM2INT(channel);
53
-
54
- // convert channel to gpio
55
- if (get_gpio_number(chan, &gpio))
56
- return Qnil;
57
-
58
- // does soft pwm already exist on this channel?
59
- if (pwm_exists(gpio))
60
- {
61
- rb_raise(rb_eRuntimeError, "a PWM object already exists for this GPIO channel");
62
- return Qnil;
63
- }
64
-
65
- // ensure channel is set as output
66
- if (gpio_direction[gpio] != OUTPUT)
67
- {
68
- rb_raise(rb_eRuntimeError, "you must setup the GPIO channel as output "
69
- "first with RPi::GPIO.setup CHANNEL, :as => :output");
70
- return Qnil;
71
- }
72
-
73
- rb_iv_set(self, "@gpio", UINT2NUM(gpio));
74
- rb_iv_set(self, "@running", Qfalse);
75
- PWM_set_frequency(self, frequency);
76
- return self;
77
- }
78
-
79
- // RPi::GPIO::PWM#start
80
- VALUE PWM_start(VALUE self, VALUE duty_cycle)
81
- {
82
- pwm_start(NUM2UINT(rb_iv_get(self, "@gpio")));
83
- PWM_set_duty_cycle(self, duty_cycle);
84
- rb_iv_set(self, "@running", Qtrue);
85
- return self;
86
- }
87
-
88
- // RPi::GPIO::PWM#gpio
89
- VALUE PWM_get_gpio(VALUE self)
90
- {
91
- return rb_iv_get(self, "@gpio");
92
- }
93
-
94
- // RPi::GPIO::PWM#duty_cycle
95
- VALUE PWM_get_duty_cycle(VALUE self)
96
- {
97
- return rb_iv_get(self, "@duty_cycle");
98
- }
99
-
100
- // RPi::GPIO::PWM#duty_cycle=
101
- VALUE PWM_set_duty_cycle(VALUE self, VALUE duty_cycle)
102
- {
103
- float dc = (float) NUM2DBL(duty_cycle);
104
- if (dc < 0.0f || dc > 100.0f)
105
- {
106
- rb_raise(rb_eArgError, "duty cycle must be between 0.0 and 100.0");
107
- return Qnil;
108
- }
109
-
110
- rb_iv_set(self, "@duty_cycle", duty_cycle);
111
- pwm_set_duty_cycle(NUM2UINT(rb_iv_get(self, "@gpio")), dc);
112
- return self;
113
- }
114
-
115
- // RPi::GPIO::PWM#frequency
116
- VALUE PWM_get_frequency(VALUE self)
117
- {
118
- return rb_iv_get(self, "@frequency");
119
- }
120
-
121
- // RPi::GPIO::PWM#frequency=
122
- VALUE PWM_set_frequency(VALUE self, VALUE frequency)
123
- {
124
- float freq = (float) NUM2DBL(frequency);
125
- if (freq <= 0.0f)
126
- {
127
- rb_raise(rb_eArgError, "frequency must be greater than 0.0");
128
- return Qnil;
129
- }
130
-
131
- rb_iv_set(self, "@frequency", frequency);
132
- pwm_set_frequency(NUM2UINT(rb_iv_get(self, "@gpio")), freq);
133
- return self;
134
- }
135
-
136
- // RPi::GPIO::PWM#stop
137
- VALUE PWM_stop(VALUE self)
138
- {
139
- pwm_stop(NUM2UINT(rb_iv_get(self, "@gpio")));
140
- rb_iv_set(self, "@running", Qfalse);
141
- return self;
142
- }
143
-
144
- // RPi::GPIO::PWM#running?
145
- VALUE PWM_get_running(VALUE self)
146
- {
147
- return rb_iv_get(self, "@running");
148
- }
@@ -1,41 +0,0 @@
1
- /*
2
- Original code by Ben Croston modified for Ruby by Nick Lowery
3
- (github.com/clockvapor)
4
- Copyright (c) 2014-2015 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 "soft_pwm.h"
29
- #include "common.h"
30
- #include "c_gpio.h"
31
-
32
- void define_pwm_class_stuff(void);
33
- VALUE PWM_initialize(VALUE self, VALUE channel, VALUE frequency);
34
- VALUE PWM_start(VALUE self, VALUE duty_cycle);
35
- VALUE PWM_get_gpio(VALUE self);
36
- VALUE PWM_get_duty_cycle(VALUE self);
37
- VALUE PWM_set_duty_cycle(VALUE self, VALUE duty_cycle);
38
- VALUE PWM_get_frequency(VALUE self);
39
- VALUE PWM_set_frequency(VALUE self, VALUE frequency);
40
- VALUE PWM_stop(VALUE self);
41
- VALUE PWM_get_running(VALUE self);
@@ -1,45 +0,0 @@
1
- /*
2
- Original code by Ben Croston modified for Ruby by Nick Lowery
3
- (github.com/clockvapor)
4
- Copyright (c) 2014-2015 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 "rpi_gpio.h"
28
- #include "rb_pwm.h"
29
- #include "rb_gpio.h"
30
-
31
- VALUE m_RPi = Qnil;
32
- VALUE m_GPIO = Qnil;
33
-
34
- void Init_rpi_gpio()
35
- {
36
- define_modules();
37
- define_gpio_module_stuff();
38
- define_pwm_class_stuff();
39
- }
40
-
41
- void define_modules(void)
42
- {
43
- m_RPi = rb_define_module("RPi");
44
- m_GPIO = rb_define_module_under(m_RPi, "GPIO");
45
- }
@@ -1,28 +0,0 @@
1
- /*
2
- Original code by Ben Croston modified for Ruby by Nick Lowery
3
- (github.com/clockvapor)
4
- Copyright (c) 2014-2015 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
- void Init_rpi_gpio();
28
- void define_modules(void);
@@ -1,235 +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-2018 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 <stdlib.h>
28
- #include <pthread.h>
29
- #include <time.h>
30
- #include "c_gpio.h"
31
- #include "soft_pwm.h"
32
- pthread_t threads;
33
-
34
- struct pwm
35
- {
36
- unsigned int gpio;
37
- float freq;
38
- float dutycycle;
39
- float basetime;
40
- float slicetime;
41
- struct timespec req_on, req_off;
42
- int running;
43
- struct pwm *next;
44
- };
45
- struct pwm *pwm_list = NULL;
46
-
47
- void remove_pwm(unsigned int gpio)
48
- {
49
- struct pwm *p = pwm_list;
50
- struct pwm *prev = NULL;
51
- struct pwm *temp;
52
-
53
- while (p != NULL)
54
- {
55
- if (p->gpio == gpio)
56
- {
57
- if (prev == NULL) {
58
- pwm_list = p->next;
59
- } else {
60
- prev->next = p->next;
61
- }
62
- temp = p;
63
- p = p->next;
64
- temp->running = 0; // signal the thread to stop. The thread will free() the pwm struct when it's done with it.
65
- } else {
66
- prev = p;
67
- p = p->next;
68
- }
69
- }
70
- }
71
-
72
- void calculate_times(struct pwm *p)
73
- {
74
- long long usec;
75
-
76
- usec = (long long)(p->dutycycle * p->slicetime * 1000.0);
77
- p->req_on.tv_sec = (int)(usec / 1000000LL);
78
- usec -= (long long)p->req_on.tv_sec * 1000000LL;
79
- p->req_on.tv_nsec = (long)usec * 1000L;
80
-
81
- usec = (long long)((100.0-p->dutycycle) * p->slicetime * 1000.0);
82
- p->req_off.tv_sec = (int)(usec / 1000000LL);
83
- usec -= (long long)p->req_off.tv_sec * 1000000LL;
84
- p->req_off.tv_nsec = (long)usec * 1000L;
85
- }
86
-
87
- void full_sleep(struct timespec *req)
88
- {
89
- struct timespec rem = {0};
90
-
91
- if (nanosleep(req,&rem) == -1)
92
- full_sleep(&rem);
93
- }
94
-
95
- void *pwm_thread(void *threadarg)
96
- {
97
- struct pwm *p = (struct pwm *)threadarg;
98
-
99
- while (p->running)
100
- {
101
-
102
- if (p->dutycycle > 0.0)
103
- {
104
- output_gpio(p->gpio, 1);
105
- full_sleep(&p->req_on);
106
- }
107
-
108
- if (p->dutycycle < 100.0)
109
- {
110
- output_gpio(p->gpio, 0);
111
- full_sleep(&p->req_off);
112
- }
113
- }
114
-
115
- // clean up
116
- output_gpio(p->gpio, 0);
117
- free(p);
118
- pthread_exit(NULL);
119
- }
120
-
121
- struct pwm *add_new_pwm(unsigned int gpio)
122
- {
123
- struct pwm *new_pwm;
124
-
125
- new_pwm = malloc(sizeof(struct pwm));
126
- new_pwm->gpio = gpio;
127
- new_pwm->running = 0;
128
- new_pwm->next = NULL;
129
- // default to 1 kHz frequency, dutycycle 0.0
130
- new_pwm->freq = 1000.0;
131
- new_pwm->dutycycle = 0.0;
132
- new_pwm->basetime = 1.0; // 1 ms
133
- new_pwm->slicetime = 0.01; // 0.01 ms
134
- calculate_times(new_pwm);
135
- return new_pwm;
136
- }
137
-
138
- struct pwm *find_pwm(unsigned int gpio)
139
- /* Return the pwm record for gpio, creating it if it does not exist */
140
- {
141
- struct pwm *p = pwm_list;
142
-
143
- if (pwm_list == NULL)
144
- {
145
- pwm_list = add_new_pwm(gpio);
146
- return pwm_list;
147
- }
148
-
149
- while (p != NULL)
150
- {
151
- if (p->gpio == gpio)
152
- return p;
153
- if (p->next == NULL)
154
- {
155
- p->next = add_new_pwm(gpio);
156
- return p->next;
157
- }
158
- p = p->next;
159
- }
160
- return NULL;
161
- }
162
-
163
- void pwm_set_duty_cycle(unsigned int gpio, float dutycycle)
164
- {
165
- struct pwm *p;
166
-
167
- if (dutycycle < 0.0 || dutycycle > 100.0)
168
- {
169
- // btc fixme - error
170
- return;
171
- }
172
-
173
- if ((p = find_pwm(gpio)) != NULL)
174
- {
175
- p->dutycycle = dutycycle;
176
- calculate_times(p);
177
- }
178
- }
179
-
180
- void pwm_set_frequency(unsigned int gpio, float freq)
181
- {
182
- struct pwm *p;
183
-
184
- if (freq <= 0.0) // to avoid divide by zero
185
- {
186
- // btc fixme - error
187
- return;
188
- }
189
-
190
- if ((p = find_pwm(gpio)) != NULL)
191
- {
192
- p->basetime = 1000.0 / freq; // calculated in ms
193
- p->slicetime = p->basetime / 100.0;
194
- calculate_times(p);
195
- }
196
- }
197
-
198
- void pwm_start(unsigned int gpio)
199
- {
200
- struct pwm *p;
201
-
202
- if (((p = find_pwm(gpio)) == NULL) || p->running)
203
- return;
204
-
205
- p->running = 1;
206
- if (pthread_create(&threads, NULL, pwm_thread, (void *)p) != 0)
207
- {
208
- // btc fixme - error
209
- p->running = 0;
210
- return;
211
- }
212
- pthread_detach(threads);
213
- }
214
-
215
- void pwm_stop(unsigned int gpio)
216
- {
217
- remove_pwm(gpio);
218
- }
219
-
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;
235
- }