Example #1
0
class MTSMBus(I2CBus):
    """ Multi-thread compatible SMBus bus.

    This is just a wrapper of SMBus, serializing I/O on the bus for use
    in multi-threaded context and adding _i2c_ variants of block transfers.
    """

    def __init__(self, bus_id=1, **kwargs):
        """
        :param int bus_id: the SMBus id (see Raspberry Pi documentation)
        :param kwargs: parameters transmitted to :py:class:`smbus.SMBus` initializer
        """
        I2CBus.__init__(self, **kwargs)
        self._bus = SMBus(bus_id)
        # I/O serialization lock
        self._lock = threading.Lock()

    def read_byte(self, addr):
        with self._lock:
            return self._bus.read_byte(addr)

    def write_byte(self, addr, data):
        with self._lock:
            self._bus.write_byte(addr, data)

    def read_byte_data(self, addr, reg):
        with self._lock:
            return self._bus.read_byte_data(addr, reg)

    def write_byte_data(self, addr, reg, data):
        with self._lock:
            self._bus.write_byte_data(addr, reg, data)

    def read_word_data(self, addr, reg):
        with self._lock:
            return self._bus.read_word_data(addr, reg)

    def write_word_data(self, addr, reg, data):
        with self._lock:
            self._bus.write_word_data(addr, reg, data)

    def read_block_data(self, addr, reg):
        with self._lock:
            return self._bus.read_block_data(addr, reg)

    def write_block_data(self, addr, reg, data):
        with self._lock:
            self._bus.write_block_data(addr, reg, data)

    def read_i2c_block_data(self, addr, reg, count):
        with self._lock:
            return self._bus.read_i2c_block_data(addr, reg, count)

    def write_i2c_block_data(self, addr, reg, data):
        with self._lock:
            self._bus.write_i2c_block_data(addr, reg, data)
Example #2
0
class LocalhostSMBusSlave(SMBusSlave):
    def __init__(self, bus, address):
        SMBusSlave.__init__(self, bus, address)
        self.bus = SMBus(bus)
        self.address = address

    #return: one byte hex string without '0x': '12'
    def get_byte(self, offset):
        #        print "%s %s" % (datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-4], sys._getframe().f_code.co_name)
        ret = self.bus.read_byte_data(self.address, offset)
        time.sleep(self.interval)
        data = hex(ret)
        return data[2:].zfill(2)

    #input: offset:str, data:int
    def set_byte(self, offset, data):
        #        print "%s %s" % (datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-4], sys._getframe().f_code.co_name)
        self.bus.write_byte_data(self.address, offset, data)
        time.sleep(self.interval)

    #return: two byte hex string without '0x': '1234'
    def get_word(self, offset):
        #        print "%s %s" % (datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-4], sys._getframe().f_code.co_name)
        ret = self.bus.read_word_data(self.address, offset)
        data = hex(ret)
        time.sleep(self.interval)
        return data[2:].zfill(4)

    def set_word(self, offset, data):
        #        print "%s %s" % (datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-4], sys._getframe().f_code.co_name)
        if sys.byteorder == "big":
            data = ((data & 0xff00) >> 8) + ((data & 0x00ff) << 8)
        self.bus.write_word_data(self.address, offset, data)
        time.sleep(self.interval)

    #return: hex string list per byte,without '0x' :['12', '0a']
    def get_block(self, offset, length="32"):
        #        print "%s %s" % (datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-4], sys._getframe().f_code.co_name)
        ret = self.bus.read_block_data(self.address, offset)
        time.sleep(self.interval)
        hex_ret = [hex(i)[2:].zfill(2) for i in ret]
        return hex_ret

    def set_block(self, offset, data):
        #        print "%s %s" % (datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-4], sys._getframe().f_code.co_name)
        data_arr = [(data & 0x00ff), ((data & 0xff00) >> 8)]
        #self.bus.write_i2c_block_data(self.address, offset, data_arr)
        self.bus.write_block_data(self.address, offset, data_arr)
        time.sleep(self.interval)
