@@ -206,12 +206,12 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_unlock_obj, busio_spi_obj_unlock);
206206
207207//| .. method:: SPI.write(buffer, \*, start=0, end=len(buffer))
208208//|
209- //| Write the data contained in ``buf ``. Requires the SPI being locked.
209+ //| Write the data contained in ``buffer ``. The SPI object must be locked.
210210//| If the buffer is empty, nothing happens.
211211//|
212- //| :param bytearray buffer: buffer containing the bytes to write
213- //| :param int start: Index to start writing from
214- //| :param int end: Index to read up to but not include
212+ //| :param bytearray buffer: Write out the data in this buffer
213+ //| :param int start: Start of the slice of ``buffer`` to write out: ``buffer[start:end]``
214+ //| :param int end: End of the slice; this index is not included
215215//|
216216STATIC mp_obj_t busio_spi_write (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
217217 enum { ARG_buffer , ARG_start , ARG_end };
@@ -247,14 +247,14 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 2, busio_spi_write);
247247
248248//| .. method:: SPI.readinto(buffer, \*, start=0, end=len(buffer), write_value=0)
249249//|
250- //| Read into the buffer specified by ``buf `` while writing zeroes .
251- //| Requires the SPI being locked.
250+ //| Read into `` buffer`` while writing ``write_value `` for each byte read .
251+ //| The SPI object must be locked.
252252//| If the number of bytes to read is 0, nothing happens.
253253//|
254- //| :param bytearray buffer: buffer to write into
255- //| :param int start: Index to start writing at
256- //| :param int end: Index to write up to but not include
257- //| :param int write_value: Value to write reading. (Usually ignored.)
254+ //| :param bytearray buffer: Read data into this buffer
255+ //| :param int start: Start of the slice of ``buffer`` to read into: ``buffer[start:end]``
256+ //| :param int end: End of the slice; this index is not included
257+ //| :param int write_value: Value to write while reading. (Usually ignored.)
258258//|
259259STATIC mp_obj_t busio_spi_readinto (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
260260 enum { ARG_buffer , ARG_start , ARG_end , ARG_write_value };
@@ -288,6 +288,68 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m
288288}
289289MP_DEFINE_CONST_FUN_OBJ_KW (busio_spi_readinto_obj , 2 , busio_spi_readinto );
290290
291+ //| .. method:: SPI.write_readinto(buffer_out, buffer_in, \*, out_start=0, out_end=len(buffer_out), in_start=0, in_end=len(buffer_in))
292+ //|
293+ //| Write out the data in ``buffer_out`` while simultaneously reading data into ``buffer_in``.
294+ //| The SPI object must be locked.
295+ //| The lengths of the slices defined by ``buffer_out[out_start:out_end]`` and ``buffer_in[in_start:in_end]``
296+ //| must be equal.
297+ //| If buffer slice lengths are both 0, nothing happens.
298+ //|
299+ //| :param bytearray buffer_out: Write out the data in this buffer
300+ //| :param bytearray buffer_in: Read data into this buffer
301+ //| :param int out_start: Start of the slice of buffer_out to write out: ``buffer_out[out_start:out_end]``
302+ //| :param int out_end: End of the slice; this index is not included
303+ //| :param int in_start: Start of the slice of ``buffer_in`` to read into: ``buffer_in[in_start:in_end]``
304+ //| :param int in_end: End of the slice; this index is not included
305+ //|
306+ STATIC mp_obj_t busio_spi_write_readinto (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
307+ enum { ARG_buffer_out , ARG_buffer_in , ARG_out_start , ARG_out_end , ARG_in_start , ARG_in_end };
308+ static const mp_arg_t allowed_args [] = {
309+ { MP_QSTR_buffer_out , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
310+ { MP_QSTR_buffer_in , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
311+ { MP_QSTR_out_start , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0 } },
312+ { MP_QSTR_out_end , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = INT_MAX } },
313+ { MP_QSTR_in_start , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0 } },
314+ { MP_QSTR_in_end , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = INT_MAX } },
315+ };
316+ busio_spi_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
317+ raise_error_if_deinited (common_hal_busio_spi_deinited (self ));
318+ check_lock (self );
319+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
320+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
321+
322+ mp_buffer_info_t buf_out_info ;
323+ mp_get_buffer_raise (args [ARG_buffer_out ].u_obj , & buf_out_info , MP_BUFFER_READ );
324+ int32_t out_start = args [ARG_out_start ].u_int ;
325+ uint32_t out_length = buf_out_info .len ;
326+ normalize_buffer_bounds (& out_start , args [ARG_out_end ].u_int , & out_length );
327+
328+ mp_buffer_info_t buf_in_info ;
329+ mp_get_buffer_raise (args [ARG_buffer_in ].u_obj , & buf_in_info , MP_BUFFER_WRITE );
330+ int32_t in_start = args [ARG_in_start ].u_int ;
331+ uint32_t in_length = buf_in_info .len ;
332+ normalize_buffer_bounds (& in_start , args [ARG_in_end ].u_int , & in_length );
333+
334+ if (out_length != in_length ) {
335+ mp_raise_ValueError ("buffer slices must be of equal length" );
336+ }
337+
338+ if (out_length == 0 ) {
339+ return mp_const_none ;
340+ }
341+
342+ bool ok = common_hal_busio_spi_transfer (self ,
343+ ((uint8_t * )buf_out_info .buf ) + out_start ,
344+ ((uint8_t * )buf_in_info .buf ) + in_start ,
345+ out_length );
346+ if (!ok ) {
347+ mp_raise_OSError (MP_EIO );
348+ }
349+ return mp_const_none ;
350+ }
351+ MP_DEFINE_CONST_FUN_OBJ_KW (busio_spi_write_readinto_obj , 2 , busio_spi_write_readinto );
352+
291353STATIC const mp_rom_map_elem_t busio_spi_locals_dict_table [] = {
292354 { MP_ROM_QSTR (MP_QSTR_deinit ), MP_ROM_PTR (& busio_spi_deinit_obj ) },
293355 { MP_ROM_QSTR (MP_QSTR___enter__ ), MP_ROM_PTR (& default___enter___obj ) },
@@ -299,6 +361,7 @@ STATIC const mp_rom_map_elem_t busio_spi_locals_dict_table[] = {
299361
300362 { MP_ROM_QSTR (MP_QSTR_readinto ), MP_ROM_PTR (& busio_spi_readinto_obj ) },
301363 { MP_ROM_QSTR (MP_QSTR_write ), MP_ROM_PTR (& busio_spi_write_obj ) },
364+ { MP_ROM_QSTR (MP_QSTR_write_readinto ), MP_ROM_PTR (& busio_spi_write_readinto_obj ) },
302365};
303366STATIC MP_DEFINE_CONST_DICT (busio_spi_locals_dict , busio_spi_locals_dict_table );
304367
0 commit comments