8000 add background read files · sparkfun/circuitpython@f14b4c6 · GitHub
[go: up one dir, main page]

Skip to content

Commit f14b4c6

Browse files
committed
add background read files
1 parent b83a1d7 commit f14b4c6

File tree

5 files changed

+566
-92
lines changed

5 files changed

+566
-92
lines changed

ports/raspberrypi/audio_dma.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,25 @@ void __not_in_flash_func(isr_dma_0)(void) {
480480
}
481481
if (MP_STATE_PORT(background_pio)[i] != NULL) {
482482
rp2pio_statemachine_obj_t *pio = MP_STATE_PORT(background_pio)[i];
483-
rp2pio_statemachine_dma_complete(pio, i);
483+
rp2pio_statemachine_dma_complete_write(pio, i);
484+
}
485+
}
486+
}
487+
488+
void __not_in_flash_func(isr_dma_1)(void) {
489+
for (size_t i = 0; i < NUM_DMA_CHANNELS; i++) {
490+
uint32_t mask = 1 << i;
491+
if ((dma_hw->intr & mask) == 0) {
492+
continue;
493+
}
494+
// acknowledge interrupt early. Doing so late means that you could lose an
495+
// interrupt if the buffer is very small and the DMA operation
496+
// completed by the time callback_add() / dma_complete() returned. This
497+
// affected PIO continuous write more than audio.
498+
dma_hw->ints1 = mask;
499+
if (MP_STATE_PORT(background_pio)[i] != NULL) {
500+
rp2pio_statemachine_obj_t *pio = MP_STATE_PORT(background_pio)[i];
501+
rp2pio_statemachine_dma_complete_read(pio, i);
484502
}
485503
}
486504
}

ports/raspberrypi/bindings/rp2pio/StateMachine.c

Lines changed: 192 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -535,10 +535,10 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_obj, 2, rp2pio_statemachine
535535
//| """
536536
//| ...
537537

