Skip to content

Commit a58bf23

Browse files
committed
raspberry: StateMachine: Add support for wrap=, wrap_target=
1 parent a50b058 commit a58bf23

File tree

11 files changed

+58
-27
lines changed

11 files changed

+58
-27
lines changed

ports/raspberrypi/bindings/rp2pio/StateMachine.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,10 @@
8787
//| auto_push: bool = False,
8888
//| push_threshold: int = 32,
8989
//| in_shift_right: bool = True,
90-
//| user_interruptible: bool = True) -> None:
90+
//| user_interruptible: bool = True,
91+
//| wrap_target: int = 0,
92+
//| wrap: int = -1,
93+
//| ) -> None:
9194
//|
9295
//| """Construct a StateMachine object on the given pins with the given program.
9396
//|
@@ -136,6 +139,10 @@
136139
//| that causes an infinite loop, you will be able to interrupt the loop.
137140
//| However, if you are writing to a device that can get into a bad state if a read or write
138141
//| is interrupted, you may want to set this to False after your program has been vetted.
142+
//| :param int wrap_target The target instruction number of automatic wrap. Defaults to the first instruction of the program.
143+
//| :param int wrap The instruction after which to wrap to the ``wrap``
144+
//| instruction. As a special case, -1 (the default) indicates the
145+
//| last instruction of the program.
139146
//| """
140147
//| ...
141148
//|
@@ -155,7 +162,9 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
155162
ARG_auto_pull, ARG_pull_threshold, ARG_out_shift_right,
156163
ARG_wait_for_txstall,
157164
ARG_auto_push, ARG_push_threshold, ARG_in_shift_right,
158-
ARG_user_interruptible,};
165+
ARG_user_interruptible,
166+
ARG_wrap_target,
167+
ARG_wrap,};
159168
static const mp_arg_t allowed_args[] = {
160169
{ MP_QSTR_program, MP_ARG_REQUIRED | MP_ARG_OBJ },
161170
{ MP_QSTR_frequency, MP_ARG_REQUIRED | MP_ARG_INT },
@@ -194,6 +203,9 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
194203
{ MP_QSTR_push_threshold, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 32} },
195204
{ MP_QSTR_in_shift_right, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
196205
{ MP_QSTR_user_interruptible, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
206+
207+
{ MP_QSTR_wrap_target, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
208+
{ MP_QSTR_wrap, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
197209
};
198210
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
199211
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -254,6 +266,9 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
254266
mp_raise_ValueError(translate("Init program size invalid"));
255267
}
256268

269+
int wrap = args[ARG_wrap].u_int;
270+
int wrap_target = args[ARG_wrap_target].u_int;
271+
257272
common_hal_rp2pio_statemachine_construct(self,
258273
bufinfo.buf, bufinfo.len / 2,
259274
args[ARG_frequency].u_int,
@@ -269,7 +284,8 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n
269284
args[ARG_auto_pull].u_bool, pull_threshold, args[ARG_out_shift_right].u_bool,
270285
args[ARG_wait_for_txstall].u_bool,
271286
args[ARG_auto_push].u_bool, push_threshold, args[ARG_in_shift_right].u_bool,
272-
args[ARG_user_interruptible].u_bool);
287+
args[ARG_user_interruptible].u_bool,
288+
wrap_target, wrap);
273289
return MP_OBJ_FROM_PTR(self);
274290
}
275291

ports/raspberrypi/bindings/rp2pio/StateMachine.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
5151
bool auto_pull, uint8_t pull_threshold, bool out_shift_right,
5252
bool wait_for_txstall,
5353
bool auto_push, uint8_t push_threshold, bool in_shift_right,
54-
bool user_interruptible);
54+
bool user_interruptible,
55+
int wrap_taget, int wrap);
5556

5657
void common_hal_rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self);
5758
bool common_hal_rp2pio_statemachine_deinited(rp2pio_statemachine_obj_t *self);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self,
134134
false, 32, false, // shift out left to start with MSB
135135
false, // Wait for txstall
136136
false, 32, false, // in settings
137-
false); // Not user-interruptible.
137+
false, // Not user-interruptible.
138+
0, -1); // wrap settings
138139

139140
self->playing = false;
140141
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
@@ -63,7 +63,7 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self,
6363

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

8384
uint32_t actual_frequency = common_hal_rp2pio_statemachine_get_frequency(&self->state_machine);
8485
if (actual_frequency < MIN_MIC_CLOCK) {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,13 @@ void common_hal_imagecapture_parallelimagecapture_construct(imagecapture_paralle
118118
false, 32, false, // out settings
119119
false, // wait for txstall
120120
true, 32, true, // in settings
121-
false); // Not user-interruptible.
121+
false, // Not user-interruptible.
122+
2, 5); // wrap settings
122123

123124

124125
PIO pio = self->state_machine.pio;
125126
uint8_t pio_index = pio_get_index(pio);
126127
uint sm = self->state_machine.state_machine;
127-
rp2pio_statemachine_set_wrap(&self->state_machine, 2, 5);
128128
}
129129

