Skip to content

Commit 33f5598

Browse files
committed
Stub 'continuous write' functionality
1 parent 6425e93 commit 33f5598

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

ports/raspberrypi/bindings/rp2pio/StateMachine.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,82 @@ STATIC mp_obj_t rp2pio_statemachine_write(size_t n_args, const mp_obj_t *pos_arg
426426
}
427427
MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_obj, 2, rp2pio_statemachine_write);
428428

429+
//| def continuous_write(self, buffer: Optional[ReadableBuffer], *, start: int = 0, end: Optional[int] = None) -> None:
430+
//| """Write the data contained in ``buffer`` to the state machine repeatedly until stopped. If the buffer is empty or None, an existing continuous_write is canceled.
431+
//|
432+
//| Writes to the FIFO will match the input buffer's element size. For example, bytearray elements
433+
//| will perform 8 bit writes to the PIO FIFO. The RP2040's memory bus will duplicate the value into
434+
//| the other byte positions. So, pulling more data in the PIO assembly will read the duplicated values.
435+
//|
436+
//| To perform 16 or 32 bits writes into the FIFO use an `array.array` with a type code of the desired
437+
//| size.
438+
//|
439+
//| To atomically change from one buffer to another, simply call
440+
//| `StateMachine.continuous_write` again with a different buffer.
441+
//| The call will only return once outputting the new buffer has started.
442+
//|
443+
//| If the buffer is modified while it is being written out, the updated
444+
//| values will be used. However, because of interactions between CPU
445+
//| writes, DMA and the PIO FIFO are complex, it is difficult to predict
446+
//| the result of modifying multiple values. Instead, alternate between
447+
//| a pair of buffers.
448+
//|
449+
//| :param ~circuitpython_typing.ReadableBuffer buffer: Write out the data in this buffer
450+
//| :param int start: Start of the slice of ``buffer`` to write out: ``buffer[start:end]``
451+
//| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)``"""
452+
//| ...
453+
//|
454+
STATIC mp_obj_t rp2pio_statemachine_start_continuous_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
455+
enum { ARG_buffer, ARG_start, ARG_end };
456+
static const mp_arg_t allowed_args[] = {
457+
{ MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
458+
{ MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
459+
{ MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
460+
};
461+
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
462+
check_for_deinit(self);
463+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
464+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
465+
466+
mp_buffer_info_t bufinfo = {};
467+
if (args[ARG_buffer].u_obj != mp_const_none) {
468+
mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ);
469+
}
470+
int32_t start = args[ARG_start].u_int;
471+
size_t length = bufinfo.len;
472+
normalize_buffer_bounds(&start, args[ARG_end].u_int, &length);
473+
bool ok = true;
474+
if (length == 0) {
475+
ok = common_hal_rp2pio_statemachine_end_continuous_write(self);
476+
} else {
477+
uint8_t *original_pointer = bufinfo.buf;
478+
int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL);
479+
if (stride_in_bytes > 4) {
480+
mp_raise_ValueError(translate("Buffer elements must be 4 bytes long or less"));
481+
}
482+
483+
ok = common_hal_rp2pio_statemachine_start_continuous_write(self, ((uint8_t *)bufinfo.buf) + start, length, stride_in_bytes);
484+
}
485+
if (!ok) {
486+
mp_raise_OSError(MP_EIO);
487+
}
488+
return mp_const_none;
489+
}
490+
MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_start_continuous_write_obj, 2, rp2pio_statemachine_start_continuous_write);
491+
492+
//| def end_continuous_write(self) -> None:
493+
//| """Stop a continuous write, if one is in progress."""
494+
//|
495+
STATIC mp_obj_t rp2pio_statemachine_obj_end_continuous_write(mp_obj_t self_in) {
496+
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
497+
bool ok = common_hal_rp2pio_statemachine_end_continuous_write(self);
498+
if (!ok) {
499+
mp_raise_OSError(MP_EIO);
500+
}
501+
return mp_const_none;
502+
}
429503

504+
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_end_continuous_write_obj, rp2pio_statemachine_obj_end_continuous_write);
430505
//| def readinto(self, buffer: WriteableBuffer, *, start: int = 0, end: Optional[int] = None) -> None:
431506
//| """Read into ``buffer``. If the number of bytes to read is 0, nothing happens. The buffer
432507
//| includes any data added to the fifo even if it was added before this was called.
@@ -646,6 +721,8 @@ STATIC const mp_rom_map_elem_t rp2pio_statemachine_locals_dict_table[] = {
646721
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&rp2pio_statemachine_readinto_obj) },
647722
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&rp2pio_statemachine_write_obj) },
648723
{ MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&rp2pio_statemachine_write_readinto_obj) },
724+
{ MP_ROM_QSTR(MP_QSTR_start_continuous_write), MP_ROM_PTR(&rp2pio_statemachine_start_continuous_write_obj) },
725+
{ MP_ROM_QSTR(MP_QSTR_end_continuous_write), MP_ROM_PTR(&rp2pio_statemachine_end_continuous_write_obj) },
649726

650727
{ MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&rp2pio_statemachine_frequency_obj) },
651728
{ MP_ROM_QSTR(MP_QSTR_rxstall), MP_ROM_PTR(&rp2pio_statemachine_rxstall_obj) },

ports/raspberrypi/bindings/rp2pio/StateMachine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ void common_hal_rp2pio_statemachine_run(rp2pio_statemachine_obj_t *self, const u
6565

6666
// Writes out the given data.
6767
bool common_hal_rp2pio_statemachine_write(rp2pio_statemachine_obj_t *self, const uint8_t *data, size_t len, uint8_t stride_in_bytes);
68+
bool common_hal_rp2pio_statemachine_start_continuous_write(rp2pio_statemachine_obj_t *self, const uint8_t *data, size_t len, uint8_t stride_in_bytes);
69+
bool common_hal_rp2pio_statemachine_end_continuous_write(rp2pio_statemachine_obj_t *self);
6870
bool common_hal_rp2pio_statemachine_readinto(rp2pio_statemachine_obj_t *self, uint8_t *data, size_t len, uint8_t stride_in_bytes);
6971
bool common_hal_rp2pio_statemachine_write_readinto(rp2pio_statemachine_obj_t *self,
7072
const uint8_t *data_out, size_t out_len, uint8_t out_stride_in_bytes,

ports/raspberrypi/common-hal/rp2pio/StateMachine.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,3 +848,11 @@ uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self) {
848848
uint8_t sm = self->state_machine;
849849
return _current_program_offset[pio_index][sm];
850850
}
851+
852+
bool common_hal_rp2pio_statemachine_start_continuous_write(rp2pio_statemachine_obj_t *self, const uint8_t *data, size_t len, uint8_t stride_in_bytes) {
853+
return false;
854+
}
855+
856+
bool common_hal_rp2pio_statemachine_end_continuous_write(rp2pio_statemachine_obj_t *self) {
857+
return false;
858+
}

0 commit comments

Comments
 (0)