Skip to content

Commit 52cfbb6

Browse files
committed
address review comments, add beginning of api for double-buffering
1 parent 129be82 commit 52cfbb6

File tree

4 files changed

+141
-104
lines changed

4 files changed

+141
-104
lines changed

ports/raspberrypi/bindings/rp2pio/StateMachine.c

Lines changed: 77 additions & 60 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_write(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,10 +553,11 @@ static void fill_buf_info_write(sm_buf_info *info, mp_obj_t obj, size_t *stride_
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_loop2, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
560561
{ 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]);
@@ -566,14 +567,17 @@ static mp_obj_t rp2pio_statemachine_background_write(size_t n_args, const mp_obj
566567

567568
sm_buf_info once_info;
568569
sm_buf_info loop_info;
570+
sm_buf_info loop2_info;
569571
size_t stride_in_bytes = 0;
570-
fill_buf_info_write(&once_info, args[ARG_once].u_obj, &stride_in_bytes);
571-
fill_buf_info_write(&loop_info, args[ARG_loop].u_obj, &stride_in_bytes);
572+
fill_buf_info(&once_info, args[ARG_once].u_obj, &stride_in_bytes, MP_BUFFER_READ);
573+
fill_buf_info(&loop_info, args[ARG_loop].u_obj, &stride_in_bytes, MP_BUFFER_READ);
574+
fill_buf_info(&loop2_info, args[ARG_loop2].u_obj, &stride_in_bytes, MP_BUFFER_READ);
572575
if (!stride_in_bytes) {
573576
return mp_const_none;
574577
}
575578

576-
bool ok = common_hal_rp2pio_statemachine_background_write(self, &once_info, &loop_info, stride_in_bytes, args[ARG_swap].u_bool);
579+
bool ok = common_hal_rp2pio_statemachine_background_write(self, &once_info, &loop_info, &loop2_info,
580+
stride_in_bytes, args[ARG_swap].u_bool);
577581

578582
if (mp_hal_is_interrupted()) {
579583
return mp_const_none;
@@ -611,32 +615,27 @@ static mp_obj_t rp2pio_statemachine_obj_get_writing(mp_obj_t self_in) {
611615
}
612616
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_writing_obj, rp2pio_statemachine_obj_get_writing);
613617

614-
const mp_obj_property_t rp2pio_statemachine_writing_obj = {
615-
.base.type = &mp_type_property,
616-
.proxy = {(mp_obj_t)&rp2pio_statemachine_get_writing_obj,
617-
MP_ROM_NONE,
618-
MP_ROM_NONE},
619-
};
620-
618+
MP_PROPERTY_GETTER(rp2pio_statemachine_writing_obj,
619+
(mp_obj_t)&rp2pio_statemachine_get_writing_obj);
621620

622621

623-
//| pending: int
624622
//| pending_write: int
623+
//| pending: int
625624
//| """Returns the number of pending buffers for background writing.
626625
//|
627-
//| If the number is 0, then a `StateMachine.background_write` call will not block."""
626+
//| If the number is 0, then a `StateMachine.background_write` call will not block.
627+
//| Note that `pending` is a deprecated alias for `pending_write` and will be removed
628+
//| in a future version of CircuitPython."""
629+
630+
628631
static mp_obj_t rp2pio_statemachine_obj_get_pending_write(mp_obj_t self_in) {
629632
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
630633
return mp_obj_new_int(common_hal_rp2pio_statemachine_get_pending_write(self));
631634
}
632635
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_pending_write_obj, rp2pio_statemachine_obj_get_pending_write);
633636

634-
const mp_obj_property_t rp2pio_statemachine_pending_write_obj = {
635-
.base.type = &mp_type_property,
636-
.proxy = {(mp_obj_t)&rp2pio_statemachine_get_pending_write_obj,
637-
MP_ROM_NONE,
638-
MP_ROM_NONE},
639-
};
637+
MP_PROPERTY_GETTER(rp2pio_statemachine_pending_write_obj,
638+
(mp_obj_t)&rp2pio_statemachine_get_pending_write_obj);
640639

641640

642641
// =================================================================================================================================
@@ -677,28 +676,13 @@ const mp_obj_property_t rp2pio_statemachine_pending_write_obj = {
677676
//| """
678677
//| ...
679678

680-
static void fill_buf_info_read(sm_buf_info *info, mp_obj_t obj, size_t *stride_in_bytes) {
681-
if (obj != mp_const_none) {
682-
info->obj = obj;
683-
mp_get_buffer_raise(obj, &info->info, MP_BUFFER_WRITE);
684-
size_t stride = mp_binary_get_size('@', info->info.typecode, NULL);
685-
if (stride > 4) {
686-
mp_raise_ValueError(MP_ERROR_TEXT("Buffer elements must be 4 bytes long or less"));
687-
}
688-
if (*stride_in_bytes && stride != *stride_in_bytes) {
689-
mp_raise_ValueError(MP_ERROR_TEXT("Mismatched data size"));
690-
}
691-
*stride_in_bytes = stride;
692-
} else {
693-
memset(info, 0, sizeof(*info));
694-
}
695-
}
696679

697680
static mp_obj_t rp2pio_statemachine_background_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
698-
enum { ARG_once, ARG_loop, ARG_swap };
681+
enum { ARG_once, ARG_loop, ARG_loop2, ARG_swap };
699682
static const mp_arg_t allowed_args[] = {
700683
{ MP_QSTR_once, MP_ARG_OBJ, {.u_obj = mp_const_none} },
701684
{ 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} },
702686
{ MP_QSTR_swap, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
703687
};
704688
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
@@ -708,14 +692,17 @@ static mp_obj_t rp2pio_statemachine_background_read(size_t n_args, const mp_obj_
708692

709693
sm_buf_info once_read_info;
710694
sm_buf_info loop_read_info;
695+
sm_buf_info loop2_read_info;
711696
size_t stride_in_bytes = 0;
712-
fill_buf_info_read(&once_read_info, args[ARG_once].u_obj, &stride_in_bytes);
713-
fill_buf_info_read(&loop_read_info, args[ARG_loop].u_obj, &stride_in_bytes);
697+
fill_buf_info(&once_read_info, args[ARG_once].u_obj, &stride_in_bytes, MP_BUFFER_WRITE);
698+
fill_buf_info(&loop_read_info, args[ARG_loop].u_obj, &stride_in_bytes, MP_BUFFER_WRITE);
699+
fill_buf_info(&loop2_read_info, args[ARG_loop].u_obj, &stride_in_bytes, MP_BUFFER_WRITE);
714700
if (!stride_in_bytes) {
715701
return mp_const_none;
716702
}
717703

718-
bool ok = common_hal_rp2pio_statemachine_background_read(self, &once_read_info, &loop_read_info, stride_in_bytes, args[ARG_swap].u_bool);
704+
bool ok = common_hal_rp2pio_statemachine_background_read(self, &once_read_info, &loop_read_info, &loop2_read_info,
705+
stride_in_bytes, args[ARG_swap].u_bool);
719706

720707
if (mp_hal_is_interrupted()) {
721708
return mp_const_none;
@@ -752,12 +739,8 @@ static mp_obj_t rp2pio_statemachine_obj_get_reading(mp_obj_t self_in) {
752739
}
753740
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_reading_obj, rp2pio_statemachine_obj_get_reading);
754741

755-
const mp_obj_property_t rp2pio_statemachine_reading_obj = {
756-
.base.type = &mp_type_property,
757-
.proxy = {(mp_obj_t)&rp2pio_statemachine_get_reading_obj,
758-
MP_ROM_NONE,
759-
MP_ROM_NONE},
760-
};
742+
MP_PROPERTY_GETTER(rp2pio_statemachine_reading_obj,
743+
(mp_obj_t)&rp2pio_statemachine_get_reading_obj);
761744

762745
//| pending_read: int
763746
//| """Returns the number of pending buffers for background reading.
@@ -769,12 +752,8 @@ static mp_obj_t rp2pio_statemachine_obj_get_pending_read(mp_obj_t self_in) {
769752
}
770753
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_pending_read_obj, rp2pio_statemachine_obj_get_pending_read);
771754

772-
const mp_obj_property_t rp2pio_statemachine_pending_read_obj = {
773-
.base.type = &mp_type_property,
774-
.proxy = {(mp_obj_t)&rp2pio_statemachine_get_pending_read_obj,
775-
MP_ROM_NONE,
776-
MP_ROM_NONE},
777-
};
755+
MP_PROPERTY_GETTER(rp2pio_statemachine_pending_read_obj,
756+
(mp_obj_t)&rp2pio_statemachine_get_pending_read_obj);
778757

779758

780759
// =================================================================================================================================
@@ -991,13 +970,8 @@ static mp_obj_t rp2pio_statemachine_obj_get_txstall(mp_obj_t self_in) {
991970
}
992971
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_txstall_obj, rp2pio_statemachine_obj_get_txstall);
993972

994-
const mp_obj_property_t rp2pio_statemachine_txstall_obj = {
995-
.base.type = &mp_type_property,
996-
.proxy = {(mp_obj_t)&rp2pio_statemachine_get_txstall_obj,
997-
MP_ROM_NONE,
998-
MP_ROM_NONE},
999-
};
1000-
973+
MP_PROPERTY_GETTER(rp2pio_statemachine_txstall_obj,
974+
(mp_obj_t)&rp2pio_statemachine_get_txstall_obj);
1001975

1002976
//| rxstall: bool
1003977
//| """True when the state machine has stalled due to a full RX FIFO since the last
@@ -1081,6 +1055,45 @@ MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_rxfifo_obj, rp2pio_statemachin
10811055
MP_PROPERTY_GETTER(rp2pio_statemachine_rxfifo_obj,
10821056
(mp_obj_t)&rp2pio_statemachine_get_rxfifo_obj);
10831057

1058+
//| last_read: array
1059+
//| """Returns the buffer most recently filled by background reads.
1060+
//|
1061+
//| This property is self-clearing -- once read, subsequent reads
1062+
//| will return a zero-length buffer until the background read buffer
1063+
//| changes or restarts.
1064+
//|
1065+
//| """
1066+
static mp_obj_t rp2pio_statemachine_obj_get_last_read(mp_obj_t self_in) {
1067+
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
1068+
check_for_deinit(self);
1069+
return common_hal_rp2pio_statemachine_get_last_read(self);
1070+
}
1071+
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_last_read_obj, rp2pio_statemachine_obj_get_last_read);
1072+
1073+
MP_PROPERTY_GETTER(rp2pio_statemachine_last_read_obj,
1074+
(mp_obj_t)&rp2pio_statemachine_get_last_read_obj);
1075+
1076+
1077+
//| last_write: array
1078+
//| """Returns the buffer most recently emptied by background writes.
1079+
//|
1080+
//| This property is self-clearing -- once read, subsequent reads
1081+
//| will return a zero-length buffer until the background write buffer
1082+
//| changes or restarts.
1083+
//|
1084+
//| """
1085+
//|
1086+
static mp_obj_t rp2pio_statemachine_obj_get_last_write(mp_obj_t self_in) {
1087+
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
1088+
check_for_deinit(self);
1089+
return common_hal_rp2pio_statemachine_get_last_write(self);
1090+
}
1091+
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_last_write_obj, rp2pio_statemachine_obj_get_last_write);
1092+
1093+
MP_PROPERTY_GETTER(rp2pio_statemachine_last_write_obj,
1094+
(mp_obj_t)&rp2pio_statemachine_get_last_write_obj);
1095+
1096+
10841097

