summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoroli <oli@example.com>2021-10-09 10:20:39 +0100
committerDamien George <damien@micropython.org>2021-11-19 13:35:28 +1100
commit0a9335ecaa2bda2de1af86be426c9ed6c8849f16 (patch)
treede8dd2093818461fc07556c490309f2cd0243434
parent3dc9a42bc2a048153be742f96bd3d7f0a030ea84 (diff)
rp2/rp2_pio: Support exec with sideset.
The rp2.StateMachine.exec errors when supplying a sideset action. This commit passes the sideset_opt from the StateMachine though to the parser. It also adds some value validation to the sideset operator. Additionally, the "word" method is added to the exec to allow any other unsupported opcodes. Fixes issue #7924.
-rw-r--r--ports/rp2/modules/rp2.py12
-rw-r--r--ports/rp2/rp2_pio.c7
2 files changed, 14 insertions, 5 deletions
diff --git a/ports/rp2/modules/rp2.py b/ports/rp2/modules/rp2.py
index c7e4d1fdd..1e4bb26cf 100644
--- a/ports/rp2/modules/rp2.py
+++ b/ports/rp2/modules/rp2.py
@@ -88,6 +88,10 @@ class PIOASMEmit:
def side(self, value):
self.num_sideset += 1
if self.pass_ > 0:
+ if self.sideset_count == 0:
+ raise PIOASMError("no sideset")
+ elif value >= (1 << self.sideset_count):
+ raise PIOASMError("sideset too large")
set_bit = 13 - self.sideset_count
self.prog[_PROG_DATA][-1] |= self.sideset_opt << 12 | value << set_bit
return self
@@ -269,17 +273,17 @@ def asm_pio(**kw):
# sideset_count is inclusive of enable bit
-def asm_pio_encode(instr, sideset_count):
+def asm_pio_encode(instr, sideset_count, sideset_opt=False):
emit = PIOASMEmit()
- emit.delay_max = 31
emit.sideset_count = sideset_count
- if emit.sideset_count:
- emit.delay_max >>= emit.sideset_count
+ emit.sideset_opt = sideset_opt != 0
+ emit.delay_max = 31 >> (emit.sideset_count + emit.sideset_opt)
emit.pass_ = 1
emit.num_instr = 0
emit.num_sideset = 0
gl = _pio_funcs
+ gl["word"] = emit.word
gl["nop"] = emit.nop
# gl["jmp"] = emit.jmp currently not supported
gl["wait"] = emit.wait
diff --git a/ports/rp2/rp2_pio.c b/ports/rp2/rp2_pio.c
index 414fa8bd7..fe09ebe24 100644
--- a/ports/rp2/rp2_pio.c
+++ b/ports/rp2/rp2_pio.c
@@ -613,7 +613,12 @@ STATIC mp_obj_t rp2_state_machine_exec(mp_obj_t self_in, mp_obj_t instr_in) {
mp_obj_t rp2_module = mp_import_name(MP_QSTR_rp2, mp_const_none, MP_OBJ_NEW_SMALL_INT(0));
mp_obj_t asm_pio_encode = mp_load_attr(rp2_module, MP_QSTR_asm_pio_encode);
uint32_t sideset_count = self->pio->sm[self->sm].pinctrl >> PIO_SM0_PINCTRL_SIDESET_COUNT_LSB;
- mp_obj_t encoded_obj = mp_call_function_2(asm_pio_encode, instr_in, MP_OBJ_NEW_SMALL_INT(sideset_count));
+ uint8_t sideset_opt = !!(self->pio->sm[self->sm].execctrl & (1 << PIO_SM0_EXECCTRL_SIDE_EN_LSB));
+ mp_obj_t args[3];
+ args[0] = instr_in;
+ args[1] = MP_OBJ_NEW_SMALL_INT(sideset_count);
+ args[2] = MP_OBJ_NEW_SMALL_INT(sideset_opt);
+ mp_obj_t encoded_obj = mp_call_function_n_kw(asm_pio_encode, 3, 0, args);
mp_int_t encoded = mp_obj_get_int(encoded_obj);
pio_sm_exec(self->pio, self->sm, encoded);
return mp_const_none;