|
33 | 33 | #include "shared-bindings/microcontroller/Pin.h"
|
34 | 34 | #include "shared-bindings/util.h"
|
35 | 35 |
|
| 36 | +#include "lib/utils/buffer_helper.h" |
36 | 37 | #include "lib/utils/context_manager_helpers.h"
|
37 | 38 | #include "py/mperrno.h"
|
38 | 39 | #include "py/runtime.h"
|
@@ -236,37 +237,67 @@ STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *args) {
|
236 | 237 | }
|
237 | 238 | MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_spi_readinto_obj, 2, 2, bitbangio_spi_readinto);
|
238 | 239 |
|
239 |
| -//| .. method:: SPI.write_readinto(buffer_out, buffer_in) |
| 240 | +//| .. method:: SPI.write_readinto(buffer_out, buffer_in, \*, out_start=0, out_end=len(buffer_out), in_start=0, in_end=len(buffer_in)) |
240 | 241 | //|
|
241 | 242 | //| Write out the data in ``buffer_out`` while simultaneously reading data into ``buffer_in``.
|
242 |
| -STATIC mp_obj_t bitbangio_spi_write_readinto(size_t n_args, const mp_obj_t *args) { |
243 |
| - bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(args[0]); |
| 243 | +//| The SPI object must be locked. |
| 244 | +//| The lengths of the slices defined by ``buffer_out[out_start:out_end]`` and ``buffer_in[in_start:in_end]`` |
| 245 | +//| must be equal. |
| 246 | +//| If buffer slice lengths are both 0, nothing happens. |
| 247 | +//| |
| 248 | +//| :param bytearray buffer_out: Write out the data in this buffer |
| 249 | +//| :param bytearray buffer_in: Read data into this buffer |
| 250 | +//| :param int out_start: Start of the slice of buffer_out to write out: ``buffer_out[out_start:out_end]`` |
| 251 | +//| :param int out_end: End of the slice; this index is not included |
| 252 | +//| :param int in_start: Start of the slice of ``buffer_in`` to read into: ``buffer_in[in_start:in_end]`` |
| 253 | +//| :param int in_end: End of the slice; this index is not included |
| 254 | +//| |
| 255 | +STATIC mp_obj_t bitbangio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { |
| 256 | + enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; |
| 257 | + static const mp_arg_t allowed_args[] = { |
| 258 | + { MP_QSTR_buffer_out, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, |
| 259 | + { MP_QSTR_buffer_in, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, |
| 260 | + { MP_QSTR_out_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, |
| 261 | + { MP_QSTR_out_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, |
| 262 | + { MP_QSTR_in_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, |
| 263 | + { MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, |
| 264 | + }; |
| 265 | + bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); |
244 | 266 | raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
|
245 | 267 |
|
246 |
| - mp_buffer_info_t bufinfoin; |
247 |
| - mp_get_buffer_raise(args[2], &bufinfoin, MP_BUFFER_WRITE); |
| 268 | + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; |
| 269 | + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); |
248 | 270 |
|
249 |
| - if (bufinfoin.len == 0) { |
250 |
| - return mp_const_none; |
251 |
| - } |
| 271 | + mp_buffer_info_t buf_out_info; |
| 272 | + mp_get_buffer_raise(args[ARG_buffer_out].u_obj, &buf_out_info, MP_BUFFER_READ); |
| 273 | + int32_t out_start = args[ARG_out_start].u_int; |
| 274 | + uint32_t out_length = buf_out_info.len; |
| 275 | + normalize_buffer_bounds(&out_start, args[ARG_out_end].u_int, &out_length); |
252 | 276 |
|
253 |
| - mp_buffer_info_t bufinfoout; |
254 |
| - mp_get_buffer_raise(args[1], &bufinfoout, MP_BUFFER_READ); |
| 277 | + mp_buffer_info_t buf_in_info; |
| 278 | + mp_get_buffer_raise(args[ARG_buffer_in].u_obj, &buf_in_info, MP_BUFFER_WRITE); |
| 279 | + int32_t in_start = args[ARG_in_start].u_int; |
| 280 | + uint32_t in_length = buf_in_info.len; |
| 281 | + normalize_buffer_bounds(&in_start, args[ARG_in_end].u_int, &in_length); |
255 | 282 |
|
256 |
| - if (bufinfoout.len != bufinfoin.len) { |
257 |
| - mp_raise_ValueError("buffers must be of equal length"); |
| 283 | + if (out_length != in_length) { |
| 284 | + mp_raise_ValueError("buffer slices must be of equal length"); |
| 285 | + } |
| 286 | + |
| 287 | + if (out_length == 0) { |
| 288 | + return mp_const_none; |
258 | 289 | }
|
259 | 290 |
|
260 | 291 | bool ok = shared_module_bitbangio_spi_transfer(self,
|
261 |
| - ((uint8_t*)bufinfoout.buf), |
262 |
| - ((uint8_t*)bufinfoin.buf), |
263 |
| - bufinfoin.len); |
| 292 | + ((uint8_t*)buf_out_info.buf) + out_start, |
| 293 | + ((uint8_t*)buf_in_info.buf) + in_start, |
| 294 | + out_length); |
264 | 295 | if (!ok) {
|
265 | 296 | mp_raise_OSError(MP_EIO);
|
266 | 297 | }
|
267 | 298 | return mp_const_none;
|
268 | 299 | }
|
269 |
| -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_spi_write_readinto_obj, 3, 3, bitbangio_spi_write_readinto); |
| 300 | +MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_write_readinto_obj, 2, bitbangio_spi_write_readinto); |
270 | 301 |
|
271 | 302 | STATIC const mp_rom_map_elem_t bitbangio_spi_locals_dict_table[] = {
|
272 | 303 | { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bitbangio_spi_deinit_obj) },
|
|
0 commit comments