i2c  1.4.2
RoadNarrows Robotics I2C Package
i2c.py
Go to the documentation of this file.
1 #
2 # Package: RoadNarrows Robotics I2C
3 #
4 # Module: rnr.i2c
5 #
6 # Link: https://roadnarrows.com
7 #
8 # File: i2c.py
9 #
10 
11 ## \file
12 ##
13 ## $LastChangedDate: 2016-02-04 09:24:32 -0700 (Thu, 04 Feb 2016) $
14 ## $Rev: 4304 $
15 ##
16 ## \brief RoadNarrows Robotics I2C module.
17 ##
18 ## \author: Robin Knight (robin.knight@roadnarrows.com)
19 ##
20 ## \copyright
21 ## \h_copy 2016-2017. RoadNarrows LLC.\n
22 ## http://www.roadnarrows.com\n
23 ## All Rights Reserved
24 #
25 # @EulaBegin@
26 #
27 # Permission is hereby granted, without written agreement and without
28 # license or royalty fees, to use, copy, modify, and distribute this
29 # software and its documentation for any purpose, provided that
30 # (1) The above copyright notice and the following two paragraphs
31 # appear in all copies of the source code and (2) redistributions
32 # including binaries reproduces these notices in the supporting
33 # documentation. Substantial modifications to this software may be
34 # copyrighted by their authors and need not follow the licensing terms
35 # described here, provided that the new terms are clearly indicated in
36 # all files where they apply.
37 #
38 # IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
39 # OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
40 # PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
41 # DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
42 # EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
43 # THE POSSIBILITY OF SUCH DAMAGE.
44 #
45 # THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
46 # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
47 # FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
48 # "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
49 # PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
50 #
51 # @EulaEnd@
52 #
53 
54 """
55 RoadNarrows Robotics I2C.
56 """
57 
58 import os
59 
60 import rnr.i2ccore as i2ccore
61 import rnr.basetypes as basetypes
62 
63 
64 # ------------------------------------------------------------------------------
65 # Fixed Data
66 # ------------------------------------------------------------------------------
67 
68 #
69 # Seven bit addresses
70 #
71 I2C_ADDR_LOW = 0x08 ## lowest address
72 I2C_ADDR_HIGH = 0x77 ## higest address
73 I2C_ADDR_NONE = 0xffff ## no address
74 
75 
76 # ------------------------------------------------------------------------------
77 # Class I2CException
78 # ------------------------------------------------------------------------------
79 
80 ##
81 ## \brief I2C exception class.
82 ##
83 class I2CException(Exception):
84  ##
85  ## \brief Constructor.
86  ##
87  ## \param msg Error message string.
88  ##
89  def __init__(self, msg):
90  ## error message attribute
91  self.message = msg
92 
93  def __repr__(self):
94  return "I2CException(%s)" % (repr(self.message))
95 
96  def __str__(self):
97  return self.message
98 
99 
100 #-------------------------------------------------------------------------------
101 # Class i2c
102 #-------------------------------------------------------------------------------
103 
104 ##
105 ## \brief I2C class.
106 ##
107 class i2c:
108  #
109  ## \brief Class constructor.
110  #
111  def __init__(self):
112  self.m_device = ""
113  self.m_fd = -1
114  self.m_addr = I2C_ADDR_NONE
115 
116  #
117  ## \brief Destructor.
118  #
119  def __del__(self):
120  if self.m_fd >= 0:
121  self.close()
122 
123  #
124  ## \brief Open a I2C bus device.
125  ##
126  ## Raises I2CException on error.
127  ##
128  ## \param device I2C device name (e.g. /dev/i2c-3).
129  #
130  def open(self, device):
131  fd = i2ccore.i2ccore_open(device)
132  if fd < 0:
133  e = -fd
134  raise I2CException("%s: open(): %s: (errno=%d)." % \
135  (device, os.strerror(e), e))
136  self.m_device = device
137  self.m_fd = fd;
138 
139  #
140  ## \brief Close an open I2C bus device.
141  ##
142  ## Raises I2CException on error.
143  #
144  def close(self):
145  if self.m_fd >= 0:
146  rc = i2ccore.i2ccore_close(self.m_fd)
147  if rc < 0:
148  e = -rc
149  raise I2CException("%s: close(): %s: (errno=%d)." % \
150  (self.m_device, os.strerror(e), e))
151  self.m_device = ""
152  self.m_fd = -1
153  self.m_addr = I2C_ADDR_NONE
154 
155  #
156  ## \brief Test if I2C bus is open.
157  ##
158  ## \return True or False.
159  #
160  def is_open(self):
161  if self.m_fd < 0:
162  return False
163  else:
164  return True
165 
166  #
167  ## \brief Read data from an attached device connected to the open I2C bus.
168  ##
169  ## Raises I2CException on error.
170  ##
171  ## \param addr Attached device address.
172  ## \param count Number of bytes to read.
173  ##
174  ## \return List of bytes.
175  #
176  def read(self, addr, count):
177  try:
178  rbuf = basetypes.ByteBuf(count)
179  except AssertionError, inst:
180  raise I2CException("%s: read(0x%02x, ...): %s" % \
181  (self.m_device, addr, inst.message))
182  n = i2ccore.i2ccore_read(self.m_fd, self.m_addr, addr,
183  rbuf.getSwigObj(), basetypes.sizeof(rbuf))
184  if n < 0:
185  e = -n
186  raise I2CException("%s: read(0x%02x, ...): %s: (errno=%d)." % \
187  (self.m_device, addr, os.strerror(e), e))
188  self.m_addr = addr
189  try:
190  rbuf.copyFromSwigObj(n)
191  except AssertionError, inst:
192  raise I2CException("%s: read(0x%02x, ...): %s" % \
193  (self.m_device, addr, inst.message))
194  return rbuf.buf
195 
196  #
197  ## \brief Write data to an attached device connected to the open I2C bus.
198  ##
199  ## Raises I2CException on error.
200  ##
201  ## \param addr Attached device address.
202  ## \param buf Buffer to write.
203  #
204  def write(self, addr, buf):
205  try:
206  wbuf = basetypes.ByteBuf.Clone(buf)
207  wbuf.copyToSwigObj(len(wbuf))
208  except AssertionError, inst:
209  raise I2CException("%s: write(0x%02x, ...): %s" % \
210  (self.m_device, addr, inst.message))
211  n = i2ccore.i2ccore_write(self.m_fd, self.m_addr, addr,
212  wbuf.getSwigObj(), len(wbuf))
213  if n < 0:
214  e = -n
215  raise I2CException("%s: write(0x%02x, ...): %s: (errno=%d)." % \
216  (self.m_device, addr, os.strerror(e), e))
217  self.m_addr = addr
218 
219  #
220  ## \brief Transfer data to an attached device connected to the open I2C bus
221  ## and receive response.
222  ##
223  ## \note Not all devices support optimize transfer. Use write_read() as an
224  ## alternate is these cases.
225  ##
226  ## Raises I2CException on error.
227  ##
228  ## \param addr Attached device address.
229  ## \param buf Buffer to transfer.
230  ## \param count Number of bytes to read back.
231  #
232  def transfer(self, addr, buf, count):
233  try:
234  wbuf = basetypes.ByteBuf.Clone(buf)
235  wbuf.copyToSwigObj(len(wbuf))
236  rbuf = basetypes.ByteBuf(count)
237  except AssertionError, inst:
238  raise I2CException("%s: transfer(0x%02x, ...): %s" % \
239  (self.m_device, addr, inst.message))
240  rc = i2ccore.i2ccore_transfer(self.m_fd, self.m_addr, addr,
241  wbuf.getSwigObj(), len(wbuf),
242  rbuf.getSwigObj(), basetypes.sizeof(rbuf))
243  if rc < 0:
244  e = -rc
245  raise I2CException("%s: transfer(0x%02x, ...): %s: (errno=%d)." % \
246  (self.m_device, addr, os.strerror(e), e))
247  self.m_addr = addr
248  try:
249  rbuf.copyFromSwigObj(n)
250  except AssertionError, inst:
251  raise I2CException("%s: read(0x%02x, ...): %s" % \
252  (self.m_device, addr, inst.message))
253  return rbuf.buf
254 
255  #
256  ## \brief Write/read data to/from an attached device connected to the open
257  ## I2C bus.
258  ##
259  ## Raises I2CException on error.
260  ##
261  ## \param addr Attached device address.
262  ## \param buf Buffer to transfer.
263  ## \param count Number of bytes to read back.
264  ##
265  ## \return List of bytes.
266  #
267  def write_read(self, addr, buf, count):
268  self.write(addr, buf)
269  return self.read(addr, count)
270 
271  #
272  ## \brief Test for the existence of a device with the given address.
273  ##
274  ## \param addr Device address to check.
275  ##
276  ## \return True or False.
277  #
278  def check(self, addr):
279  rc = i2ccore.i2ccore_check(self.m_fd, self.m_addr, addr)
280  self.m_addr = addr
281  if rc == 1:
282  return True
283  else:
284  return False
285 
286  #
287  ## \brief Scan I2C bus for all attached devices.
288  ##
289  ## \return List of addresses of found devices.
290  #
291  def scan(self):
292  found = []
293  for addr in range(I2C_ADDR_LOW, I2C_ADDR_HIGH+1):
294  if self.check(addr):
295  found += [addr]
296  return found
m_device
Definition: i2c.py:112
def __del__(self)
Destructor.
Definition: i2c.py:119
def check(self, addr)
Test for the existence of a device with the given address.
Definition: i2c.py:278
I2C class.
Definition: i2c.py:107
def write(self, addr, buf)
Write data to an attached device connected to the open I2C bus.
Definition: i2c.py:204
def transfer(self, addr, buf, count)
Transfer data to an attached device connected to the open I2C bus and receive response.
Definition: i2c.py:232
def read(self, addr, count)
Read data from an attached device connected to the open I2C bus.
Definition: i2c.py:176
def scan(self)
Scan I2C bus for all attached devices.
Definition: i2c.py:291
def close(self)
Close an open I2C bus device.
Definition: i2c.py:144
def write_read(self, addr, buf, count)
Write/read data to/from an attached device connected to the open I2C bus.
Definition: i2c.py:267
def open(self, device)
Open a I2C bus device.
Definition: i2c.py:130
def is_open(self)
Test if I2C bus is open.
Definition: i2c.py:160
message
error message attribute
Definition: i2c.py:91
def __init__(self)
Class constructor.
Definition: i2c.py:111
no address
Definition: i2c.py:83
RoadNarrows Robotics Swigged Core Python Interface Module.
Definition: i2ccore.py:1
def __init__(self, msg)
Constructor.
Definition: i2c.py:89