Example #3
0
class I2CDevice:
    def __init__(self, addr=None, addr_default=None, bus=BUS_NUMBER):
        if not addr:
            # try autodetect address, else use default if provided
            try:
                self.addr = int('0x{}'.format(
                    findall("[0-9a-z]{2}(?!:)", check_output(['/usr/sbin/i2cdetect', '-y', str(BUS_NUMBER)]).decode())[0]), base=16) \
                    if exists('/usr/sbin/i2cdetect') else addr_default
            except:
                self.addr = addr_default
        else:
            self.addr = addr
        self.bus = SMBus(bus)

    # write a single command
    def write_cmd(self, cmd):
        self.bus.write_byte(self.addr, cmd)
        sleep(0.0001)

    # write a command and argument
    def write_cmd_arg(self, cmd, data):
        self.bus.write_byte_data(self.addr, cmd, data)
        sleep(0.0001)

    # write a block of data
    def write_block_data(self, cmd, data):
        self.bus.write_block_data(self.addr, cmd, data)
        sleep(0.0001)

    # read a single byte
    def read(self):
        return self.bus.read_byte(self.addr)

    # read
    def read_data(self, cmd):
        return self.bus.read_byte_data(self.addr, cmd)

    # read a block of data
    def read_block_data(self, cmd):
        return self.bus.read_block_data(self.addr, cmd)
Example #4
0
    class LinuxI2cBus:
        """A Linux I²C device, which is itself an I²C bus.

        Should not be instantiated directly; use `LinuxI2c.find_devices`
        instead.

        This type mimics the `smbus.SMBus` read/write/close APIs.  However,
        `open` does not take any parameters, and not all APIs are available.
        """

        # note: this is not a liquidctl BaseBus, as that would cause
        # find_liquidctl_devices to try to directly instantiate it

        def __init__(self, i2c_dev):
            self._i2c_dev = i2c_dev
            self._smbus = None

            try:
                assert i2c_dev.name.startswith('i2c-')
                self._number = int(i2c_dev.name[4:])
            except:
                raise ValueError(f'cannot infer bus number')

        def find_devices(self, drivers, **kwargs):
            """Probe drivers and find compatible devices in this bus."""
            for drv in drivers:
                yield from drv.probe(self, **kwargs)

        def open(self):
            """Open the I²C bus."""
            if not self._smbus:
                try:
                    self._smbus = SMBus(self._number)
                except FileNotFoundError:
                    if Path('/sys/class/i2c-dev').exists():
                        raise
                    raise OSError('kernel module i2c-dev not loaded') from None

        def read_byte(self, address):
            """Read a single byte from a device."""
            value = self._smbus.read_byte(address)
            _LOGGER.debug('read byte @ 0x%02x: 0x%02x', address, value)
            return value

        def read_byte_data(self, address, register):
            """Read a single byte from a designated register."""
            value = self._smbus.read_byte_data(address, register)
            _LOGGER.debug('read byte data @ 0x%02x:0x%02x: 0x%02x', address,
                          register, value)
            return value

        def read_word_data(self, address, register):
            """Read a single 2-byte word from a given register."""
            value = self._smbus.read_word_data(address, register)
            _LOGGER.debug('read word data @ 0x%02x:0x%02x: 0x%04x', address,
                          register, value)
            return value

        def read_block_data(self, address, register):
            """Read a block of up to  32 bytes from a given register."""
            data = self._smbus.read_block_data(address, register)
            _LOGGER.debug('read block data @ 0x%02x:0x%02x: %r', address,
                          register, LazyHexRepr(data))
            return data

        def write_byte(self, address, value):
            """Write a single byte to a device."""
            _LOGGER.debug('writing byte @ 0x%02x: 0x%02x', address, value)
            return self._smbus.write_byte(address, value)

        def write_byte_data(self, address, register, value):
            """Write a single byte to a designated register."""
            _LOGGER.debug('writing byte data @ 0x%02x:0x%02x: 0x%02x', address,
                          register, value)
            return self._smbus.write_byte_data(address, register, value)

        def write_word_data(self, address, register, value):
            """Write a single 2-byte word to a designated register."""
            _LOGGER.debug('writing word data @ 0x%02x:0x%02x: 0x%04x', address,
                          register, value)
            return self._smbus.write_word_data(address, register, value)

        def write_block_data(self, address, register, data):
            """Write a block of byte data to a given register."""
            _LOGGER.debug('writing block data @ 0x%02x:0x%02x: %r', address,
                          register, LazyHexRepr(data))
            return self._smbus.write_block_data(address, register, data)

        def close(self):
            """Close the I²C connection."""
            if self._smbus:
                self._smbus.close()
                self._smbus = None

        def load_eeprom(self, address):
            """Return EEPROM name and data in `address`, or None if N/A."""

            # uses kernel facilities to avoid directly reading from the EEPROM
            # or managing its pages, also avoiding the need for unsafe=smbus

            dev = f'{self._number}-{address:04x}'
            try:
                name = self._i2c_dev.joinpath(dev, 'name').read_text().strip()
                eeprom = self._i2c_dev.joinpath(dev, 'eeprom').read_bytes()
                return LinuxEeprom(name, eeprom)
            except Exception as err:
                return None

        @property
        def name(self):
            return self._i2c_dev.name

        @property
        def description(self):
            return self._try_sysfs_read('name')

        @property
        def parent_vendor(self):
            return self._try_sysfs_read_hex('device/vendor')

        @property
        def parent_device(self):
            return self._try_sysfs_read_hex('device/device')

        @property
        def parent_subsystem_vendor(self):
            return self._try_sysfs_read_hex('device/subsystem_vendor')

        @property
        def parent_subsystem_device(self):
            return self._try_sysfs_read_hex('device/subsystem_device')

        @property
        def parent_driver(self):
            try:
                return Path(
                    os.readlink(self._i2c_dev.joinpath('device/driver'))).name
            except FileNotFoundError:
                return None

        def __str__(self):
            if self.description:
                return f'{self.name}: {self.description}'
            return self.name

        def __repr__(self):
            def hexid(maybe):
                if maybe is not None:
                    return f'{maybe:#06x}'
                return 'None'

            return f'{self.__class__.__name__}: name: {self.name!r}, ' \
                   f'description: {self.description!r}, ' \
                   f'parent_vendor: {hexid(self.parent_vendor)}, ' \
                   f'parent_device: {hexid(self.parent_device)}, ' \
                   f'parent_subsystem_vendor: {hexid(self.parent_subsystem_vendor)}, ' \
                   f'parent_subsystem_device: {hexid(self.parent_subsystem_device)}, ' \
                   f'parent_driver: {self.parent_driver!r}'

        def _try_sysfs_read(self, *sub, default=None):
            try:
                return self._i2c_dev.joinpath(*sub).read_text().rstrip()
            except FileNotFoundError:
                return default

        def _try_sysfs_read_hex(self, *sub, default=None):
            try:
                return int(self._i2c_dev.joinpath(*sub).read_text(), base=16)
            except FileNotFoundError:
                return default
