Skip to content

raspberry: StateMachine: Add support for wrap=, wrap_target= #6029

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions ports/raspberrypi/bindings/rp2pio/StateMachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@
//| auto_push: bool = False,
//| push_threshold: int = 32,
//| in_shift_right: bool = True,
//| user_interruptible: bool = True) -> None:
//| user_interruptible: bool = True,
//| wrap_target: int = 0,
//| wrap: int = -1,
//| ) -> None:
//|
//| """Construct a StateMachine object on the given pins with the given program.
//|
Expand Down Expand Up @@ -136,6 +139,10 @@
//| that causes an infinite loop, you will be able to interrupt the loop.
//| However, if you are writing to a device that can get into a bad state if a read or write
//| is interrupted, you may want to set this to False after your program has been vetted.
//| :param int wrap_target: The target instruction number of automatic wrap. Defaults to the first instruction of the program.
//| :param int wrap: The instruction after which to wrap to the ``wrap``
//| instruction. As a special case, -1 (the default) indicates the
//| last instruction of the program.
//| """
//| ...
//|
Expand All @@ -155,7 +162,9 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
ARG_auto_pull, ARG_pull_threshold, ARG_out_shift_right,
ARG_wait_for_txstall,
ARG_auto_push, ARG_push_threshold, ARG_in_shift_right,
ARG_user_interruptible,};
ARG_user_interruptible,
ARG_wrap_target,
ARG_wrap,};
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_program, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_frequency, MP_ARG_REQUIRED | MP_ARG_INT },
Expand Down Expand Up @@ -194,6 +203,9 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
{ MP_QSTR_push_threshold, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 32} },
{ MP_QSTR_in_shift_right, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
{ MP_QSTR_user_interruptible, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },

{ MP_QSTR_wrap_target, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_wrap, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
Expand Down Expand Up @@ -254,6 +266,9 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
mp_raise_ValueError(translate("Init program size invalid"));
}

int wrap = args[ARG_wrap].u_int;
int wrap_target = args[ARG_wrap_target].u_int;

common_hal_rp2pio_statemachine_construct(self,
bufinfo.buf, bufinfo.len / 2,
args[ARG_frequency].u_int,
Expand All @@ -269,7 +284,8 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
args[ARG_auto_pull].u_bool, pull_threshold, args[ARG_out_shift_right].u_bool,
args[ARG_wait_for_txstall].u_bool,
args[ARG_auto_push].u_bool, push_threshold, args[ARG_in_shift_right].u_bool,
args[ARG_user_interruptible].u_bool);
args[ARG_user_interruptible].u_bool,
wrap_target, wrap);
return MP_OBJ_FROM_PTR(self);
}

Expand Down
3 changes: 2 additions & 1 deletion ports/raspberrypi/bindings/rp2pio/StateMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
bool auto_pull, uint8_t pull_threshold, bool out_shift_right,
bool wait_for_txstall,
bool auto_push, uint8_t push_threshold, bool in_shift_right,
bool user_interruptible);
bool user_interruptible,
int wrap_taget, int wrap);

void common_hal_rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self);
bool common_hal_rp2pio_statemachine_deinited(rp2pio_statemachine_obj_t *self);
Expand Down
3 changes: 2 additions & 1 deletion ports/raspberrypi/common-hal/audiobusio/I2SOut.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self,
false, 32, false, // shift out left to start with MSB
false, // Wait for txstall
false, 32, false, // in settings
false); // Not user-interruptible.
false, // Not user-interruptible.
0, -1); // wrap settings

self->playing = false;
audio_dma_init(&self->dma);
Expand Down
5 changes: 3 additions & 2 deletions ports/raspberrypi/common-hal/audiobusio/PDMIn.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self,

// Use the state machine to manage pins.
common_hal_rp2pio_statemachine_construct(&self->state_machine,
pdmin, sizeof(pdmin) / sizeof(pdmin[0]),
pdmin, MP_ARRAY_SIZE(pdmin),
sample_rate * 32 * 2, // Frequency based on sample rate
NULL, 0,
NULL, 1, 0, 0xffffffff, // out pin
Expand All @@ -78,7 +78,8 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self,
false, 32, false, // out settings
false, // Wait for txstall
false, 32, true, // in settings
false); // Not user-interruptible.
false, // Not user-interruptible.
0, -1); // wrap settings

uint32_t actual_frequency = common_hal_rp2pio_statemachine_get_frequency(&self->state_machine);
if (actual_frequency < MIN_MIC_CLOCK) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@ void common_hal_imagecapture_parallelimagecapture_construct(imagecapture_paralle
false, 32, false, // out settings
false, // wait for txstall
true, 32, true, // in settings
false); // Not user-interruptible.
false, // Not user-interruptible.
2, 5); // wrap settings


PIO pio = self->state_machine.pio;
uint8_t pio_index = pio_get_index(pio);
uint sm = self->state_machine.state_machine;
rp2pio_statemachine_set_wrap(&self->state_machine, 2, 5);
}

