i2c-devices 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|