i2c.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. # -*- coding: utf-8-*-
  2. #
  3. # This file is part of stdd, the simple time display daemon,
  4. # written by Helmut Pozimski <helmut@pozimski.eu>,
  5. # licensed under the 3-clause BSD license
  6. # This file was originally written by Written by Limor Fried, Kevin Townsend
  7. # and Mikey Sklar for Adafruit Industries. BSD license,
  8. # all text above must be included in any redistribution
  9. """
  10. ===========================================================================
  11. AdafruitI2c Class
  12. ===========================================================================
  13. """
  14. from __future__ import print_function
  15. from smbus import SMBus
  16. class AdafruitI2c(object):
  17. """ This class provides low level i2c access.
  18. """
  19. @staticmethod
  20. def get_pi_revision():
  21. """Gets the version number of the Raspberry Pi board"""
  22. # Courtesy quick2wire-python-api
  23. # https://github.com/quick2wire/quick2wire-python-api
  24. try:
  25. with open('/proc/cpuinfo', 'r') as file_obj:
  26. for line in file_obj:
  27. if line.startswith('Revision'):
  28. return 1 if line.rstrip()[-1] in ['1', '2'] else 2
  29. except IOError:
  30. return 0
  31. @staticmethod
  32. def get_pi_i2c_bus_number():
  33. """ Gets the I2C bus number /dev/i2c# """
  34. return 1 if AdafruitI2c.get_pi_revision() > 1 else 0
  35. def __init__(self, address, busnum=-1, debug=False):
  36. self.address = address
  37. # By default, the correct I2C bus is auto-detected using /proc/cpuinfo
  38. # Alternatively, you can hard-code the bus version below:
  39. # self.bus = smbus.SMBus(0); # Force I2C0 (early 256MB Pi's)
  40. # self.bus = smbus.SMBus(1); # Force I2C1 (512MB Pi's)
  41. self.bus = SMBus(
  42. busnum if busnum >= 0 else AdafruitI2c.get_pi_i2c_bus_number())
  43. self.debug = debug
  44. @staticmethod
  45. def reverse_byte_order(data):
  46. """Reverses the byte order of an int (16-bit) or long (32-bit) value"""
  47. # Courtesy Vishal Sapre
  48. byte_count = len(hex(data)[2:].replace('L', '')[::2])
  49. val = 0
  50. for i in range(byte_count):
  51. val = (val << 8) | (data & 0xff)
  52. data >>= 8
  53. return val
  54. @staticmethod
  55. def err_msg():
  56. """Raises an exception."""
  57. raise Exception("cannot connect to device, check hardware address!")
  58. def write8(self, reg, value):
  59. """Writes an 8-bit value to the specified register/address"""
  60. try:
  61. self.bus.write_byte_data(self.address, reg, value)
  62. if self.debug:
  63. print("I2C: Wrote 0x%02X to register 0x%02X" % (value, reg))
  64. except IOError:
  65. return self.err_msg()
  66. def write16(self, reg, value):
  67. """Writes a 16-bit value to the specified register/address pair"""
  68. try:
  69. self.bus.write_word_data(self.address, reg, value)
  70. if self.debug:
  71. print("I2C: Wrote 0x%02X to register pair 0x%02X,0x%02X" %
  72. (value, reg, reg+1))
  73. except IOError:
  74. return self.err_msg()
  75. def write_list(self, reg, w_list):
  76. """Writes an array of bytes using I2C format"""
  77. try:
  78. if self.debug:
  79. print("I2C: Writing list to register 0x%02X:" % reg)
  80. print(w_list)
  81. self.bus.write_i2c_block_data(self.address, reg, w_list)
  82. except IOError:
  83. return self.err_msg()
  84. def read_list(self, reg, length):
  85. """Read a list of bytes from the I2C device"""
  86. try:
  87. results = self.bus.read_i2c_block_data(self.address, reg, length)
  88. if self.debug:
  89. print ("I2C: Device 0x % 02X returned the following from \
  90. reg 0x % 02X" % (self.address, reg))
  91. print(results)
  92. return results
  93. except IOError:
  94. return self.err_msg()
  95. def read_u8(self, reg):
  96. """Read an unsigned byte from the I2C device"""
  97. try:
  98. result = self.bus.read_byte_data(self.address, reg)
  99. if self.debug:
  100. print("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
  101. (self.address, result & 0xFF, reg))
  102. return result
  103. except IOError:
  104. return self.err_msg()
  105. def read_s8(self, reg):
  106. """Reads a signed byte from the I2C device"""
  107. try:
  108. result = self.bus.read_byte_data(self.address, reg)
  109. if result > 127:
  110. result -= 256
  111. if self.debug:
  112. print("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
  113. (self.address, result & 0xFF, reg))
  114. return result
  115. except IOError:
  116. return self.err_msg()
  117. def read_u16(self, reg):
  118. """Reads an unsigned 16-bit value from the I2C device"""
  119. try:
  120. hibyte = self.read_u8(reg)
  121. lobyte = self.read_u8(reg+1)
  122. result = (hibyte << 8) + lobyte
  123. if self.debug:
  124. print("I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (
  125. self.address, result & 0xFFFF, reg))
  126. return result
  127. except IOError:
  128. return self.err_msg()
  129. def read_s16(self, reg):
  130. """Reads a signed 16-bit value from the I2C device"""
  131. try:
  132. hibyte = self.read_s8(reg)
  133. lobyte = self.read_u8(reg+1)
  134. result = (hibyte << 8) + lobyte
  135. if self.debug:
  136. print("I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" %
  137. (self.address, result & 0xFFFF, reg))
  138. return result
  139. except IOError:
  140. return self.err_msg()
  141. def read_u16_rev(self, reg):
  142. """Reads an unsigned 16-bit value from the I2C device with rev byte
  143. order.
  144. """
  145. try:
  146. lobyte = self.read_u8(reg)
  147. hibyte = self.read_u8(reg+1)
  148. result = (hibyte << 8) + lobyte
  149. if self.debug:
  150. print("I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" %
  151. (self.address, result & 0xFFFF, reg))
  152. return result
  153. except IOError:
  154. return self.err_msg()
  155. def read_s16_rev(self, reg):
  156. """Reads a signed 16-bit value from the I2C device with rev byte
  157. order.
  158. """
  159. try:
  160. lobyte = self.read_s8(reg)
  161. hibyte = self.read_u8(reg+1)
  162. result = (hibyte << 8) + lobyte
  163. if self.debug:
  164. print("I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (
  165. self.address, result & 0xFFFF, reg))
  166. return result
  167. except IOError:
  168. return self.err_msg()
  169. if __name__ == '__main__':
  170. try:
  171. BUS = AdafruitI2c(address=0)
  172. print("Default I2C bus is accessible")
  173. except:
  174. print("Error accessing default I2C bus")