10851098
static const mp_rom_map_elem_t rp2pio_statemachine_locals_dict_table[] = {
10861099
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&rp2pio_statemachine_deinit_obj) },
@@ -1117,6 +1130,10 @@ static const mp_rom_map_elem_t rp2pio_statemachine_locals_dict_table[] = {
11171130
{ MP_ROM_QSTR(MP_QSTR_pc), MP_ROM_PTR(&rp2pio_statemachine_pc_obj) },
11181131

11191132
{ MP_ROM_QSTR(MP_QSTR_rxfifo), MP_ROM_PTR(&rp2pio_statemachine_rxfifo_obj) },
1133+
1134+
{ MP_ROM_QSTR(MP_QSTR_last_read), MP_ROM_PTR(&rp2pio_statemachine_last_read_obj) },
1135+
{ MP_ROM_QSTR(MP_QSTR_last_write), MP_ROM_PTR(&rp2pio_statemachine_last_write_obj) },
1136+
11201137
};
11211138
static MP_DEFINE_CONST_DICT(rp2pio_statemachine_locals_dict, rp2pio_statemachine_locals_dict_table);
11221139

ports/raspberrypi/bindings/rp2pio/StateMachine.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,13 @@ void common_hal_rp2pio_statemachine_run(rp2pio_statemachine_obj_t *self, const u
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);
5353

