i2c 0.1.1 → 0.2.0
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.
- 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
|