Skip to content

Commit 472e6bc

Browse files
authored
Merge pull request #8223 from jepler/sm-mayeexec
rp2: Add StateMachine(may_exec=, offset=)
2 parents 7432bbc + 10330b2 commit 472e6bc

File tree

12 files changed

+222
-154
lines changed

12 files changed

+222
-154
lines changed

locale/circuitpython.pot

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,22 @@ msgstr ""
251251
msgid "%q=%q"
252252
msgstr ""
253253

254+
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
255+
msgid "%q[%u] shifts in more bits than pin count"
256+
msgstr ""
257+
258+
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
259+
msgid "%q[%u] shifts out more bits than pin count"
260+
msgstr ""
261+
262+
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
263+
msgid "%q[%u] uses extra pin"
264+
msgstr ""
265+
266+
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
267+
msgid "%q[%u] waits on input outside of count"
268+
msgstr ""
269+
254270
#: ports/espressif/common-hal/espidf/__init__.c
255271
#, c-format
256272
msgid "%s error 0x%x"
@@ -1161,26 +1177,6 @@ msgstr ""
11611177
msgid "Input/output error"
11621178
msgstr ""
11631179

1164-
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
1165-
#, c-format
1166-
msgid "Instruction %d shifts in more bits than pin count"
1167-
msgstr ""
1168-
1169-
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
1170-
#, c-format
1171-
msgid "Instruction %d shifts out more bits than pin count"
1172-
msgstr ""
1173-
1174-
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
1175-
#, c-format
1176-
msgid "Instruction %d uses extra pin"
1177-
msgstr ""
1178-
1179-
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
1180-
#, c-format
1181-
msgid "Instruction %d waits on input outside of count"
1182-
msgstr ""
1183-
11841180
#: ports/nrf/common-hal/_bleio/__init__.c
11851181
msgid "Insufficient authentication"
11861182
msgstr ""
@@ -1352,38 +1348,31 @@ msgid "Mismatched swap flag"
13521348
msgstr ""
13531349

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

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

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

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

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

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

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

13891378
#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c

ports/raspberrypi/bindings/rp2pio/StateMachine.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
//| program: ReadableBuffer,
6363
//| frequency: int,
6464
//| *,
65+
//| may_exec: Optional[ReadableBuffer] = None,
6566
//| init: Optional[ReadableBuffer] = None,
6667
//| first_out_pin: Optional[microcontroller.Pin] = None,
6768
//| out_pin_count: int = 1,
@@ -93,13 +94,18 @@
9394
//| user_interruptible: bool = True,
9495
//| wrap_target: int = 0,
9596
//| wrap: int = -1,
97+
//| offset: int = -1,
9698
//| ) -> None:
9799
//| """Construct a StateMachine object on the given pins with the given program.
98100
//|
99101
//| :param ReadableBuffer program: the program to run with the state machine
100102
//| :param int frequency: the target clock frequency of the state machine. Actual may be less. Use 0 for system clock speed.
101103
//| :param ReadableBuffer init: a program to run once at start up. This is run after program
102104
//| is started so instructions may be intermingled
105+
//| :param ReadableBuffer may_exec: Instructions that may be executed via `StateMachine.run` calls.
106+
//| Some elements of the `StateMachine`'s configuration are inferred from the instructions used;
107+
//| for instance, if there is no ``in`` or ``push`` instruction, then the `StateMachine` is configured without a receive FIFO.
108+
//| In this case, passing a ``may_exec`` program containing an ``in`` instruction such as ``in x``, a receive FIFO will be configured.
103109
//| :param ~microcontroller.Pin first_out_pin: the first pin to use with the OUT instruction
104110
//| :param int out_pin_count: the count of consecutive pins to use with OUT starting at first_out_pin
105111
//| :param int initial_out_pin_state: the initial output value for out pins starting at first_out_pin
@@ -146,13 +152,16 @@
146152
//| :param int wrap: The instruction after which to wrap to the ``wrap``
147153
//| instruction. As a special case, -1 (the default) indicates the
148154
//| last instruction of the program.
155+
//| :param int offset: A specific offset in the state machine's program memory where the program must be loaded.
156+
//| The default value, -1, allows the program to be loaded at any offset.
157+
//| This is appropriate for most programs.
149158
//| """
150159
//| ...
151160

