From 9d82293ad181848d05fd44eef7d46e85c17b3a49 Mon Sep 17 00:00:00 2001 From: ladyada Date: Fri, 17 Aug 2018 13:41:10 -0400 Subject: [PATCH 1/3] add write_then_readinto support for linux (and possibly others!) --- adafruit_bus_device/i2c_device.py | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/adafruit_bus_device/i2c_device.py b/adafruit_bus_device/i2c_device.py index d2ee118..df4afcc 100644 --- a/adafruit_bus_device/i2c_device.py +++ b/adafruit_bus_device/i2c_device.py @@ -101,6 +101,41 @@ def write(self, buf, **kwargs): """ self.i2c.writeto(self.device_address, buf, **kwargs) + def write_then_readinto(self, out_buffer, in_buffer, + out_start=0, out_end=None, in_start=0, in_end=None, stop=True): + """ + Write the bytes from ``out_buffer`` to the device, then immediately + reads into ``in_buffer`` from the device. The number of bytes read + will be the length of ``in_buffer``. + Transmits a stop bit after the write, if ``stop`` is set. + + If ``out_start`` or ``out_end`` is provided, then the output buffer + will be sliced as if ``out_buffer[out_start:out_end]``. This will + not cause an allocation like ``buffer[out_start:out_end]`` will so + it saves memory. + + If ``in_start`` or ``in_end`` is provided, then the input buffer + will be sliced as if ``in_buffer[in_start:in_end]``. This will not + cause an allocation like ``in_buffer[in_start:in_end]`` will so + it saves memory. + + :param bytearray out_buffer: buffer containing the bytes to write + :param bytearray in_buffer: buffer containing the bytes to read into + :param int out_start: Index to start writing from + :param int out_end: Index to read up to but not include + :param int in_start: Index to start writing at + :param int in_end: Index to write up to but not include + :param bool stop: If true, output an I2C stop condition after the buffer is written + """ + if hasattr(self.i2c, 'writeto_then_readfrom'): + # In linux, at least, this is a special kernel function call + self.i2c.writeto_then_readfrom(self.device_address, out_buffer, in_buffer, + out_start, out_end, in_start, in_end, stop) + else: + # If we don't have a special implementation, we can fake it with two calls + self.write(out_buffer, start=out_start, end=out_end, stop=stop) + self.readinto(in_buffer, start=in_start, end=in_end) + def __enter__(self): while not self.i2c.try_lock(): pass From 6dcbe4bf33591c854e16959a72a4f2c03ee4ef52 Mon Sep 17 00:00:00 2001 From: ladyada Date: Fri, 17 Aug 2018 13:58:05 -0400 Subject: [PATCH 2/3] pylint fix & a typo --- adafruit_bus_device/i2c_device.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/adafruit_bus_device/i2c_device.py b/adafruit_bus_device/i2c_device.py index df4afcc..e18792b 100644 --- a/adafruit_bus_device/i2c_device.py +++ b/adafruit_bus_device/i2c_device.py @@ -57,7 +57,7 @@ class I2CDevice: device.write(bytes_read) """ def __init__(self, i2c, device_address): - # Verify that a deivce with that address exists. + # Verify that a device with that address exists. while not i2c.try_lock(): pass try: @@ -101,6 +101,7 @@ def write(self, buf, **kwargs): """ self.i2c.writeto(self.device_address, buf, **kwargs) +#pylint: disable-msg=too-many-arguments def write_then_readinto(self, out_buffer, in_buffer, out_start=0, out_end=None, in_start=0, in_end=None, stop=True): """ @@ -136,6 +137,8 @@ def write_then_readinto(self, out_buffer, in_buffer, self.write(out_buffer, start=out_start, end=out_end, stop=stop) self.readinto(in_buffer, start=in_start, end=in_end) +#pylint: enable-msg=too-many-arguments + def __enter__(self): while not self.i2c.try_lock(): pass From 9a164067f5ea2804fabc999de89f2a953a96df2c Mon Sep 17 00:00:00 2001 From: ladyada Date: Fri, 17 Aug 2018 14:19:47 -0400 Subject: [PATCH 3/3] force labeling of extra args --- adafruit_bus_device/i2c_device.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_bus_device/i2c_device.py b/adafruit_bus_device/i2c_device.py index e18792b..0a4f5b0 100644 --- a/adafruit_bus_device/i2c_device.py +++ b/adafruit_bus_device/i2c_device.py @@ -102,7 +102,7 @@ def write(self, buf, **kwargs): self.i2c.writeto(self.device_address, buf, **kwargs) #pylint: disable-msg=too-many-arguments - def write_then_readinto(self, out_buffer, in_buffer, + def write_then_readinto(self, out_buffer, in_buffer, *, out_start=0, out_end=None, in_start=0, in_end=None, stop=True): """ Write the bytes from ``out_buffer`` to the device, then immediately