chip-gpio 0.1.2 → 0.2.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.
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: []