54-
bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *self, const sm_buf_info *once, const sm_buf_info *loop, uint8_t stride_in_bytes, bool swap);
55-
bool common_hal_rp2pio_statemachine_background_read(rp2pio_statemachine_obj_t *self, const sm_buf_info *once_read, const sm_buf_info *loop_read, uint8_t stride_in_bytes, bool swap);
54+
bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *self,
55+
const sm_buf_info *once_write_buf, const sm_buf_info *loop_write_buf, const sm_buf_info *loop2_write_buf,
56+
uint8_t stride_in_bytes, bool swap);
57+
58+
bool common_hal_rp2pio_statemachine_background_read(rp2pio_statemachine_obj_t *self,
59+
const sm_buf_info *once_read_buf, const sm_buf_info *loop_read_buf, const sm_buf_info *loop2_read_buf,
60+
uint8_t stride_in_bytes, bool swap);
5661

5762
bool common_hal_rp2pio_statemachine_stop_background_write(rp2pio_statemachine_obj_t *self);
5863
bool common_hal_rp2pio_statemachine_stop_background_read(rp2pio_statemachine_obj_t *self);
@@ -85,3 +90,6 @@ int common_hal_rp2pio_statemachine_get_pc(rp2pio_statemachine_obj_t *self);
8590
void common_hal_rp2pio_statemachine_set_interrupt_handler(rp2pio_statemachine_obj_t *self, void (*handler)(void *), void *arg, int mask);
8691

8792
mp_obj_t common_hal_rp2pio_statemachine_get_rxfifo(rp2pio_statemachine_obj_t *self);
93+
94+
mp_obj_t common_hal_rp2pio_statemachine_get_last_read(rp2pio_statemachine_obj_t *self);
95+
mp_obj_t common_hal_rp2pio_statemachine_get_last_write(rp2pio_statemachine_obj_t *self);

0 commit comments

Comments
 (0)