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
data/ext/rpi_gpio/c_gpio.h
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-2020 Nick Lowery
|
5
5
|
|
6
6
|
Copyright (c) 2013-2015 Ben Croston
|
7
7
|
|
@@ -36,10 +36,10 @@ void set_low_event(int gpio, int enable);
|
|
36
36
|
int eventdetected(int gpio);
|
37
37
|
void cleanup(void);
|
38
38
|
|
39
|
-
#define SETUP_OK
|
40
|
-
#define SETUP_DEVMEM_FAIL
|
41
|
-
#define SETUP_MALLOC_FAIL
|
42
|
-
#define SETUP_MMAP_FAIL
|
39
|
+
#define SETUP_OK 0
|
40
|
+
#define SETUP_DEVMEM_FAIL 1
|
41
|
+
#define SETUP_MALLOC_FAIL 2
|
42
|
+
#define SETUP_MMAP_FAIL 3
|
43
43
|
#define SETUP_CPUINFO_FAIL 4
|
44
44
|
#define SETUP_NOT_RPI_FAIL 5
|
45
45
|
|
data/ext/rpi_gpio/common.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-2020 Nick Lowery
|
5
5
|
|
6
6
|
Copyright (c) 2013-2014 Ben Croston
|
7
7
|
|
@@ -47,8 +47,7 @@ int check_gpio_priv(void)
|
|
47
47
|
// check mmap setup has worked
|
48
48
|
if (!module_setup)
|
49
49
|
{
|
50
|
-
rb_raise(rb_eRuntimeError, "no access to /dev/mem. Try "
|
51
|
-
"running as root!");
|
50
|
+
rb_raise(rb_eRuntimeError, "no access to /dev/mem. Try running as root!");
|
52
51
|
return 2;
|
53
52
|
}
|
54
53
|
return 0;
|
@@ -67,10 +66,8 @@ int get_gpio_number(int channel, unsigned int *gpio)
|
|
67
66
|
|
68
67
|
// check channel number is in range
|
69
68
|
if ( (gpio_mode == BCM && (channel < 0 || channel > 53))
|
70
|
-
|| (gpio_mode == BOARD && (channel < 1 || channel > 26) &&
|
71
|
-
|
72
|
-
|| (gpio_mode == BOARD && (channel < 1 || channel > 40) &&
|
73
|
-
rpiinfo.p1_revision == 3))
|
69
|
+
|| (gpio_mode == BOARD && (channel < 1 || channel > 26) && rpiinfo.p1_revision != 3)
|
70
|
+
|| (gpio_mode == BOARD && (channel < 1 || channel > 40) && rpiinfo.p1_revision == 3) )
|
74
71
|
{
|
75
72
|
rb_raise(rb_eArgError, "the channel sent is invalid on a Raspberry Pi");
|
76
73
|
return 4;
|
@@ -81,8 +78,7 @@ int get_gpio_number(int channel, unsigned int *gpio)
|
|
81
78
|
{
|
82
79
|
if (*(*pin_to_gpio+channel) == -1)
|
83
80
|
{
|
84
|
-
rb_raise(rb_eArgError, "the channel sent is invalid on a Raspberry "
|
85
|
-
"Pi");
|
81
|
+
rb_raise(rb_eArgError, "the channel sent is invalid on a Raspberry Pi");
|
86
82
|
return 5;
|
87
83
|
} else {
|
88
84
|
*gpio = *(*pin_to_gpio+channel);
|
data/ext/rpi_gpio/common.h
CHANGED
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-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
|
@@ -24,9 +24,15 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
24
|
SOFTWARE.
|
25
25
|
*/
|
26
26
|
|
27
|
+
/* See the following for up to date information:
|
28
|
+
* https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
|
29
|
+
*/
|
30
|
+
|
27
31
|
#include <stdio.h>
|
32
|
+
#include <stdint.h>
|
28
33
|
#include <stdlib.h>
|
29
34
|
#include <string.h>
|
35
|
+
#include <arpa/inet.h>
|
30
36
|
#include "cpuinfo.h"
|
31
37
|
|
32
38
|
int get_rpi_info(rpi_info *info)
|
@@ -35,24 +41,33 @@ int get_rpi_info(rpi_info *info)
|
|
35
41
|
char buffer[1024];
|
36
42
|
char hardware[1024];
|
37
43
|
char revision[1024];
|
38
|
-
char *rev;
|
39
44
|
int found = 0;
|
40
45
|
int len;
|
41
46
|
|
42
|
-
if ((fp = fopen("/proc/
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
if (strcmp(hardware, "BCM2708") == 0 ||
|
48
|
-
strcmp(hardware, "BCM2709") == 0 ||
|
49
|
-
strcmp(hardware, "BCM2835") == 0 ||
|
50
|
-
strcmp(hardware, "BCM2836") == 0 ||
|
51
|
-
strcmp(hardware, "BCM2837") == 0 ) {
|
52
|
-
found = 1;
|
47
|
+
if ((fp = fopen("/proc/device-tree/system/linux,revision", "r"))) {
|
48
|
+
uint32_t n;
|
49
|
+
if (fread(&n, sizeof(n), 1, fp) != 1) {
|
50
|
+
fclose(fp);
|
51
|
+
return -1;
|
53
52
|
}
|
54
|
-
|
53
|
+
sprintf(revision, "%x", ntohl(n));
|
54
|
+
found = 1;
|
55
55
|
}
|
56
|
+
else if ((fp = fopen("/proc/cpuinfo", "r"))) {
|
57
|
+
while(!feof(fp) && fgets(buffer, sizeof(buffer), fp)) {
|
58
|
+
sscanf(buffer, "Hardware : %s", hardware);
|
59
|
+
if (strcmp(hardware, "BCM2708") == 0 ||
|
60
|
+
strcmp(hardware, "BCM2709") == 0 ||
|
61
|
+
strcmp(hardware, "BCM2835") == 0 ||
|
62
|
+
strcmp(hardware, "BCM2836") == 0 ||
|
63
|
+
strcmp(hardware, "BCM2837") == 0 ) {
|
64
|
+
found = 1;
|
65
|
+
}
|
66
|
+
sscanf(buffer, "Revision : %s", revision);
|
67
|
+
}
|
68
|
+
}
|
69
|
+
else
|
70
|
+
return -1;
|
56
71
|
fclose(fp);
|
57
72
|
|
58
73
|
if (!found)
|
@@ -65,36 +80,56 @@ int get_rpi_info(rpi_info *info)
|
|
65
80
|
// new scheme
|
66
81
|
//info->rev = revision[len-1]-'0';
|
67
82
|
strcpy(info->revision, revision);
|
68
|
-
switch (revision[len-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
83
|
+
switch (revision[len-3]) {
|
84
|
+
case '0' :
|
85
|
+
switch (revision[len-2]) {
|
86
|
+
case '0': info->type = "Model A"; info->p1_revision = 2; break;
|
87
|
+
case '1': info->type = "Model B"; info->p1_revision = 2; break;
|
88
|
+
case '2': info->type = "Model A+"; info->p1_revision = 3; break;
|
89
|
+
case '3': info->type = "Model B+"; info->p1_revision = 3; break;
|
90
|
+
case '4': info->type = "Pi 2 Model B"; info->p1_revision = 3; break;
|
91
|
+
case '5': info->type = "Alpha"; info->p1_revision = 3; break;
|
92
|
+
case '6': info->type = "Compute Module 1"; info->p1_revision = 0; break;
|
93
|
+
case '8': info->type = "Pi 3 Model B"; info->p1_revision = 3; break;
|
94
|
+
case '9': info->type = "Zero"; info->p1_revision = 3; break;
|
95
|
+
case 'a': info->type = "Compute Module 3"; info->p1_revision = 0; break;
|
96
|
+
case 'c': info->type = "Zero W"; info->p1_revision = 3; break;
|
97
|
+
case 'd': info->type = "Pi 3 Model B+"; info->p1_revision = 3; break;
|
98
|
+
case 'e': info->type = "Pi 3 Model A+"; info->p1_revision = 3; break;
|
99
|
+
default : info->type = "Unknown"; info->p1_revision = 3; break;
|
100
|
+
} break;
|
101
|
+
case '1':
|
102
|
+
switch (revision[len-2]) {
|
103
|
+
case '0': info->type = "Compute Module 3+"; info->p1_revision = 0; break;
|
104
|
+
case '1': info->type = "Pi 4 Model B"; info->p1_revision = 3; break;
|
105
|
+
default : info->type = "Unknown"; info->p1_revision = 3; break;
|
106
|
+
} break;
|
107
|
+
default: info->type = "Unknown"; info->p1_revision = 3; break;
|
108
|
+
}
|
109
|
+
|
110
|
+
switch (revision[len-4]) {
|
111
|
+
case '0': info->processor = "BCM2835"; break;
|
112
|
+
case '1': info->processor = "BCM2836"; break;
|
113
|
+
case '2': info->processor = "BCM2837"; break;
|
114
|
+
case '3': info->processor = "BCM2711"; break;
|
115
|
+
default : info->processor = "Unknown"; break;
|
116
|
+
}
|
117
|
+
switch (revision[len-5]) {
|
118
|
+
case '0': info->manufacturer = "Sony"; break;
|
119
|
+
case '1': info->manufacturer = "Egoman"; break;
|
120
|
+
case '2': info->manufacturer = "Embest"; break;
|
121
|
+
case '3': info->manufacturer = "Sony Japan"; break;
|
122
|
+
case '4': info->manufacturer = "Embest"; break;
|
123
|
+
case '5': info->manufacturer = "Stadium"; break;
|
124
|
+
default : info->manufacturer = "Unknown"; break;
|
125
|
+
}
|
126
|
+
switch (strtol((char[]){revision[len-6],0}, NULL, 16) & 7) {
|
127
|
+
case 0: info->ram = "256M"; break;
|
128
|
+
case 1: info->ram = "512M"; break;
|
129
|
+
case 2: info->ram = "1G"; break;
|
130
|
+
case 3: info->ram = "2G"; break;
|
131
|
+
case 4: info->ram = "4G"; break;
|
132
|
+
default: info->ram = "Unknown"; break;
|
98
133
|
}
|
99
134
|
} else {
|
100
135
|
// old scheme
|
@@ -104,88 +139,105 @@ int get_rpi_info(rpi_info *info)
|
|
104
139
|
info->type = "Unknown";
|
105
140
|
strcpy(info->revision, revision);
|
106
141
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
else
|
111
|
-
rev = revision;
|
142
|
+
uint64_t rev;
|
143
|
+
sscanf(revision, "%llx", &rev);
|
144
|
+
rev = rev & 0xefffffff; // ignore preceeding 1000 for overvolt
|
112
145
|
|
113
|
-
if (
|
114
|
-
(strcmp(rev, "0003") == 0)) {
|
146
|
+
if (rev == 0x0002 || rev == 0x0003) {
|
115
147
|
info->type = "Model B";
|
116
148
|
info->p1_revision = 1;
|
117
149
|
info->ram = "256M";
|
150
|
+
info->manufacturer = "Egoman";
|
118
151
|
info->processor = "BCM2835";
|
119
|
-
} else if (
|
152
|
+
} else if (rev == 0x0004) {
|
120
153
|
info->type = "Model B";
|
121
154
|
info->p1_revision = 2;
|
122
155
|
info->ram = "256M";
|
123
|
-
info->manufacturer = "Sony";
|
156
|
+
info->manufacturer = "Sony UK";
|
124
157
|
info->processor = "BCM2835";
|
125
|
-
} else if (
|
158
|
+
} else if (rev == 0x0005) {
|
126
159
|
info->type = "Model B";
|
127
160
|
info->p1_revision = 2;
|
128
161
|
info->ram = "256M";
|
129
162
|
info->manufacturer = "Qisda";
|
130
163
|
info->processor = "BCM2835";
|
131
|
-
} else if (
|
164
|
+
} else if (rev == 0x0006) {
|
132
165
|
info->type = "Model B";
|
133
166
|
info->p1_revision = 2;
|
134
167
|
info->ram = "256M";
|
135
168
|
info->manufacturer = "Egoman";
|
136
169
|
info->processor = "BCM2835";
|
137
|
-
} else if (
|
170
|
+
} else if (rev == 0x0007) {
|
138
171
|
info->type = "Model A";
|
139
172
|
info->p1_revision = 2;
|
140
173
|
info->ram = "256M";
|
141
174
|
info->manufacturer = "Egoman";
|
142
175
|
info->processor = "BCM2835";
|
143
|
-
} else if (
|
176
|
+
} else if (rev == 0x0008) {
|
144
177
|
info->type = "Model A";
|
145
178
|
info->p1_revision = 2;
|
146
179
|
info->ram = "256M";
|
147
|
-
info->manufacturer = "Sony";
|
180
|
+
info->manufacturer = "Sony UK";
|
148
181
|
info->processor = "BCM2835";
|
149
|
-
} else if (
|
182
|
+
} else if (rev == 0x0009) {
|
150
183
|
info->type = "Model A";
|
151
184
|
info->p1_revision = 2;
|
152
185
|
info->ram = "256M";
|
153
186
|
info->manufacturer = "Qisda";
|
154
187
|
info->processor = "BCM2835";
|
155
|
-
} else if (
|
188
|
+
} else if (rev == 0x000d) {
|
156
189
|
info->type = "Model B";
|
157
190
|
info->p1_revision = 2;
|
158
191
|
info->ram = "512M";
|
159
192
|
info->manufacturer = "Egoman";
|
160
193
|
info->processor = "BCM2835";
|
161
|
-
} else if (
|
194
|
+
} else if (rev == 0x000e) {
|
162
195
|
info->type = "Model B";
|
163
196
|
info->p1_revision = 2;
|
164
197
|
info->ram = "512M";
|
165
|
-
info->manufacturer = "Sony";
|
198
|
+
info->manufacturer = "Sony UK";
|
166
199
|
info->processor = "BCM2835";
|
167
|
-
} else if (
|
200
|
+
} else if (rev == 0x000f) {
|
168
201
|
info->type = "Model B";
|
169
202
|
info->p1_revision = 2;
|
170
203
|
info->ram = "512M";
|
171
204
|
info->manufacturer = "Qisda";
|
172
205
|
info->processor = "BCM2835";
|
173
|
-
} else if (
|
174
|
-
|
175
|
-
info->
|
206
|
+
} else if (rev == 0x0010) {
|
207
|
+
info->type = "Model B+";
|
208
|
+
info->p1_revision = 3;
|
209
|
+
info->ram = "512M";
|
210
|
+
info->manufacturer = "Sony UK";
|
211
|
+
info->processor = "BCM2835";
|
212
|
+
} else if (rev == 0x0011) {
|
213
|
+
info->type = "Compute Module 1";
|
176
214
|
info->p1_revision = 0;
|
177
215
|
info->ram = "512M";
|
216
|
+
info->manufacturer = "Sony UK";
|
178
217
|
info->processor = "BCM2835";
|
179
|
-
} else if (
|
218
|
+
} else if (rev == 0x0012) {
|
180
219
|
info->type = "Model A+";
|
181
220
|
info->p1_revision = 3;
|
182
221
|
info->ram = "256M";
|
222
|
+
info->manufacturer = "Sony UK";
|
183
223
|
info->processor = "BCM2835";
|
184
|
-
} else if (
|
185
|
-
(strcmp(rev, "0013") == 0)) {
|
224
|
+
} else if (rev == 0x0013) {
|
186
225
|
info->type = "Model B+";
|
187
226
|
info->p1_revision = 3;
|
188
227
|
info->ram = "512M";
|
228
|
+
info->manufacturer = "Embest";
|
229
|
+
info->processor = "BCM2835";
|
230
|
+
} else if (rev == 0x0014) {
|
231
|
+
info->type = "Compute Module 1";
|
232
|
+
info->p1_revision = 0;
|
233
|
+
info->ram = "512M";
|
234
|
+
info->manufacturer = "Embest";
|
235
|
+
info->processor = "BCM2835";
|
236
|
+
} else if (rev == 0x0015) {
|
237
|
+
info->type = "Model A+";
|
238
|
+
info->p1_revision = 3;
|
239
|
+
info->ram = "Unknown";
|
240
|
+
info->manufacturer = "Embest";
|
189
241
|
info->processor = "BCM2835";
|
190
242
|
} else { // don't know - assume revision 3 p1 connector
|
191
243
|
info->p1_revision = 3;
|
data/ext/rpi_gpio/cpuinfo.h
CHANGED
@@ -3,7 +3,7 @@ Original code by Ben Croston modified for Ruby by Nick Lowery
|
|
3
3
|
(github.com/clockvapor)
|
4
4
|
Copyright (c) 2014-2016 Nick Lowery
|
5
5
|
|
6
|
-
Copyright (c)
|
6
|
+
Copyright (c) 2012-2015 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/event_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) 2013-
|
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
|
@@ -28,6 +28,7 @@ SOFTWARE.
|
|
28
28
|
#include <sys/epoll.h>
|
29
29
|
#include <stdio.h>
|
30
30
|
#include <stdlib.h>
|
31
|
+
#include <errno.h>
|
31
32
|
#include <fcntl.h>
|
32
33
|
#include <unistd.h>
|
33
34
|
#include <string.h>
|
@@ -67,16 +68,34 @@ int epfd_thread = -1;
|
|
67
68
|
int epfd_blocking = -1;
|
68
69
|
|
69
70
|
/************* /sys/class/gpio functions ************/
|
71
|
+
#define x_write(fd, buf, len) do { \
|
72
|
+
size_t x_write_len = (len); \
|
73
|
+
\
|
74
|
+
if ((size_t)write((fd), (buf), x_write_len) != x_write_len) { \
|
75
|
+
close(fd); \
|
76
|
+
return (-1); \
|
77
|
+
} \
|
78
|
+
} while (/* CONSTCOND */ 0)
|
79
|
+
|
70
80
|
int gpio_export(unsigned int gpio)
|
71
81
|
{
|
72
82
|
int fd, len;
|
73
83
|
char str_gpio[3];
|
84
|
+
char filename[33];
|
74
85
|
|
75
|
-
|
86
|
+
snprintf(filename, sizeof(filename), "/sys/class/gpio/gpio%d", gpio);
|
87
|
+
|
88
|
+
/* return if gpio already exported */
|
89
|
+
if (access(filename, F_OK) != -1) {
|
90
|
+
return 0;
|
91
|
+
}
|
92
|
+
|
93
|
+
if ((fd = open("/sys/class/gpio/export", O_WRONLY)) < 0) {
|
76
94
|
return -1;
|
95
|
+
}
|
77
96
|
|
78
97
|
len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio);
|
79
|
-
|
98
|
+
x_write(fd, str_gpio, len);
|
80
99
|
close(fd);
|
81
100
|
|
82
101
|
return 0;
|
@@ -91,7 +110,7 @@ int gpio_unexport(unsigned int gpio)
|
|
91
110
|
return -1;
|
92
111
|
|
93
112
|
len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio);
|
94
|
-
|
113
|
+
x_write(fd, str_gpio, len);
|
95
114
|
close(fd);
|
96
115
|
|
97
116
|
return 0;
|
@@ -114,15 +133,13 @@ int gpio_set_direction(unsigned int gpio, unsigned int in_flag)
|
|
114
133
|
break;
|
115
134
|
nanosleep(&delay, NULL);
|
116
135
|
}
|
117
|
-
if (retry >= 100)
|
136
|
+
if (retry >= 100)
|
118
137
|
return -1;
|
119
|
-
}
|
120
138
|
|
121
|
-
if (in_flag)
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
}
|
139
|
+
if (in_flag)
|
140
|
+
x_write(fd, "in", 3);
|
141
|
+
else
|
142
|
+
x_write(fd, "out", 4);
|
126
143
|
|
127
144
|
close(fd);
|
128
145
|
return 0;
|
@@ -138,7 +155,7 @@ int gpio_set_edge(unsigned int gpio, unsigned int edge)
|
|
138
155
|
if ((fd = open(filename, O_WRONLY)) < 0)
|
139
156
|
return -1;
|
140
157
|
|
141
|
-
|
158
|
+
x_write(fd, stredge[edge], strlen(stredge[edge]) + 1);
|
142
159
|
close(fd);
|
143
160
|
return 0;
|
144
161
|
}
|
@@ -223,7 +240,6 @@ struct gpios *new_gpio(unsigned int gpio)
|
|
223
240
|
void delete_gpio(unsigned int gpio)
|
224
241
|
{
|
225
242
|
struct gpios *g = gpio_list;
|
226
|
-
struct gpios *temp;
|
227
243
|
struct gpios *prev = NULL;
|
228
244
|
|
229
245
|
while (g != NULL) {
|
@@ -232,9 +248,7 @@ void delete_gpio(unsigned int gpio)
|
|
232
248
|
gpio_list = g->next;
|
233
249
|
else
|
234
250
|
prev->next = g->next;
|
235
|
-
|
236
|
-
g = g->next;
|
237
|
-
free(temp);
|
251
|
+
free(g);
|
238
252
|
return;
|
239
253
|
} else {
|
240
254
|
prev = g;
|
@@ -337,10 +351,7 @@ void *poll_thread(void *threadarg)
|
|
337
351
|
|
338
352
|
thread_running = 1;
|
339
353
|
while (thread_running) {
|
340
|
-
|
341
|
-
thread_running = 0;
|
342
|
-
pthread_exit(NULL);
|
343
|
-
}
|
354
|
+
n = epoll_wait(epfd_thread, &events, 1, -1);
|
344
355
|
if (n > 0) {
|
345
356
|
lseek(events.data.fd, 0, SEEK_SET);
|
346
357
|
if (read(events.data.fd, &buf, 1) != 1) {
|
@@ -353,12 +364,21 @@ void *poll_thread(void *threadarg)
|
|
353
364
|
} else {
|
354
365
|
gettimeofday(&tv_timenow, NULL);
|
355
366
|
timenow = tv_timenow.tv_sec*1E6 + tv_timenow.tv_usec;
|
356
|
-
if (g->bouncetime == -666 || timenow - g->lastcall > g->bouncetime*1000 || g->lastcall == 0 || g->lastcall > timenow) {
|
367
|
+
if (g->bouncetime == -666 || timenow - g->lastcall > (unsigned int)g->bouncetime*1000 || g->lastcall == 0 || g->lastcall > timenow) {
|
357
368
|
g->lastcall = timenow;
|
358
369
|
event_occurred[g->gpio] = 1;
|
359
370
|
run_callbacks(g->gpio);
|
360
371
|
}
|
361
372
|
}
|
373
|
+
} else if (n == -1) {
|
374
|
+
/* If a signal is received while we are waiting,
|
375
|
+
epoll_wait will return with an EINTR error.
|
376
|
+
Just try again in that case. */
|
377
|
+
if (errno == EINTR) {
|
378
|
+
continue;
|
379
|
+
}
|
380
|
+
thread_running = 0;
|
381
|
+
pthread_exit(NULL);
|
362
382
|
}
|
363
383
|
}
|
364
384
|
thread_running = 0;
|
@@ -406,26 +426,29 @@ int event_detected(unsigned int gpio)
|
|
406
426
|
}
|
407
427
|
}
|
408
428
|
|
409
|
-
void event_cleanup(
|
429
|
+
void event_cleanup(int gpio)
|
410
430
|
// gpio of -666 means clean every channel used
|
411
431
|
{
|
412
432
|
struct gpios *g = gpio_list;
|
413
|
-
struct gpios *
|
433
|
+
struct gpios *next_gpio = NULL;
|
414
434
|
|
415
435
|
while (g != NULL) {
|
416
|
-
|
417
|
-
|
436
|
+
next_gpio = g->next;
|
437
|
+
if ((gpio == -666) || ((int)g->gpio == gpio))
|
418
438
|
remove_edge_detect(g->gpio);
|
419
|
-
|
439
|
+
g = next_gpio;
|
420
440
|
}
|
421
|
-
if (gpio_list == NULL)
|
422
|
-
if (epfd_blocking != -1)
|
441
|
+
if (gpio_list == NULL) {
|
442
|
+
if (epfd_blocking != -1) {
|
423
443
|
close(epfd_blocking);
|
424
444
|
epfd_blocking = -1;
|
425
|
-
|
445
|
+
}
|
446
|
+
if (epfd_thread != -1) {
|
426
447
|
close(epfd_thread);
|
427
448
|
epfd_thread = -1;
|
449
|
+
}
|
428
450
|
thread_running = 0;
|
451
|
+
}
|
429
452
|
}
|
430
453
|
|
431
454
|
void event_cleanup_all(void)
|
@@ -447,13 +470,14 @@ int add_edge_detect(unsigned int gpio, unsigned int edge, int bouncetime)
|
|
447
470
|
|
448
471
|
i = gpio_event_added(gpio);
|
449
472
|
if (i == 0) { // event not already added
|
450
|
-
if ((g = new_gpio(gpio)) == NULL)
|
473
|
+
if ((g = new_gpio(gpio)) == NULL) {
|
451
474
|
return 2;
|
475
|
+
}
|
452
476
|
|
453
477
|
gpio_set_edge(gpio, edge);
|
454
478
|
g->edge = edge;
|
455
479
|
g->bouncetime = bouncetime;
|
456
|
-
} else if (i == edge) { // get existing event
|
480
|
+
} else if (i == (int)edge) { // get existing event
|
457
481
|
g = get_gpio(gpio);
|
458
482
|
if ((bouncetime != -666 && g->bouncetime != bouncetime) || // different event bouncetime used
|
459
483
|
(g->thread_added)) // event already added
|
@@ -501,13 +525,12 @@ int blocking_wait_for_edge(unsigned int gpio, unsigned int edge, int bouncetime,
|
|
501
525
|
int finished = 0;
|
502
526
|
int initial_edge = 1;
|
503
527
|
|
504
|
-
if (callback_exists(gpio))
|
528
|
+
if (callback_exists(gpio))
|
505
529
|
return -1;
|
506
|
-
}
|
507
530
|
|
508
531
|
// add gpio if it has not been added already
|
509
532
|
ed = gpio_event_added(gpio);
|
510
|
-
if (ed == edge) { // get existing record
|
533
|
+
if (ed == (int)edge) { // get existing record
|
511
534
|
g = get_gpio(gpio);
|
512
535
|
if (g->bouncetime != -666 && g->bouncetime != bouncetime) {
|
513
536
|
return -1;
|
@@ -541,16 +564,23 @@ int blocking_wait_for_edge(unsigned int gpio, unsigned int edge, int bouncetime,
|
|
541
564
|
|
542
565
|
// wait for edge
|
543
566
|
while (!finished) {
|
544
|
-
|
567
|
+
n = epoll_wait(epfd_blocking, &events, 1, timeout);
|
568
|
+
if (n == -1) {
|
569
|
+
/* If a signal is received while we are waiting,
|
570
|
+
epoll_wait will return with an EINTR error.
|
571
|
+
Just try again in that case. */
|
572
|
+
if (errno == EINTR) {
|
573
|
+
continue;
|
574
|
+
}
|
545
575
|
epoll_ctl(epfd_blocking, EPOLL_CTL_DEL, g->value_fd, &ev);
|
546
576
|
return -2;
|
547
577
|
}
|
548
|
-
if (initial_edge) {
|
578
|
+
if (initial_edge) { // first time triggers with current state, so ignore
|
549
579
|
initial_edge = 0;
|
550
580
|
} else {
|
551
581
|
gettimeofday(&tv_timenow, NULL);
|
552
582
|
timenow = tv_timenow.tv_sec*1E6 + tv_timenow.tv_usec;
|
553
|
-
if (g->bouncetime == -666 || timenow - g->lastcall > g->bouncetime*1000 || g->lastcall == 0 || g->lastcall > timenow) {
|
583
|
+
if (g->bouncetime == -666 || timenow - g->lastcall > (unsigned int)g->bouncetime*1000 || g->lastcall == 0 || g->lastcall > timenow) {
|
554
584
|
g->lastcall = timenow;
|
555
585
|
finished = 1;
|
556
586
|
}
|