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