Source code for piripherals.bus

"""Wrapper classes to abstract bus access."""

from functools import partial
try:
    from smbus import SMBus
except:
    try:
        from smbus2 import SMBus
    except:
        pass

__all__ = ['Bus', 'Device']


[docs]class Bus: """Abstraction for a data bus, i.e. I2C. Args: bus: something with read and write methods. It does not have such methods, bus is passed to ``SMBus(bus)``. The ``bus`` need to have at least the following methods - ``read_byte_data(addr,reg)`` -> ``byte`` - ``write_byte_data(addr,reg,byte)`` and additionally - ``read_word_data(addr,reg)`` -> ``word`` - ``write_word_data(addr,reg,work)`` - ``read_i2c_block_data(addr,reg,size)`` -> ``[byte,...]`` - ``write_i2c_block_data(addr,reg,[byte,...])`` If these are not present, it will read/write words and blocks using ``read_byte_data`` and ``write_byte_data``. The bus usually is an ``smbus.SMBus`` or ``smbus2.SMBus`` instance. - https://pypi.python.org/pypi/smbus2/ - https://pypi.python.org/pypi/smbus-cffi/ - https://packages.debian.org/de/stretch/python-smbus """ def __init__(self, bus=1): if not hasattr(bus, 'read_byte_data'): bus = SMBus(bus) self.read_byte = bus.read_byte_data try: self.read_word = bus.read_word_data except: pass try: self.read_block = bus.read_i2c_block_data except: pass self.write_byte = bus.write_byte_data try: self.write_word = bus.write_word_data except: pass try: self.write_block = bus.write_i2c_block_data except: pass
[docs] def read_byte(self, addr, reg): """read a byte. Args: addr (int): address of device to read the byte from reg (int): register to be read Returns: int: the byte, that was read """ raise NotImplementedException()
[docs] def read_word(self, addr, reg): """read a word (2 bytes). Args: addr (int): address of device to read the word from reg (int): base register, low byte of the word is there, high byte is at reg+1 Returns: int: the word, that was read """ return self.read_byte(addr, reg) | self.read_byte(addr, reg + 1) << 8
[docs] def read_block(self, addr, reg, n): """read a block of bytes. Args: addr (int): address of device to read the block from reg (int): base register, first byte of the block n (int): # of bytes to read n<=32 Returns: list of int: bytes, that were read """ blocks = [] for i in range(n): blocks.append(self.read_byte(addr, reg + i)) return blocks
[docs] def write_byte(self, addr, reg, byte): """write a byte. Args: addr (int): address of device to write the byte to reg (int): register to write to byte (int): byte to be written """ raise NotImplementedException()
[docs] def write_word(self, addr, reg, word): """write a word (2 bytes). Args: addr (int): address of device to write the word to reg (int): base register, low byte of the word is there, high byte is at reg+1 word (int): word to be written """ self.write_byte(addr, reg, word & 0xff) self.write_byte(addr, reg + 1, (word >> 8) & 0xff)
[docs] def write_block(self, addr, reg, block): """write a block of bytes. Args: addr (int): address of device to write the block to reg (int): base register, first byte of the block block (list of int): bytes to be written, len(block)<=32 """ for b in block: self.write_byte(addr, reg, b) reg += 1
[docs] def device(self, addr): """Get a Device. Args: addr (int): device address Returns: Device: device at given address """ return Device(self, addr)
[docs]class Device: """Abstraction of a device on a bus. It has the same methods as Bus, but with the ``addr`` already set. Args: bus (Bus): the bus the Device is attached to addr (int): address of the device """ def __init__(self, bus, addr): self.read_byte = partial(bus.read_byte, addr) self.read_word = partial(bus.read_word, addr) self.read_block = partial(bus.read_block, addr) self.write_byte = partial(bus.write_byte, addr) self.write_word = partial(bus.write_word, addr) self.write_block = partial(bus.write_block, addr) def __getitem__(self, r): return self.read_byte(r) def __setitem__(self, r, b): self.write_byte(r, b)