pi_driver 0.0.2 → 0.0.3
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 +4 -4
- data/lib/pi_driver.rb +3 -1
- data/lib/pi_driver/device.rb +6 -0
- data/lib/pi_driver/device/mcp23017.rb +129 -0
- data/lib/pi_driver/device/mcp23017/hardware_address.rb +37 -0
- data/lib/pi_driver/device/mcp23017/port.rb +23 -0
- data/lib/pi_driver/device/mcp23017/register.rb +98 -0
- data/lib/pi_driver/device/mcp23017/register/defval.rb +14 -0
- data/lib/pi_driver/device/mcp23017/register/gpinten.rb +14 -0
- data/lib/pi_driver/device/mcp23017/register/gpio.rb +14 -0
- data/lib/pi_driver/device/mcp23017/register/gppu.rb +14 -0
- data/lib/pi_driver/device/mcp23017/register/intcap.rb +14 -0
- data/lib/pi_driver/device/mcp23017/register/intcon.rb +14 -0
- data/lib/pi_driver/device/mcp23017/register/intf.rb +14 -0
- data/lib/pi_driver/device/mcp23017/register/iocon.rb +41 -0
- data/lib/pi_driver/device/mcp23017/register/iodir.rb +14 -0
- data/lib/pi_driver/device/mcp23017/register/ipol.rb +14 -0
- data/lib/pi_driver/device/mcp23017/register/olat.rb +14 -0
- data/lib/pi_driver/device/mcp23017/register/register_helper.rb +50 -0
- data/lib/pi_driver/i2c_master.rb +6 -15
- data/lib/pi_driver/pin.rb +25 -49
- data/lib/pi_driver/pin/board.rb +65 -0
- data/lib/pi_driver/pin/direction.rb +13 -0
- data/lib/pi_driver/pin/directory_helper.rb +32 -0
- data/lib/pi_driver/pin/file_helper.rb +32 -0
- data/lib/pi_driver/utils.rb +10 -0
- data/lib/pi_driver/utils/argument_helper.rb +19 -0
- data/lib/pi_driver/utils/byte.rb +21 -0
- data/lib/pi_driver/utils/edge.rb +17 -0
- data/lib/pi_driver/utils/interrupt.rb +60 -0
- data/lib/pi_driver/utils/state.rb +13 -0
- data/test/device/mcp23017/test_alias.rb +27 -0
- data/test/device/mcp23017/test_error.rb +37 -0
- data/test/device/mcp23017/test_hardware_address.rb +29 -0
- data/test/device/mcp23017/test_i2c_master.rb +10 -0
- data/test/device/mcp23017/test_read.rb +63 -0
- data/test/device/mcp23017/test_register.rb +118 -0
- data/test/device/mcp23017/test_write.rb +49 -0
- data/test/device/mcp23017_test_helper.rb +13 -0
- data/test/i2c_master/test_ack.rb +26 -0
- data/test/i2c_master/test_address.rb +15 -0
- data/test/i2c_master/test_alias.rb +7 -0
- data/test/i2c_master/test_clock_stretch.rb +26 -0
- data/test/i2c_master/test_read.rb +27 -0
- data/test/i2c_master/test_speed.rb +11 -0
- data/test/i2c_master/test_start.rb +11 -0
- data/test/i2c_master/test_stop.rb +24 -0
- data/test/i2c_master/test_write.rb +29 -0
- data/test/i2c_master_test_helper.rb +28 -0
- data/test/pin/test_alias.rb +23 -0
- data/test/pin/test_clear.rb +15 -0
- data/test/pin/test_clear_interrupt.rb +10 -0
- data/test/pin/test_error.rb +35 -0
- data/test/pin/test_input.rb +23 -0
- data/test/pin/test_interrupt.rb +51 -0
- data/test/pin/test_is_clear.rb +17 -0
- data/test/pin/test_is_input.rb +14 -0
- data/test/pin/test_is_output.rb +14 -0
- data/test/pin/test_is_set.rb +17 -0
- data/test/pin/test_output.rb +38 -0
- data/test/pin/test_set.rb +15 -0
- data/test/pin_test_helper.rb +45 -0
- data/test/test_helper.rb +14 -0
- data/test/utils/test_error.rb +31 -0
- data/test/utils/test_interrupt.rb +109 -0
- data/test/utils_test_helper.rb +6 -0
- metadata +73 -5
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module PiDriver
|
|
2
|
+
class Device
|
|
3
|
+
class MCP23017
|
|
4
|
+
class Register
|
|
5
|
+
class RegisterHelper
|
|
6
|
+
IODIR = :iodir
|
|
7
|
+
IPOL = :ipol
|
|
8
|
+
GPINTEN = :gpinten
|
|
9
|
+
DEFVAL = :defval
|
|
10
|
+
INTCON = :intcon
|
|
11
|
+
IOCON = :iocon
|
|
12
|
+
GPPU = :gppu
|
|
13
|
+
INTF = :intf
|
|
14
|
+
INTCAP = :intcap
|
|
15
|
+
GPIO = :gpio
|
|
16
|
+
OLAT = :olat
|
|
17
|
+
|
|
18
|
+
VALID_REGISTERS = [
|
|
19
|
+
IODIR,
|
|
20
|
+
IPOL,
|
|
21
|
+
GPINTEN,
|
|
22
|
+
DEFVAL,
|
|
23
|
+
INTCON,
|
|
24
|
+
IOCON,
|
|
25
|
+
GPPU,
|
|
26
|
+
INTF,
|
|
27
|
+
INTCAP,
|
|
28
|
+
GPIO,
|
|
29
|
+
OLAT
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
def self.address(options)
|
|
33
|
+
bank = options[:bank]
|
|
34
|
+
port = options[:port]
|
|
35
|
+
register = options[:register]
|
|
36
|
+
|
|
37
|
+
port_index = Port::VALID_PORTS.index(port)
|
|
38
|
+
register_index = VALID_REGISTERS.index(register)
|
|
39
|
+
|
|
40
|
+
if bank == Utils::State::LOW
|
|
41
|
+
port_index + register_index * 0x02
|
|
42
|
+
else
|
|
43
|
+
port_index * 0x10 + register_index
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
data/lib/pi_driver/i2c_master.rb
CHANGED
|
@@ -5,7 +5,6 @@ module PiDriver
|
|
|
5
5
|
@delta_time = @frequency ** -1.0
|
|
6
6
|
@clock_pin = options[:clock_pin]
|
|
7
7
|
@data_pin = options[:data_pin]
|
|
8
|
-
@num_bits = 8
|
|
9
8
|
stop
|
|
10
9
|
end
|
|
11
10
|
|
|
@@ -50,9 +49,9 @@ module PiDriver
|
|
|
50
49
|
private
|
|
51
50
|
|
|
52
51
|
def send_data(byte)
|
|
53
|
-
bits = byte_to_bits
|
|
52
|
+
bits = Utils::Byte.byte_to_bits(byte)
|
|
54
53
|
bits.each do |bit|
|
|
55
|
-
bit ==
|
|
54
|
+
bit == Utils::State::HIGH ? release_data_pin : drive_data_pin
|
|
56
55
|
release_clock_pin
|
|
57
56
|
drive_clock_pin
|
|
58
57
|
end
|
|
@@ -60,20 +59,12 @@ module PiDriver
|
|
|
60
59
|
|
|
61
60
|
def read_data
|
|
62
61
|
bits = []
|
|
63
|
-
|
|
62
|
+
Utils::Byte::NUM_BITS_PER_BYTE.times do
|
|
64
63
|
release_clock_pin
|
|
65
64
|
bits << @data_pin.value
|
|
66
65
|
drive_clock_pin
|
|
67
66
|
end
|
|
68
|
-
bits_to_byte(bits)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def byte_to_bits(byte)
|
|
72
|
-
byte.to_s(2).rjust(@num_bits, '0').chars.map(&:to_i)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def bits_to_byte(bits)
|
|
76
|
-
bits.join.to_i(2)
|
|
67
|
+
Utils::Byte.bits_to_byte(bits)
|
|
77
68
|
end
|
|
78
69
|
|
|
79
70
|
def release_data_pin
|
|
@@ -82,7 +73,7 @@ module PiDriver
|
|
|
82
73
|
end
|
|
83
74
|
|
|
84
75
|
def drive_data_pin
|
|
85
|
-
@data_pin.output
|
|
76
|
+
@data_pin.output Utils::State::LOW
|
|
86
77
|
observe_speed_requirement
|
|
87
78
|
end
|
|
88
79
|
|
|
@@ -93,7 +84,7 @@ module PiDriver
|
|
|
93
84
|
end
|
|
94
85
|
|
|
95
86
|
def drive_clock_pin
|
|
96
|
-
@clock_pin.output
|
|
87
|
+
@clock_pin.output Utils::State::LOW
|
|
97
88
|
observe_speed_requirement
|
|
98
89
|
end
|
|
99
90
|
|
data/lib/pi_driver/pin.rb
CHANGED
|
@@ -1,30 +1,29 @@
|
|
|
1
|
-
require_relative 'pin/argument_helper'
|
|
2
1
|
require_relative 'pin/board'
|
|
3
2
|
require_relative 'pin/direction'
|
|
4
|
-
require_relative 'pin/edge'
|
|
5
3
|
require_relative 'pin/file_helper'
|
|
6
|
-
require_relative 'pin/value'
|
|
7
4
|
|
|
8
5
|
module PiDriver
|
|
9
6
|
class Pin
|
|
10
7
|
attr_reader :gpio_number
|
|
11
8
|
|
|
12
9
|
def initialize(gpio_number, options = {})
|
|
13
|
-
@argument_helper = ArgumentHelper.new
|
|
10
|
+
@argument_helper = Utils::ArgumentHelper.new prefix: "PiDriver::Pin"
|
|
14
11
|
|
|
15
12
|
@gpio_number = gpio_number
|
|
16
13
|
@argument_helper.check(:gpio_number, @gpio_number, Board::VALID_NUMBERS)
|
|
17
14
|
|
|
15
|
+
@argument_helper.prefix = "PiDriver::Pin ##{gpio_number}"
|
|
16
|
+
|
|
18
17
|
@direction = options[:direction] || Direction::INPUT
|
|
19
18
|
@argument_helper.check(:direction, @direction, Direction::VALID_DIRECTIONS)
|
|
20
19
|
|
|
21
|
-
@
|
|
22
|
-
@argument_helper.check(:
|
|
20
|
+
@state = options[:state] || Utils::State::LOW
|
|
21
|
+
@argument_helper.check(:state, @state, Utils::State::VALID_STATES)
|
|
23
22
|
|
|
24
23
|
@file_helper = FileHelper.new @gpio_number
|
|
25
24
|
@file_helper.write_export
|
|
26
25
|
@file_helper.write_direction(@direction)
|
|
27
|
-
input? ? @file_helper.read_value : @file_helper.write_value(@
|
|
26
|
+
input? ? @file_helper.read_value : @file_helper.write_value(@state)
|
|
28
27
|
end
|
|
29
28
|
|
|
30
29
|
def input
|
|
@@ -36,12 +35,12 @@ module PiDriver
|
|
|
36
35
|
@direction == Direction::INPUT
|
|
37
36
|
end
|
|
38
37
|
|
|
39
|
-
def output(
|
|
40
|
-
@argument_helper.check(:
|
|
41
|
-
@
|
|
38
|
+
def output(state = Utils::State::LOW)
|
|
39
|
+
@argument_helper.check(:state, state, Utils::State::VALID_STATES)
|
|
40
|
+
@state = state
|
|
42
41
|
@direction = Direction::OUTPUT
|
|
43
42
|
@file_helper.write_direction(@direction)
|
|
44
|
-
@file_helper.write_value(@
|
|
43
|
+
@file_helper.write_value(@state)
|
|
45
44
|
end
|
|
46
45
|
|
|
47
46
|
def output?
|
|
@@ -50,70 +49,47 @@ module PiDriver
|
|
|
50
49
|
|
|
51
50
|
def clear
|
|
52
51
|
return unless output?
|
|
53
|
-
@
|
|
54
|
-
@file_helper.write_value(@
|
|
55
|
-
@
|
|
52
|
+
@state = Utils::State::LOW
|
|
53
|
+
@file_helper.write_value(@state)
|
|
54
|
+
@state
|
|
56
55
|
end
|
|
57
56
|
|
|
58
57
|
alias_method :off, :clear
|
|
59
58
|
|
|
60
59
|
def clear?
|
|
61
|
-
|
|
60
|
+
state == Utils::State::LOW
|
|
62
61
|
end
|
|
63
62
|
|
|
64
63
|
alias_method :off?, :clear?
|
|
65
64
|
|
|
66
65
|
def set
|
|
67
66
|
return unless output?
|
|
68
|
-
@
|
|
69
|
-
@file_helper.write_value(@
|
|
70
|
-
@
|
|
67
|
+
@state = Utils::State::HIGH
|
|
68
|
+
@file_helper.write_value(@state)
|
|
69
|
+
@state
|
|
71
70
|
end
|
|
72
71
|
|
|
73
72
|
alias_method :on, :set
|
|
74
73
|
|
|
75
74
|
def set?
|
|
76
|
-
|
|
75
|
+
state == Utils::State::HIGH
|
|
77
76
|
end
|
|
78
77
|
|
|
79
78
|
alias_method :on?, :set?
|
|
80
79
|
|
|
81
|
-
def
|
|
82
|
-
input? ? @file_helper.read_value : @
|
|
80
|
+
def state
|
|
81
|
+
input? ? @file_helper.read_value : @state
|
|
83
82
|
end
|
|
84
83
|
|
|
85
|
-
def interrupt(edge = Edge::RISING)
|
|
86
|
-
@argument_helper.check(:edge, edge, Edge::VALID_EDGES)
|
|
84
|
+
def interrupt(edge = Utils::Edge::RISING)
|
|
85
|
+
@argument_helper.check(:edge, edge, Utils::Edge::VALID_EDGES)
|
|
87
86
|
@edge = edge
|
|
88
|
-
|
|
89
|
-
@
|
|
90
|
-
last_value = @file_helper.read_value
|
|
91
|
-
loop do
|
|
92
|
-
new_value = @file_helper.read_value
|
|
93
|
-
yield if block_given? && interrupted?(new_value, last_value)
|
|
94
|
-
last_value = new_value
|
|
95
|
-
end
|
|
96
|
-
end
|
|
87
|
+
@interrupt = Utils::Interrupt.new(@edge) { @file_helper.read_value }
|
|
88
|
+
@interrupt.start { yield }
|
|
97
89
|
end
|
|
98
90
|
|
|
99
91
|
def clear_interrupt
|
|
100
|
-
@
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
private
|
|
104
|
-
|
|
105
|
-
def interrupted?(new_value, last_value)
|
|
106
|
-
rising_edge = new_value == Value::HIGH && last_value == Value::LOW
|
|
107
|
-
falling_edge = new_value == Value::LOW && last_value == Value::HIGH
|
|
108
|
-
|
|
109
|
-
case @edge
|
|
110
|
-
when :rising
|
|
111
|
-
rising_edge
|
|
112
|
-
when :falling
|
|
113
|
-
falling_edge
|
|
114
|
-
when :both
|
|
115
|
-
rising_edge || falling_edge
|
|
116
|
-
end
|
|
92
|
+
@interrupt.clear if @interrupt
|
|
117
93
|
end
|
|
118
94
|
end
|
|
119
95
|
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module PiDriver
|
|
2
|
+
class Pin
|
|
3
|
+
class Board
|
|
4
|
+
PIN11 = 0
|
|
5
|
+
PIN12 = 1
|
|
6
|
+
PIN13 = 2
|
|
7
|
+
PIN15 = 3
|
|
8
|
+
PIN16 = 4
|
|
9
|
+
PIN18 = 5
|
|
10
|
+
PIN22 = 6
|
|
11
|
+
PIN07 = 7
|
|
12
|
+
PIN03 = 8
|
|
13
|
+
PIN05 = 9
|
|
14
|
+
PIN24 = 10
|
|
15
|
+
PIN26 = 11
|
|
16
|
+
PIN19 = 12
|
|
17
|
+
PIN21 = 13
|
|
18
|
+
PIN23 = 14
|
|
19
|
+
PIN08 = 15
|
|
20
|
+
PIN10 = 16
|
|
21
|
+
PIN29 = 21
|
|
22
|
+
PIN31 = 22
|
|
23
|
+
PIN33 = 23
|
|
24
|
+
PIN35 = 24
|
|
25
|
+
PIN37 = 25
|
|
26
|
+
PIN32 = 26
|
|
27
|
+
PIN36 = 27
|
|
28
|
+
PIN38 = 28
|
|
29
|
+
PIN40 = 29
|
|
30
|
+
PIN27 = 30
|
|
31
|
+
PIN28 = 31
|
|
32
|
+
|
|
33
|
+
VALID_NUMBERS = [
|
|
34
|
+
PIN11,
|
|
35
|
+
PIN12,
|
|
36
|
+
PIN13,
|
|
37
|
+
PIN15,
|
|
38
|
+
PIN16,
|
|
39
|
+
PIN18,
|
|
40
|
+
PIN22,
|
|
41
|
+
PIN07,
|
|
42
|
+
PIN03,
|
|
43
|
+
PIN05,
|
|
44
|
+
PIN24,
|
|
45
|
+
PIN26,
|
|
46
|
+
PIN19,
|
|
47
|
+
PIN21,
|
|
48
|
+
PIN23,
|
|
49
|
+
PIN08,
|
|
50
|
+
PIN10,
|
|
51
|
+
PIN29,
|
|
52
|
+
PIN31,
|
|
53
|
+
PIN33,
|
|
54
|
+
PIN35,
|
|
55
|
+
PIN37,
|
|
56
|
+
PIN32,
|
|
57
|
+
PIN36,
|
|
58
|
+
PIN38,
|
|
59
|
+
PIN40,
|
|
60
|
+
PIN27,
|
|
61
|
+
PIN28
|
|
62
|
+
]
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module PiDriver
|
|
2
|
+
class Pin
|
|
3
|
+
class DirectoryHelper
|
|
4
|
+
# TODO figure out environment variables for test
|
|
5
|
+
# DIR_BASE = '/sys/class'
|
|
6
|
+
DIR_BASE = File.expand_path '~/pi/gpio/sys/class'
|
|
7
|
+
DIR_GPIO = "#{DIR_BASE}/gpio"
|
|
8
|
+
|
|
9
|
+
def initialize(gpio_number)
|
|
10
|
+
@gpio_number = gpio_number
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def direction
|
|
14
|
+
"#{dir_pin}/direction"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def export
|
|
18
|
+
"#{DIR_GPIO}/export"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def value
|
|
22
|
+
"#{dir_pin}/value"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def dir_pin
|
|
28
|
+
"#{DIR_GPIO}/gpio#{@gpio_number}"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require_relative 'directory_helper'
|
|
2
|
+
|
|
3
|
+
module PiDriver
|
|
4
|
+
class Pin
|
|
5
|
+
class FileHelper
|
|
6
|
+
def initialize(gpio_number)
|
|
7
|
+
@gpio_number = gpio_number
|
|
8
|
+
@directory_helper = DirectoryHelper.new @gpio_number
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def read_direction
|
|
12
|
+
File.read(@directory_helper.direction).to_sym
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def read_value
|
|
16
|
+
File.read(@directory_helper.value).to_i
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def write_direction(direction)
|
|
20
|
+
File.write(@directory_helper.direction, direction)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def write_export
|
|
24
|
+
File.write(@directory_helper.export, @gpio_number)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def write_value(value)
|
|
28
|
+
File.write(@directory_helper.value, value)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|