pi_driver 0.0.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
+ SHA1:
3
+ metadata.gz: bc90f84fe49ba85fc4c6e0f5b3af5e6396952733
4
+ data.tar.gz: 30d3039abade3868c00a0872176b243452e3a39b
5
+ SHA512:
6
+ metadata.gz: d7c63839480a43a98c4a26e7e9aa20bd4d5e196b697f2eb6db48098997ffb21e2f8fd97db4cff0e5cbe01c140d3837fa8f170bdcd1f986eb2d16ec42d25c4725
7
+ data.tar.gz: '0635499eee9f47a2479e2759d72399231bce35417ccac7a9d673c858d0c3bb93ed3e018482ece97be0fc04290164f64a363e5b90cdeb708a86e245f22143f582'
data/bin/pin.rb ADDED
@@ -0,0 +1,4 @@
1
+ # ruby -Ilib ./bin/pin.rb 10
2
+
3
+ require 'pi_driver'
4
+ puts PiDriver::Pin.new(ARGV[0]).clear?
@@ -0,0 +1,106 @@
1
+ module PiDriver
2
+ class I2CMaster
3
+ def initialize(options = {})
4
+ @frequency = 100_000
5
+ @delta_time = @frequency ** -1.0
6
+ @clock_pin = options[:clock_pin]
7
+ @data_pin = options[:data_pin]
8
+ @num_bits = 8
9
+ stop
10
+ end
11
+
12
+ def stop
13
+ release_clock_pin
14
+ release_data_pin
15
+ end
16
+
17
+ def start
18
+ drive_data_pin
19
+ drive_clock_pin
20
+ end
21
+
22
+ def write(byte)
23
+ send_data byte
24
+ byte
25
+ end
26
+
27
+ def read
28
+ release_data_pin
29
+ read_data
30
+ end
31
+
32
+ def ack
33
+ release_data_pin
34
+ release_clock_pin
35
+ success = @data_pin.clear?
36
+ drive_clock_pin
37
+ success
38
+ end
39
+
40
+ private
41
+
42
+ # def send_address(direction = :read)
43
+ # byte = @slave_address << 1
44
+ # byte += Pin::Value::HIGH if direction == :read
45
+ # send_data byte
46
+ # end
47
+
48
+ def send_data(byte)
49
+ bits = byte_to_bits byte
50
+ bits.each do |bit|
51
+ bit == Pin::Value::HIGH ? release_data_pin : drive_data_pin
52
+ release_clock_pin
53
+ drive_clock_pin
54
+ end
55
+ end
56
+
57
+ def read_data
58
+ bits = []
59
+ @num_bits.times do
60
+ release_clock_pin
61
+ bits << @data_pin.value
62
+ drive_clock_pin
63
+ end
64
+ bits_to_byte(bits)
65
+ end
66
+
67
+ def byte_to_bits(byte)
68
+ byte.to_s(2).rjust(@num_bits, '0').chars.map(&:to_i)
69
+ end
70
+
71
+ def bits_to_byte(bits)
72
+ bits.join.to_i(2)
73
+ end
74
+
75
+ def release_data_pin
76
+ @data_pin.input
77
+ observe_speed_requirement
78
+ end
79
+
80
+ def drive_data_pin
81
+ @data_pin.output Pin::Value::LOW
82
+ observe_speed_requirement
83
+ end
84
+
85
+ def release_clock_pin
86
+ @clock_pin.input
87
+ observe_clock_stretch
88
+ observe_speed_requirement
89
+ end
90
+
91
+ def drive_clock_pin
92
+ @clock_pin.output Pin::Value::LOW
93
+ observe_speed_requirement
94
+ end
95
+
96
+ def observe_clock_stretch
97
+ # 1ms timeout typical
98
+ loop { break if @clock_pin.set?}
99
+ end
100
+
101
+ def observe_speed_requirement
102
+ start = Time.now
103
+ loop { break if (Time.now - start) > @delta_time }
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,165 @@
1
+ module PiDriver
2
+ class Pin
3
+ # delete this and below
4
+ DIR_BASE = File.expand_path '~/pi/gpio/sys/class'
5
+ # # uncomment below, delete this
6
+ # DIR_BASE = '/sys/class'
7
+
8
+ DIR_GPIO = "#{DIR_BASE}/gpio"
9
+
10
+ attr_reader :gpio_number
11
+
12
+ class Direction
13
+ INPUT = :in
14
+ OUTPUT = :out
15
+ VALID_DIRECTIONS = [INPUT, OUTPUT]
16
+ end
17
+
18
+ class Edge
19
+ RISING = :rising
20
+ FALLING = :falling
21
+ BOTH = :both
22
+ NONE = :none
23
+ VALID_EDGES = [RISING, FALLING, BOTH, NONE]
24
+ end
25
+
26
+ class Value
27
+ LOW = 0
28
+ HIGH = 1
29
+ VALID_VALUES = [LOW, HIGH]
30
+ end
31
+
32
+ def initialize(gpio_number, options = {})
33
+ direction = options[:direction] || Direction::INPUT
34
+ value = options[:value] || Value::LOW
35
+
36
+ write_export gpio_number
37
+
38
+ write_direction(direction)
39
+ input? ? read_value : write_value(value)
40
+ end
41
+
42
+ def input
43
+ write_direction(Direction::INPUT) unless input?
44
+ end
45
+
46
+ def input?
47
+ @direction == Direction::INPUT
48
+ end
49
+
50
+ def output(value = Value::LOW)
51
+ write_direction(Direction::OUTPUT) unless output?
52
+ write_value(value)
53
+ end
54
+
55
+ def output?
56
+ @direction == Direction::OUTPUT
57
+ end
58
+
59
+ def clear
60
+ return unless output?
61
+ write_value(Value::LOW) unless clear?
62
+ @value
63
+ end
64
+
65
+ def clear?
66
+ value == Value::LOW
67
+ end
68
+
69
+ def set
70
+ return unless output?
71
+ write_value(Value::HIGH) unless set?
72
+ @value
73
+ end
74
+
75
+ def set?
76
+ value == Value::HIGH
77
+ end
78
+
79
+ def value
80
+ input? ? read_value : @value
81
+ end
82
+
83
+ def interrupt(edge = Edge::RISING)
84
+ check_arg(:edge, edge, Edge::VALID_EDGES)
85
+
86
+ @edge = edge
87
+
88
+ @interrupt_thread = Thread.new do
89
+ last_value = read_value
90
+ loop do
91
+ new_value = read_value
92
+ yield if block_given? && interrupted?(new_value, last_value)
93
+ last_value = new_value
94
+ end
95
+ end
96
+ end
97
+
98
+ def clear_interrupt
99
+ @interrupt_thread.kill if @interrupt_thread
100
+ end
101
+
102
+ private
103
+
104
+ def check_arg(type, arg, valid_options)
105
+ valid_options_for_message = valid_options.map { |value| ":#{value}"}.join(', ')
106
+ message = "Pin #{@gpio_number} invalid #{type}: #{arg} expected to be one of #{valid_options_for_message}"
107
+ raise ArgumentError, message unless valid_options.include?(arg)
108
+ end
109
+
110
+ def dir_pin
111
+ "#{DIR_GPIO}/gpio#{@gpio_number}"
112
+ end
113
+
114
+ def interrupted?(new_value, last_value)
115
+ rising_edge = new_value == Value::HIGH && last_value == Value::LOW
116
+ falling_edge = new_value == Value::LOW && last_value == Value::HIGH
117
+
118
+ case @edge
119
+ when :rising
120
+ rising_edge
121
+ when :falling
122
+ falling_edge
123
+ when :both
124
+ rising_edge || falling_edge
125
+ end
126
+ end
127
+
128
+ def path_direction
129
+ "#{dir_pin}/direction"
130
+ end
131
+
132
+ def path_export
133
+ "#{DIR_GPIO}/export"
134
+ end
135
+
136
+ def path_value
137
+ "#{dir_pin}/value"
138
+ end
139
+
140
+ def read_direction
141
+ @direction = File.read(path_direction).to_sym
142
+ end
143
+
144
+ def read_value
145
+ @value = File.read(path_value).to_i
146
+ end
147
+
148
+ def write_direction(direction)
149
+ check_arg(:direction, direction, Direction::VALID_DIRECTIONS)
150
+ @direction = direction
151
+ File.write(path_direction, @direction)
152
+ end
153
+
154
+ def write_export(gpio_number)
155
+ @gpio_number = gpio_number
156
+ File.write(path_export, @gpio_number)
157
+ end
158
+
159
+ def write_value(value)
160
+ check_arg(:value, value, Value::VALID_VALUES)
161
+ @value = value
162
+ File.write(path_value, @value)
163
+ end
164
+ end
165
+ end
data/lib/pi_driver.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'pi_driver/pin'
2
+ require 'pi_driver/i2c_master'
3
+
4
+ module PiDriver
5
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pi_driver
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Lucas Winningham
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mocha
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'
27
+ description: Ruby driver for Raspberry Pi
28
+ email: lucas.winningham@gmail.com
29
+ executables:
30
+ - pin.rb
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - bin/pin.rb
35
+ - lib/pi_driver.rb
36
+ - lib/pi_driver/i2c_master.rb
37
+ - lib/pi_driver/pin.rb
38
+ homepage: http://rubygems.org/gems/pi_driver
39
+ licenses:
40
+ - MIT
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 2.6.14
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: Ruby driver for Raspberry Pi
62
+ test_files: []