Skip to content

rp2: Add StateMachine(may_exec=, offset=) #8223

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 11 commits into from
Aug 9, 2023
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
62 changes: 26 additions & 36 deletions locale/circuitpython.pot
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,22 @@ msgstr ""
msgid "%q=%q"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "%q[%u] shifts in more bits than pin count"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "%q[%u] shifts out more bits than pin count"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "%q[%u] uses extra pin"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "%q[%u] waits on input outside of count"
msgstr ""

#: ports/espressif/common-hal/espidf/__init__.c
#, c-format
msgid "%s error 0x%x"
Expand Down Expand Up @@ -1161,26 +1177,6 @@ msgstr ""
msgid "Input/output error"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
#, c-format
msgid "Instruction %d shifts in more bits than pin count"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
#, c-format
msgid "Instruction %d shifts out more bits than pin count"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
#, c-format
msgid "Instruction %d uses extra pin"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
#, c-format
msgid "Instruction %d waits on input outside of count"
msgstr ""

#: ports/nrf/common-hal/_bleio/__init__.c
msgid "Insufficient authentication"
msgstr ""
Expand Down Expand Up @@ -1352,38 +1348,31 @@ msgid "Mismatched swap flag"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
#, c-format
msgid "Missing first_in_pin. Instruction %d reads pin(s)"
msgid "Missing first_in_pin. %q[%u] reads pin(s)"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
#, c-format
msgid "Missing first_in_pin. Instruction %d shifts in from pin(s)"
msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
#, c-format
msgid "Missing first_in_pin. Instruction %d waits based on pin"
msgid "Missing first_in_pin. %q[%u] waits based on pin"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
#, c-format
msgid "Missing first_out_pin. Instruction %d shifts out to pin(s)"
msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
#, c-format
msgid "Missing first_out_pin. Instruction %d writes pin(s)"
msgid "Missing first_out_pin. %q[%u] writes pin(s)"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
#, c-format
msgid "Missing first_set_pin. Instruction %d sets pin(s)"
msgid "Missing first_set_pin. %q[%u] sets pin(s)"
msgstr ""

#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
#, c-format
msgid "Missing jmp_pin. Instruction %d jumps on pin"
msgid "Missing jmp_pin. %q[%u] jumps on pin"
msgstr ""

#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c
Expand Down Expand Up @@ -1825,7 +1814,8 @@ msgstr ""

#: shared-bindings/_bleio/__init__.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c
#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c
#: shared-module/displayio/Bitmap.c
msgid "Read-only"
msgstr ""

Expand Down Expand Up @@ -4021,7 +4011,7 @@ msgstr ""
msgid "sosfilt requires iterable arguments"
msgstr ""

#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c
#: shared-bindings/bitmaptools/__init__.c
msgid "source palette too large"
msgstr ""

Expand Down
23 changes: 20 additions & 3 deletions ports/raspberrypi/bindings/rp2pio/StateMachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
//| program: ReadableBuffer,
//| frequency: int,
//| *,
//| may_exec: Optional[ReadableBuffer] = None,
//| init: Optional[ReadableBuffer] = None,
//| first_out_pin: Optional[microcontroller.Pin] = None,
//| out_pin_count: int = 1,
Expand Down Expand Up @@ -93,13 +94,18 @@
//| user_interruptible: bool = True,
//| wrap_target: int = 0,
//| wrap: int = -1,
//| offset: int = -1,
//| ) -> None:
//| """Construct a StateMachine object on the given pins with the given program.
//|
//| :param ReadableBuffer program: the program to run with the state machine
//| :param int frequency: the target clock frequency of the state machine. Actual may be less. Use 0 for system clock speed.
//| :param ReadableBuffer init: a program to run once at start up. This is run after program
//| is started so instructions may be intermingled
//| :param ReadableBuffer may_exec: Instructions that may be executed via `StateMachine.run` calls.
//| Some elements of the `StateMachine`'s configuration are inferred from the instructions used;
//| for instance, if there is no ``in`` or ``push`` instruction, then the `StateMachine` is configured without a receive FIFO.
//| In this case, passing a ``may_exec`` program containing an ``in`` instruction such as ``in x``, a receive FIFO will be configured.
//| :param ~microcontroller.Pin first_out_pin: the first pin to use with the OUT instruction
//| :param int out_pin_count: the count of consecutive pins to use with OUT starting at first_out_pin
//| :param int initial_out_pin_state: the initial output value for out pins starting at first_out_pin
Expand Down Expand Up @@ -146,13 +152,16 @@
//| :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.
//| :param int offset: A specific offset in the state machine's program memory where the program must be loaded.
//| The default value, -1, allows the program to be loaded at any offset.
//| This is appropriate for most programs.
//| """
//| ...

STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
rp2pio_statemachine_obj_t *self = m_new_obj(rp2pio_statemachine_obj_t);
self->base.type = &rp2pio_statemachine_type;
enum { ARG_program, ARG_frequency, ARG_init,
enum { ARG_program, ARG_frequency, ARG_init, ARG_may_exec,
ARG_first_out_pin, ARG_out_pin_count, ARG_initial_out_pin_state, ARG_initial_out_pin_direction,
ARG_first_in_pin, ARG_in_pin_count,
ARG_pull_in_pin_up, ARG_pull_in_pin_down,
Expand All @@ -166,11 +175,13 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
ARG_auto_push, ARG_push_threshold, ARG_in_shift_right,
ARG_user_interruptible,
ARG_wrap_target,
ARG_wrap,};
ARG_wrap,
ARG_offset,};
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 },
{ MP_QSTR_init, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_may_exec, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },

{ MP_QSTR_first_out_pin, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_out_pin_count, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
Expand Down Expand Up @@ -209,6 +220,7 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n

{ 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_QSTR_offset, 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 All @@ -220,6 +232,10 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
init_bufinfo.len = 0;
mp_get_buffer(args[ARG_init].u_obj, &init_bufinfo, MP_BUFFER_READ);

mp_buffer_info_t may_exec_bufinfo;
may_exec_bufinfo.len = 0;
mp_get_buffer(args[ARG_may_exec].u_obj, &may_exec_bufinfo, MP_BUFFER_READ);

// We don't validate pin in use here because we may be ok sharing them within a PIO.
const mcu_pin_obj_t *first_out_pin =
validate_obj_is_pin_or_none(args[ARG_first_out_pin].u_obj, MP_QSTR_first_out_pin);
Expand Down Expand Up @@ -264,6 +280,7 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
bufinfo.buf, bufinfo.len / 2,
args[ARG_frequency].u_int,
init_bufinfo.buf, init_bufinfo.len / 2,
may_exec_bufinfo.buf, may_exec_bufinfo.len / 2,
first_out_pin, out_pin_count, args[ARG_initial_out_pin_state].u_int, args[ARG_initial_out_pin_direction].u_int,
first_in_pin, in_pin_count, args[ARG_pull_in_pin_up].u_int, args[ARG_pull_in_pin_down].u_int,
first_set_pin, set_pin_count, args[ARG_initial_set_pin_state].u_int, args[ARG_initial_set_pin_direction].u_int,
Expand All @@ -276,7 +293,7 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
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,
wrap_target, wrap);
wrap_target, wrap, args[ARG_offset].u_int);
return MP_OBJ_FROM_PTR(self);
}

Expand Down
4 changes: 3 additions & 1 deletion ports/raspberrypi/bindings/rp2pio/StateMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
const uint16_t *program, size_t program_len,
size_t frequency,
const uint16_t *init, size_t init_len,
const uint16_t *may_exec, size_t may_exec_len,
const mcu_pin_obj_t *first_out_pin, uint8_t out_pin_count, uint32_t initial_out_pin_state, uint32_t initial_out_pin_direction,
const mcu_pin_obj_t *first_in_pin, uint8_t in_pin_count, uint32_t pull_pin_up, uint32_t pull_pin_down,
const mcu_pin_obj_t *first_set_pin, uint8_t set_pin_count, uint32_t initial_set_pin_state, uint32_t initial_set_pin_direction,
Expand All @@ -53,7 +54,8 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
bool wait_for_txstall,
bool auto_push, uint8_t push_threshold, bool in_shift_right,
bool user_interruptible,
int wrap_taget, int wrap);
int wrap_taget, int wrap,
int offset);

void common_hal_rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self);
bool common_hal_rp2pio_statemachine_deinited(rp2pio_statemachine_obj_t *self);
Expand Down
6 changes: 4 additions & 2 deletions ports/raspberrypi/common-hal/audiobusio/I2SOut.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self,
&self->state_machine,
program, program_len,
44100 * 32 * 6, // Clock at 44.1 khz to warm the DAC up.
NULL, 0,
NULL, 0, // init
NULL, 0, // may_exec
data, 1, 0, 0xffffffff, // out pin
NULL, 0, // in pins
0, 0, // in pulls
Expand All @@ -135,7 +136,8 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self,
false, // Wait for txstall
false, 32, false, // in settings
false, // Not user-interruptible.
0, -1); // wrap settings
0, -1, // wrap settings
PIO_ANY_OFFSET);

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 @@ -66,6 +66,7 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self,
pdmin, MP_ARRAY_SIZE(pdmin),
sample_rate * 32 * 2, // Frequency based on sample rate
NULL, 0,
NULL, 0, // may_exec
NULL, 1, 0, 0xffffffff, // out pin
data_pin, 1, // in pins
0, 0, // in pulls
Expand All @@ -79,8 +80,8 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self,
false, // Wait for txstall
false, 32, true, // in settings
false, // Not user-interruptible.
0, -1); // wrap settings

