rpi_gpio 0.4.0 → 0.7.1
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 +4 -4
- data/LICENSE +2 -2
- data/README.md +50 -9
- data/ext/rpi_gpio/c_gpio.c +56 -16
- data/ext/rpi_gpio/c_gpio.h +3 -3
- data/ext/rpi_gpio/common.c +6 -3
- data/ext/rpi_gpio/common.h +12 -11
- data/ext/rpi_gpio/cpuinfo.c +9 -4
- data/ext/rpi_gpio/extconf.rb +1 -3
- data/ext/rpi_gpio/rb_gpio.c +89 -32
- data/ext/rpi_gpio/rb_gpio.h +3 -1
- data/ext/rpi_gpio/rb_pwm.h +2 -2
- data/ext/rpi_gpio/rpi_gpio.c +2 -2
- data/ext/rpi_gpio/soft_pwm.c +3 -3
- data/lib/rpi_gpio.rb +329 -0
- metadata +27 -20
- data/Gemfile +0 -4
- data/Gemfile.lock +0 -36
- data/Rakefile +0 -3
- data/ext/rpi_gpio/event_gpio.c +0 -605
- data/ext/rpi_gpio/event_gpio.h +0 -40
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e85a39df6149e36f76739cbb642208a635cc20fa3a7e201ea0207c2070fc4765
|
|
4
|
+
data.tar.gz: 36b825467b90ebe19c1bcd431847bbc596ea94fdd31e7c5b99fdda31f3efc87c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fa6f1aa7414cdcfc349b2f06c4108fc6819634f8f6a1d3dd5aa70cf8f6e040e0c0a06d32342af3d36c5207673c86640895918e4c6651e74205b6da62d8608056
|
|
7
|
+
data.tar.gz: bed6f48051ae7eb6c62eb3394cd18c7f1e4f8b5b543a50a38b9ebe091260b0f5a512b46aa89b69f0e3a011c58f51e9a0921b0d2f76acccaf5640a3ed072ff1bc
|
data/LICENSE
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2014-
|
|
4
|
-
Copyright (c) 2012-
|
|
3
|
+
Copyright (c) 2014-2026 Nick Lowery
|
|
4
|
+
Copyright (c) 2012-2021 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
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# rpi_gpio v0.
|
|
1
|
+
# rpi_gpio v0.7.1
|
|
2
2
|
|
|
3
3
|
Ruby conversion of [RPi.GPIO Python module](https://pypi.python.org/pypi/RPi.GPIO)
|
|
4
4
|
|
|
@@ -8,8 +8,9 @@ Manipulate your Raspberry Pi's GPIO pins from Ruby!
|
|
|
8
8
|
|
|
9
9
|
- Boolean input/output
|
|
10
10
|
- Software-driven PWM (written in C for speed)
|
|
11
|
+
- Event-driven input (blocking and non-blocking)
|
|
11
12
|
|
|
12
|
-
Up-to-date with RPi.GPIO Python module version 0.7.
|
|
13
|
+
Up-to-date with RPi.GPIO Python module version 0.7.1, so it works on all Raspberry Pi models!
|
|
13
14
|
|
|
14
15
|
## Sample Usage
|
|
15
16
|
|
|
@@ -38,9 +39,20 @@ RPi::GPIO.set_numbering :bcm
|
|
|
38
39
|
To receive input from a GPIO pin, you must first initialize it as an input pin:
|
|
39
40
|
```ruby
|
|
40
41
|
RPi::GPIO.setup PIN_NUM, :as => :input
|
|
42
|
+
# or
|
|
43
|
+
RPi::GPIO.setup [PIN1_NUM, PIN2_NUM, ...], :as => :input
|
|
41
44
|
```
|
|
42
45
|
The pin number will differ based on your selected numbering system and which pin you want to use.
|
|
43
46
|
|
|
47
|
+
You can use the additional hash argument `:pull` to apply a pull-up or pull-down resistor to the input pin like so:
|
|
48
|
+
```ruby
|
|
49
|
+
RPi::GPIO.setup PIN_NUM, :as => :input, :pull => :down
|
|
50
|
+
# or
|
|
51
|
+
RPi::GPIO.setup PIN_NUM, :as => :input, :pull => :up
|
|
52
|
+
# or (not necessary; :off is the default value)
|
|
53
|
+
RPi::GPIO.setup PIN_NUM, :as => :input, :pull => :off
|
|
54
|
+
```
|
|
55
|
+
|
|
44
56
|
Now you can use the calls
|
|
45
57
|
```ruby
|
|
46
58
|
RPi::GPIO.high? PIN_NUM
|
|
@@ -48,13 +60,40 @@ RPi::GPIO.low? PIN_NUM
|
|
|
48
60
|
```
|
|
49
61
|
to receive either `true` or `false`.
|
|
50
62
|
|
|
51
|
-
|
|
63
|
+
If you prefer to use a callback when a pin edge is detected, you can use the `watch` method:
|
|
52
64
|
```ruby
|
|
53
|
-
RPi::GPIO.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
RPi::GPIO.watch PIN_NUM, :on => :rising do |pin, value| # :on supports :rising, :falling, and :both
|
|
66
|
+
...
|
|
67
|
+
end
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`watch` also supports the optional `bounce_time` parameter found in the Python module to prevent duplicate events from firing:
|
|
71
|
+
```ruby
|
|
72
|
+
RPi::GPIO.watch PIN_NUM, :on => :falling, :bounce_time => 200 do |pin, value|
|
|
73
|
+
...
|
|
74
|
+
end
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
To stop watching a pin, use `stop_watching`:
|
|
78
|
+
```ruby
|
|
79
|
+
RPi::GPIO.stop_watching PIN_NUM
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
If you want to block execution until a pin edge is detected, there's `wait_for_edge`:
|
|
83
|
+
```ruby
|
|
84
|
+
puts 'Waiting to start...'
|
|
85
|
+
RPi::GPIO.wait_for_edge PIN_NUM, :rising # :rising, :falling, and :both are also supported here
|
|
86
|
+
puts 'Here we go!'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`wait_for_edge` accepts optional `bounce_time` and `timeout` arguments too:
|
|
90
|
+
```ruby
|
|
91
|
+
puts 'Waiting to start...'
|
|
92
|
+
value = RPi::GPIO.wait_for_edge PIN_NUM, :falling, :bounce_time => 200, :timeout => 5000
|
|
93
|
+
if value.nil? # nil is returned if the timeout is reached
|
|
94
|
+
print 'You took too long. '
|
|
95
|
+
end
|
|
96
|
+
puts 'Here we go!'
|
|
58
97
|
```
|
|
59
98
|
|
|
60
99
|
#### Output
|
|
@@ -62,6 +101,8 @@ RPi::GPIO.setup PIN_NUM, :as => :input, :pull => :off
|
|
|
62
101
|
To send output to a GPIO pin, you must first initialize it as an output pin:
|
|
63
102
|
```ruby
|
|
64
103
|
RPi::GPIO.setup PIN_NUM, :as => :output
|
|
104
|
+
# or
|
|
105
|
+
RPi::GPIO.setup [PIN1_NUM, PIN2_NUM, ...], :as => :output
|
|
65
106
|
```
|
|
66
107
|
Now you can use the calls
|
|
67
108
|
```ruby
|
|
@@ -139,7 +180,7 @@ to clean up all pins and to also reset the selected numbering mode.
|
|
|
139
180
|
|
|
140
181
|
Original Python code by Ben Croston modified for Ruby by Nick Lowery
|
|
141
182
|
|
|
142
|
-
Copyright (c) 2014-
|
|
183
|
+
Copyright (c) 2014-2026 [Nick Lowery](https://github.com/ClockVapor)
|
|
143
184
|
|
|
144
185
|
View LICENSE for full license.
|
|
145
186
|
|
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-2026 Nick Lowery
|
|
5
5
|
|
|
6
|
-
Copyright (c) 2012-
|
|
6
|
+
Copyright (c) 2012-2021 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
|
|
@@ -34,6 +34,8 @@ SOFTWARE.
|
|
|
34
34
|
|
|
35
35
|
#define BCM2708_PERI_BASE_DEFAULT 0x20000000
|
|
36
36
|
#define BCM2709_PERI_BASE_DEFAULT 0x3f000000
|
|
37
|
+
#define BCM2710_PERI_BASE_DEFAULT 0x3f000000
|
|
38
|
+
#define BCM2711_PERI_BASE_DEFAULT 0xfe000000
|
|
37
39
|
#define GPIO_BASE_OFFSET 0x200000
|
|
38
40
|
#define FSEL_OFFSET 0 // 0x0000
|
|
39
41
|
#define SET_OFFSET 7 // 0x001c / 4
|
|
@@ -72,7 +74,9 @@ int setup(void)
|
|
|
72
74
|
uint8_t *gpio_mem;
|
|
73
75
|
uint32_t peri_base = 0;
|
|
74
76
|
uint32_t gpio_base;
|
|
75
|
-
|
|
77
|
+
uint8_t ranges[12] = { 0 };
|
|
78
|
+
uint8_t rev[4] = { 0 };
|
|
79
|
+
uint32_t cpu = 0;
|
|
76
80
|
FILE *fp;
|
|
77
81
|
char buffer[1024];
|
|
78
82
|
char hardware[1024];
|
|
@@ -88,18 +92,51 @@ int setup(void)
|
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
94
|
|
|
91
|
-
// revert to /dev/mem method - requires root
|
|
95
|
+
// revert to /dev/mem method - requires root privileges
|
|
92
96
|
|
|
93
|
-
|
|
94
|
-
|
|
97
|
+
if ((fp = fopen("/proc/device-tree/soc/ranges", "rb")) != NULL)
|
|
98
|
+
{
|
|
95
99
|
// get peri base from device tree
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
peri_base
|
|
100
|
+
if (fread(ranges, 1, sizeof(ranges), fp) >= 8) {
|
|
101
|
+
peri_base = ranges[4] << 24 | ranges[5] << 16 | ranges[6] << 8 | ranges[7] << 0;
|
|
102
|
+
if (!peri_base) {
|
|
103
|
+
peri_base = ranges[8] << 24 | ranges[9] << 16 | ranges[10] << 8 | ranges[11] << 0;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if ((ranges[0] != 0x7e) ||
|
|
107
|
+
(ranges[1] != 0x00) ||
|
|
108
|
+
(ranges[2] != 0x00) ||
|
|
109
|
+
(ranges[3] != 0x00) ||
|
|
110
|
+
((peri_base != BCM2708_PERI_BASE_DEFAULT) &&
|
|
111
|
+
(peri_base != BCM2709_PERI_BASE_DEFAULT) &&
|
|
112
|
+
(peri_base != BCM2711_PERI_BASE_DEFAULT))) {
|
|
113
|
+
// invalid ranges file
|
|
114
|
+
peri_base = 0;
|
|
99
115
|
}
|
|
100
116
|
fclose(fp);
|
|
101
|
-
}
|
|
102
|
-
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// guess peri_base based on /proc/device-tree/system/linux,revision
|
|
120
|
+
if (!peri_base) {
|
|
121
|
+
if ((fp = fopen("/proc/device-tree/system/linux,revision", "rb")) != NULL) {
|
|
122
|
+
if (fread(rev, 1, sizeof(rev), fp) == 4) {
|
|
123
|
+
cpu = (rev[2] >> 4) & 0xf;
|
|
124
|
+
switch (cpu) {
|
|
125
|
+
case 0 : peri_base = BCM2708_PERI_BASE_DEFAULT;
|
|
126
|
+
break;
|
|
127
|
+
case 1 :
|
|
128
|
+
case 2 : peri_base = BCM2709_PERI_BASE_DEFAULT;
|
|
129
|
+
break;
|
|
130
|
+
case 3 : peri_base = BCM2711_PERI_BASE_DEFAULT;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
fclose(fp);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// guess peri_base based on /proc/cpuinfo hardware field
|
|
139
|
+
if (!peri_base) {
|
|
103
140
|
if ((fp = fopen("/proc/cpuinfo", "r")) == NULL)
|
|
104
141
|
return SETUP_CPUINFO_FAIL;
|
|
105
142
|
|
|
@@ -108,20 +145,23 @@ int setup(void)
|
|
|
108
145
|
if (strcmp(hardware, "BCM2708") == 0 || strcmp(hardware, "BCM2835") == 0) {
|
|
109
146
|
// pi 1 hardware
|
|
110
147
|
peri_base = BCM2708_PERI_BASE_DEFAULT;
|
|
111
|
-
found = 1;
|
|
112
148
|
} else if (strcmp(hardware, "BCM2709") == 0 || strcmp(hardware, "BCM2836") == 0) {
|
|
113
149
|
// pi 2 hardware
|
|
114
150
|
peri_base = BCM2709_PERI_BASE_DEFAULT;
|
|
115
|
-
|
|
151
|
+
} else if (strcmp(hardware, "BCM2710") == 0 || strcmp(hardware, "BCM2837") == 0) {
|
|
152
|
+
// pi 3 hardware
|
|
153
|
+
peri_base = BCM2710_PERI_BASE_DEFAULT;
|
|
154
|
+
} else if (strcmp(hardware, "BCM2711") == 0) {
|
|
155
|
+
// pi 4 hardware
|
|
156
|
+
peri_base = BCM2711_PERI_BASE_DEFAULT;
|
|
116
157
|
}
|
|
117
158
|
}
|
|
118
159
|
fclose(fp);
|
|
119
|
-
if (!found)
|
|
120
|
-
return SETUP_NOT_RPI_FAIL;
|
|
121
160
|
}
|
|
122
161
|
|
|
123
162
|
if (!peri_base)
|
|
124
|
-
return
|
|
163
|
+
return SETUP_NO_PERI_ADDR;
|
|
164
|
+
|
|
125
165
|
gpio_base = peri_base + GPIO_BASE_OFFSET;
|
|
126
166
|
|
|
127
167
|
// mmap the GPIO memory registers
|
data/ext/rpi_gpio/c_gpio.h
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-2026 Nick Lowery
|
|
5
5
|
|
|
6
|
-
Copyright (c)
|
|
6
|
+
Copyright (c) 2012-2021 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
|
|
@@ -41,7 +41,7 @@ void cleanup(void);
|
|
|
41
41
|
#define SETUP_MALLOC_FAIL 2
|
|
42
42
|
#define SETUP_MMAP_FAIL 3
|
|
43
43
|
#define SETUP_CPUINFO_FAIL 4
|
|
44
|
-
#define
|
|
44
|
+
#define SETUP_NO_PERI_ADDR 5
|
|
45
45
|
|
|
46
46
|
#define INPUT 1 // is really 0 for control register!
|
|
47
47
|
#define OUTPUT 0 // is really 1 for control register!
|
data/ext/rpi_gpio/common.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-2026 Nick Lowery
|
|
5
5
|
|
|
6
|
-
Copyright (c) 2013-
|
|
6
|
+
Copyright (c) 2013-2021 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
|
|
@@ -32,6 +32,9 @@ int gpio_mode = MODE_UNKNOWN;
|
|
|
32
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
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
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
|
+
const int (*pin_to_gpio)[41];
|
|
36
|
+
int gpio_direction[54];
|
|
37
|
+
rpi_info rpiinfo;
|
|
35
38
|
int setup_error = 0;
|
|
36
39
|
int module_setup = 0;
|
|
37
40
|
|
|
@@ -47,7 +50,7 @@ int check_gpio_priv(void)
|
|
|
47
50
|
// check mmap setup has worked
|
|
48
51
|
if (!module_setup)
|
|
49
52
|
{
|
|
50
|
-
rb_raise(rb_eRuntimeError, "no access to /dev/mem.
|
|
53
|
+
rb_raise(rb_eRuntimeError, "no access to /dev/mem. try running as root!");
|
|
51
54
|
return 2;
|
|
52
55
|
}
|
|
53
56
|
return 0;
|
data/ext/rpi_gpio/common.h
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-2026 Nick Lowery
|
|
5
5
|
|
|
6
|
-
Copyright (c) 2013-
|
|
6
|
+
Copyright (c) 2013-2021 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
|
|
@@ -34,14 +34,15 @@ SOFTWARE.
|
|
|
34
34
|
#define I2C 42
|
|
35
35
|
#define PWM 43
|
|
36
36
|
|
|
37
|
-
int gpio_mode;
|
|
38
|
-
const int pin_to_gpio_rev1[41];
|
|
39
|
-
const int pin_to_gpio_rev2[41];
|
|
40
|
-
const int pin_to_gpio_rev3[41];
|
|
41
|
-
const int (*pin_to_gpio)[41];
|
|
42
|
-
int gpio_direction[54];
|
|
43
|
-
rpi_info rpiinfo;
|
|
44
|
-
int setup_error;
|
|
45
|
-
int module_setup;
|
|
37
|
+
extern int gpio_mode;
|
|
38
|
+
extern const int pin_to_gpio_rev1[41];
|
|
39
|
+
extern const int pin_to_gpio_rev2[41];
|
|
40
|
+
extern const int pin_to_gpio_rev3[41];
|
|
41
|
+
extern const int (*pin_to_gpio)[41];
|
|
42
|
+
extern int gpio_direction[54];
|
|
43
|
+
extern rpi_info rpiinfo;
|
|
44
|
+
extern int setup_error;
|
|
45
|
+
extern int module_setup;
|
|
46
|
+
|
|
46
47
|
int check_gpio_priv(void);
|
|
47
48
|
int get_gpio_number(int channel, unsigned int *gpio);
|
data/ext/rpi_gpio/cpuinfo.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-2026 Nick Lowery
|
|
5
5
|
|
|
6
|
-
Copyright (c) 2012-
|
|
6
|
+
Copyright (c) 2012-2021 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
|
|
@@ -25,7 +25,7 @@ SOFTWARE.
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
/* See the following for up to date information:
|
|
28
|
-
*
|
|
28
|
+
*https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#raspberry-pi-revision-codes
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
#include <stdio.h>
|
|
@@ -58,6 +58,7 @@ int get_rpi_info(rpi_info *info)
|
|
|
58
58
|
sscanf(buffer, "Hardware : %s", hardware);
|
|
59
59
|
if (strcmp(hardware, "BCM2708") == 0 ||
|
|
60
60
|
strcmp(hardware, "BCM2709") == 0 ||
|
|
61
|
+
strcmp(hardware, "BCM2711") == 0 ||
|
|
61
62
|
strcmp(hardware, "BCM2835") == 0 ||
|
|
62
63
|
strcmp(hardware, "BCM2836") == 0 ||
|
|
63
64
|
strcmp(hardware, "BCM2837") == 0 ) {
|
|
@@ -102,6 +103,9 @@ int get_rpi_info(rpi_info *info)
|
|
|
102
103
|
switch (revision[len-2]) {
|
|
103
104
|
case '0': info->type = "Compute Module 3+"; info->p1_revision = 0; break;
|
|
104
105
|
case '1': info->type = "Pi 4 Model B"; info->p1_revision = 3; break;
|
|
106
|
+
case '2': info->type = "Zero 2 W"; info->p1_revision = 3; break;
|
|
107
|
+
case '3': info->type = "Pi 400"; info->p1_revision = 3; break;
|
|
108
|
+
case '4': info->type = "Compute Module 4"; info->p1_revision = 0; break;
|
|
105
109
|
default : info->type = "Unknown"; info->p1_revision = 3; break;
|
|
106
110
|
} break;
|
|
107
111
|
default: info->type = "Unknown"; info->p1_revision = 3; break;
|
|
@@ -115,7 +119,7 @@ int get_rpi_info(rpi_info *info)
|
|
|
115
119
|
default : info->processor = "Unknown"; break;
|
|
116
120
|
}
|
|
117
121
|
switch (revision[len-5]) {
|
|
118
|
-
case '0': info->manufacturer = "Sony"; break;
|
|
122
|
+
case '0': info->manufacturer = "Sony UK"; break;
|
|
119
123
|
case '1': info->manufacturer = "Egoman"; break;
|
|
120
124
|
case '2': info->manufacturer = "Embest"; break;
|
|
121
125
|
case '3': info->manufacturer = "Sony Japan"; break;
|
|
@@ -129,6 +133,7 @@ int get_rpi_info(rpi_info *info)
|
|
|
129
133
|
case 2: info->ram = "1G"; break;
|
|
130
134
|
case 3: info->ram = "2G"; break;
|
|
131
135
|
case 4: info->ram = "4G"; break;
|
|
136
|
+
case 5: info->ram = "8G"; break;
|
|
132
137
|
default: info->ram = "Unknown"; break;
|
|
133
138
|
}
|
|
134
139
|
} else {
|
data/ext/rpi_gpio/extconf.rb
CHANGED
data/ext/rpi_gpio/rb_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-2026 Nick Lowery
|
|
5
5
|
|
|
6
|
-
Copyright (c) 2012-
|
|
6
|
+
Copyright (c) 2012-2021 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
|
|
@@ -57,6 +57,9 @@ void define_gpio_module_stuff(void)
|
|
|
57
57
|
rb_define_module_function(m_GPIO, "high?", GPIO_test_high, 1);
|
|
58
58
|
rb_define_module_function(m_GPIO, "low?", GPIO_test_low, 1);
|
|
59
59
|
rb_define_module_function(m_GPIO, "set_warnings", GPIO_set_warnings, 1);
|
|
60
|
+
rb_define_module_function(m_GPIO, "get_gpio_number", GPIO_get_gpio_number, 1);
|
|
61
|
+
rb_define_module_function(m_GPIO, "channel_from_gpio", GPIO_channel_from_gpio, 1);
|
|
62
|
+
rb_define_module_function(m_GPIO, "ensure_gpio_input", GPIO_ensure_gpio_input, 1);
|
|
60
63
|
|
|
61
64
|
for (i = 0; i < 54; i++) {
|
|
62
65
|
gpio_direction[i] = -1;
|
|
@@ -97,8 +100,8 @@ int mmap_gpio_mem(void)
|
|
|
97
100
|
} else if (result == SETUP_CPUINFO_FAIL) {
|
|
98
101
|
rb_raise(rb_eRuntimeError, "unable to open /proc/cpuinfo");
|
|
99
102
|
return 4;
|
|
100
|
-
} else if (result ==
|
|
101
|
-
rb_raise(rb_eRuntimeError, "
|
|
103
|
+
} else if (result == SETUP_NO_PERI_ADDR) {
|
|
104
|
+
rb_raise(rb_eRuntimeError, "cannot determine SOC peripheral base address");
|
|
102
105
|
return 5;
|
|
103
106
|
} else { // result == SETUP_OK
|
|
104
107
|
module_setup = 1;
|
|
@@ -121,19 +124,25 @@ int is_gpio_initialized(unsigned int gpio)
|
|
|
121
124
|
|
|
122
125
|
int is_gpio_output(unsigned int gpio)
|
|
123
126
|
{
|
|
127
|
+
if (!is_gpio_initialized(gpio)) {
|
|
128
|
+
return 0;
|
|
129
|
+
}
|
|
124
130
|
if (gpio_direction[gpio] != OUTPUT) {
|
|
125
|
-
if (gpio_direction[gpio] != INPUT) {
|
|
126
|
-
rb_raise(rb_eRuntimeError,
|
|
127
|
-
"you must setup the GPIO channel first with "
|
|
128
|
-
"RPi::GPIO.setup CHANNEL, :as => :input or "
|
|
129
|
-
"RPi::GPIO.setup CHANNEL, :as => :output");
|
|
130
|
-
return 0;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
131
|
rb_raise(rb_eRuntimeError, "GPIO channel not setup as output");
|
|
134
132
|
return 0;
|
|
135
133
|
}
|
|
134
|
+
return 1;
|
|
135
|
+
}
|
|
136
136
|
|
|
137
|
+
int is_gpio_input(unsigned int gpio)
|
|
138
|
+
{
|
|
139
|
+
if (!is_gpio_initialized(gpio)) {
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
142
|
+
if (gpio_direction[gpio] != INPUT) {
|
|
143
|
+
rb_raise(rb_eRuntimeError, "GPIO channel not setup as input");
|
|
144
|
+
return 0;
|
|
145
|
+
}
|
|
137
146
|
return 1;
|
|
138
147
|
}
|
|
139
148
|
|
|
@@ -170,7 +179,7 @@ VALUE GPIO_clean_up(int argc, VALUE *argv, VALUE self)
|
|
|
170
179
|
if (module_setup && !setup_error) {
|
|
171
180
|
if (channel == -666) {
|
|
172
181
|
// clean up any /sys/class exports
|
|
173
|
-
event_cleanup_all
|
|
182
|
+
rb_funcall(m_GPIO, rb_intern("event_cleanup_all"), 0);
|
|
174
183
|
|
|
175
184
|
// set everything back to input
|
|
176
185
|
for (i = 0; i < 54; i++) {
|
|
@@ -182,7 +191,7 @@ VALUE GPIO_clean_up(int argc, VALUE *argv, VALUE self)
|
|
|
182
191
|
}
|
|
183
192
|
} else {
|
|
184
193
|
// clean up any /sys/class exports
|
|
185
|
-
event_cleanup(gpio);
|
|
194
|
+
rb_funcall(m_GPIO, rb_intern("event_cleanup"), 1, INT2NUM(gpio));
|
|
186
195
|
|
|
187
196
|
// set everything back to input
|
|
188
197
|
if (gpio_direction[gpio] != -1) {
|
|
@@ -392,12 +401,12 @@ VALUE GPIO_set_high(VALUE self, VALUE channel)
|
|
|
392
401
|
int chan_count = RARRAY_LEN(channel_list);
|
|
393
402
|
|
|
394
403
|
for (int i = 0; i < chan_count; i++) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
404
|
+
chan = NUM2INT(rb_ary_entry(channel_list, i));
|
|
405
|
+
if (get_gpio_number(chan, &gpio) || !is_gpio_output(gpio) || check_gpio_priv()) {
|
|
406
|
+
return Qnil;
|
|
407
|
+
} else {
|
|
408
|
+
output_gpio(gpio, 1);
|
|
409
|
+
}
|
|
401
410
|
}
|
|
402
411
|
|
|
403
412
|
return self;
|
|
@@ -406,19 +415,19 @@ VALUE GPIO_set_high(VALUE self, VALUE channel)
|
|
|
406
415
|
// RPi::GPIO.set_low(channel)
|
|
407
416
|
VALUE GPIO_set_low(VALUE self, VALUE channel)
|
|
408
417
|
{
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
418
|
+
unsigned int gpio;
|
|
419
|
+
int chan = -1;
|
|
420
|
+
VALUE channel_list = _extract_channels(channel);
|
|
421
|
+
int chan_count = RARRAY_LEN(channel_list);
|
|
422
|
+
|
|
423
|
+
for (int i = 0; i < chan_count; i++) {
|
|
424
|
+
chan = NUM2INT(rb_ary_entry(channel_list, i));
|
|
425
|
+
if (get_gpio_number(chan, &gpio) || !is_gpio_output(gpio) || check_gpio_priv()) {
|
|
426
|
+
return Qnil;
|
|
427
|
+
} else {
|
|
428
|
+
output_gpio(gpio, 0);
|
|
429
|
+
}
|
|
420
430
|
}
|
|
421
|
-
}
|
|
422
431
|
|
|
423
432
|
return self;
|
|
424
433
|
}
|
|
@@ -451,3 +460,51 @@ VALUE GPIO_set_warnings(VALUE self, VALUE setting)
|
|
|
451
460
|
gpio_warnings = RTEST(setting);
|
|
452
461
|
return self;
|
|
453
462
|
}
|
|
463
|
+
|
|
464
|
+
// RPi::GPIO.get_gpio_number(channel)
|
|
465
|
+
VALUE GPIO_get_gpio_number(VALUE self, VALUE channel)
|
|
466
|
+
{
|
|
467
|
+
int chan;
|
|
468
|
+
unsigned int gpio;
|
|
469
|
+
|
|
470
|
+
chan = NUM2INT(channel);
|
|
471
|
+
if (get_gpio_number(chan, &gpio)) {
|
|
472
|
+
return Qnil;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
return INT2NUM(gpio);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
static unsigned int chan_from_gpio(unsigned int gpio)
|
|
479
|
+
{
|
|
480
|
+
int chan;
|
|
481
|
+
int chans;
|
|
482
|
+
|
|
483
|
+
if (gpio_mode == BCM)
|
|
484
|
+
return gpio;
|
|
485
|
+
if (rpiinfo.p1_revision == 0) // not applicable for compute module
|
|
486
|
+
return -1;
|
|
487
|
+
else if (rpiinfo.p1_revision == 1 || rpiinfo.p1_revision == 2)
|
|
488
|
+
chans = 26;
|
|
489
|
+
else
|
|
490
|
+
chans = 40;
|
|
491
|
+
for (chan=1; chan<=chans; chan++)
|
|
492
|
+
if (*(*pin_to_gpio+chan) == (int)gpio)
|
|
493
|
+
return chan;
|
|
494
|
+
return -1;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// RPi::GPIO.channel_from_gpio(gpio)
|
|
498
|
+
VALUE GPIO_channel_from_gpio(VALUE self, VALUE gpio)
|
|
499
|
+
{
|
|
500
|
+
unsigned int gpio_ = NUM2INT(gpio);
|
|
501
|
+
unsigned int channel = chan_from_gpio(gpio_);
|
|
502
|
+
return INT2NUM(channel);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// RPi::GPIO.ensure_gpio_input(gpio)
|
|
506
|
+
VALUE GPIO_ensure_gpio_input(VALUE self, VALUE gpio)
|
|
507
|
+
{
|
|
508
|
+
unsigned int gpio_ = NUM2INT(gpio);
|
|
509
|
+
return is_gpio_input(gpio_) ? Qtrue : Qfalse;
|
|
510
|
+
}
|
data/ext/rpi_gpio/rb_gpio.h
CHANGED
|
@@ -26,7 +26,6 @@ SOFTWARE.
|
|
|
26
26
|
|
|
27
27
|
#include "ruby.h"
|
|
28
28
|
#include "c_gpio.h"
|
|
29
|
-
#include "event_gpio.h"
|
|
30
29
|
#include "cpuinfo.h"
|
|
31
30
|
#include "common.h"
|
|
32
31
|
#include "rb_pwm.h"
|
|
@@ -45,3 +44,6 @@ VALUE GPIO_set_low(VALUE self, VALUE channel);
|
|
|
45
44
|
VALUE GPIO_test_high(VALUE self, VALUE channel);
|
|
46
45
|
VALUE GPIO_test_low(VALUE self, VALUE channel);
|
|
47
46
|
VALUE GPIO_set_warnings(VALUE self, VALUE setting);
|
|
47
|
+
VALUE GPIO_get_gpio_number(VALUE self, VALUE channel);
|
|
48
|
+
VALUE GPIO_channel_from_gpio(VALUE self, VALUE gpio);
|
|
49
|
+
VALUE GPIO_ensure_gpio_input(VALUE self, VALUE gpio);
|
data/ext/rpi_gpio/rb_pwm.h
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-2026 Nick Lowery
|
|
5
5
|
|
|
6
|
-
Copyright (c) 2013-
|
|
6
|
+
Copyright (c) 2013-2021 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
|
data/ext/rpi_gpio/rpi_gpio.c
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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-2026 Nick Lowery
|
|
5
5
|
|
|
6
6
|
Copyright (c) 2013-2014 Ben Croston
|
|
7
7
|
|
|
@@ -31,7 +31,7 @@ SOFTWARE.
|
|
|
31
31
|
VALUE m_RPi = Qnil;
|
|
32
32
|
VALUE m_GPIO = Qnil;
|
|
33
33
|
|
|
34
|
-
void Init_rpi_gpio()
|
|
34
|
+
void Init_rpi_gpio(void)
|
|
35
35
|
{
|
|
36
36
|
define_modules();
|
|
37
37
|
define_gpio_module_stuff();
|
data/ext/rpi_gpio/soft_pwm.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-2026 Nick Lowery
|
|
5
5
|
|
|
6
|
-
Copyright (c) 2013-
|
|
6
|
+
Copyright (c) 2013-2021 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
|
|
@@ -29,7 +29,6 @@ SOFTWARE.
|
|
|
29
29
|
#include <time.h>
|
|
30
30
|
#include "c_gpio.h"
|
|
31
31
|
#include "soft_pwm.h"
|
|
32
|
-
pthread_t threads;
|
|
33
32
|
|
|
34
33
|
struct pwm
|
|
35
34
|
{
|
|
@@ -197,6 +196,7 @@ void pwm_set_frequency(unsigned int gpio, float freq)
|
|
|
197
196
|
|
|
198
197
|
void pwm_start(unsigned int gpio)
|
|
199
198
|
{
|
|
199
|
+
pthread_t threads;
|
|
200
200
|
struct pwm *p;
|
|
201
201
|
|
|
202
202
|
if (((p = find_pwm(gpio)) == NULL) || p->running)
|