@@ -57,7 +57,7 @@ class I2CDevice:
5757 device.write(bytes_read)
5858 """
5959 def __init__ (self , i2c , device_address ):
60- # Verify that a deivce with that address exists.
60+ # Verify that a device with that address exists.
6161 while not i2c .try_lock ():
6262 pass
6363 try :
@@ -101,6 +101,44 @@ def write(self, buf, **kwargs):
101101 """
102102 self .i2c .writeto (self .device_address , buf , ** kwargs )
103103
104+ #pylint: disable-msg=too-many-arguments
105+ def write_then_readinto (self , out_buffer , in_buffer , * ,
106+ out_start = 0 , out_end = None , in_start = 0 , in_end = None , stop = True ):
107+ """
108+ Write the bytes from ``out_buffer`` to the device, then immediately
109+ reads into ``in_buffer`` from the device. The number of bytes read
110+ will be the length of ``in_buffer``.
111+ Transmits a stop bit after the write, if ``stop`` is set.
112+
113+ If ``out_start`` or ``out_end`` is provided, then the output buffer
114+ will be sliced as if ``out_buffer[out_start:out_end]``. This will
115+ not cause an allocation like ``buffer[out_start:out_end]`` will so
116+ it saves memory.
117+
118+ If ``in_start`` or ``in_end`` is provided, then the input buffer
119+ will be sliced as if ``in_buffer[in_start:in_end]``. This will not
120+ cause an allocation like ``in_buffer[in_start:in_end]`` will so
121+ it saves memory.
122+
123+ :param bytearray out_buffer: buffer containing the bytes to write
124+ :param bytearray in_buffer: buffer containing the bytes to read into
125+ :param int out_start: Index to start writing from
126+ :param int out_end: Index to read up to but not include
127+ :param int in_start: Index to start writing at
128+ :param int in_end: Index to write up to but not include
129+ :param bool stop: If true, output an I2C stop condition after the buffer is written
130+ """
131+ if hasattr (self .i2c , 'writeto_then_readfrom' ):
132+ # In linux, at least, this is a special kernel function call
133+ self .i2c .writeto_then_readfrom (self .device_address , out_buffer , in_buffer ,
134+ out_start , out_end , in_start , in_end , stop )
135+ else :
136+ # If we don't have a special implementation, we can fake it with two calls
137+ self .write (out_buffer , start = out_start , end = out_end , stop = stop )
138+ self .readinto (in_buffer , start = in_start , end = in_end )
139+
140+ #pylint: enable-msg=too-many-arguments
141+
104142 def __enter__ (self ):
105143 while not self .i2c .try_lock ():
106144 pass
0 commit comments