i2c-devices 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/ChangeLog +1 -1
- data/Rakefile +2 -0
- data/i2c-devices.gemspec +2 -0
- data/lib/i2c.rb +1 -1
- data/lib/i2c/device/acm1602ni.rb +2 -1
- data/lib/i2c/device/adt7410.rb +6 -3
- data/lib/i2c/device/aqm0802.rb +2 -2
- data/lib/i2c/device/hd44780.rb +58 -23
- data/lib/i2c/driver.rb +12 -1
- data/lib/i2c/driver/gpio.rb +165 -151
- data/lib/i2c/driver/i2c-dev.rb +46 -43
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2bb4b37022204715281e0f2410f0f630cc309d4
|
4
|
+
data.tar.gz: 8679f5547940d54b6ac03b5b39599f3d566b9c1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd7b98970e4d83b67286638d57f2896563f5cb8de142241a7909f100e71b11700e6ebdc81736abefcf356e86e34a6c4d06d8719d214647954c011097437c0867
|
7
|
+
data.tar.gz: fb036c7d5d2fce53bec00b9a264edc3d7e01be93063611d17a636c6d2f53e365ae067487384a2864c39691bfb941d57516a36c02da37d5a1da9d5aafdd63a00c
|
data/ChangeLog
CHANGED
data/Rakefile
CHANGED
data/i2c-devices.gemspec
CHANGED
@@ -16,6 +16,8 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.homepage = 'https://github.com/cho45/ruby-i2c-devices'
|
17
17
|
s.license = 'MIT'
|
18
18
|
s.require_paths = ["lib"]
|
19
|
+
s.extra_rdoc_files = ['README.md']
|
20
|
+
s.rdoc_options << '--main' << 'README.md'
|
19
21
|
|
20
22
|
s.add_development_dependency "bundler", "~> 1.5"
|
21
23
|
s.add_development_dependency "rake"
|
data/lib/i2c.rb
CHANGED
data/lib/i2c/device/acm1602ni.rb
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
require "i2c/device/hd44780"
|
4
4
|
|
5
|
-
#
|
5
|
+
# 16x02 LCD module with I2C.
|
6
|
+
# Note: This device only run under speed=50kHz.
|
6
7
|
# http://akizukidenshi.com/catalog/g/gP-05693/
|
7
8
|
class I2CDevice::ACM1602NI < I2CDevice::HD44780
|
8
9
|
def initialize(args={})
|
data/lib/i2c/device/adt7410.rb
CHANGED
@@ -2,20 +2,23 @@
|
|
2
2
|
|
3
3
|
require "i2c"
|
4
4
|
|
5
|
+
# Analog Devices ADT7410 (temperture sensor)
|
6
|
+
# http://www.analog.com/en/mems-sensors/digital-temperature-sensors/adt7410/products/product.html
|
5
7
|
class I2CDevice::ADT7410 < I2CDevice
|
6
|
-
|
8
|
+
|
9
|
+
OPERATION_MODE = { # :nodoc:
|
7
10
|
0b00 => :continuous_conversion,
|
8
11
|
0b01 => :one_shot,
|
9
12
|
0b10 => :one_sps_mode,
|
10
13
|
0b11 => :shutdown,
|
11
14
|
}
|
12
15
|
|
13
|
-
INT_CT_MODE = {
|
16
|
+
INT_CT_MODE = { # :nodoc:
|
14
17
|
0 => :interrupt_mode,
|
15
18
|
1 => :comparator_mode,
|
16
19
|
}
|
17
20
|
|
18
|
-
RESOLUTION = {
|
21
|
+
RESOLUTION = { # :nodoc:
|
19
22
|
0 => 13,
|
20
23
|
1 => 16,
|
21
24
|
}
|
data/lib/i2c/device/aqm0802.rb
CHANGED
@@ -24,7 +24,7 @@ class I2CDevice::AQM0802A < I2CDevice::HD44780
|
|
24
24
|
end
|
25
25
|
|
26
26
|
|
27
|
-
#
|
27
|
+
# Must set is = 1 by function_set before call.
|
28
28
|
def internal_osc_frequency(bs, f)
|
29
29
|
raise "is must be 1" unless @is == 1
|
30
30
|
f &= 0b111
|
@@ -47,7 +47,7 @@ class I2CDevice::AQM0802A < I2CDevice::HD44780
|
|
47
47
|
sleep 300e-3
|
48
48
|
end
|
49
49
|
|
50
|
-
# is
|
50
|
+
# <tt>is</tt> :: [Integer] Instruction set 1: extension, 0: normal
|
51
51
|
def function_set(dl, n, f, is)
|
52
52
|
@is = is
|
53
53
|
i2cset(0, 0b00100000 | (dl<<4) | (n<<3) | (f<<2) | (is))
|
data/lib/i2c/device/hd44780.rb
CHANGED
@@ -21,6 +21,8 @@ class I2CDevice::HD44780 < I2CDevice
|
|
21
21
|
initialize_lcd
|
22
22
|
end
|
23
23
|
|
24
|
+
# Initialize LCD controller sequence
|
25
|
+
# Display is cleared.
|
24
26
|
def initialize_lcd
|
25
27
|
function_set(1, 1, 0)
|
26
28
|
sleep 4.1e-3
|
@@ -32,6 +34,12 @@ class I2CDevice::HD44780 < I2CDevice
|
|
32
34
|
clear
|
33
35
|
end
|
34
36
|
|
37
|
+
# <tt>line</tt> :: [Integer] Line number
|
38
|
+
# <tt>str</tt> :: [String] Display string
|
39
|
+
# <tt>force</tt> :: [true | false] Write data forcely.
|
40
|
+
#
|
41
|
+
# Note: This method keep previous put_line strings and does not write without change.
|
42
|
+
# You must specify _force_ to override this behaviour.
|
35
43
|
def put_line(line, str, force=false)
|
36
44
|
str.force_encoding(Encoding::BINARY)
|
37
45
|
str.gsub!(/#{MAP.keys.join('|')}/, MAP)
|
@@ -48,17 +56,19 @@ class I2CDevice::HD44780 < I2CDevice
|
|
48
56
|
@lines[line] = str
|
49
57
|
end
|
50
58
|
|
59
|
+
# <tt>n</tt> :: [Integer] Character code.
|
60
|
+
# <tt>array</tt> :: [Array[Integer]] Character data.
|
51
61
|
# Usage:
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
+
# lcd.define_character(0, [
|
63
|
+
# 0,1,1,1,0,
|
64
|
+
# 1,0,0,0,1,
|
65
|
+
# 1,1,0,1,1,
|
66
|
+
# 1,0,1,0,1,
|
67
|
+
# 1,1,0,1,1,
|
68
|
+
# 1,0,0,0,1,
|
69
|
+
# 1,0,0,0,1,
|
70
|
+
# 0,1,1,1,0,
|
71
|
+
# ])
|
62
72
|
def define_character(n, array)
|
63
73
|
raise "n < 8" unless n < 8
|
64
74
|
raise "array size must be 40 (5x8)" unless array.size == 40
|
@@ -72,61 +82,86 @@ class I2CDevice::HD44780 < I2CDevice
|
|
72
82
|
sleep 60e-6
|
73
83
|
end
|
74
84
|
|
75
|
-
def clear
|
76
|
-
@lines.clear
|
77
|
-
clear_display
|
78
|
-
end
|
79
|
-
|
80
85
|
def clear_display
|
86
|
+
@lines.clear
|
81
87
|
i2cset(0, 0b00000001)
|
82
88
|
sleep 2.16e-3
|
83
89
|
end
|
84
90
|
|
91
|
+
alias clear_display clear
|
92
|
+
|
85
93
|
def return_home
|
86
94
|
i2cset(0, 0b00000010)
|
87
95
|
sleep 1.52e-3
|
88
96
|
end
|
89
97
|
|
90
|
-
# i_d
|
91
|
-
#
|
98
|
+
# <tt>i_d</tt> :: [Integer] Increment or decrement
|
99
|
+
# 0 :: Decrement
|
100
|
+
# 1 :: Increment
|
101
|
+
# <tt>s</tt> :: [Integer] Shift entire display
|
102
|
+
# 0 :: Right
|
103
|
+
# 1 :: Left
|
92
104
|
def entry_mode_set(i_d, s)
|
93
105
|
i2cset(0, 0b00000100 | (i_d<<1) | (s))
|
94
106
|
sleep 60e-6
|
95
107
|
end
|
96
108
|
|
97
|
-
# d
|
98
|
-
#
|
99
|
-
#
|
109
|
+
# <tt>d</tt> :: [Integer] Set entire display on/off
|
110
|
+
# 0 :: Off
|
111
|
+
# 1 :: On
|
112
|
+
# <tt>c</tt> :: [Integer] Cursor on/off
|
113
|
+
# 0 :: Off
|
114
|
+
# 1 :: On
|
115
|
+
# <tt>b</tt> :: [Integer] Blink cursor
|
116
|
+
# 0 :: Off
|
117
|
+
# 1 :: On
|
100
118
|
def display_on_off_control(d, c, b)
|
101
119
|
i2cset(0, 0b00001000 | (d<<2) | (c<<1) | (b))
|
102
120
|
sleep 60e-6
|
103
121
|
end
|
104
122
|
|
123
|
+
# <tt>s_c</tt> :: [Integer] Cursor or display
|
124
|
+
# 0 :: Cursor shift
|
125
|
+
# 1 :: Display shift
|
126
|
+
# <tt>r_l</tt> :: [Integer] Direction
|
127
|
+
# 0 :: Left
|
128
|
+
# 1 :: Right
|
105
129
|
def cursor_or_display_shift(s_c, r_l)
|
106
130
|
i2cset(0, 0b00010000 | (s_c<<3) | (r_l<<2))
|
107
131
|
sleep 60e-6
|
108
132
|
end
|
109
133
|
|
110
|
-
# dl
|
111
|
-
#
|
112
|
-
#
|
134
|
+
# <tt>dl</tt> :: [Integer] Data length
|
135
|
+
# 0 :: 4bit
|
136
|
+
# 1 :: 8bit
|
137
|
+
# <tt>n</tt> :: [Integer] Number of display lines
|
138
|
+
# 0 :: 1-line
|
139
|
+
# 1 :: 2-line
|
140
|
+
# <tt>f</tt> :: [Integer] Character font
|
141
|
+
# 0 :: Normal
|
142
|
+
# 1 :: Double font
|
113
143
|
def function_set(dl, n, f)
|
114
144
|
i2cset(0, 0b00100000 | (dl<<4) | (n<<3) | (f<<2))
|
115
145
|
sleep 60e-6
|
116
146
|
end
|
117
147
|
|
148
|
+
# <tt>address</tt> :: [Integer] CGRAM address 6-bit
|
118
149
|
def set_cgram_address(address)
|
119
150
|
address = address & 0b00111111
|
120
151
|
i2cset(0, 0b01000000 | address)
|
121
152
|
sleep 60e-6
|
122
153
|
end
|
123
154
|
|
155
|
+
# <tt>address</tt> :: [Integer] DDRAM address 7-bit
|
124
156
|
def set_ddram_address(address)
|
125
157
|
address = address & 0b01111111
|
126
158
|
i2cset(0, 0b10000000 | address)
|
127
159
|
sleep 60e-6
|
128
160
|
end
|
129
161
|
|
162
|
+
# <tt>Returns</tt> :: [Hash] Result
|
163
|
+
# :busy :: [true | false] Busy flag
|
164
|
+
# :address_counter :: [Integer] Current address count. 7-bit
|
130
165
|
def read_busy_flag_and_address
|
131
166
|
read = i2cget(0b01000000)
|
132
167
|
{
|
data/lib/i2c/driver.rb
CHANGED
@@ -1,16 +1,27 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
require "i2c"
|
3
4
|
|
4
5
|
module I2CDevice::Driver
|
5
6
|
# Abstract class for I2CDevice::Driver
|
6
|
-
class
|
7
|
+
class Base
|
7
8
|
include I2CDevice::Driver
|
8
9
|
end
|
9
10
|
|
11
|
+
# Low-level method for i2cget
|
12
|
+
# Driver must implement this.
|
13
|
+
# <tt>address</tt> :: [Integer] 7-bit slave address without r/w bit. MSB is always 0.
|
14
|
+
# <tt>data</tt> :: [Array[Integer]] Writing bytes array.
|
15
|
+
# Returns :: [String] Wrote bytes
|
10
16
|
def i2cget(address, param, length=1)
|
11
17
|
raise NotImplementedError
|
12
18
|
end
|
13
19
|
|
20
|
+
# Low-level method for i2cset
|
21
|
+
# Driver must implement this.
|
22
|
+
# <tt>address</tt> :: [Integer] 7-bit slave address without r/w bit. MSB is always 0.
|
23
|
+
# <tt>data</tt> :: [Array[Integer]] Writing bytes array.
|
24
|
+
# Returns :: [String] Wrote bytes
|
14
25
|
def i2cset(address, *data)
|
15
26
|
raise NotImplementedError
|
16
27
|
end
|
data/lib/i2c/driver/gpio.rb
CHANGED
@@ -5,195 +5,209 @@ Generic software I2C Driver based on /sys/class/gpio.
|
|
5
5
|
THIS MODULE WORKS WITH VERY SLOW SPEED ABOUT JUST 1kHz (normaly 100kHz).
|
6
6
|
=end
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
@@DEBUG = false
|
8
|
+
class I2CDevice::Driver::GPIO < Base
|
9
|
+
@@DEBUG = false
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
11
|
+
def self.export(pin) #:nodoc:
|
12
|
+
File.open("/sys/class/gpio/export", "w") do |f|
|
13
|
+
f.syswrite(pin)
|
16
14
|
end
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
17
|
+
def self.unexport(pin) #:nodoc:
|
18
|
+
File.open("/sys/class/gpio/unexport", "w") do |f|
|
19
|
+
f.syswrite(pin)
|
22
20
|
end
|
21
|
+
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
23
|
+
def self.direction(pin, direction) #:nodoc:
|
24
|
+
# [:in, :out, :high, :low].include?(direction) or raise "direction must be :in, :out, :high or :low"
|
25
|
+
File.open("/sys/class/gpio/gpio#{pin}/direction", "w") do |f|
|
26
|
+
f.syswrite(direction)
|
29
27
|
end
|
28
|
+
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
30
|
+
def self.read(pin) #:nodoc:
|
31
|
+
File.open("/sys/class/gpio/gpio#{pin}/value", "r") do |f|
|
32
|
+
f.sysread(1).to_i
|
35
33
|
end
|
34
|
+
end
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
36
|
+
def self.write(pin, val) #:nodoc:
|
37
|
+
File.open("/sys/class/gpio/gpio#{pin}/value", "w") do |f|
|
38
|
+
f.syswrite(val && val.nonzero?? "1" : "0")
|
41
39
|
end
|
40
|
+
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
42
|
+
def self.finalizer(ports) #:nodoc:
|
43
|
+
proc do
|
44
|
+
ports.each do |pin|
|
45
|
+
GPIO.unexport(pin)
|
48
46
|
end
|
49
47
|
end
|
48
|
+
end
|
50
49
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
50
|
+
# Pin-number of SDA
|
51
|
+
attr_reader :sda
|
52
|
+
# Pin-number of SCL
|
53
|
+
attr_reader :scl
|
54
|
+
# Clock speed in kHz
|
55
|
+
attr_reader :speed
|
56
|
+
|
57
|
+
# <tt>opts[:sda]</tt> :: [Integer] Pin-number of SDA
|
58
|
+
# <tt>opts[:scl]</tt> :: [Integer] Pin-number of SCL
|
59
|
+
# <tt>[ opts[:speed] = 1 ]</tt> :: [Integer] Clock speed in kHz
|
60
|
+
def initialize(opts={})
|
61
|
+
@sda = opts[:sda] or raise "opts[:sda] = [gpio pin number] is required"
|
62
|
+
@scl = opts[:scl] or raise "opts[:scl] = [gpio pin number] is required"
|
63
|
+
@speed = opts[:speed] || 1 # kHz but insane
|
64
|
+
@clock = 1.0 / (@speed * 1000)
|
65
|
+
|
66
|
+
begin
|
67
|
+
GPIO.export(@sda)
|
68
|
+
GPIO.export(@scl)
|
69
|
+
rescue Errno::EBUSY => e
|
70
|
+
end
|
71
|
+
ObjectSpace.define_finalizer(self, self.class.finalizer([@scl, @sda]))
|
72
|
+
begin
|
73
|
+
GPIO.direction(@sda, :high)
|
74
|
+
GPIO.direction(@scl, :high)
|
75
|
+
GPIO.direction(@sda, :in)
|
76
|
+
GPIO.direction(@scl, :in)
|
77
|
+
rescue Errno::EACCES => e # writing to gpio after export is failed in a while
|
78
|
+
retry
|
79
|
+
end
|
80
|
+
end
|
58
81
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
retry
|
72
|
-
end
|
82
|
+
# Interface of I2CDevice::Driver
|
83
|
+
def i2cget(address, param, length=1)
|
84
|
+
ret = ""
|
85
|
+
start_condition
|
86
|
+
unless write( (address << 1) + 0)
|
87
|
+
raise I2CDevice::I2CIOError, "Unknown slave device (address:#{address})"
|
88
|
+
end
|
89
|
+
write(param)
|
90
|
+
stop_condition # AVR stucked with SCL low without this (Does not AVR support Sr condition?)
|
91
|
+
start_condition
|
92
|
+
unless write( (address << 1) + 1)
|
93
|
+
raise I2CDevice::I2CIOError, "Unknown slave device (address:#{address})"
|
73
94
|
end
|
95
|
+
length.times do |n|
|
96
|
+
ret << read(n != length - 1).chr
|
97
|
+
end
|
98
|
+
ret
|
99
|
+
ensure
|
100
|
+
stop_condition
|
101
|
+
end
|
74
102
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
raise I2CDevice::I2CIOError, "Unknown slave device (address:#{address})"
|
86
|
-
end
|
87
|
-
length.times do |n|
|
88
|
-
ret << read(n != length - 1).chr
|
103
|
+
# Interface of I2CDevice::Driver
|
104
|
+
def i2cset(address, *data)
|
105
|
+
sent = 0
|
106
|
+
start_condition
|
107
|
+
unless write( (address << 1) + 0)
|
108
|
+
raise I2CDevice::I2CIOError, "Unknown slave device (address:#{address})"
|
109
|
+
end
|
110
|
+
data.each do |c|
|
111
|
+
unless write(c)
|
112
|
+
break
|
89
113
|
end
|
90
|
-
|
91
|
-
ensure
|
92
|
-
stop_condition
|
114
|
+
sent += 1
|
93
115
|
end
|
116
|
+
sent
|
117
|
+
ensure
|
118
|
+
stop_condition
|
119
|
+
end
|
94
120
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
107
|
-
sent
|
108
|
-
ensure
|
109
|
-
stop_condition
|
121
|
+
private
|
122
|
+
|
123
|
+
# Send start condition (or repeated start condition)
|
124
|
+
# raise I2CDevice::I2CBUSBusy if SCL line is low
|
125
|
+
def start_condition
|
126
|
+
p :start_condition if @@DEBUG
|
127
|
+
sleep @clock
|
128
|
+
GPIO.direction(@sda, :in)
|
129
|
+
GPIO.direction(@scl, :in)
|
130
|
+
if GPIO.read(@scl) == 0
|
131
|
+
raise I2CDevice::I2CBUSBusy, "BUS is busy"
|
110
132
|
end
|
111
133
|
|
112
|
-
|
134
|
+
sleep @clock / 2
|
135
|
+
GPIO.direction(@scl, :high)
|
136
|
+
sleep @clock / 2
|
137
|
+
GPIO.direction(@sda, :low)
|
138
|
+
sleep @clock
|
139
|
+
end
|
113
140
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
141
|
+
# Send stop condition.
|
142
|
+
def stop_condition
|
143
|
+
p :stop_condition if @@DEBUG
|
144
|
+
GPIO.direction(@scl, :low)
|
145
|
+
sleep @clock / 2
|
146
|
+
GPIO.direction(@sda, :low)
|
147
|
+
sleep @clock / 2
|
148
|
+
GPIO.direction(@scl, :in)
|
149
|
+
sleep @clock / 2
|
150
|
+
GPIO.direction(@sda, :in)
|
151
|
+
sleep @clock / 2
|
152
|
+
end
|
153
|
+
|
154
|
+
# Write one _byte_ to BUS.
|
155
|
+
def write(byte)
|
156
|
+
p [:write, byte] if @@DEBUG
|
157
|
+
GPIO.direction(@scl, :low)
|
158
|
+
sleep @clock
|
159
|
+
|
160
|
+
7.downto(0) do |n|
|
161
|
+
GPIO.direction(@sda, byte[n] == 1 ? :high : :low)
|
118
162
|
GPIO.direction(@scl, :in)
|
119
|
-
|
120
|
-
|
163
|
+
until GPIO.read(@scl) == 1
|
164
|
+
# clock streching
|
165
|
+
sleep @clock
|
121
166
|
end
|
122
|
-
|
123
|
-
sleep @clock / 2
|
124
|
-
GPIO.direction(@scl, :high)
|
125
|
-
sleep @clock / 2
|
126
|
-
GPIO.direction(@sda, :low)
|
127
167
|
sleep @clock
|
128
|
-
end
|
129
|
-
|
130
|
-
def stop_condition
|
131
|
-
p :stop_condition if @@DEBUG
|
132
168
|
GPIO.direction(@scl, :low)
|
133
|
-
|
134
|
-
|
135
|
-
sleep @clock / 2
|
136
|
-
GPIO.direction(@scl, :in)
|
137
|
-
sleep @clock / 2
|
138
|
-
GPIO.direction(@sda, :in)
|
139
|
-
sleep @clock / 2
|
169
|
+
GPIO.write(@sda, false)
|
170
|
+
sleep @clock
|
140
171
|
end
|
141
172
|
|
142
|
-
|
143
|
-
|
144
|
-
|
173
|
+
GPIO.direction(@sda, :in)
|
174
|
+
GPIO.direction(@scl, :in)
|
175
|
+
sleep @clock / 2
|
176
|
+
ack = GPIO.read(@sda) == 0
|
177
|
+
sleep @clock / 2
|
178
|
+
while GPIO.read(@scl) == 0
|
145
179
|
sleep @clock
|
180
|
+
end
|
181
|
+
GPIO.direction(@scl, :low)
|
182
|
+
ack
|
183
|
+
end
|
146
184
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
end
|
154
|
-
sleep @clock
|
155
|
-
GPIO.direction(@scl, :low)
|
156
|
-
GPIO.write(@sda, false)
|
157
|
-
sleep @clock
|
158
|
-
end
|
185
|
+
# Read one byte from BUS.
|
186
|
+
# <tt>ack</tt> :: [true|flase] Send ack for this read.
|
187
|
+
# Returns :: [Integer] Byte
|
188
|
+
def read(ack=true)
|
189
|
+
p [:read, ack] if @@DEBUG
|
190
|
+
ret = 0
|
159
191
|
|
160
|
-
|
192
|
+
GPIO.direction(@scl, :low)
|
193
|
+
sleep @clock
|
194
|
+
GPIO.direction(@sda, :in)
|
195
|
+
|
196
|
+
8.times do
|
161
197
|
GPIO.direction(@scl, :in)
|
162
198
|
sleep @clock / 2
|
163
|
-
|
199
|
+
ret = (ret << 1) | GPIO.read(@sda)
|
164
200
|
sleep @clock / 2
|
165
|
-
while GPIO.read(@scl) == 0
|
166
|
-
sleep @clock
|
167
|
-
end
|
168
|
-
GPIO.direction(@scl, :low)
|
169
|
-
ack
|
170
|
-
end
|
171
|
-
|
172
|
-
def read(ack=true)
|
173
|
-
p [:read, ack] if @@DEBUG
|
174
|
-
ret = 0
|
175
|
-
|
176
201
|
GPIO.direction(@scl, :low)
|
177
202
|
sleep @clock
|
178
|
-
|
179
|
-
|
180
|
-
8.times do
|
181
|
-
GPIO.direction(@scl, :in)
|
182
|
-
sleep @clock / 2
|
183
|
-
ret = (ret << 1) | GPIO.read(@sda)
|
184
|
-
sleep @clock / 2
|
185
|
-
GPIO.direction(@scl, :low)
|
186
|
-
sleep @clock
|
187
|
-
end
|
203
|
+
end
|
188
204
|
|
189
|
-
|
205
|
+
GPIO.direction(@sda, ack ? :low : :high)
|
190
206
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
end
|
207
|
+
GPIO.write(@scl, true)
|
208
|
+
sleep @clock
|
209
|
+
GPIO.write(@scl, false)
|
210
|
+
sleep @clock
|
211
|
+
ret
|
197
212
|
end
|
198
213
|
end
|
199
|
-
|
data/lib/i2c/driver/i2c-dev.rb
CHANGED
@@ -2,53 +2,56 @@
|
|
2
2
|
require "i2c"
|
3
3
|
require "i2c/driver"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
raise I2CDevice::I2CIOError, "/dev/i2c-0 is required"
|
27
|
-
end
|
28
|
-
|
29
|
-
@path = path
|
5
|
+
class I2CDevice::Driver::I2CDev < Base
|
6
|
+
# ioctl command
|
7
|
+
# Ref. https://www.kernel.org/pub/linux/kernel/people/marcelo/linux-2.4/include/linux/i2c.h
|
8
|
+
I2C_RETRIES = 0x0701
|
9
|
+
I2C_TIMEOUT = 0x0702
|
10
|
+
I2C_SLAVE = 0x0703
|
11
|
+
I2C_SLAVE_FORCE = 0x0706
|
12
|
+
I2C_TENBIT = 0x0704
|
13
|
+
I2C_FUNCS = 0x0705
|
14
|
+
I2C_RDWR = 0x0707
|
15
|
+
I2C_SMBUS = 0x0720
|
16
|
+
I2C_UDELAY = 0x0705
|
17
|
+
I2C_MDELAY = 0x0706
|
18
|
+
|
19
|
+
# This depends on /dev/i2c-* (i2c-dev) feature on Linux. You may load i2c-dev kernel module.
|
20
|
+
# <tt>path</tt> :: [String] Path to /dev/i2c-* file.
|
21
|
+
#
|
22
|
+
# If _path_ is not specified, this method use <tt>Dir.glob("/dev/i2c-*").last</tt> for _path_
|
23
|
+
def initialize(path=nil)
|
24
|
+
if path.nil?
|
25
|
+
path = Dir.glob("/dev/i2c-*").sort.last
|
30
26
|
end
|
31
27
|
|
32
|
-
|
33
|
-
|
34
|
-
i2c.ioctl(I2C_SLAVE, address)
|
35
|
-
i2c.syswrite(param.chr)
|
36
|
-
ret = i2c.sysread(length)
|
37
|
-
i2c.close
|
38
|
-
ret
|
39
|
-
rescue Errno::EIO => e
|
40
|
-
raise I2CDevice::I2CIOError, e.message
|
28
|
+
unless File.exist?(path)
|
29
|
+
raise I2CDevice::I2CIOError, "/dev/i2c-0 is required"
|
41
30
|
end
|
42
31
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
32
|
+
@path = path
|
33
|
+
end
|
34
|
+
|
35
|
+
# Interface of I2CDevice::Driver
|
36
|
+
def i2cget(address, param, length)
|
37
|
+
i2c = File.open(@path, "r+")
|
38
|
+
i2c.ioctl(I2C_SLAVE, address)
|
39
|
+
i2c.syswrite(param.chr)
|
40
|
+
ret = i2c.sysread(length)
|
41
|
+
i2c.close
|
42
|
+
ret
|
43
|
+
rescue Errno::EIO => e
|
44
|
+
raise I2CDevice::I2CIOError, e.message
|
51
45
|
end
|
52
|
-
end
|
53
46
|
|
47
|
+
# Interface of I2CDevice::Driver
|
48
|
+
def i2cset(address, *data)
|
49
|
+
i2c = File.open(@path, "r+")
|
50
|
+
i2c.ioctl(I2C_SLAVE, address)
|
51
|
+
i2c.syswrite(data.pack("C*"))
|
52
|
+
i2c.close
|
53
|
+
rescue Errno::EIO => e
|
54
|
+
raise I2CDevice::I2CIOError, e.message
|
55
|
+
end
|
56
|
+
end
|
54
57
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i2c-devices
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- cho45
|
@@ -42,7 +42,8 @@ description: i2c-devices is a drivers for i2c devices
|
|
42
42
|
email: cho45@lowreal.net
|
43
43
|
executables: []
|
44
44
|
extensions: []
|
45
|
-
extra_rdoc_files:
|
45
|
+
extra_rdoc_files:
|
46
|
+
- README.md
|
46
47
|
files:
|
47
48
|
- .gitignore
|
48
49
|
- ChangeLog
|
@@ -72,7 +73,9 @@ licenses:
|
|
72
73
|
- MIT
|
73
74
|
metadata: {}
|
74
75
|
post_install_message:
|
75
|
-
rdoc_options:
|
76
|
+
rdoc_options:
|
77
|
+
- --main
|
78
|
+
- README.md
|
76
79
|
require_paths:
|
77
80
|
- lib
|
78
81
|
required_ruby_version: !ruby/object:Gem::Requirement
|