538-
static void fill_buf_info(sm_buf_info *info, mp_obj_t obj, size_t *stride_in_bytes) {
538+
static void fill_buf_info(sm_buf_info *info, mp_obj_t obj, size_t *stride_in_bytes, mp_uint_t direction) {
539539
if (obj != mp_const_none) {
540540
info->obj = obj;
541-
mp_get_buffer_raise(obj, &info->info, MP_BUFFER_READ);
541+
mp_get_buffer_raise(obj, &info->info, direction);
542542
size_t stride = mp_binary_get_size('@', info->info.typecode, NULL);
543543
if (stride > 4) {
544544
mp_raise_ValueError(MP_ERROR_TEXT("Buffer elements must be 4 bytes long or less"));
@@ -553,27 +553,29 @@ static void fill_buf_info(sm_buf_info *info, mp_obj_t obj, size_t *stride_in_byt
553553
}
554554

555555
static mp_obj_t rp2pio_statemachine_background_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
556-
enum { ARG_once, ARG_loop, ARG_swap };
556+
enum { ARG_once, ARG_loop, ARG_loop2, ARG_swap };
557557
static const mp_arg_t allowed_args[] = {
558558
{ MP_QSTR_once, MP_ARG_OBJ, {.u_obj = mp_const_none} },
559559
{ MP_QSTR_loop, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
560-
{ MP_QSTR_swap, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
560+
{ MP_QSTR_loop2, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
561+
{ MP_QSTR_swap, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
561562
};
562563
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
563564
check_for_deinit(self);
564565
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
565566
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
566567

567-
sm_buf_info once_info;
568-
sm_buf_info loop_info;
569568
size_t stride_in_bytes = 0;
570-
fill_buf_info(&once_info, args[ARG_once].u_obj, &stride_in_bytes);
571-
fill_buf_info(&loop_info, args[ARG_loop].u_obj, &stride_in_bytes);
569+
570+
fill_buf_info(&self->once_write_buf_info, args[ARG_once].u_obj, &stride_in_bytes, MP_BUFFER_READ);
571+
fill_buf_info(&self->loop_write_buf_info, args[ARG_loop].u_obj, &stride_in_bytes, MP_BUFFER_READ);
572+
fill_buf_info(&self->loop2_write_buf_info, args[ARG_loop2].u_obj, &stride_in_bytes, MP_BUFFER_READ);
573+
572574
if (!stride_in_bytes) {
573575
return mp_const_none;
574576
}
575577

576-
bool ok = common_hal_rp2pio_statemachine_background_write(self, &once_info, &loop_info, stride_in_bytes, args[ARG_swap].u_bool);
578+
bool ok = common_hal_rp2pio_statemachine_background_write(self, stride_in_bytes, args[ARG_swap].u_bool);
577579

578580
if (mp_hal_is_interrupted()) {
579581
return mp_const_none;
@@ -602,6 +604,7 @@ static mp_obj_t rp2pio_statemachine_obj_stop_background_write(mp_obj_t self_in)
602604
}
603605
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_stop_background_write_obj, rp2pio_statemachine_obj_stop_background_write);
604606

607+
605608
//| writing: bool
606609
//| """Returns True if a background write is in progress"""
607610
static mp_obj_t rp2pio_statemachine_obj_get_writing(mp_obj_t self_in) {
@@ -613,18 +616,145 @@ MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_writing_obj, rp2pio_statemachi
613616
MP_PROPERTY_GETTER(rp2pio_statemachine_writing_obj,
614617
(mp_obj_t)&rp2pio_statemachine_get_writing_obj);
615618

619+
//| pending_write: int
616620
//| pending: int
617621
//| """Returns the number of pending buffers for background writing.
618622
//|
619-
//| If the number is 0, then a `StateMachine.background_write` call will not block."""
620-
static mp_obj_t rp2pio_statemachine_obj_get_pending(mp_obj_t self_in) {
623+
//| If the number is 0, then a `StateMachine.background_write` call will not block.
624+
//| Note that `pending` is a deprecated alias for `pending_write` and will be removed
625+
//| in a future version of CircuitPython."""
626+
627+
628+
static mp_obj_t rp2pio_statemachine_obj_get_pending_write(mp_obj_t self_in) {
621629
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
622-
return mp_obj_new_int(common_hal_rp2pio_statemachine_get_pending(self));
630+
return mp_obj_new_int(common_hal_rp2pio_statemachine_get_pending_write(self));
623631
}
624-
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_pending_obj, rp2pio_statemachine_obj_get_pending);
632+
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_pending_write_obj, rp2pio_statemachine_obj_get_pending_write);
625633

626634
MP_PROPERTY_GETTER(rp2pio_statemachine_pending_obj,
627-
(mp_obj_t)&rp2pio_statemachine_get_pending_obj);
635+
(mp_obj_t)&rp2pio_statemachine_get_pending_write_obj);
636+
637+
MP_PROPERTY_GETTER(rp2pio_statemachine_pending_write_obj,
638+
(mp_obj_t)&rp2pio_statemachine_get_pending_write_obj);
639+
640+
641+
// =================================================================================================================================
642+
643+
//| def background_read(
644+
//| self,
645+
//| once: Optional[WriteableBuffer] = None,
646+
//| *,
647+
//| loop: Optional[WriteableBuffer] = None,
648+
//| swap: bool = False,
649+
//| ) -> None:
650+
//| """Read data from the RX fifo in the background, with optional looping.
651+
//|
652+
//| First, if any previous ``once`` or ``loop`` buffer has not been started, this function blocks until they have been started.
653+
//| This means that any ``once`` or ``loop`` buffer will be read at least once.
654+
//| Then the ``once`` and/or ``loop`` buffers are queued. and the function returns.
655+
//| The ``once`` buffer (if specified) will be read just once.
656+
//| Finally, the ``loop`` buffer (if specified) will continue being read indefinitely.
657+
//|
658+
//| Reads from the FIFO will match the input buffer's element size. For example, bytearray elements
659+
//| will perform 8 bit reads from the PIO FIFO. The RP2040's memory bus will duplicate the value into
660+
//| the other byte positions. So, pulling more data in the PIO assembly will read the duplicated values.
661+
//|
662+
//| To perform 16 or 32 bits reads from the FIFO use an `array.array` with a type code of the desired
663+
//| size, or use `memoryview.cast` to change the interpretation of an
664+
//| existing buffer. To receive just part of a larger buffer, slice a `memoryview`
665+
//| of it.
666+
//|
667+
//| Most use cases will probably only use one of ``once`` or ``loop``.
668+
//|
669+
//| Having neither ``once`` nor ``loop`` terminates an existing
670+
//| background looping read after exactly a whole loop. This is in contrast to
671+
//| `stop_background_read`, which interrupts an ongoing DMA operation.
672+
//|
673+
//| :param ~Optional[circuitpython_typing.WriteableBuffer] once: Data to be read once
674+
//| :param ~Optional[circuitpython_typing.WriteableBuffer] loop: Data to be read repeatedly
675+
//| :param bool swap: For 2- and 4-byte elements, swap (reverse) the byte order
676+
//| """
677+
//| ...
678+
679+
680+
static mp_obj_t rp2pio_statemachine_background_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
681+
enum { ARG_once, ARG_loop, ARG_loop2, ARG_swap };
682+
static const mp_arg_t allowed_args[] = {
683+
{ MP_QSTR_once, MP_ARG_OBJ, {.u_obj = mp_const_none} },
684+
{ MP_QSTR_loop, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
685+
{ MP_QSTR_loop2, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
686+
{ MP_QSTR_swap, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
687+
};
688+
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
689+
check_for_deinit(self);
690+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
691+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
692+
693+
size_t stride_in_bytes = 0;
694+
695+
fill_buf_inf 2851 o(&self->once_read_buf_info, args[ARG_once].u_obj, &stride_in_bytes, MP_BUFFER_WRITE);
696+
fill_buf_info(&self->loop_read_buf_info, args[ARG_loop].u_obj, &stride_in_bytes, MP_BUFFER_WRITE);
697+
fill_buf_info(&self->loop2_read_buf_info, args[ARG_loop2].u_obj, &stride_in_bytes, MP_BUFFER_WRITE);
698+
699+
if (!stride_in_bytes) {
700+
return mp_const_none;
701+
}
702+
703+
bool ok = common_hal_rp2pio_statemachine_background_read(self, stride_in_bytes, args[ARG_swap].u_bool);
704+
705+
if (mp_hal_is_interrupted()) {
706+
return mp_const_none;
707+
}
708+
if (!ok) {
709+
mp_raise_OSError(MP_EIO);
710+
}
711+
return mp_const_none;
712+
}
713+
MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_background_read_obj, 1, rp2pio_statemachine_background_read);
714+
715+
//| def stop_background_read(self) -> None:
716+
//| """Immediately stop a background read, if one is in progress. Any
717+
//| DMA in progress is halted, but items already in the RX FIFO are not
718+
//| affected."""
719+
static mp_obj_t rp2pio_statemachine_obj_stop_background_read(mp_obj_t self_in) {
720+
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
721+
bool ok = common_hal_rp2pio_statemachine_stop_background_read(self);
722+
if (mp_hal_is_interrupted()) {
723+
return mp_const_none;
724+
}
725+
if (!ok) {
726+
mp_raise_OSError(MP_EIO);
727+
}
728+
return mp_const_none;
729+
}
730+
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_stop_background_read_obj, rp2pio_statemachine_obj_stop_background_read);
731+
732+
//| reading: bool
733+
//| """Returns True if a background read is in progress"""
734+
static mp_obj_t rp2pio_statemachine_obj_get_reading(mp_obj_t self_in) {
735+
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
736+
return mp_obj_new_bool(common_hal_rp2pio_statemachine_get_reading(self));
737+
}
738+
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_reading_obj, rp2pio_statemachine_obj_get_reading);
739+
740+
MP_PROPERTY_GETTER(rp2pio_statemachine_reading_obj,
741+
(mp_obj_t)&rp2pio_statemachine_get_reading_obj);
742+
743+
//| pending_read: int
744+
//| """Returns the number of pending buffers for background reading.
745+
//|
746+
//| If the number is 0, then a `StateMachine.background_read` call will not block."""
747+
static mp_obj_t rp2pio_statemachine_obj_get_pending_read(mp_obj_t self_in) {
748+
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
749+
return mp_obj_new_int(common_hal_rp2pio_statemachine_get_pending_read(self));
750+
}
751+
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_pending_read_obj, rp2pio_statemachine_obj_get_pending_read);
752+
753+
MP_PROPERTY_GETTER(rp2pio_statemachine_pending_read_obj,
754+
(mp_obj_t)&rp2pio_statemachine_get_pending_read_obj);
755+
756+
757+
// =================================================================================================================================
628758

629759
//| def readinto(
630760
//| self,
@@ -924,6 +1054,42 @@ MP_PROPERTY_GETTER(rp2pio_statemachine_rxfifo_obj,
9241054
(mp_obj_t)&rp2pio_statemachine_get_rxfifo_obj);
9251055

9261056

1057+
//| last_read: array.array
1058+
//| """Returns the buffer most recently filled by background reads.
1059+
//|
1060+
//| This property is self-clearing -- once read, subsequent reads
1061+
//| will return a zero-length buffer until the background read buffer
1062+
//| changes or restarts.
1063+
//| """
1064+
static mp_obj_t rp2pio_statemachine_obj_get_last_read(mp_obj_t self_in) {
1065+
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
1066+
check_for_deinit(self);
1067+
return common_hal_rp2pio_statemachine_get_last_read(self);
1068+
}
1069+
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_last_read_obj, rp2pio_statemachine_obj_get_last_read);
1070+
1071+
MP_PROPERTY_GETTER(rp2pio_statemachine_last_read_obj,
1072+
(mp_obj_t)&rp2pio_statemachine_get_last_read_obj);
1073+
1074+
1075+
//| last_write: array.array
1076+
//| """Returns the buffer most recently emptied by background writes.
1077+
//|
1078+
//| This property is self-clearing -- once read, subsequent reads
1079+
//| will return a zero-length buffer until the background write buffer
1080+
//| changes or restarts.
1081+
//| """
1082+
//|
1083+
static mp_obj_t rp2pio_statemachine_obj_get_last_write(mp_obj_t self_in) {
1084+
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
1085+
check_for_deinit(self);
1086+
return common_hal_rp2pio_statemachine_get_last_write(self);
1087+
}
1088+
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_last_write_obj, rp2pio_statemachine_obj_get_last_write);
1089+
1090+
MP_PROPERTY_GETTER(rp2pio_statemachine_last_write_obj,
1091+
(mp_obj_t)&rp2pio_statemachine_get_last_write_obj);
1092+
9271093
static const mp_rom_map_elem_t rp2pio_statemachine_locals_dict_table[] = {
9281094
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&rp2pio_statemachine_deinit_obj) },
9291095
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
@@ -938,10 +1104,17 @@ static const mp_rom_map_elem_t rp2pio_statemachine_locals_dict_table[] = {
9381104
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&rp2pio_statemachine_readinto_obj) },
9391105
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&rp2pio_statemachine_write_obj) },
9401106
{ MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&rp2pio_statemachine_write_readinto_obj) },
1107+
9411108
{ MP_ROM_QSTR(MP_QSTR_background_write), MP_ROM_PTR(&rp2pio_statemachine_background_write_obj) },
9421109
{ MP_ROM_QSTR(MP_QSTR_stop_background_write), MP_ROM_PTR(&rp2pio_statemachine_stop_background_write_obj) },
9431110
{ MP_ROM_QSTR(MP_QSTR_writing), MP_ROM_PTR(&rp2pio_statemachine_writing_obj) },
944-
{ MP_ROM_QSTR(MP_QSTR_pending), MP_ROM_PTR(&rp2pio_statemachine_pending_obj) },
1111+
{ MP_ROM_QSTR(MP_QSTR_pending), MP_ROM_PTR(&rp2pio_statemachine_pending_write_obj) },
1112+
{ MP_ROM_QSTR(MP_QSTR_pending_write), MP_ROM_PTR(&rp2pio_statemachine_pending_write_obj) },
1113+
1114+
{ MP_ROM_QSTR(MP_QSTR_background_read), MP_ROM_PTR(&rp2pio_statemachine_background_read_obj) },
1115+
{ MP_ROM_QSTR(MP_QSTR_stop_background_read), MP_ROM_PTR(&rp2pio_statemachine_stop_background_read_obj) },
1116+
{ MP_ROM_QSTR(MP_QSTR_reading), MP_ROM_PTR(&rp2pio_statemachine_reading_obj) },
1117+
{ MP_ROM_QSTR(MP_QSTR_pending_read), MP_ROM_PTR(&rp2pio_statemachine_pending_read_obj) },
9451118

