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.
pull/7979/head
oli 2021-10-09 10:20:39 +01:00 zatwierdzone przez Damien George
rodzic 3dc9a42bc2
commit 0a9335ecaa
2 zmienionych plików z 14 dodań i 5 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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;