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
|