void common_hal_imagecapture_parallelimagecapture_deinit(imagecapture_parallelimagecapture_obj_t *self) {
Expand Down
3 changes: 2 additions & 1 deletion ports/raspberrypi/common-hal/neopixel_write/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
false, 32, true, // RX setting we don't use
false, // claim pins
false, // Not user-interruptible.
false); // No sideset enable
false, // No sideset enable
0, -1); // wrap
if (!ok) {
// Do nothing. Maybe bitbang?
return;
Expand Down
5 changes: 3 additions & 2 deletions ports/raspberrypi/common-hal/paralleldisplay/ParallelBus.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void common_hal_paralleldisplay_parallelbus_construct(paralleldisplay_parallelbu
}

common_hal_rp2pio_statemachine_construct(&self->state_machine,
parallel_program, sizeof(parallel_program) / sizeof(parallel_program[0]),
parallel_program, MP_ARRAY_SIZE(parallel_program),
frequency * 2, // frequency multiplied by 2 as 2 PIO instructions
NULL, 0, // init
data0, 8, 0, 255, // first out pin, # out pins
Expand All @@ -106,7 +106,8 @@ void common_hal_paralleldisplay_parallelbus_construct(paralleldisplay_parallelbu
true, 8, true, // TX, auto pull every 8 bits. shift left to output msb first
false, // wait for TX stall
false, 32, true, // RX setting we don't use
false); // Not user-interruptible.
false, // Not user-interruptible.
0, -1); // wrap settings

common_hal_rp2pio_statemachine_never_reset(&self->state_machine);
}
Expand Down
3 changes: 2 additions & 1 deletion ports/raspberrypi/common-hal/pulseio/PulseIn.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self,
true, 32, true, // RX auto-push every 32 bits
false, // claim pins
false, // Not user-interruptible.
false); // No sideset enable
false, // No sideset enable
0, -1); // wrap settings

if (!ok) {
mp_raise_RuntimeError(translate("All state machines in use"));
Expand Down
4 changes: 3 additions & 1 deletion ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode
false, 32, false, // out settings
false, // Wait for txstall
false, 32, false, // in settings
false); // Not user-interruptible.
false, // Not user-interruptible.
0, MP_ARRAY_SIZE(encoder) - 1 // wrap settings
);

// We're guaranteed by the init code that some output will be available promptly
uint8_t quiescent_state;
Expand Down
29 changes: 18 additions & 11 deletions ports/raspberrypi/common-hal/rp2pio/StateMachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
bool auto_push, uint8_t push_threshold, bool in_shift_right,
bool claim_pins,
bool user_interruptible,
bool sideset_enable
bool sideset_enable,
int wrap_target, int wrap
) {
// Create a program id that isn't the pointer so we can store it without storing the original object.
uint32_t program_id = ~((uint32_t)program);
Expand Down Expand Up @@ -289,7 +290,18 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
if (jmp_pin != NULL) {
sm_config_set_jmp_pin(&c, jmp_pin->number);
}
sm_config_set_wrap(&c, program_offset, program_offset + program_len - 1);

mp_arg_validate_int_range(wrap, -1, program_len - 1, MP_QSTR_wrap);
if (wrap == -1) {
wrap = program_len - 1;
}

mp_arg_validate_int_range(wrap_target, 0, program_len - 1, MP_QSTR_wrap_target);

wrap += program_offset;
wrap_target += program_offset;

sm_config_set_wrap(&c, wrap_target, wrap);
sm_config_set_in_shift(&c, in_shift_right, auto_push, push_threshold);
sm_config_set_out_shift(&c, out_shift_right, auto_pull, pull_threshold);

Expand Down Expand Up @@ -348,7 +360,8 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
bool auto_pull, uint8_t pull_threshold, bool out_shift_right,
bool wait_for_txstall,
bool auto_push, uint8_t push_threshold, bool in_shift_right,
bool user_interruptible) {
bool user_interruptible,
int wrap_target, int wrap) {

// First, check that all pins are free OR already in use by any PIO if exclusive_pin_use is false.
uint32_t pins_we_use = wait_gpio_mask;
Expand Down Expand Up @@ -510,7 +523,8 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
auto_push, push_threshold, in_shift_right,
true /* claim pins */,
user_interruptible,
sideset_enable);
sideset_enable,
wrap_target, wrap);
if (!ok) {
mp_raise_RuntimeError(translate("All state machines in use"));
}
Expand Down Expand Up @@ -834,10 +848,3 @@ uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self) {
uint8_t sm = self->state_machine;
return _current_program_offset[pio_index][sm];
}

void rp2pio_statemachine_set_wrap(rp2pio_statemachine_obj_t *self, uint wrap_target, uint wrap) {
uint8_t sm = self->state_machine;
uint8_t offset = rp2pio_statemachine_program_offset(self);

pio_sm_set_wrap(self->pio, sm, offset + wrap_target, offset + wrap);
}
4 changes: 2 additions & 2 deletions ports/raspberrypi/common-hal/rp2pio/StateMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
bool auto_push, uint8_t push_threshold, bool in_shift_right,
bool claim_pins,
bool interruptible,
bool sideset_enable);
bool sideset_enable,
int wrap_target, int wrap);

uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self);
void rp2pio_statemachine_set_wrap(rp2pio_statemachine_obj_t *self, uint wrap_target, uint wrap);

void rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self, bool leave_pins);

Expand Down