Skip to content

Commit 9d82293

Browse files
committed
add write_then_readinto support for linux (and possibly others!)
1 parent 442431b commit 9d82293

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

adafruit_bus_device/i2c_device.py

+35
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,41 @@ def write(self, buf, **kwargs):
101101
"""
102102
self.i2c.writeto(self.device_address, buf, **kwargs)
103103

104+
def write_then_readinto(self, out_buffer, in_buffer,
105+
out_start=0, out_end=None, in_start=0, in_end=None, stop=True):
106+
"""
107+
Write the bytes from ``out_buffer`` to the device, then immediately
108+
reads into ``in_buffer`` from the device. The number of bytes read
109+
will be the length of ``in_buffer``.
110+
Transmits a stop bit after the write, if ``stop`` is set.
111+
112+
If ``out_start`` or ``out_end`` is provided, then the output buffer
113+
will be sliced as if ``out_buffer[out_start:out_end]``. This will
114+
not cause an allocation like ``buffer[out_start:out_end]`` will so
115+
it saves memory.
116+
117+
If ``in_start`` or ``in_end`` is provided, then the input buffer
118+
will be sliced as if ``in_buffer[in_start:in_end]``. This will not
119+
cause an allocation like ``in_buffer[in_start:in_end]`` will so
120+
it saves memory.
121+
122+
:param bytearray out_buffer: buffer containing the bytes to write
123+
:param bytearray in_buffer: buffer containing the bytes to read into
124+
:param int out_start: Index to start writing from
125+
:param int out_end: Index to read up to but not include
126+
:param int in_start: Index to start writing at
127+
:param int in_end: Index to write up to but not include
128+
:param bool stop: If true, output an I2C stop condition after the buffer is written
129+
"""
130+
if hasattr(self.i2c, 'writeto_then_readfrom'):
131+
# In linux, at least, this is a special kernel function call
132+
self.i2c.writeto_then_readfrom(self.device_address, out_buffer, in_buffer,
133+
out_start, out_end, in_start, in_end, stop)
134+
else:
135+
# If we don't have a special implementation, we can fake it with two calls
136+
self.write(out_buffer, start=out_start, end=out_end, stop=stop)
137+
self.readinto(in_buffer, start=in_start, end=in_end)
138+
104139
def __enter__(self):
105140
while not self.i2c.try_lock():
106141
pass

0 commit comments

Comments
 (0)