chip-gpio 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/chip-gpio/Pin.rb +113 -4
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f903c553740c40251896f7771c0237eee77771f
|
4
|
+
data.tar.gz: e6ab168e83e807f875925289aaa35ceebdb0fa46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2cddb6c9c50672b87df47248af15634242f226d0275eb57c6d362358b9d732f08c503001eab4557f0020383c2b0c0e6b19526386bc8b6bc41666b28db73f8ba
|
7
|
+
data.tar.gz: 5ef453d94969e0c611bc8b828bc34dba82ea1ad1573c45d6560f2ad6aa68ba0f68ac6804b977980c9928ccb3a381758022bea28c9a33e16d06acd5a785296912
|
data/lib/chip-gpio/Pin.rb
CHANGED
@@ -1,11 +1,24 @@
|
|
1
|
+
require 'epoll'
|
2
|
+
|
1
3
|
module ChipGPIO
|
2
4
|
module Pin
|
3
5
|
class Pin
|
4
6
|
attr_reader :gpio_number
|
7
|
+
attr_reader :pin_name
|
5
8
|
|
6
|
-
def initialize(gpio_number)
|
9
|
+
def initialize(gpio_number, pin_name)
|
7
10
|
@gpio_number = gpio_number
|
11
|
+
@pin_name = pin_name
|
8
12
|
@base_path = "/sys/class/gpio/gpio#{@gpio_number}"
|
13
|
+
|
14
|
+
@interrupt_thread = nil
|
15
|
+
@stop_waiting = false
|
16
|
+
@stop_waiting_lock = Mutex.new
|
17
|
+
|
18
|
+
@interrupt_procs = []
|
19
|
+
@interrupt_procs_lock = Mutex.new
|
20
|
+
|
21
|
+
@interrupt_pipe_read, @interrupt_pipe_write = IO.pipe()
|
9
22
|
end
|
10
23
|
|
11
24
|
def available?
|
@@ -45,6 +58,52 @@ module ChipGPIO
|
|
45
58
|
File.open("#{@base_path}/direction", "w") { |f| f.write(v) }
|
46
59
|
end
|
47
60
|
|
61
|
+
def edge
|
62
|
+
v = File.read("#{@base_path}/edge").strip
|
63
|
+
case v
|
64
|
+
when "both"
|
65
|
+
return :both
|
66
|
+
when "rising"
|
67
|
+
return :rising
|
68
|
+
when "falling"
|
69
|
+
return :falling
|
70
|
+
else
|
71
|
+
throw "Unexpected edge #{v}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def edge=(e)
|
76
|
+
case e
|
77
|
+
when :both
|
78
|
+
v = "both"
|
79
|
+
when :rising
|
80
|
+
v = "rising"
|
81
|
+
when :falling
|
82
|
+
v = "falling"
|
83
|
+
else
|
84
|
+
throw "Unexpected edge: #{e}; must be :both, :rising, or :falling"
|
85
|
+
end
|
86
|
+
|
87
|
+
File.open("#{@base_path}/edge", "w") { |f| f.write(v) }
|
88
|
+
end
|
89
|
+
|
90
|
+
def active_low
|
91
|
+
v = File.read("#{@base_path}/active_low").strip
|
92
|
+
case v
|
93
|
+
when "0"
|
94
|
+
return false
|
95
|
+
when "1"
|
96
|
+
return true
|
97
|
+
else
|
98
|
+
throw "Unexpectd active_low: #{v}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def active_low=(b)
|
103
|
+
v = !!b ? "1" : "0"
|
104
|
+
File.open("#{@base_path}/active_low", "w") { |f| f.write(v) }
|
105
|
+
end
|
106
|
+
|
48
107
|
def value
|
49
108
|
throw "Pin is not currently available" if !self.available?
|
50
109
|
|
@@ -63,8 +122,58 @@ module ChipGPIO
|
|
63
122
|
v = v.to_s
|
64
123
|
File.open("#{@base_path}/value", "w") { |f| f.write(v) }
|
65
124
|
end
|
66
|
-
end
|
67
125
|
|
126
|
+
def on_interrupt(&proc)
|
127
|
+
return if !proc
|
128
|
+
throw "Interrupt is only valid for input pins" if direction != :input
|
129
|
+
|
130
|
+
@interrupt_procs_lock.synchronize { @interrupt_procs << proc }
|
131
|
+
|
132
|
+
if !@interrupt_thread
|
133
|
+
@interrupt_thread = Thread.new("#{@base_path}/value") do |pin_path|
|
134
|
+
|
135
|
+
fd = open(pin_path, 'r')
|
136
|
+
|
137
|
+
epoll = Epoll.create()
|
138
|
+
epoll.add(fd, Epoll::PRI)
|
139
|
+
epoll.add(@interrupt_pipe_read, Epoll::IN)
|
140
|
+
|
141
|
+
#read the value once before polling
|
142
|
+
fd.seek(0)
|
143
|
+
fd.read()
|
144
|
+
|
145
|
+
while true
|
146
|
+
stop = false
|
147
|
+
@stop_waiting_lock.synchronize { stop = @stop_waiting }
|
148
|
+
break if stop
|
149
|
+
|
150
|
+
evlist = epoll.wait()
|
151
|
+
|
152
|
+
evlist.each do |ev|
|
153
|
+
|
154
|
+
if ev.data.fileno == fd.fileno
|
155
|
+
ev.data.seek(0)
|
156
|
+
value = ev.data.read().delete("\n")
|
157
|
+
|
158
|
+
procs = []
|
159
|
+
@interrupt_procs_lock.synchronize { procs = @interrupt_procs.dup() }
|
160
|
+
|
161
|
+
procs.each { |p| p.call(value) }
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def cancel_interrupt()
|
170
|
+
@stop_waiting_lock.synchronize { @stop_waiting = true }
|
171
|
+
@interrupt_pipe_write.write("0")
|
172
|
+
@interrupt_thread.join()
|
173
|
+
@interrupt_thread = nil
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
68
177
|
end
|
69
178
|
|
70
179
|
def self.get_xio_base
|
@@ -91,8 +200,8 @@ module ChipGPIO
|
|
91
200
|
|
92
201
|
pins = {}
|
93
202
|
|
94
|
-
cis.each_with_index { |gpio, index|
|
95
|
-
xio.each_with_index { |gpio, index|
|
203
|
+
cis.each_with_index { |gpio, index| sym = "CSI#{index}".to_sym; pins[sym] = Pin::Pin.new(gpio, sym) }
|
204
|
+
xio.each_with_index { |gpio, index| sym = "XIO#{index}".to_sym; pins[sym] = Pin::Pin.new(gpio, sym) }
|
96
205
|
|
97
206
|
return pins
|
98
207
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chip-gpio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
12
|
-
dependencies:
|
11
|
+
date: 2017-01-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: epoll
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
description: A ruby gem to control the IO hardware the CHIP computer
|
14
28
|
email: james@jameswilliams.me
|
15
29
|
executables: []
|