Example #5
0
#  DroneBot Workshop 2019
#  https://dronebotworkshop.com

# https://raspberrypi.stackexchange.com/questions/8469/meaning-of-cmd-param-in-write-i2c-block-data
# http://wiki.erazor-zone.de/wiki%3alinux%3apython%3asmbus%3adoc

from smbus import SMBus
import time
from pdb import set_trace as st
from sys import exit

addr = 0x8  # bus address
bus = SMBus(1)  # indicates /dev/ic2-1

steerings = ['b', 'b', 't', 'b', 't', 't', 'b', 'b']
durations = [200, 134, 855, 565, 777, 254, 686, 741]

i = 0

while i < len(steerings):
    steering = ord(steerings[i])
    x_duration = "{:05}".format(durations[i])
    duration = [ord(d) for d in x_duration]
    print("%s %i %i %s" % (steerings[i], steering, durations[i], duration))
    bus.write_block_data(addr, steering, duration)
    time.sleep(0.95)
    i += 1

time.sleep(0.1)
Example #6
0
bus = SMBus(1)  # indicates /dev/ic2-1
"""
while 1:
    nb = input(">>>>   ")
    if int(nb) == 9:
        exit()
    msg= bus.read_i2c_block_data(addr, 7)
    st()
"""

while 1:
    print("combien de nombres a envoyer...")
    nb = input(">>>>   ")
    msg = [x + 48 for x in list(range(int(nb)))]
    print(msg)
    bus.write_block_data(addr, 7, msg)
    if int(nb) == 9:
        break