152161
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) {
153162
rp2pio_statemachine_obj_t *self = m_new_obj(rp2pio_statemachine_obj_t);
154163
self->base.type = &rp2pio_statemachine_type;
155-
enum { ARG_program, ARG_frequency, ARG_init,
164+
enum { ARG_program, ARG_frequency, ARG_init, ARG_may_exec,
156165
ARG_first_out_pin, ARG_out_pin_count, ARG_initial_out_pin_state, ARG_initial_out_pin_direction,
157166
ARG_first_in_pin, ARG_in_pin_count,
158167
ARG_pull_in_pin_up, ARG_pull_in_pin_down,
@@ -166,11 +175,13 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
166175
ARG_auto_push, ARG_push_threshold, ARG_in_shift_right,
167176
ARG_user_interruptible,
168177
ARG_wrap_target,
169-
ARG_wrap,};
178+
ARG_wrap,
179+
ARG_offset,};
170180
static const mp_arg_t allowed_args[] = {
171181
{ MP_QSTR_program, MP_ARG_REQUIRED | MP_ARG_OBJ },
172182
{ MP_QSTR_frequency, MP_ARG_REQUIRED | MP_ARG_INT },
173183
{ MP_QSTR_init, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
184+
{ MP_QSTR_may_exec, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
174185

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

210221
{ MP_QSTR_wrap_target, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
211222
{ MP_QSTR_wrap, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
223+
{ MP_QSTR_offset, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
212224
};
213225
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
214226
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -220,6 +232,10 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
220232
init_bufinfo.len = 0;
221233
mp_get_buffer(args[ARG_init].u_obj, &init_bufinfo, MP_BUFFER_READ);
222234

235+
mp_buffer_info_t may_exec_bufinfo;
236+
may_exec_bufinfo.len = 0;
237+
mp_get_buffer(args[ARG_may_exec].u_obj, &may_exec_bufinfo, MP_BUFFER_READ);
238+
223239
// We don't validate pin in use here because we may be ok sharing them within a PIO.
224240
const mcu_pin_obj_t *first_out_pin =
225241
validate_obj_is_pin_or_none(args[ARG_first_out_pin].u_obj, MP_QSTR_first_out_pin);
@@ -264,6 +280,7 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
264280
bufinfo.buf, bufinfo.len / 2,
265281
args[ARG_frequency].u_int,
266282
init_bufinfo.buf, init_bufinfo.len / 2,
283+
may_exec_bufinfo.buf, may_exec_bufinfo.len / 2,
267284
first_out_pin, out_pin_count, args[ARG_initial_out_pin_state].u_int, args[ARG_initial_out_pin_direction].u_int,
268285
first_in_pin, in_pin_count, args[ARG_pull_in_pin_up].u_int, args[ARG_pull_in_pin_down].u_int,
269286
first_set_pin, set_pin_count, args[ARG_initial_set_pin_state].u_int, args[ARG_initial_set_pin_direction].u_int,
@@ -276,7 +293,7 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
276293
args[ARG_wait_for_txstall].u_bool,
277294
args[ARG_auto_push].u_bool, push_threshold, args[ARG_in_shift_right].u_bool,
278295
args[ARG_user_interruptible].u_bool,
279-
wrap_target, wrap);
296+
wrap_target, wrap, args[ARG_offset].u_int);
280297
return MP_OBJ_FROM_PTR(self);
281298
}
282299

ports/raspberrypi/bindings/rp2pio/StateMachine.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
4141
const uint16_t *program, size_t program_len,
4242
size_t frequency,
4343
const uint16_t *init, size_t init_len,
44+
const uint16_t *may_exec, size_t may_exec_len,
4445
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,
4546
const mcu_pin_obj_t *first_in_pin, uint8_t in_pin_count, uint32_t pull_pin_up, uint32_t pull_pin_down,
4647
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,
@@ -53,7 +54,8 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
5354
bool wait_for_txstall,
5455
bool auto_push, uint8_t push_threshold, bool in_shift_right,
5556
bool user_interruptible,
56-
int wrap_taget, int wrap);
57+
int wrap_taget, int wrap,
58+
int offset);
5759

5860
void common_hal_rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self);
5961
bool common_hal_rp2pio_statemachine_deinited(rp2pio_statemachine_obj_t *self);

ports/raspberrypi/common-hal/audiobusio/I2SOut.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self,
121121
&self->state_machine,
122122
program, program_len,
123123
44100 * 32 * 6, // Clock at 44.1 khz to warm the DAC up.
124-
NULL, 0,
124+
NULL, 0, // init
125+
NULL, 0, // may_exec
125126
data, 1, 0, 0xffffffff, // out pin
126127
NULL, 0, // in pins
127128
0, 0, // in pulls
@@ -135,7 +136,8 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self,
135136
false, // Wait for txstall
136137
false, 32, false, // in settings
137138
false, // Not user-interruptible.
138-
0, -1); // wrap settings
139+
0, -1, // wrap settings
140+
PIO_ANY_OFFSET);
139141

140142
self->playing = false;
141143
audio_dma_init(&self->dma);

