smbus.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. """pysmbus - A ure Python implementation of the I2C SMBus protocol."""
  2. # Copyright (C) 2015 Bjorn Tillenius <bjorn@tilenius.me>
  3. #
  4. # This library is free software; you can redistribute it and/or
  5. # # modify it under the terms of the GNU Library General Public
  6. # License as published by the Free Software Foundation;
  7. # version 2 of the License.
  8. #
  9. # This library is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. # Library General Public License for more details.
  13. # You should have received a copy of the GNU Library General Public
  14. # License along with this library; if not, write to the Free Software
  15. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  16. # MA 02110-1301 USA
  17. import posix
  18. import struct
  19. from fcntl import ioctl
  20. from ctypes import c_int, c_uint8, POINTER, Structure
  21. I2C_SLAVE = 0x0703
  22. I2C_SMBUS = 0x0720
  23. I2C_SMBUS_WRITE = 0
  24. I2C_SMBUS_READ = 1
  25. I2C_SMBUS_BYTE_DATA = 2
  26. LP_c_uint8 = POINTER(c_uint8)
  27. class i2c_smbus_msg(Structure):
  28. _fields_ = [
  29. ('read_write', c_uint8), # Should be c_char, but c_uint8 is the
  30. # same size is makes it easier to
  31. # support both Python 2.7 and 3.x.
  32. ('command', c_uint8),
  33. ('size', c_int),
  34. ('data', LP_c_uint8)]
  35. __slots__ = [name for name,type in _fields_]
  36. class SMBus(object):
  37. def __init__(self, bus):
  38. self.fd = posix.open("/dev/i2c-{}".format(bus), posix.O_RDWR)
  39. self.addr = None
  40. def _set_addr(self, addr):
  41. if self.addr != addr:
  42. ioctl(self.fd, I2C_SLAVE, addr);
  43. def write_byte_data(self, i2c_addr, register, value):
  44. """Write a single byte to a designated register."""
  45. self._set_addr(i2c_addr)
  46. byte_value = c_uint8(value)
  47. data_pointer = LP_c_uint8(byte_value)
  48. msg = i2c_smbus_msg(
  49. read_write=I2C_SMBUS_WRITE, command=register,
  50. size=I2C_SMBUS_BYTE_DATA, data=data_pointer)
  51. ioctl(self.fd, I2C_SMBUS, msg)
  52. def write_byte(self, i2c_addr, value):
  53. self._set_addr(i2c_addr)
  54. posix.write(self.fd, bytes([value]))
  55. def read_byte_data(self, i2c_addr, register):
  56. """Read a single byte from a designated register."""
  57. self._set_addr(i2c_addr)
  58. data_pointer = LP_c_uint8(c_uint8())
  59. msg = i2c_smbus_msg(
  60. read_write=I2C_SMBUS_READ, command=register,
  61. size=I2C_SMBUS_BYTE_DATA, data=data_pointer)
  62. ioctl(self.fd, I2C_SMBUS, msg)
  63. [result] = struct.unpack("@b", data_pointer.contents)
  64. return result
  65. def read_byte(self, i2c_addr):
  66. self._set_addr(i2c_addr)
  67. return posix.read(self.fd, 1)