time.sleep(0.1)
"""
while 1:
    nb = input('>>>> ')
    lec = bus.read_byte(addr)
    print(type(lec))
    print(lec)
    print("\n")
    if int(nb) == 9:
        break;
"""

# time.sleep(1)
Example #7
0
        if len(data) != expected_data:
            print(
                f"Input is {len(data)} ints long. Must be {expected_data} ({int(expected_data/4)} sets of 4)"
            )
        else:
            vals = []
            for i in range(int(expected_data / 4)):
                # Take sets of 4 integers and remove '0x' from hex() value
                hexState = hex(int(data[i * 4:(i + 1) * 4]))[2:]

                # Forward pad sets of 4 hex values with 0s
                while len(hexState) < 4:
                    hexState = "0" + hexState

                print(f"state hex: {hexState}")

                vals.append(int(hexState[0:2], 16))
                vals.append(int(hexState[2:4], 16))

            print(f"vals: {vals}")
            bus.write_block_data(addr, 0x2, vals)
            time.sleep(1.0 / 1000.0)
            # response = "message passed to Teensy over I2C"

        # sock.sendall(response.encode('utf-8'))

finally:
    print("closing socket")
    sock.close()
Example #8
0
from smbus import SMBus
 
addr = 0x8 # bus address
bus = SMBus(0) # indicates /dev/ic2-0
 
numb = 1
 
while numb == 1:
    
    read = input("Read madthya write ah? ");
    if read == 0:
        #commands = input(">>>>   ")
        #numbers = [int(i) for i in list(commands.split(" "))]
        num = [12,13,14]
        bus.write_block_data(addr,6,num)
    elif read == 1:
        n=3
        a = []
        for i in range(n):
            a.append(bus.read_byte_data(addr,200))
        print(a)
        
    else:
        numb = 0
