mruby-sysfs-gpio 0.9.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 +7 -0
- data/LICENSE +28 -0
- data/README.md +48 -0
- data/lib/mruby/gpio/sysfs/gpio_sysfs.rb +309 -0
- data/lib/mruby/gpio/sysfs/version.rb +5 -0
- data/lib/mruby/gpio/sysfs.rb +4 -0
- data/lib/mruby/gpio.rb +3 -0
- metadata +51 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0f1089ddaf2fac2419d96329266191f95fa186ce6874c413ec760ce613cea778
|
4
|
+
data.tar.gz: dbf651b91a38c20574400416d68927b453337acf658869b178eeef63dab0918d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bc9b8550ef886b679203cf5cd129cae6e3a56593c2fd4205ce9c0cbee68fb98411e0083aaaf2a512d51f401dfea87f9a2b54ab9da78bf056cfbfc03b5179af05
|
7
|
+
data.tar.gz: 3752775990083bc49c7a28fcead23d017adcc8a28d7ceadf5d32f58d2809646cdfbced9b1d0933eae3d0e86174b8f5c89ca55dcb19b6a7fa6c84899fccfc1a5a
|
data/LICENSE
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
BSD 3-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2023, Shimane IT Open-Innovation Center.
|
4
|
+
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
7
|
+
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
13
|
+
and/or other materials provided with the distribution.
|
14
|
+
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
16
|
+
contributors may be used to endorse or promote products derived from
|
17
|
+
this software without specific prior written permission.
|
18
|
+
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# GPIO class using Linux sysfs.
|
2
|
+
|
3
|
+
 >> [source code](test/led5sw1_event.rb) / [schematic](img/led5sw1_schema.png)
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+
This is an implementation of the GPIO class library for Linux.
|
8
|
+
Follows [mruby, mruby/c common I/O API guidelines.](https://github.com/mruby/microcontroller-peripheral-interface-guide)
|
9
|
+
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
$ gem install mruby-sysfs-gpio
|
14
|
+
|
15
|
+
|
16
|
+
## Features
|
17
|
+
|
18
|
+
* Configure the pin as an input or output. (if hardware allows)
|
19
|
+
* Has an extension that allows you to define code to be executed when the input changes.
|
20
|
+
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
about RaspberryPi...
|
25
|
+
|
26
|
+
```
|
27
|
+
# Flash LED a.k.a. ElChika (in japanese)
|
28
|
+
# Connect Pin #37 (GPIO26) to LED.
|
29
|
+
|
30
|
+
require "mruby/gpio" # or "mruby/gpio/sysfs"
|
31
|
+
|
32
|
+
led = GPIO.new(26, GPIO::OUT)
|
33
|
+
while true
|
34
|
+
led.write( 1 )
|
35
|
+
sleep 1
|
36
|
+
led.write( 0 )
|
37
|
+
sleep 1
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
Other case, see original guidelines.
|
42
|
+
|
43
|
+
https://github.com/mruby/microcontroller-peripheral-interface-guide/blob/main/mruby_io_GPIO_en.md
|
44
|
+
|
45
|
+
|
46
|
+
## Licence
|
47
|
+
|
48
|
+
BSD 3-Clause License. see LICENSE file.
|
@@ -0,0 +1,309 @@
|
|
1
|
+
#
|
2
|
+
# GPIO class using Linux sysfs.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2023 Shimane IT Open-Innovation Center.
|
5
|
+
#
|
6
|
+
# see: LICENSE file.
|
7
|
+
# see: https://github.com/mruby/microcontroller-peripheral-interface-guide/blob/main/mruby_io_GPIO_en.md
|
8
|
+
#
|
9
|
+
# frozen_string_literal: true
|
10
|
+
#
|
11
|
+
|
12
|
+
##
|
13
|
+
# class GPIO
|
14
|
+
#
|
15
|
+
class GPIO
|
16
|
+
DRIVER = "sysfs"
|
17
|
+
|
18
|
+
# Constants
|
19
|
+
IN = 0b0000_0001
|
20
|
+
OUT = 0b0000_0010
|
21
|
+
HIGH_Z = 0b0000_0100
|
22
|
+
PULL_UP = 0b0000_1000
|
23
|
+
PULL_DOWN = 0b0001_0000
|
24
|
+
OPEN_DRAIN = 0b0010_0000
|
25
|
+
|
26
|
+
# extend
|
27
|
+
RISING = 0b0100_0000
|
28
|
+
FALLING = 0b1000_0000
|
29
|
+
BOTH = 0b1100_0000
|
30
|
+
UNUSED = 0b0000_0000
|
31
|
+
|
32
|
+
PATH_SYSFS = "/sys/class/gpio"
|
33
|
+
|
34
|
+
|
35
|
+
##
|
36
|
+
# set pin to use
|
37
|
+
#
|
38
|
+
#@param [Integer] pin pin number
|
39
|
+
#@!visibility private
|
40
|
+
#
|
41
|
+
def self._set_use( pin )
|
42
|
+
File.binwrite("#{PATH_SYSFS}/export", pin.to_s) rescue nil
|
43
|
+
10.times {
|
44
|
+
return if File.writable?("#{PATH_SYSFS}/gpio#{pin}/direction")
|
45
|
+
sleep 0.1
|
46
|
+
}
|
47
|
+
raise "Can't write SYSFS node"
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
##
|
52
|
+
# set pin to unused.
|
53
|
+
#
|
54
|
+
#@param [Integer] pin pin number
|
55
|
+
#@!visibility private
|
56
|
+
#
|
57
|
+
def self._set_unused( pin )
|
58
|
+
File.binwrite("#{PATH_SYSFS}/unexport", pin.to_s) rescue nil
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
##
|
63
|
+
# set in or out setting.
|
64
|
+
#
|
65
|
+
#@param [Integer] pin pin number
|
66
|
+
#@param [Constant] params modes
|
67
|
+
#@!visibility private
|
68
|
+
#
|
69
|
+
def self._set_dir( pin, params )
|
70
|
+
flag_retry = false
|
71
|
+
|
72
|
+
begin
|
73
|
+
case (params & (IN|OUT|HIGH_Z|OPEN_DRAIN))
|
74
|
+
when IN
|
75
|
+
File.binwrite("#{PATH_SYSFS}/gpio#{pin}/direction", "in")
|
76
|
+
return IN
|
77
|
+
when OUT
|
78
|
+
File.binwrite("#{PATH_SYSFS}/gpio#{pin}/direction", "out")
|
79
|
+
return OUT
|
80
|
+
when HIGH_Z, OPEN_DRAIN
|
81
|
+
raise ArgumentError, "Unsupported."
|
82
|
+
end
|
83
|
+
|
84
|
+
rescue Errno::ENOENT =>ex
|
85
|
+
raise ex if flag_retry
|
86
|
+
_set_use( pin )
|
87
|
+
flag_retry = true
|
88
|
+
retry
|
89
|
+
end
|
90
|
+
|
91
|
+
return nil
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
##
|
96
|
+
# set pull-up or pull-down
|
97
|
+
#
|
98
|
+
#@!visibility private
|
99
|
+
#
|
100
|
+
def self._set_pull( pin, params )
|
101
|
+
case (params & (PULL_UP|PULL_DOWN))
|
102
|
+
when PULL_UP, PULL_DOWN
|
103
|
+
raise "Unsupported."
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
##
|
109
|
+
# Specify the physical pin indicated by "pin" and change the mode of the GPIO.
|
110
|
+
#
|
111
|
+
#@param [Integer] pin pin number
|
112
|
+
#@param [Constant] params modes
|
113
|
+
#@return [nil]
|
114
|
+
#@raise [ArgumentError]
|
115
|
+
#
|
116
|
+
def self.setmode( pin, params )
|
117
|
+
if params == UNUSED
|
118
|
+
_set_unused( pin )
|
119
|
+
return nil
|
120
|
+
end
|
121
|
+
|
122
|
+
if ! _set_dir( pin, params )
|
123
|
+
raise ArgumentError, "You must specify one of IN, OUT and HIGH_Z"
|
124
|
+
end
|
125
|
+
|
126
|
+
_set_pull( pin, params )
|
127
|
+
|
128
|
+
return nil
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
##
|
133
|
+
# Returns the value read from the specified pin as either 0 or 1.
|
134
|
+
#
|
135
|
+
#@param [Integer] pin pin number
|
136
|
+
#@return [Integer]
|
137
|
+
#
|
138
|
+
def self.read_at( pin )
|
139
|
+
return File.binread("#{PATH_SYSFS}/gpio#{pin}/value", 10).to_i
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
##
|
144
|
+
# Return true If the value read from the specified pin is high (==1)
|
145
|
+
#
|
146
|
+
#@param [Integer] pin pin number
|
147
|
+
#@return [Boolean]
|
148
|
+
#
|
149
|
+
def self.high_at?( pin )
|
150
|
+
return read_at(pin) == 1
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
##
|
155
|
+
# Return true If the value read from the specified pin is low (==0)
|
156
|
+
#
|
157
|
+
#@param [Integer] pin pin number
|
158
|
+
#@return [Boolean]
|
159
|
+
#
|
160
|
+
def self.low_at?( pin )
|
161
|
+
return read_at(pin) == 0
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
##
|
166
|
+
# Output a value to the specified pin.
|
167
|
+
#
|
168
|
+
#@param [Integer] pin pin number
|
169
|
+
#@param [Integer] value data
|
170
|
+
#@return [void]
|
171
|
+
#
|
172
|
+
def self.write_at( pin, value )
|
173
|
+
case value
|
174
|
+
when 0,1
|
175
|
+
File.binwrite("#{PATH_SYSFS}/gpio#{pin}/value", value.to_s)
|
176
|
+
else
|
177
|
+
raise RangeError
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
##
|
183
|
+
# constructor
|
184
|
+
#
|
185
|
+
#@param [Integer] pin pin number
|
186
|
+
#@param [Constant] params modes
|
187
|
+
#
|
188
|
+
def initialize( pin, params )
|
189
|
+
@pin = pin
|
190
|
+
GPIO.setmode( pin, params )
|
191
|
+
@value = File.open("#{PATH_SYSFS}/gpio#{pin}/value", "r+:ASCII-8BIT")
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
##
|
196
|
+
# Return the loaded value as 0 or 1.
|
197
|
+
#
|
198
|
+
#@return [Integer]
|
199
|
+
#
|
200
|
+
def read()
|
201
|
+
@value.sysseek( 0 )
|
202
|
+
return @value.sysread( 10 ).to_i
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
##
|
207
|
+
# If the loaded value is high level (==1), it returns true.
|
208
|
+
#
|
209
|
+
#@return [Boolean]
|
210
|
+
#
|
211
|
+
def high?()
|
212
|
+
return read() == 1
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
##
|
217
|
+
# If the loaded value is low-level (==0), return true.
|
218
|
+
#
|
219
|
+
#@return [Boolean]
|
220
|
+
#
|
221
|
+
def low?()
|
222
|
+
return read() == 0
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
##
|
227
|
+
# Specify the value to output to the pin as either 0 or 1.
|
228
|
+
#
|
229
|
+
#@param [Integer] value
|
230
|
+
#@return [void]
|
231
|
+
#
|
232
|
+
def write( value )
|
233
|
+
@value.syswrite( value == 0 ? "0" : "1" )
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
##
|
238
|
+
# Change the GPIO mode at any timing.
|
239
|
+
#
|
240
|
+
#@param [Constant] params modes
|
241
|
+
#@return [nil]
|
242
|
+
#
|
243
|
+
def setmode( params )
|
244
|
+
if params == UNUSED
|
245
|
+
GPIO._set_unused( @pin )
|
246
|
+
return nil
|
247
|
+
end
|
248
|
+
|
249
|
+
GPIO._set_dir( @pin, params )
|
250
|
+
GPIO._set_pull( @pin, params )
|
251
|
+
|
252
|
+
return nil
|
253
|
+
end
|
254
|
+
|
255
|
+
|
256
|
+
##
|
257
|
+
# rising/falling edge event
|
258
|
+
# (extend)
|
259
|
+
#
|
260
|
+
#@param [Constant] edge GPIO::RISING, GPIO::FALLING or GPIO::BOTH
|
261
|
+
#@param [Integer] bounce_ms bounce time (milliseconds)
|
262
|
+
#@return [Thread] event thread.
|
263
|
+
#
|
264
|
+
#@example
|
265
|
+
# gpio.event( GPIO::RISING ) { puts "Rising UP." }
|
266
|
+
#
|
267
|
+
def event( edge, bounce_ms:50, &block )
|
268
|
+
if !@event_thread
|
269
|
+
File.binwrite("#{PATH_SYSFS}/gpio#{@pin}/edge", "both")
|
270
|
+
@bounce_time = bounce_ms / 1000.0
|
271
|
+
@events_rising = []
|
272
|
+
@events_falling = []
|
273
|
+
|
274
|
+
@value.sysseek( 0 )
|
275
|
+
v1 = @value.sysread( 10 ).to_i
|
276
|
+
|
277
|
+
@event_thread = Thread.new {
|
278
|
+
while true
|
279
|
+
@value.sysseek(0)
|
280
|
+
rs,ws,es = IO.select(nil, nil, [@value], 1)
|
281
|
+
|
282
|
+
sleep @bounce_time
|
283
|
+
v2 = @value.sysread(10).to_i
|
284
|
+
|
285
|
+
if v1 == 0 && v2 == 1
|
286
|
+
@events_rising.each {|event| event.call( v2 ) }
|
287
|
+
elsif v1 == 1 && v2 == 0
|
288
|
+
@events_falling.each {|event| event.call( v2 ) }
|
289
|
+
end
|
290
|
+
|
291
|
+
v1 = v2
|
292
|
+
end
|
293
|
+
}
|
294
|
+
end
|
295
|
+
|
296
|
+
case edge
|
297
|
+
when RISING
|
298
|
+
@events_rising << block
|
299
|
+
when FALLING
|
300
|
+
@events_falling << block
|
301
|
+
when BOTH
|
302
|
+
@events_rising << block
|
303
|
+
@events_falling << block
|
304
|
+
end
|
305
|
+
|
306
|
+
return @event_thread
|
307
|
+
end
|
308
|
+
|
309
|
+
end
|
data/lib/mruby/gpio.rb
ADDED
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mruby-sysfs-gpio
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- HirohitoHigashi
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-10-13 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
- higashi@s-itoc.jp
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- LICENSE
|
21
|
+
- README.md
|
22
|
+
- lib/mruby/gpio.rb
|
23
|
+
- lib/mruby/gpio/sysfs.rb
|
24
|
+
- lib/mruby/gpio/sysfs/gpio_sysfs.rb
|
25
|
+
- lib/mruby/gpio/sysfs/version.rb
|
26
|
+
homepage: https://github.com/HirohitoHigashi/mruby-mio/tree/main/mruby-sysfs-gpio
|
27
|
+
licenses:
|
28
|
+
- BSD 3-CLAUSE
|
29
|
+
metadata:
|
30
|
+
homepage_uri: https://github.com/HirohitoHigashi/mruby-mio/tree/main/mruby-sysfs-gpio
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 2.6.0
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
requirements: []
|
46
|
+
rubygems_version: 3.4.13
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: GPIO class library using Linux sysfs. compliant with mruby, mruby/c common
|
50
|
+
I/O API guidelines.
|
51
|
+
test_files: []
|