9461119
{ MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&rp2pio_statemachine_frequency_obj) },
9471120
{ MP_ROM_QSTR(MP_QSTR_rxstall), MP_ROM_PTR(&rp2pio_statemachine_rxstall_obj) },
@@ -952,6 +1125,10 @@ static const mp_rom_map_elem_t rp2pio_statemachine_locals_dict_table[] = {
9521125
{ MP_ROM_QSTR(MP_QSTR_pc), MP_ROM_PTR(&rp2pio_statemachine_pc_obj) },
9531126

9541127
{ MP_ROM_QSTR(MP_QSTR_rxfifo), MP_ROM_PTR(&rp2pio_statemachine_rxfifo_obj) },
1128+
1129+
{ MP_ROM_QSTR(MP_QSTR_last_read), MP_ROM_PTR(&rp2pio_statemachine_last_read_obj) },
1130+
{ MP_ROM_QSTR(MP_QSTR_last_write), MP_ROM_PTR(&rp2pio_statemachine_last_write_obj) },
1131+
9551132
};
9561133
static MP_DEFINE_CONST_DICT(rp2pio_statemachine_locals_dict, rp2pio_statemachine_locals_dict_table);
9571134

ports/raspberrypi/bindings/rp2pio/StateMachine.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
3333
bool wait_for_txstall,
3434
bool auto_push, uint8_t push_threshold, bool in_shift_right,
3535
bool user_interruptible,
36-
int wrap_taget, int wrap,
36+
int wrap_target, int wrap,
3737
int offset,
3838
int fifo_type,
3939
int mov_status_type,
@@ -50,10 +50,22 @@ void common_hal_rp2pio_statemachine_run(rp2pio_statemachine_obj_t *self, const u
5050

5151
// Lengths are in bytes.
5252
bool common_hal_rp2pio_statemachine_write(rp2pio_statemachine_obj_t *self, const uint8_t *data, size_t len, uint8_t stride_in_bytes, bool swap);
53-
bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *self, const sm_buf_info *once_obj, const sm_buf_info *loop_obj, uint8_t stride_in_bytes, bool swap);
53+
54+
bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *self,
55+
uint8_t stride_in_bytes, bool swap);
56+
57+
bool common_hal_rp2pio_statemachine_background_read(rp2pio_statemachine_obj_t *self,
58+
uint8_t stride_in_bytes, bool swap);
59+
5460
bool common_hal_rp2pio_statemachine_stop_background_write(rp2pio_statemachine_obj_t *self);
55-
mp_int_t common_hal_rp2pio_statemachine_get_pending(rp2pio_statemachine_obj_t *self);
61+
bool common_hal_rp2pio_statemachine_stop_background_read(rp2pio_statemachine_obj_t *self);
62+
63+
mp_int_t common_hal_rp2pio_statemachine_get_pending_write(rp2pio_statemachine_obj_t *self);
64+
mp_int_t common_hal_rp2pio_statemachine_get_pending_read(rp2pio_statemachine_obj_t *self);
65+
5666
bool common_hal_rp2pio_statemachine_get_writing(rp2pio_statemachine_obj_t *self);
67+
bool common_hal_rp2pio_statemachine_get_reading(rp2pio_statemachine_obj_t *self);
68+
5769
bool common_hal_rp2pio_statemachine_readinto(rp2pio_statemachine_obj_t *self, uint8_t *data, size_t len, uint8_t stride_in_bytes, bool swap);
5870
bool common_hal_rp2pio_statemachine_write_readinto(rp2pio_statemachine_obj_t *self,
5971
const uint8_t *data_out, size_t out_len, uint8_t out_stride_in_bytes,
@@ -65,6 +77,7 @@ void common_hal_rp2pio_statemachine_set_frequency(rp2pio_statemachine_obj_t *sel
6577

6678
bool common_hal_rp2pio_statemachine_get_rxstall(rp2pio_statemachine_obj_t *self);
6779
void common_hal_rp2pio_statemachine_clear_rxfifo(rp2pio_statemachine_obj_t *self);
80+
6881
bool common_hal_rp2pio_statemachine_get_txstall(rp2pio_statemachine_obj_t *self);
6982
void common_hal_rp2pio_statemachine_clear_txstall(rp2pio_statemachine_obj_t *self);
7083
size_t common_hal_rp2pio_statemachine_get_in_waiting(rp2pio_statemachine_obj_t *self);
@@ -75,3 +88,6 @@ int common_hal_rp2pio_statemachine_get_pc(rp2pio_statemachine_obj_t *self);
7588
void common_hal_rp2pio_statemachine_set_interrupt_handler(rp2pio_statemachine_obj_t *self, void (*handler)(void *), void *arg, int mask);
7689

7790
mp_obj_t common_hal_rp2pio_statemachine_get_rxfifo(rp2pio_statemachine_obj_t *self);
91+
92+
mp_obj_t common_hal_rp2pio_statemachine_get_last_read(rp2pio_statemachine_obj_t *self);
93+
mp_obj_t common_hal_rp2pio_statemachine_get_last_write(rp2pio_statemachine_obj_t *self);

0 commit comments

Comments
 (0)
0