Example #9
0
    class LinuxI2cBus:
        """A Linux I²C device, which is itself an I²C bus.

        Should not be instantiated directly; use `LinuxI2c.find_devices`
        instead.

        This type mimics the `smbus.SMBus` read/write/close APIs.  However,
        `open` does not take any parameters, and not all APIs are available.
        """

        # note: this is not a liquidctl BaseBus, as that would cause
        # find_liquidctl_devices to try to directly instantiate it

        def __init__(self, i2c_dev):
            if not i2c_dev.name.startswith('i2c-'):
                raise ValueError('not a bus or unsupported adapter')

            self._i2c_dev = i2c_dev
            self._smbus = None
            self._number = int(i2c_dev.name[4:])

        def find_devices(self, drivers, **kwargs):
            """Probe drivers and find compatible devices in this bus."""
            for drv in drivers:
                yield from drv.probe(self, **kwargs)

        def open(self):
            """Open the I²C bus."""
            if not self._smbus:
                try:
                    self._smbus = SMBus(self._number)
                except FileNotFoundError:
                    if Path('/sys/class/i2c-dev').exists():
                        raise
                    raise OSError('kernel module i2c-dev not loaded') from None

        def read_byte(self, address):
            """Read a single byte from a device."""
            value = self._smbus.read_byte(address)
            _LOGGER.debug('read byte @ 0x%02x:0x%02x', address, value)
            return value

        def read_byte_data(self, address, register):
            """Read a single byte from a designated register."""
            value = self._smbus.read_byte_data(address, register)
            _LOGGER.debug('read byte data @ 0x%02x:0x%02x 0x%02x',
                          address, register, value)
            return value

        def read_word_data(self, address, register):
            """Read a single 2-byte word from a given register."""
            value = self._smbus.read_word_data(address, register)
            _LOGGER.debug('read word data @ 0x%02x:0x%02x 0x%02x',
                          address, register, value)
            return value

        def read_block_data(self, address, register):
            """Read a block of up to  32 bytes from a given register."""
            data = self._smbus.read_block_data(address, register)
            _LOGGER.debug('read block data @ 0x%02x:0x%02x: %r',
                          address, register, LazyHexRepr(data))
            return data

        def write_byte(self, address, value):
            """Write a single byte to a device."""
            _LOGGER.debug('writing byte @ 0x%02x: 0x%02x', address, value)
            return self._smbus.write_byte(address, value)

        def write_byte_data(self, address, register, value):
            """Write a single byte to a designated register."""
            _LOGGER.debug('writing byte data @ 0x%02x:0x%02x 0x%02x',
                          address, register, value)
            return self._smbus.write_byte_data(address, register, value)

        def write_word_data(self, address, register, value):
            """Write a single 2-byte word to a designated register."""
            _LOGGER.debug('writing word data @ 0x%02x:0x%02x 0x%02x',
                          address, register, value)
            return self._smbus.write_word_data(address, register, value)

        def write_block_data(self, address, register, data):
            """Write a block of byte data to a given register."""
            _LOGGER.debug('writing block data @ 0x%02x:0x%02x %r',
                          address, register, LazyHexRepr(data))
            return self._smbus.write_block_data(address, register, data)

        def close(self):
            """Close the I²C connection."""
            if self._smbus:
                self._smbus.close()
                self._smbus = None

        def load_eeprom(self, address):
            """Return EEPROM name and data in `address`, or None if N/A."""

            # uses kernel facilities to avoid directly reading from the EEPROM
            # or managing its pages, also avoiding the need for unsafe=smbus

            dev = f'{self._number}-{address:04x}'
            try:
                name = self._i2c_dev.joinpath(dev, 'name').read_text().strip()

                # work around a bug in the kernel by reading the ee1004 eeprom
                # in small enough chunks
                # related: #416 ("DDR4 support broken on Linux 5.16.3")
                # related: https://lore.kernel.org/lkml/[email protected]/
                eeprom_path = self._i2c_dev.joinpath(dev, 'eeprom')
                eeprom_size = eeprom_path.stat().st_size
                _LOGGER.debug('path=%s, size=%s', eeprom_path, eeprom_size)
                with eeprom_path.open(mode='rb', buffering=0) as f:
                    eeprom = bytearray()
                    while len(eeprom) < eeprom_size:
                        b = f.read(128)
                        if not b:
                            break
                        eeprom.extend(b)

                return LinuxEeprom(name, eeprom)
            except FileNotFoundError:
                return None

        @property
        def name(self):
            return self._i2c_dev.name

        @property
        def description(self):
            return self._try_sysfs_read('name')

        @property
        def parent_vendor(self):
            return self._try_sysfs_read_hex('device/vendor')

        @property
        def parent_device(self):
            return self._try_sysfs_read_hex('device/device')

        @property
        def parent_subsystem_vendor(self):
            return self._try_sysfs_read_hex('device/subsystem_vendor')

        @property
        def parent_subsystem_device(self):
            return self._try_sysfs_read_hex('device/subsystem_device')

        @property
        def parent_driver(self):
            try:
                return Path(os.readlink(self._i2c_dev.joinpath('device/driver'))).name
            except FileNotFoundError:
                return None

        def __str__(self):
            if self.description:
                return f'{self.name}: {self.description}'
            return self.name

        def __repr__(self):
            def hexid(maybe):
                if maybe is not None:
                    return f'{maybe:#06x}'
                return 'None'

            return f'{self.__class__.__name__}: name: {self.name!r}, description:' \
                   f' {self.description!r}, parent_vendor: {hexid(self.parent_vendor)},' \
                   f' parent_device: {hexid(self.parent_device)}, parent_subsystem_vendor:' \
                   f' {hexid(self.parent_subsystem_vendor)},' \
                   f' parent_subsystem_device: {hexid(self.parent_subsystem_device)},' \
                   f' parent_driver: {self.parent_driver!r}'

        def _try_sysfs_read(self, *sub, default=None):
            try:
                return self._i2c_dev.joinpath(*sub).read_text().rstrip()
            except FileNotFoundError:
                return default

        def _try_sysfs_read_hex(self, *sub, default=None):
            try:
                return int(self._i2c_dev.joinpath(*sub).read_text(), base=16)
            except FileNotFoundError:
                return default