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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chip-gpio/Pin.rb +113 -4
  3. metadata +17 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a0aadd6093c95dca4fe6b0954d49b95f83939f31
4
- data.tar.gz: a0d02a82de5cf742972635168fbebd2b5e5313bd
3
+ metadata.gz: 3f903c553740c40251896f7771c0237eee77771f
4
+ data.tar.gz: e6ab168e83e807f875925289aaa35ceebdb0fa46
5
5
  SHA512:
6
- metadata.gz: d4c585a8fba5f94e479cc001ffabdc8cbd5409f3bfca5051c517063f400e8b39f0ba6609ee769b0b14488d28352d08c5d169be5d188a5c6b78c67cca270b8d66
7
- data.tar.gz: '038d8703191146132f6882a9d38cf5906baa3be0b7cd337b77146d3199ddb5a1cc41451b3fb17734561000c357c66a6f70344e246633e670f49558b2f1ecea71'
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| pins["CSI#{index}".to_sym] = Pin::Pin.new(gpio) }
95
- xio.each_with_index { |gpio, index| pins["XIO#{index}".to_sym] = Pin::Pin.new(gpio) }
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.1.2
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-19 00:00:00.000000000 Z
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: []