130130
void common_hal_imagecapture_parallelimagecapture_deinit(imagecapture_parallelimagecapture_obj_t *self) {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
7878
false, 32, true, // RX setting we don't use
7979
false, // claim pins
8080
false, // Not user-interruptible.
81-
false); // No sideset enable
81+
false, // No sideset enable
82+
0, -1); // wrap
8283
if (!ok) {
8384
// Do nothing. Maybe bitbang?
8485
return;

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ void common_hal_paralleldisplay_parallelbus_construct(paralleldisplay_parallelbu
9292
}
9393

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

111112
common_hal_rp2pio_statemachine_never_reset(&self->state_machine);
112113
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self,
7474
true, 32, true, // RX auto-push every 32 bits
7575
false, // claim pins
7676
false, // Not user-interruptible.
77-
false); // No sideset enable
77+
false, // No sideset enable
78+
0, -1); // wrap settings
7879

7980
if (!ok) {
8081
mp_raise_RuntimeError(translate("All state machines in use"));

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode
9292
false, 32, false, // out settings
9393
false, // Wait for txstall
9494
false, 32, false, // in settings
95-
false); // Not user-interruptible.
95+
false, // Not user-interruptible.
96+
0, MP_ARRAY_SIZE(encoder) - 1 // wrap settings
97+
);
9698

9799
// We're guaranteed by the init code that some output will be available promptly
98100
uint8_t quiescent_state;

ports/raspberrypi/common-hal/rp2pio/StateMachine.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
165165
bool auto_push, uint8_t push_threshold, bool in_shift_right,
166166
bool claim_pins,
167167
bool user_interruptible,
168-
bool sideset_enable
168+
bool sideset_enable,
169+
int wrap_target, int wrap
169170
) {
170171
// Create a program id that isn't the pointer so we can store it without storing the original object.
171172
uint32_t program_id = ~((uint32_t)program);
@@ -289,7 +290,18 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
289290
if (jmp_pin != NULL) {
290291
sm_config_set_jmp_pin(&c, jmp_pin->number);
291292
}
292-
sm_config_set_wrap(&c, program_offset, program_offset + program_len - 1);
293+
294+
mp_arg_validate_int_range(wrap, -1, program_len - 1, MP_QSTR_wrap);
295+
if (wrap == -1) {
296+
wrap = program_len - 1;
297+
}
298+
299+
mp_arg_validate_int_range(wrap_target, 0, program_len - 1, MP_QSTR_wrap_target);
300+
301+
wrap += program_offset;
302+
wrap_target += program_offset;
303+
304+
sm_config_set_wrap(&c, wrap_target, wrap);
293305
sm_config_set_in_shift(&c, in_shift_right, auto_push, push_threshold);
294306
sm_config_set_out_shift(&c, out_shift_right, auto_pull, pull_threshold);
295307

@@ -348,7 +360,8 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
348360
bool auto_pull, uint8_t pull_threshold, bool out_shift_right,
349361
bool wait_for_txstall,
350362
bool auto_push, uint8_t push_threshold, bool in_shift_right,
351-
bool user_interruptible) {
363+
bool user_interruptible,
364+
int wrap_target, int wrap) {
352365

353366
// First, check that all pins are free OR already in use by any PIO if exclusive_pin_use is false.
354367
uint32_t pins_we_use = wait_gpio_mask;
@@ -510,7 +523,8 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
510523
auto_push, push_threshold, in_shift_right,
511524
true /* claim pins */,
512525
user_interruptible,
513-
sideset_enable);
526+
sideset_enable,
527+
wrap_target, wrap);
514528
if (!ok) {
515529
mp_raise_RuntimeError(translate("All state machines in use"));
516530
}
@@ -834,10 +848,3 @@ uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self) {
834848
uint8_t sm = self->state_machine;
835849
return _current_program_offset[pio_index][sm];
836850
}
837-
838-
void rp2pio_statemachine_set_wrap(rp2pio_statemachine_obj_t *self, uint wrap_target, uint wrap) {
839-
uint8_t sm = self->state_machine;
840-
uint8_t offset = rp2pio_statemachine_program_offset(self);
841-
842-
pio_sm_set_wrap(self->pio, sm, offset + wrap_target, offset + wrap);
843-
}

ports/raspberrypi/common-hal/rp2pio/StateMachine.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,10 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
7676
bool auto_push, uint8_t push_threshold, bool in_shift_right,
7777
bool claim_pins,
7878
bool interruptible,
79-
bool sideset_enable);
79+
bool sideset_enable,
80+
int wrap_target, int wrap);
8081

8182
uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self);
82-
void rp2pio_statemachine_set_wrap(rp2pio_statemachine_obj_t *self, uint wrap_target, uint wrap);
8383

8484
void rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self, bool leave_pins);
8585

0 commit comments

Comments
 (0)