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 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
+ ![TitleImage](img/led_anim.gif) >> [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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GPIO
4
+ VERSION = "0.9.0"
5
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "sysfs/version"
4
+ require_relative "sysfs/gpio_sysfs"
data/lib/mruby/gpio.rb ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "gpio/sysfs"
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: []