Yet Another WebIOPi+
 All Classes Namespaces Files Functions Variables Macros Pages
mcp23XXX.py
Go to the documentation of this file.
1 # Copyright 2012-2013 Eric Ptak - trouch.com
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 from webiopi.utils.types import toint
16 from webiopi.devices.i2c import I2C
17 from webiopi.devices.spi import SPI
18 from webiopi.devices.digital import GPIOPort
19 
21  IODIR = 0x00
22  IPOL = 0x01
23  GPINTEN = 0x02
24  DEFVAL = 0x03
25  INTCON = 0x04
26  IOCON = 0x05
27  GPPU = 0x06
28  INTF = 0x07
29  INTCAP = 0x08
30  GPIO = 0x09
31  OLAT = 0x0A
32 
33  def __init__(self, channelCount):
34  GPIOPort.__init__(self, channelCount)
35  self.banks = int(channelCount / 8)
36 
37  def getAddress(self, register, channel=0):
38  return register * self.banks + int(channel / 8)
39 
40  def getChannel(self, register, channel):
41  self.checkDigitalChannel(channel)
42  addr = self.getAddress(register, channel)
43  mask = 1 << (channel % 8)
44  return (addr, mask)
45 
46  def __digitalRead__(self, channel):
47  (addr, mask) = self.getChannel(self.GPIO, channel)
48  d = self.readRegister(addr)
49  return (d & mask) == mask
50 
51  def __digitalWrite__(self, channel, value):
52  (addr, mask) = self.getChannel(self.GPIO, channel)
53  d = self.readRegister(addr)
54  if value:
55  d |= mask
56  else:
57  d &= ~mask
58  self.writeRegister(addr, d)
59 
60  def __getFunction__(self, channel):
61  (addr, mask) = self.getChannel(self.IODIR, channel)
62  d = self.readRegister(addr)
63  return self.IN if (d & mask) == mask else self.OUT
64 
65  def __setFunction__(self, channel, value):
66  if not value in [self.IN, self.OUT]:
67  raise ValueError("Requested function not supported")
68 
69  (addr, mask) = self.getChannel(self.IODIR, channel)
70  d = self.readRegister(addr)
71  if value == self.IN:
72  d |= mask
73  else:
74  d &= ~mask
75  self.writeRegister(addr, d)
76 
77  def __portRead__(self):
78  value = 0
79  for i in range(self.banks):
80  value |= self.readRegister(self.banks*self.GPIO+i) << 8*i
81  return value
82 
83  def __portWrite__(self, value):
84  for i in range(self.banks):
85  self.writeRegister(self.banks*self.GPIO+i, (value >> 8*i) & 0xFF)
86 
88  def __init__(self, slave, channelCount, name):
89  I2C.__init__(self, toint(slave))
90  MCP23XXX.__init__(self, channelCount)
91  self.name = name
92 
93  def __str__(self):
94  return "%s(slave=0x%02X)" % (self.name, self.slave)
95 
97  def __init__(self, slave=0x20):
98  MCP230XX.__init__(self, slave, 8, "MCP23008")
99 
101  def __init__(self, slave=0x20):
102  MCP230XX.__init__(self, slave, 8, "MCP23009")
103 
105  def __init__(self, slave=0x20):
106  MCP230XX.__init__(self, slave, 16, "MCP23017")
107 
109  def __init__(self, slave=0x20):
110  MCP230XX.__init__(self, slave, 16, "MCP23018")
111 
113  SLAVE = 0x20
114 
115  WRITE = 0x00
116  READ = 0x01
117 
118  def __init__(self, chip, slave, channelCount, name):
119  SPI.__init__(self, toint(chip), 0, 8, 10000000)
120  MCP23XXX.__init__(self, channelCount)
121  self.slave = self.SLAVE
122  iocon_value = 0x08 # Hardware Address Enable
123  iocon_addr = self.getAddress(self.IOCON)
124  self.writeRegister(iocon_addr, iocon_value)
125  self.slave = toint(slave)
126  self.name = name
127 
128  def __str__(self):
129  return "%s(chip=%d, slave=0x%02X)" % (self.name, self.chip, self.slave)
130 
131  def readRegister(self, addr):
132  d = self.xfer([(self.slave << 1) | self.READ, addr, 0x00])
133  return d[2]
134 
135  def writeRegister(self, addr, value):
136  self.writeBytes([(self.slave << 1) | self.WRITE, addr, value])
137 
139  def __init__(self, chip=0, slave=0x20):
140  MCP23SXX.__init__(self, chip, slave, 8, "MCP23S08")
141 
143  def __init__(self, chip=0, slave=0x20):
144  MCP23SXX.__init__(self, chip, slave, 8, "MCP23S09")
145 
147  def __init__(self, chip=0, slave=0x20):
148  MCP23SXX.__init__(self, chip, slave, 16, "MCP23S17")
149 
151  def __init__(self, chip=0, slave=0x20):
152  MCP23SXX.__init__(self, chip, slave, 16, "MCP23S18")
153