rpi_gpio 0.3.3 → 0.4.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.
- checksums.yaml +5 -5
- data/Gemfile.lock +18 -15
- data/LICENSE +2 -3
- data/README.md +145 -145
- data/ext/rpi_gpio/c_gpio.c +63 -50
- data/ext/rpi_gpio/c_gpio.h +5 -5
- data/ext/rpi_gpio/common.c +5 -9
- data/ext/rpi_gpio/common.h +1 -1
- data/ext/rpi_gpio/cpuinfo.c +122 -70
- data/ext/rpi_gpio/cpuinfo.h +1 -1
- data/ext/rpi_gpio/event_gpio.c +68 -38
- data/ext/rpi_gpio/event_gpio.h +2 -2
- data/ext/rpi_gpio/rb_gpio.c +453 -426
- data/ext/rpi_gpio/rb_gpio.h +47 -48
- data/ext/rpi_gpio/rb_pwm.c +10 -3
- data/ext/rpi_gpio/soft_pwm.c +26 -9
- data/ext/rpi_gpio/soft_pwm.h +3 -2
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cf2e5fe321ddea6602db36bf081dcdd9b16d1248a584c9fe2156cf3b1cc8764b
|
4
|
+
data.tar.gz: aea0df6d2ce23b6b60ffdd35a1a856c09920fda38dfdcc197f4d38b417129935
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2d50e340b0d24349c291b4927fa4bc03e3c477862659a4b6a4f81c5a6c10a94e612e70acef98299627fc299f53cad68f15606b9795b610af1e82d559face6d3
|
7
|
+
data.tar.gz: f6495cbea95ddfe0348bd9be92d716d4929329414ef49d6d6649a373f87af4a62346d1fe74631771de24a066b3b7bfcb1335efda76bda8dbd934e5d1eab644de
|
data/Gemfile.lock
CHANGED
@@ -1,28 +1,28 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rpi_gpio (0.
|
4
|
+
rpi_gpio (0.4.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
diff-lcs (1.
|
10
|
-
rake (
|
11
|
-
rake-compiler (1.
|
9
|
+
diff-lcs (1.4.4)
|
10
|
+
rake (13.0.1)
|
11
|
+
rake-compiler (1.1.1)
|
12
12
|
rake
|
13
|
-
rspec (3.
|
14
|
-
rspec-core (~> 3.
|
15
|
-
rspec-expectations (~> 3.
|
16
|
-
rspec-mocks (~> 3.
|
17
|
-
rspec-core (3.
|
18
|
-
rspec-support (~> 3.
|
19
|
-
rspec-expectations (3.
|
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
20
|
diff-lcs (>= 1.2.0, < 2.0)
|
21
|
-
rspec-support (~> 3.
|
22
|
-
rspec-mocks (3.
|
21
|
+
rspec-support (~> 3.9.0)
|
22
|
+
rspec-mocks (3.9.1)
|
23
23
|
diff-lcs (>= 1.2.0, < 2.0)
|
24
|
-
rspec-support (~> 3.
|
25
|
-
rspec-support (3.
|
24
|
+
rspec-support (~> 3.9.0)
|
25
|
+
rspec-support (3.9.3)
|
26
26
|
|
27
27
|
PLATFORMS
|
28
28
|
ruby
|
@@ -31,3 +31,6 @@ DEPENDENCIES
|
|
31
31
|
rake-compiler
|
32
32
|
rpi_gpio!
|
33
33
|
rspec
|
34
|
+
|
35
|
+
BUNDLED WITH
|
36
|
+
2.1.4
|
data/LICENSE
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2014-
|
4
|
-
Copyright (c)
|
3
|
+
Copyright (c) 2014-2020 Nick Lowery
|
4
|
+
Copyright (c) 2012-2014 Ben Croston
|
5
5
|
|
6
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
7
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -20,4 +20,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
20
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
21
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
22
|
SOFTWARE.
|
23
|
-
|
data/README.md
CHANGED
@@ -1,145 +1,145 @@
|
|
1
|
-
# rpi_gpio v0.
|
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.
|
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
|
-
```ruby
|
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
|
-
```ruby
|
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
|
-
```ruby
|
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
|
-
```ruby
|
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
|
-
```ruby
|
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
|
-
```ruby
|
64
|
-
RPi::GPIO.setup PIN_NUM, :as => :output
|
65
|
-
```
|
66
|
-
Now you can use the calls
|
67
|
-
```ruby
|
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
|
-
You can use the additional hash argument `:initialize` to set the pin's initial state like so:
|
74
|
-
```ruby
|
75
|
-
RPi::GPIO.setup PIN_NUM, :as => :output, :initialize => :high
|
76
|
-
# or
|
77
|
-
RPi::GPIO.setup PIN_NUM, :as => :output, :initialize => :low
|
78
|
-
```
|
79
|
-
|
80
|
-
#### PWM (pulse-width modulation)
|
81
|
-
|
82
|
-
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).
|
83
|
-
```ruby
|
84
|
-
pwm = RPi::GPIO::PWM.new(PIN_NUM, PWM_FREQ)
|
85
|
-
```
|
86
|
-
The `PWM_FREQ` is a value in hertz that specifies the amount of pulse cycles per second.
|
87
|
-
|
88
|
-
Now you can call the following method to start PWM:
|
89
|
-
```ruby
|
90
|
-
pwm.start DUTY_CYCLE
|
91
|
-
```
|
92
|
-
`DUTY_CYCLE` is a value from `0.0` to `100.0` indicating the percent of the time that the signal will be high.
|
93
|
-
|
94
|
-
Once running, you can get/set the PWM duty cycle with
|
95
|
-
```ruby
|
96
|
-
pwm.duty_cycle # get
|
97
|
-
pwm.duty_cycle = NEW_DUTY_CYCLE # set
|
98
|
-
```
|
99
|
-
get/set the PWM frequency with
|
100
|
-
```ruby
|
101
|
-
pwm.frequency # get
|
102
|
-
pwm.frequency = NEW_FREQUENCY # set
|
103
|
-
```
|
104
|
-
and get the PWM GPIO number with
|
105
|
-
```ruby
|
106
|
-
pwm.gpio
|
107
|
-
```
|
108
|
-
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.
|
109
|
-
|
110
|
-
To stop PWM, use
|
111
|
-
```ruby
|
112
|
-
pwm.stop
|
113
|
-
```
|
114
|
-
|
115
|
-
To check if a PWM object is currently running, use
|
116
|
-
```ruby
|
117
|
-
pwm.running?
|
118
|
-
```
|
119
|
-
|
120
|
-
#### Cleaning up
|
121
|
-
|
122
|
-
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
|
123
|
-
```ruby
|
124
|
-
RPi::GPIO.clean_up PIN_NUM
|
125
|
-
```
|
126
|
-
to release a specific pin, or
|
127
|
-
```ruby
|
128
|
-
RPi::GPIO.clean_up
|
129
|
-
```
|
130
|
-
to release all allocated pins.
|
131
|
-
|
132
|
-
Alternatively, you can call
|
133
|
-
```ruby
|
134
|
-
RPi::GPIO.reset
|
135
|
-
```
|
136
|
-
to clean up all pins and to also reset the selected numbering mode.
|
137
|
-
|
138
|
-
## Credits
|
139
|
-
|
140
|
-
Original Python code by Ben Croston modified for Ruby by Nick Lowery
|
141
|
-
|
142
|
-
Copyright (c) 2014-
|
143
|
-
|
144
|
-
View LICENSE for full license.
|
145
|
-
|
1
|
+
# rpi_gpio v0.4.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.7.0, 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
|
+
```ruby
|
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
|
+
```ruby
|
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
|
+
```ruby
|
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
|
+
```ruby
|
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
|
+
```ruby
|
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
|
+
```ruby
|
64
|
+
RPi::GPIO.setup PIN_NUM, :as => :output
|
65
|
+
```
|
66
|
+
Now you can use the calls
|
67
|
+
```ruby
|
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
|
+
You can use the additional hash argument `:initialize` to set the pin's initial state like so:
|
74
|
+
```ruby
|
75
|
+
RPi::GPIO.setup PIN_NUM, :as => :output, :initialize => :high
|
76
|
+
# or
|
77
|
+
RPi::GPIO.setup PIN_NUM, :as => :output, :initialize => :low
|
78
|
+
```
|
79
|
+
|
80
|
+
#### PWM (pulse-width modulation)
|
81
|
+
|
82
|
+
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).
|
83
|
+
```ruby
|
84
|
+
pwm = RPi::GPIO::PWM.new(PIN_NUM, PWM_FREQ)
|
85
|
+
```
|
86
|
+
The `PWM_FREQ` is a value in hertz that specifies the amount of pulse cycles per second.
|
87
|
+
|
88
|
+
Now you can call the following method to start PWM:
|
89
|
+
```ruby
|
90
|
+
pwm.start DUTY_CYCLE
|
91
|
+
```
|
92
|
+
`DUTY_CYCLE` is a value from `0.0` to `100.0` indicating the percent of the time that the signal will be high.
|
93
|
+
|
94
|
+
Once running, you can get/set the PWM duty cycle with
|
95
|
+
```ruby
|
96
|
+
pwm.duty_cycle # get
|
97
|
+
pwm.duty_cycle = NEW_DUTY_CYCLE # set
|
98
|
+
```
|
99
|
+
get/set the PWM frequency with
|
100
|
+
```ruby
|
101
|
+
pwm.frequency # get
|
102
|
+
pwm.frequency = NEW_FREQUENCY # set
|
103
|
+
```
|
104
|
+
and get the PWM GPIO number with
|
105
|
+
```ruby
|
106
|
+
pwm.gpio
|
107
|
+
```
|
108
|
+
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.
|
109
|
+
|
110
|
+
To stop PWM, use
|
111
|
+
```ruby
|
112
|
+
pwm.stop
|
113
|
+
```
|
114
|
+
|
115
|
+
To check if a PWM object is currently running, use
|
116
|
+
```ruby
|
117
|
+
pwm.running?
|
118
|
+
```
|
119
|
+
|
120
|
+
#### Cleaning up
|
121
|
+
|
122
|
+
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
|
123
|
+
```ruby
|
124
|
+
RPi::GPIO.clean_up PIN_NUM
|
125
|
+
```
|
126
|
+
to release a specific pin, or
|
127
|
+
```ruby
|
128
|
+
RPi::GPIO.clean_up
|
129
|
+
```
|
130
|
+
to release all allocated pins.
|
131
|
+
|
132
|
+
Alternatively, you can call
|
133
|
+
```ruby
|
134
|
+
RPi::GPIO.reset
|
135
|
+
```
|
136
|
+
to clean up all pins and to also reset the selected numbering mode.
|
137
|
+
|
138
|
+
## Credits
|
139
|
+
|
140
|
+
Original Python code by Ben Croston modified for Ruby by Nick Lowery
|
141
|
+
|
142
|
+
Copyright (c) 2014-2020 [Nick Lowery](https://github.com/ClockVapor)
|
143
|
+
|
144
|
+
View LICENSE for full license.
|
145
|
+
|
data/ext/rpi_gpio/c_gpio.c
CHANGED
@@ -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-
|
4
|
+
Copyright (c) 2014-2020 Nick Lowery
|
5
5
|
|
6
|
-
Copyright (c)
|
6
|
+
Copyright (c) 2012-2019 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
|
@@ -47,6 +47,11 @@ SOFTWARE.
|
|
47
47
|
#define PULLUPDN_OFFSET 37 // 0x0094 / 4
|
48
48
|
#define PULLUPDNCLK_OFFSET 38 // 0x0098 / 4
|
49
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
|
+
|
50
55
|
#define PAGE_SIZE (4*1024)
|
51
56
|
#define BLOCK_SIZE (4*1024)
|
52
57
|
|
@@ -65,7 +70,7 @@ int setup(void)
|
|
65
70
|
{
|
66
71
|
int mem_fd;
|
67
72
|
uint8_t *gpio_mem;
|
68
|
-
uint32_t peri_base;
|
73
|
+
uint32_t peri_base = 0;
|
69
74
|
uint32_t gpio_base;
|
70
75
|
unsigned char buf[4];
|
71
76
|
FILE *fp;
|
@@ -76,8 +81,7 @@ int setup(void)
|
|
76
81
|
// try /dev/gpiomem first - this does not require root privs
|
77
82
|
if ((mem_fd = open("/dev/gpiomem", O_RDWR|O_SYNC)) > 0)
|
78
83
|
{
|
79
|
-
gpio_map = (uint32_t *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0)
|
80
|
-
if ((uint32_t)gpio_map < 0) {
|
84
|
+
if ((gpio_map = (uint32_t *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0)) == MAP_FAILED) {
|
81
85
|
return SETUP_MMAP_FAIL;
|
82
86
|
} else {
|
83
87
|
return SETUP_OK;
|
@@ -99,8 +103,7 @@ int setup(void)
|
|
99
103
|
if ((fp = fopen("/proc/cpuinfo", "r")) == NULL)
|
100
104
|
return SETUP_CPUINFO_FAIL;
|
101
105
|
|
102
|
-
while(!feof(fp) && !found) {
|
103
|
-
fgets(buffer, sizeof(buffer), fp);
|
106
|
+
while(!feof(fp) && !found && fgets(buffer, sizeof(buffer), fp)) {
|
104
107
|
sscanf(buffer, "Hardware : %s", hardware);
|
105
108
|
if (strcmp(hardware, "BCM2708") == 0 || strcmp(hardware, "BCM2835") == 0) {
|
106
109
|
// pi 1 hardware
|
@@ -117,26 +120,22 @@ int setup(void)
|
|
117
120
|
return SETUP_NOT_RPI_FAIL;
|
118
121
|
}
|
119
122
|
|
123
|
+
if (!peri_base)
|
124
|
+
return SETUP_NOT_RPI_FAIL;
|
120
125
|
gpio_base = peri_base + GPIO_BASE_OFFSET;
|
121
126
|
|
122
127
|
// mmap the GPIO memory registers
|
123
|
-
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0)
|
128
|
+
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0)
|
124
129
|
return SETUP_DEVMEM_FAIL;
|
125
|
-
}
|
126
130
|
|
127
|
-
if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
|
131
|
+
if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
|
128
132
|
return SETUP_MALLOC_FAIL;
|
129
|
-
}
|
130
133
|
|
131
|
-
if ((uint32_t)gpio_mem % PAGE_SIZE)
|
132
|
-
gpio_mem += PAGE_SIZE - ((uint32_t)
|
133
|
-
}
|
134
|
-
|
135
|
-
gpio_map = (uint32_t *) mmap((void *) gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, gpio_base);
|
134
|
+
if ((uint32_t)gpio_mem % PAGE_SIZE)
|
135
|
+
gpio_mem += PAGE_SIZE - ((uint32_t)gpio_mem % PAGE_SIZE);
|
136
136
|
|
137
|
-
if ((uint32_t)
|
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
138
|
return SETUP_MMAP_FAIL;
|
139
|
-
}
|
140
139
|
|
141
140
|
return SETUP_OK;
|
142
141
|
}
|
@@ -158,9 +157,8 @@ int eventdetected(int gpio)
|
|
158
157
|
offset = EVENT_DETECT_OFFSET + (gpio/32);
|
159
158
|
bit = (1 << (gpio%32));
|
160
159
|
value = *(gpio_map+offset) & bit;
|
161
|
-
if (value)
|
160
|
+
if (value)
|
162
161
|
clear_event_detect(gpio);
|
163
|
-
}
|
164
162
|
return value;
|
165
163
|
}
|
166
164
|
|
@@ -169,11 +167,10 @@ void set_rising_event(int gpio, int enable)
|
|
169
167
|
int offset = RISING_ED_OFFSET + (gpio/32);
|
170
168
|
int shift = (gpio%32);
|
171
169
|
|
172
|
-
if (enable)
|
170
|
+
if (enable)
|
173
171
|
*(gpio_map+offset) |= 1 << shift;
|
174
|
-
|
172
|
+
else
|
175
173
|
*(gpio_map+offset) &= ~(1 << shift);
|
176
|
-
}
|
177
174
|
clear_event_detect(gpio);
|
178
175
|
}
|
179
176
|
|
@@ -196,11 +193,10 @@ void set_high_event(int gpio, int enable)
|
|
196
193
|
int offset = HIGH_DETECT_OFFSET + (gpio/32);
|
197
194
|
int shift = (gpio%32);
|
198
195
|
|
199
|
-
if (enable)
|
196
|
+
if (enable)
|
200
197
|
*(gpio_map+offset) |= (1 << shift);
|
201
|
-
|
198
|
+
else
|
202
199
|
*(gpio_map+offset) &= ~(1 << shift);
|
203
|
-
}
|
204
200
|
clear_event_detect(gpio);
|
205
201
|
}
|
206
202
|
|
@@ -209,33 +205,51 @@ void set_low_event(int gpio, int enable)
|
|
209
205
|
int offset = LOW_DETECT_OFFSET + (gpio/32);
|
210
206
|
int shift = (gpio%32);
|
211
207
|
|
212
|
-
if (enable)
|
208
|
+
if (enable)
|
213
209
|
*(gpio_map+offset) |= 1 << shift;
|
214
|
-
|
210
|
+
else
|
215
211
|
*(gpio_map+offset) &= ~(1 << shift);
|
216
|
-
}
|
217
212
|
clear_event_detect(gpio);
|
218
213
|
}
|
219
214
|
|
220
215
|
void set_pullupdn(int gpio, int pud)
|
221
216
|
{
|
222
|
-
|
223
|
-
int
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
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();
|
231
250
|
*(gpio_map+PULLUPDN_OFFSET) &= ~3;
|
251
|
+
*(gpio_map+clk_offset) = 0;
|
232
252
|
}
|
233
|
-
|
234
|
-
short_wait();
|
235
|
-
*(gpio_map+clk_offset) = 1 << shift;
|
236
|
-
short_wait();
|
237
|
-
*(gpio_map+PULLUPDN_OFFSET) &= ~3;
|
238
|
-
*(gpio_map+clk_offset) = 0;
|
239
253
|
}
|
240
254
|
|
241
255
|
void setup_gpio(int gpio, int direction, int pud)
|
@@ -265,12 +279,11 @@ void output_gpio(int gpio, int value)
|
|
265
279
|
{
|
266
280
|
int offset, shift;
|
267
281
|
|
268
|
-
if (value)
|
282
|
+
if (value) // value == HIGH
|
269
283
|
offset = SET_OFFSET + (gpio/32);
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
284
|
+
else // value == LOW
|
285
|
+
offset = CLR_OFFSET + (gpio/32);
|
286
|
+
|
274
287
|
shift = (gpio%32);
|
275
288
|
|
276
289
|
*(gpio_map+offset) = 1 << shift;
|
@@ -288,5 +301,5 @@ int input_gpio(int gpio)
|
|
288
301
|
|
289
302
|
void cleanup(void)
|
290
303
|
{
|
291
|
-
munmap((void *)
|
304
|
+
munmap((void *)gpio_map, BLOCK_SIZE);
|
292
305
|
}
|