ports/raspberrypi/common-hal/audiobusio/PDMIn.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self,
6666
pdmin, MP_ARRAY_SIZE(pdmin),
6767
sample_rate * 32 * 2, // Frequency based on sample rate
6868
NULL, 0,
69+
NULL, 0, // may_exec
6970
NULL, 1, 0, 0xffffffff, // out pin
7071
data_pin, 1, // in pins
7172
0, 0, // in pulls
@@ -79,8 +80,8 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self,
7980
false, // Wait for txstall
8081
false, 32, true, // in settings
8182
false, // Not user-interruptible.
82-
0, -1); // wrap settings
83-
83+
0, -1, // wrap settings
84+
PIO_ANY_OFFSET);
8485
uint32_t actual_frequency = common_hal_rp2pio_statemachine_get_frequency(&self->state_machine);
8586
if (actual_frequency < MIN_MIC_CLOCK) {
8687
mp_raise_ValueError(translate("sampling rate out of range"));

ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ void common_hal_imagecapture_parallelimagecapture_construct(imagecapture_paralle
102102
imagecapture_code, MP_ARRAY_SIZE(imagecapture_code),
103103
common_hal_mcu_processor_get_frequency(), // full speed (4 instructions per loop -> max pclk 30MHz @ 120MHz)
104104
0, 0, // init
105+
NULL, 0, // may_exec
105106
NULL, 0, 0, 0, // out pins
106107
pin_from_number(data_pins[0]), data_count, // in pins
107108
0, 0, // in pulls
@@ -119,7 +120,8 @@ void common_hal_imagecapture_parallelimagecapture_construct(imagecapture_paralle
119120
false, // wait for txstall
120121
true, 32, true, // in settings
121122
false, // Not user-interruptible.
122-
2, 5); // wrap settings
123+
2, 5, // wrap settings
124+
PIO_ANY_OFFSET);
123125
}
124126

125127
void common_hal_imagecapture_parallelimagecapture_deinit(imagecapture_parallelimagecapture_obj_t *self) {

ports/raspberrypi/common-hal/neopixel_write/__init__.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
7979
false, // claim pins
8080
false, // Not user-interruptible.
8181
false, // No sideset enable
82-
0, -1); // wrap
82+
0, -1, // wrap
83+
PIO_ANY_OFFSET // offset
84+
);
8385
if (!ok) {
8486
// Do nothing. Maybe bitbang?
8587
return;

ports/raspberrypi/common-hal/paralleldisplay/ParallelBus.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ void common_hal_paralleldisplay_parallelbus_construct(paralleldisplay_parallelbu
9898
parallel_program, MP_ARRAY_SIZE(parallel_program),
9999
frequency * 2, // frequency multiplied by 2 as 2 PIO instructions
100100
NULL, 0, // init
101+
NULL, 0, // may_exec
101102
data0, 8, 0, 255, // first out pin, # out pins
102103
NULL, 0, 0, 0, // first in pin, # in pins
103104
NULL, 0, 0, 0, // first set pin
@@ -110,7 +111,8 @@ void common_hal_paralleldisplay_parallelbus_construct(paralleldisplay_parallelbu
110111
false, // wait for TX stall
111112
false, 32, true, // RX setting we don't use
112113
false, // Not user-interruptible.
113-
0, -1); // wrap settings
114+
0, -1, // wrap settings
115+
PIO_ANY_OFFSET);
114116

115117
common_hal_rp2pio_statemachine_never_reset(&self->state_machine);
116118
}

ports/raspberrypi/common-hal/pulseio/PulseIn.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self,
6161
pulsein_program, MP_ARRAY_SIZE(pulsein_program),
6262
1000000, // frequency
6363
NULL, 0, // init, init_len
64+
NULL, 0, // may_exec
6465
NULL, 0, 0, 0, // first out pin, # out pins, initial_out_pin_state
6566
pin, 1, 0, 0, // first in pin, # in pins
6667
NULL, 0, 0, 0, // first set pin
@@ -73,7 +74,8 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self,
7374
false, // wait for TX stall
7475
true, 32, true, // RX auto pull every 32 bits. shift left to output msb first
7576
false, // Not user-interruptible.
76-
0, -1); // wrap settings
77+
0, -1, // wrap settings
78+
PIO_ANY_OFFSET);
7779

7880
common_hal_pulseio_pulsein_pause(self);
7981

ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode
8181
encoder, MP_ARRAY_SIZE(encoder),
8282
1000000,
8383
encoder_init, MP_ARRAY_SIZE(encoder_init), // init
84+
NULL, 0, // may_exec
8485
NULL, 0, 0, 0, // out pin
8586
pins[0], 2, // in pins
8687
3, 0, // in pulls
@@ -94,7 +95,8 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode
9495
false, // Wait for txstall
9596
false, 32, false, // in settings
9697
false, // Not user-interruptible.
97-
0, MP_ARRAY_SIZE(encoder) - 1 // wrap settings
98+
0, MP_ARRAY_SIZE(encoder) - 1, // wrap settings
99+
PIO_ANY_OFFSET
98100
);
99101

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

0 commit comments

Comments
 (0)