i2c 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +11 -4
- data/lib/i2c.rb +1 -0
- data/lib/i2c/drivers/mcp23008.rb +98 -0
- data/lib/i2c/drivers/mcp23017.rb +1 -1
- data/test/mcp23008_spec.rb +86 -0
- data/test/mcp23017_spec.rb +2 -2
- metadata +4 -2
data/README.rdoc
CHANGED
@@ -41,19 +41,26 @@ first I2c bus on the system.
|
|
41
41
|
|
42
42
|
=== MCP23017
|
43
43
|
|
44
|
-
|
44
|
+
16 bit IO-Expander MCP23017 from Microchip. Provides a wiringpi-ruby compatible
|
45
45
|
API and may therefore be used as a drop-in replacement for IO tasks on a
|
46
|
-
Raspberry Pi.
|
46
|
+
Raspberry Pi.
|
47
|
+
Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf
|
48
|
+
|
49
|
+
=== MCP23008
|
50
|
+
|
51
|
+
8 bit IO-Expander MCP23008 from Microchip. Basically a small version of the
|
52
|
+
MCP23017.
|
53
|
+
Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21919e.pdf
|
47
54
|
|
48
55
|
== Acknowledgements
|
49
56
|
|
50
57
|
The low-level IO (mainly in i2c-dev.rb) was extracted from Ruby-I2C
|
51
58
|
(http://rubyforge.org/projects/i2c/) by Jonas Bähr <jonas.baehr@fs.ei.tum.de>
|
52
59
|
|
53
|
-
==
|
60
|
+
== Copyright / Licence
|
54
61
|
|
55
62
|
This code may be used under the terms of the GNU General Public Licence, Version 2.
|
56
63
|
|
57
64
|
Copyright (c) 2012 Christoph Anderegg <christoph@christoph-anderegg.ch>
|
58
|
-
Copyright (c) 2008 Jonas Bähr
|
65
|
+
Copyright (c) 2008 Jonas Bähr <jonas.baehr@fs.ei.tum.de>
|
59
66
|
|
data/lib/i2c.rb
CHANGED
@@ -0,0 +1,98 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# I2C IO-Expander driver
|
3
|
+
# for the MCP23008 8-bit IO-Expander.
|
4
|
+
#
|
5
|
+
# The interface is compatible to the interface
|
6
|
+
# of the WiringPi gem. PWM is not supported though.
|
7
|
+
#
|
8
|
+
# Copyright (c) 2012 Christoph Anderegg <christoph@christoph-anderegg.ch>
|
9
|
+
# This file may be distributed under the terms of the GNU General Public
|
10
|
+
# License Version 2.
|
11
|
+
#
|
12
|
+
|
13
|
+
require 'i2c/i2c.rb'
|
14
|
+
|
15
|
+
# Constants for mode()
|
16
|
+
INPUT = 1
|
17
|
+
OUTPUT = 0
|
18
|
+
|
19
|
+
# Constants for write()
|
20
|
+
HIGH = 1
|
21
|
+
LOW = 0
|
22
|
+
|
23
|
+
module I2C
|
24
|
+
module Drivers
|
25
|
+
class MCP23008
|
26
|
+
# Registers
|
27
|
+
IODIR = 0x00
|
28
|
+
GPIO = 0x09
|
29
|
+
|
30
|
+
# Creates an instance representing exactly one
|
31
|
+
# MCP23008 on one I2C-bus.
|
32
|
+
#
|
33
|
+
# device: I2C-device file (usually /dev/i2c-0).
|
34
|
+
# Or an intantiated io class that supports
|
35
|
+
# the necessary operations (#read, #write
|
36
|
+
# and #ioctl).
|
37
|
+
# address: Device address on the bus.
|
38
|
+
def initialize(device, address)
|
39
|
+
if device.kind_of?(String)
|
40
|
+
@device = ::I2C.create(device)
|
41
|
+
else
|
42
|
+
[ :read, :write ].each do |m|
|
43
|
+
raise IncompatibleDeviceException,
|
44
|
+
"Missing #{m} method in device object." unless device.respond_to?(m)
|
45
|
+
end
|
46
|
+
@device = device
|
47
|
+
end
|
48
|
+
@address = address
|
49
|
+
|
50
|
+
@dir = 0xFF # Direction is input initially
|
51
|
+
@device.write(@address, IODIR, @dir)
|
52
|
+
@data = @device.read(@address, 1, GPIO).unpack("C")[0]
|
53
|
+
end
|
54
|
+
|
55
|
+
def mode?(pin)
|
56
|
+
@dir = @device.read(@address, 1, IODIR).unpack("C")[0]
|
57
|
+
return (@dir >> pin) & 0x01
|
58
|
+
end
|
59
|
+
|
60
|
+
def mode(pin, pin_mode)
|
61
|
+
raise ArgumentError, "Pin not 0-7" unless (0..7).include?(pin)
|
62
|
+
raise ArgumentError, 'invalid value' unless [0,1].include?(pin_mode)
|
63
|
+
@dir = set_bit_value(@dir, pin, pin_mode)
|
64
|
+
@device.write(@address, IODIR, @dir)
|
65
|
+
end
|
66
|
+
|
67
|
+
def []=(pin, value)
|
68
|
+
raise ArgumentError, "Pin not 0-7" unless (0..7).include?(pin)
|
69
|
+
raise ArgumentError, 'invalid value' unless [0,1].include?(value)
|
70
|
+
@data = set_bit_value(@data, pin, value)
|
71
|
+
@device.write(@address, GPIO, @data)
|
72
|
+
end
|
73
|
+
alias :write :[]=
|
74
|
+
|
75
|
+
def [](pin)
|
76
|
+
raise ArgumentError, "Pin not 0-7." unless (0..7).include?(pin)
|
77
|
+
@data = @device.read(@address, 1, GPIO).unpack("C")[0]
|
78
|
+
return (@data >> pin) & 0x01
|
79
|
+
end
|
80
|
+
alias :read :[]
|
81
|
+
|
82
|
+
private
|
83
|
+
def set_bit_value(byte, bit, value)
|
84
|
+
mask = 0x00
|
85
|
+
mask = (0x01 << bit)
|
86
|
+
case value
|
87
|
+
when 0
|
88
|
+
byte = (byte & ((~mask) & 0xFF)) & 0xFF
|
89
|
+
when 1
|
90
|
+
byte = (byte | mask) & 0xFF
|
91
|
+
else
|
92
|
+
raise ArgumentError, "Bit not 0-7."
|
93
|
+
end
|
94
|
+
byte
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/i2c/drivers/mcp23017.rb
CHANGED
@@ -69,7 +69,7 @@ module I2C
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def mode(pin, pin_mode)
|
72
|
-
raise ArgumentError, "Pin not 0-15" unless (0..
|
72
|
+
raise ArgumentError, "Pin not 0-15" unless (0..15).include?(pin)
|
73
73
|
raise ArgumentError, 'invalid value' unless [0,1].include?(pin_mode)
|
74
74
|
if 8 <= pin
|
75
75
|
@dir_b = set_bit_value(@dir_b, (pin-8), pin_mode)
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'i2c'
|
2
|
+
|
3
|
+
class MockI2CIO
|
4
|
+
attr_reader :registers
|
5
|
+
attr_reader :last_address
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@registers = Hash.new
|
9
|
+
# Initialize according to data sheet
|
10
|
+
@registers[0x00] = 0xFF
|
11
|
+
(0x01..0x0A).each do |reg|
|
12
|
+
@registers[reg] = 0x00
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def write(address, *params)
|
17
|
+
@last_address = address
|
18
|
+
if params.count >= 1
|
19
|
+
reg_addr = params.shift
|
20
|
+
index = 0
|
21
|
+
params.each do |p|
|
22
|
+
@registers[reg_addr+index] = p
|
23
|
+
index += 1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def read(address, size, *params)
|
29
|
+
@last_address = address
|
30
|
+
answer = String.new
|
31
|
+
answer.force_encoding("US-ASCII")
|
32
|
+
if (size > 0) && (params.count >= 1)
|
33
|
+
reg_addr = params.shift
|
34
|
+
(0...size).each do |index|
|
35
|
+
answer << (@registers[reg_addr+index] & 0xFF)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
answer
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe I2C::Drivers::MCP23008, "#mode?" do
|
43
|
+
it "initially returns 1 for all pin modes" do
|
44
|
+
io = MockI2CIO.new
|
45
|
+
mcp23008 = I2C::Drivers::MCP23008.new(io, 0x20)
|
46
|
+
(0..7).each do |pin|
|
47
|
+
mcp23008.mode?(pin).should eq(1)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe I2C::Drivers::MCP23008, "#mode?" do
|
53
|
+
it "returns what has been set through #mode" do
|
54
|
+
io = MockI2CIO.new
|
55
|
+
mcp23008 = I2C::Drivers::MCP23008.new(io, 0x20)
|
56
|
+
(0..500).each do |pin|
|
57
|
+
pin = rand(8)
|
58
|
+
mode = rand(2)
|
59
|
+
mcp23008.mode(pin, mode)
|
60
|
+
mcp23008.mode?(pin).should eq(mode)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe I2C::Drivers::MCP23008, "#[]" do
|
66
|
+
it "initially returns 0 for all I/O pins" do
|
67
|
+
io = MockI2CIO.new
|
68
|
+
mcp23008 = I2C::Drivers::MCP23008.new(io, 0x20)
|
69
|
+
(0..7).each do |pin|
|
70
|
+
mcp23008[pin].should eq(0)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe I2C::Drivers::MCP23008, "#[]" do
|
76
|
+
it "returns what has been set through #[]=" do
|
77
|
+
io = MockI2CIO.new
|
78
|
+
mcp23008 = I2C::Drivers::MCP23008.new(io, 0x20)
|
79
|
+
(0..500).each do |pin|
|
80
|
+
pin = rand(8)
|
81
|
+
value = rand(2)
|
82
|
+
mcp23008[pin] = value
|
83
|
+
mcp23008[pin].should eq(value)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/test/mcp23017_spec.rb
CHANGED
@@ -44,9 +44,9 @@ end
|
|
44
44
|
describe I2C::Drivers::MCP23017, "#mode?" do
|
45
45
|
it "initially returns 1 for all pin modes" do
|
46
46
|
io = MockI2CIO.new
|
47
|
-
|
47
|
+
mcp23017 = I2C::Drivers::MCP23017.new(io, 0x20)
|
48
48
|
(0..15).each do |pin|
|
49
|
-
|
49
|
+
mcp23017.mode?(pin).should eq(1)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i2c
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-26 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Interface to I2C (aka TWI) implementations. Also provides abstractions
|
15
15
|
for some I2c-devices. Created with the Raspberry Pi in mind.
|
@@ -23,7 +23,9 @@ files:
|
|
23
23
|
- lib/i2c/i2c.rb
|
24
24
|
- lib/i2c/backends/i2c-dev.rb
|
25
25
|
- lib/i2c/drivers/mcp23017.rb
|
26
|
+
- lib/i2c/drivers/mcp23008.rb
|
26
27
|
- test//mcp23017_spec.rb
|
28
|
+
- test//mcp23008_spec.rb
|
27
29
|
- rules/88-i2c.rules
|
28
30
|
- README.rdoc
|
29
31
|
homepage: https://github.com/andec/i2c
|