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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cf2e5fe321ddea6602db36bf081dcdd9b16d1248a584c9fe2156cf3b1cc8764b
4
- data.tar.gz: aea0df6d2ce23b6b60ffdd35a1a856c09920fda38dfdcc197f4d38b417129935
3
+ metadata.gz: e85a39df6149e36f76739cbb642208a635cc20fa3a7e201ea0207c2070fc4765
4
+ data.tar.gz: 36b825467b90ebe19c1bcd431847bbc596ea94fdd31e7c5b99fdda31f3efc87c
5
5
  SHA512:
6
- metadata.gz: e2d50e340b0d24349c291b4927fa4bc03e3c477862659a4b6a4f81c5a6c10a94e612e70acef98299627fc299f53cad68f15606b9795b610af1e82d559face6d3
7
- data.tar.gz: f6495cbea95ddfe0348bd9be92d716d4929329414ef49d6d6649a373f87af4a62346d1fe74631771de24a066b3b7bfcb1335efda76bda8dbd934e5d1eab644de
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-2020 Nick Lowery
4
- Copyright (c) 2012-2014 Ben Croston
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.4.0
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.0, so it works on all Raspberry Pi models!
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
- You can use the additional hash argument `:pull` to apply a pull-up or pull-down resistor to the input pin like so:
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.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
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-2020 [Nick Lowery](https://github.com/ClockVapor)
183
+ Copyright (c) 2014-2026 [Nick Lowery](https://github.com/ClockVapor)
143
184
 
144
185
  View LICENSE for full license.
145
186
 
@@ -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-2020 Nick Lowery
4
+ Copyright (c) 2014-2026 Nick Lowery
5
5
 
6
- Copyright (c) 2012-2019 Ben Croston
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
- unsigned char buf[4];
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
- // determine peri_base
94
- if ((fp = fopen("/proc/device-tree/soc/ranges", "rb")) != NULL) {
97
+ if ((fp = fopen("/proc/device-tree/soc/ranges", "rb")) != NULL)
98
+ {
95
99
  // get peri base from device tree
96
- fseek(fp, 4, SEEK_SET);
97
- if (fread(buf, 1, sizeof buf, fp) == sizeof buf) {
98
- peri_base = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3] << 0;
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
- } else {
102
- // guess peri base based on /proc/cpuinfo hardware field
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
- found = 1;
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 SETUP_NOT_RPI_FAIL;
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
@@ -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-2020 Nick Lowery
4
+ Copyright (c) 2014-2026 Nick Lowery
5
5
 
6
- Copyright (c) 2013-2015 Ben Croston
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 SETUP_NOT_RPI_FAIL 5
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!
@@ -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-2020 Nick Lowery
4
+ Copyright (c) 2014-2026 Nick Lowery
5
5
 
6
- Copyright (c) 2013-2014 Ben Croston
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. Try running as root!");
53
+ rb_raise(rb_eRuntimeError, "no access to /dev/mem. try running as root!");
51
54
  return 2;
52
55
  }
53
56
  return 0;
@@ -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-2020 Nick Lowery
4
+ Copyright (c) 2014-2026 Nick Lowery
5
5
 
6
- Copyright (c) 2013-2015 Ben Croston
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);
@@ -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-2020 Nick Lowery
4
+ Copyright (c) 2014-2026 Nick Lowery
5
5
 
6
- Copyright (c) 2012-2019 Ben Croston
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
- * https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
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 {
@@ -1,5 +1,3 @@
1
1
  require 'mkmf'
2
2
 
3
- extension_name = 'rpi_gpio'
4
- dir_config(extension_name)
5
- create_makefile(extension_name)
3
+ create_makefile 'rpi_gpio/rpi_gpio'
@@ -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-2020 Nick Lowery
4
+ Copyright (c) 2014-2026 Nick Lowery
5
5
 
6
- Copyright (c) 2012-2016 Ben Croston
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 == SETUP_NOT_RPI_FAIL) {
101
- rb_raise(rb_eRuntimeError, "not running on a RPi");
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
- chan = NUM2INT(rb_ary_entry(channel_list, i));
396
- if (get_gpio_number(chan, &gpio) || !is_gpio_output(gpio) || check_gpio_priv()) {
397
- return Qnil;
398
- } else {
399
- output_gpio(gpio, 1);
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
- unsigned int gpio;
410
- int chan = -1;
411
- VALUE channel_list = _extract_channels(channel);
412
- int chan_count = RARRAY_LEN(channel_list);
413
-
414
- for (int i = 0; i < chan_count; i++) {
415
- chan = NUM2INT(rb_ary_entry(channel_list, i));
416
- if (get_gpio_number(chan, &gpio) || !is_gpio_output(gpio) || check_gpio_priv()) {
417
- return Qnil;
418
- } else {
419
- output_gpio(gpio, 0);
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
+ }
@@ -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);
@@ -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-2015 Nick Lowery
4
+ Copyright (c) 2014-2026 Nick Lowery
5
5
 
6
- Copyright (c) 2013-2014 Ben Croston
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
@@ -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-2015 Nick Lowery
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();
@@ -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-2020 Nick Lowery
4
+ Copyright (c) 2014-2026 Nick Lowery
5
5
 
6
- Copyright (c) 2013-2018 Ben Croston
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)