0, -1, // wrap settings
PIO_ANY_OFFSET);
uint32_t actual_frequency = common_hal_rp2pio_statemachine_get_frequency(&self->state_machine);
if (actual_frequency < MIN_MIC_CLOCK) {
mp_raise_ValueError(translate("sampling rate out of range"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ void common_hal_imagecapture_parallelimagecapture_construct(imagecapture_paralle
imagecapture_code, MP_ARRAY_SIZE(imagecapture_code),
common_hal_mcu_processor_get_frequency(), // full speed (4 instructions per loop -> max pclk 30MHz @ 120MHz)
0, 0, // init
NULL, 0, // may_exec
NULL, 0, 0, 0, // out pins
pin_from_number(data_pins[0]), data_count, // in pins
0, 0, // in pulls
Expand All @@ -119,7 +120,8 @@ void common_hal_imagecapture_parallelimagecapture_construct(imagecapture_paralle
false, // wait for txstall
true, 32, true, // in settings
false, // Not user-interruptible.
2, 5); // wrap settings
2, 5, // wrap settings
PIO_ANY_OFFSET);
}

void common_hal_imagecapture_parallelimagecapture_deinit(imagecapture_parallelimagecapture_obj_t *self) {
Expand Down
4 changes: 3 additions & 1 deletion ports/raspberrypi/common-hal/neopixel_write/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
false, // claim pins
false, // Not user-interruptible.
false, // No sideset enable
0, -1); // wrap
0, -1, // wrap
PIO_ANY_OFFSET // offset
);
if (!ok) {
// Do nothing. Maybe bitbang?
return;
Expand Down
4 changes: 3 additions & 1 deletion ports/raspberrypi/common-hal/paralleldisplay/ParallelBus.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ void common_hal_paralleldisplay_parallelbus_construct(paralleldisplay_parallelbu
parallel_program, MP_ARRAY_SIZE(parallel_program),
frequency * 2, // frequency multiplied by 2 as 2 PIO instructions
NULL, 0, // init
NULL, 0, // may_exec
data0, 8, 0, 255, // first out pin, # out pins
NULL, 0, 0, 0, // first in pin, # in pins
NULL, 0, 0, 0, // first set pin
Expand All @@ -110,7 +111,8 @@ void common_hal_paralleldisplay_parallelbus_construct(paralleldisplay_parallelbu
false, // wait for TX stall
false, 32, true, // RX setting we don't use
false, // Not user-interruptible.
0, -1); // wrap settings
0, -1, // wrap settings
PIO_ANY_OFFSET);

common_hal_rp2pio_statemachine_never_reset(&self->state_machine);
}
Expand Down
4 changes: 3 additions & 1 deletion ports/raspberrypi/common-hal/pulseio/PulseIn.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self,
pulsein_program, MP_ARRAY_SIZE(pulsein_program),
1000000, // frequency
NULL, 0, // init, init_len
NULL, 0, // may_exec
NULL, 0, 0, 0, // first out pin, # out pins, initial_out_pin_state
pin, 1, 0, 0, // first in pin, # in pins
NULL, 0, 0, 0, // first set pin
Expand All @@ -73,7 +74,8 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self,
false, // wait for TX stall
true, 32, true, // RX auto pull every 32 bits. shift left to output msb first
false, // Not user-interruptible.
0, -1); // wrap settings
0, -1, // wrap settings
PIO_ANY_OFFSET);

common_hal_pulseio_pulsein_pause(self);

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 @@ -81,6 +81,7 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode
encoder, MP_ARRAY_SIZE(encoder),
1000000,
encoder_init, MP_ARRAY_SIZE(encoder_init), // init
NULL, 0, // may_exec
NULL, 0, 0, 0, // out pin
pins[0], 2, // in pins
3, 0, // in pulls
Expand All @@ -94,7 +95,8 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode
false, // Wait for txstall
false, 32, false, // in settings
false, // Not user-interruptible.
0, MP_ARRAY_SIZE(encoder) - 1 // wrap settings
0, MP_ARRAY_SIZE(encoder) - 1, // wrap settings
PIO_ANY_OFFSET
);

// We're guaranteed by the init code that some output will be available promptly
Expand Down
Loading