rpi_gpio 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b07e0dfa373704b91f27dc3a1ff51872e72da142
4
- data.tar.gz: b80c179d3b4cf44663c4ba6c0ec069c00c65e52a
3
+ metadata.gz: a0e5676feb3143ba7430bcfced058ac5e986c2ee
4
+ data.tar.gz: b916d55ecf73e17325cc630324c035dd7b6fa85b
5
5
  SHA512:
6
- metadata.gz: 5722a5a31d2e3abd129e251000842af33ab12beddabf98a2695ea1a42d80ee57e37334f92b793f2038f2ffc23d05804a6814a96f3bda02b5f2cf3d878cb82934
7
- data.tar.gz: b0ed8411d9a3965d2649fc4a0eec2db4230293da60a0e70f45f2312995cae04ba7ff765bf20a7800567725e02776cabf546ee01782db483037f12f7c9371896a
6
+ metadata.gz: 15364745c0cf985293b27ab07f6bbbad9566a7c5c20de7c4bdf496c61419a860171bbacfe3153666d3f91e9587a5031562376ecba7606bd245d01b1f61e4a5c4
7
+ data.tar.gz: e904851064c95e2268815255b30b821be6e9a7b8565b7b704001bc6a41f7280df9aae0e91d97b1917e71335896dc756e8bce423cb671166ca19b25823859e139
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rpi_gpio (0.2.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.2.5)
10
+ rake (10.4.2)
11
+ rake-compiler (0.9.5)
12
+ rake
13
+ rspec (3.3.0)
14
+ rspec-core (~> 3.3.0)
15
+ rspec-expectations (~> 3.3.0)
16
+ rspec-mocks (~> 3.3.0)
17
+ rspec-core (3.3.2)
18
+ rspec-support (~> 3.3.0)
19
+ rspec-expectations (3.3.1)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.3.0)
22
+ rspec-mocks (3.3.2)
23
+ diff-lcs (>= 1.2.0, < 2.0)
24
+ rspec-support (~> 3.3.0)
25
+ rspec-support (3.3.0)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ rake-compiler
32
+ rpi_gpio!
33
+ rspec
34
+
35
+ BUNDLED WITH
36
+ 1.10.6
data/README.md CHANGED
@@ -1,122 +1,137 @@
1
- #rpi_gpio v0.1.5
2
-
3
- Ruby conversion of [RPi.GPIO Python module](https://pypi.python.org/pypi/RPi.GPIO)
4
-
5
- ##Features
6
-
7
- Manipulate your Raspberry Pi's GPIO pins from Ruby!
8
- - Boolean input/output
9
- - Software-driven PWM (written in C for speed)
10
-
11
- ##Sample Usage
12
-
13
- I aimed to make the gem's usage exactly the same as its Python counterpart -- only with a few semantic differences to utilize Ruby's readability. If anything is confusing, you can always check [here](http://sourceforge.net/p/raspberry-gpio-python/wiki/Examples/) for the original Python module's documentation.
14
-
15
- ####Download the gem
16
-
17
- The easiest way to download the gem is to use [Bundler](http://bundler.io/) with a Gemfile. In your Gemfile, include the line
18
- ```ruby
19
- gem 'rpi_gpio'
20
- ```
21
- Then you can run `bundle install` to automatically download and compile the gem for your system. To include the gem in a Ruby file, use the line `require 'rpi_gpio'`.
22
-
23
- ####Pin numbering
24
-
25
- Before you can do anything with the GPIO pins, you need to specify how you want to number them.
26
- ```ruby
27
- RPi::GPIO.set_numbering :board
28
- # or
29
- RPi::GPIO.set_numbering :bcm
30
- ````
31
- `:board` numbering refers to the physical pin numbers on the Pi, whereas `:bcm` numbering refers to the Broadcom SOC channel numbering. Note that `:bcm` numbering differs between Pi models, while `:board` numbering does not.
32
-
33
- ####Input
34
-
35
- To receive input from a GPIO pin, you must first initialize it as an input pin:
36
- ```ruby
37
- RPi::GPIO.setup PIN_NUM, as: :input
38
- ```
39
- The pin number will differ based on your selected numbering system and which pin you want to use.
40
-
41
- Now you can use the calls
42
- ```ruby
43
- RPi::GPIO.high? PIN_NUM
44
- RPi::GPIO.low? PIN_NUM
45
- ```
46
- to receive either `true` or `false`.
47
-
48
- You can use the additional hash argument `:pull` to apply a pull-up or pull-down resistor to the input pin like so:
49
- ```ruby
50
- RPi::GPIO.setup PIN_NUM, as: :input, pull: :down
51
- # or
52
- RPi::GPIO.setup PIN_NUM, as: :input, pull: :up
53
- # or (not necessary; :off is the default value)
54
- RPi::GPIO.setup PIN_NUM, as: :input, pull: :off
55
- ```
56
-
57
- ####Output
58
-
59
- To send output to a GPIO pin, you must first initialize it as an output pin:
60
- ```ruby
61
- RPi::GPIO.setup PIN_NUM, as: :output
62
- ```
63
- Now you can use the calls
64
- ```ruby
65
- RPi::GPIO.set_high PIN_NUM
66
- RPi::GPIO.set_low PIN_NUM
67
- ```
68
- to set the pin either high or low.
69
-
70
- ####PWM (pulse-width modulation)
71
-
72
- Pulse-width modulation is a useful tool for controlling things like LED brightness or motor speed. To utilize PWM, first create a PWM object for an output pin.
73
- ```ruby
74
- pwm = RPi::GPIO::PWM.new(PIN_NUM, PWM_FREQ)
75
- ```
76
- The `PWM_FREQ` is a value in hertz that specifies the amount of pulse cycles per second.
77
-
78
- Now you can call the following method to start PWM:
79
- ```ruby
80
- pwm.start DUTY_CYCLE
81
- ```
82
- `DUTY_CYCLE` is a value from `0.0` to `100.0` indicating the percent of the time that the signal will be high.
83
-
84
- Once running, you can get/set the PWM duty cycle with
85
- ```ruby
86
- pwm.duty_cycle # get
87
- pwm.duty_cycle = NEW_DUTY_CYCLE # set
88
- ```
89
- get/set the PWM frequency with
90
- ```ruby
91
- pwm.frequency # get
92
- pwm.frequency = NEW_FREQUENCY # set
93
- ```
94
- and get the PWM GPIO pin with
95
- ```ruby
96
- pwm.pin
97
- ```
98
-
99
- To stop PWM, use
100
- ```ruby
101
- pwm.stop
102
- ```
103
-
104
- ####Cleaning up
105
-
106
- After your program is finished using the GPIO pins, it's a good idea to release them so other programs can use them later. Simply call
107
- ```ruby
108
- RPi::GPIO.clean_up PIN_NUM
109
- ```
110
- to release a specific pin, or
111
- ```ruby
112
- RPi::GPIO.clean_up
113
- ```
114
- to release all allocated pins.
115
-
116
- ##Credits
117
-
118
- Original Python code by Ben Croston modified for Ruby by Nick Lowery
119
-
120
- Copyright (c) 2014-2015 [Nick Lowery](https://github.com/ClockVapor)
121
-
122
- View LICENSE for full license.
1
+ # rpi_gpio v0.2.0
2
+
3
+ Ruby conversion of [RPi.GPIO Python module](https://pypi.python.org/pypi/RPi.GPIO)
4
+
5
+ ## Features
6
+
7
+ Manipulate your Raspberry Pi's GPIO pins from Ruby!
8
+
9
+ - Boolean input/output
10
+ - Software-driven PWM (written in C for speed)
11
+
12
+ Up-to-date with RPi.GPIO Python module version 0.5.11, so it works on all Raspberry Pi models!
13
+
14
+ ## Sample Usage
15
+
16
+ I aimed to make the gem's usage exactly the same as its Python counterpart -- only with a few semantic differences to utilize Ruby's readability. If anything is confusing, you can always check [here](http://sourceforge.net/p/raspberry-gpio-python/wiki/Examples/) for the original Python module's documentation.
17
+
18
+ #### Download the gem
19
+
20
+ The easiest way to download the gem is to use [Bundler](http://bundler.io/) with a Gemfile. In your Gemfile, include the line
21
+ ```
22
+ gem 'rpi_gpio'
23
+ ```
24
+ Then you can run `bundle install` to automatically download and compile the gem for your system. To include the gem in a Ruby file, use the line `require 'rpi_gpio'`.
25
+
26
+ #### Pin numbering
27
+
28
+ Before you can do anything with the GPIO pins, you need to specify how you want to number them.
29
+ ```
30
+ RPi::GPIO.set_numbering :board
31
+ # or
32
+ RPi::GPIO.set_numbering :bcm
33
+ ````
34
+ `:board` numbering refers to the physical pin numbers on the Pi, whereas `:bcm` numbering refers to the Broadcom SOC channel numbering. Note that `:bcm` numbering differs between Pi models, while `:board` numbering does not.
35
+
36
+ #### Input
37
+
38
+ To receive input from a GPIO pin, you must first initialize it as an input pin:
39
+ ```
40
+ RPi::GPIO.setup PIN_NUM, as: :input
41
+ ```
42
+ The pin number will differ based on your selected numbering system and which pin you want to use.
43
+
44
+ Now you can use the calls
45
+ ```
46
+ RPi::GPIO.high? PIN_NUM
47
+ RPi::GPIO.low? PIN_NUM
48
+ ```
49
+ to receive either `true` or `false`.
50
+
51
+ You can use the additional hash argument `:pull` to apply a pull-up or pull-down resistor to the input pin like so:
52
+ ```
53
+ RPi::GPIO.setup PIN_NUM, as: :input, pull: :down
54
+ # or
55
+ RPi::GPIO.setup PIN_NUM, as: :input, pull: :up
56
+ # or (not necessary; :off is the default value)
57
+ RPi::GPIO.setup PIN_NUM, as: :input, pull: :off
58
+ ```
59
+
60
+ #### Output
61
+
62
+ To send output to a GPIO pin, you must first initialize it as an output pin:
63
+ ```
64
+ RPi::GPIO.setup PIN_NUM, as: :output
65
+ ```
66
+ Now you can use the calls
67
+ ```
68
+ RPi::GPIO.set_high PIN_NUM
69
+ RPi::GPIO.set_low PIN_NUM
70
+ ```
71
+ to set the pin either high or low.
72
+
73
+ #### PWM (pulse-width modulation)
74
+
75
+ Pulse-width modulation is a useful tool for controlling things like LED brightness or motor speed. To utilize PWM, first create a PWM object for an [output pin](#output).
76
+ ```ruby
77
+ pwm = RPi::GPIO::PWM.new(PIN_NUM, PWM_FREQ)
78
+ ```
79
+ The `PWM_FREQ` is a value in hertz that specifies the amount of pulse cycles per second.
80
+
81
+ Now you can call the following method to start PWM:
82
+ ```
83
+ pwm.start DUTY_CYCLE
84
+ ```
85
+ `DUTY_CYCLE` is a value from `0.0` to `100.0` indicating the percent of the time that the signal will be high.
86
+
87
+ Once running, you can get/set the PWM duty cycle with
88
+ ```
89
+ pwm.duty_cycle # get
90
+ pwm.duty_cycle = NEW_DUTY_CYCLE # set
91
+ ```
92
+ get/set the PWM frequency with
93
+ ```
94
+ pwm.frequency # get
95
+ pwm.frequency = NEW_FREQUENCY # set
96
+ ```
97
+ and get the PWM GPIO number with
98
+ ```ruby
99
+ pwm.gpio
100
+ ```
101
+ Note that this number corresponds to `:bcm` numbering of the GPIO pins, so it will be different than pin number you used if you created the PWM with `:board` numbering.
102
+
103
+ To stop PWM, use
104
+ ```
105
+ pwm.stop
106
+ ```
107
+
108
+ To check if a PWM object is currently running, use
109
+ ```ruby
110
+ pwm.running?
111
+ ```
112
+
113
+ #### Cleaning up
114
+
115
+ After your program is finished using the GPIO pins, it's a good idea to release them so other programs can use them later. Simply call
116
+ ```
117
+ RPi::GPIO.clean_up PIN_NUM
118
+ ```
119
+ to release a specific pin, or
120
+ ```
121
+ RPi::GPIO.clean_up
122
+ ```
123
+ to release all allocated pins.
124
+
125
+ Alternatively, you can call
126
+ ```ruby
127
+ RPi::GPIO.reset
128
+ ```
129
+ to clean up all pins and to also reset the selected numbering mode.
130
+
131
+ ## Credits
132
+
133
+ Original Python code by Ben Croston modified for Ruby by Nick Lowery
134
+
135
+ Copyright (c) 2014-2015 [Nick Lowery](https://github.com/ClockVapor)
136
+
137
+ View LICENSE for full license.
@@ -0,0 +1,237 @@
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
+ }