diff --git a/docs/library/rp2.StateMachine.rst b/docs/library/rp2.StateMachine.rst index d39194e6ff..ee16ce3c51 100644 --- a/docs/library/rp2.StateMachine.rst +++ b/docs/library/rp2.StateMachine.rst @@ -82,11 +82,18 @@ Methods .. method:: StateMachine.exec(instr) - Execute a single PIO instruction. Uses `asm_pio_encode` to encode the - instruction from the given string *instr*. + Execute a single PIO instruction. + + If *instr* is a string then uses `asm_pio_encode` to encode the instruction + from the given string. >>> sm.exec("set(0, 1)") + If *instr* is an integer then it is treated as an already encoded PIO + machine code instruction to be executed. + + >>> sm.exec(rp2.asm_pio_encode("out(y, 8)", 0)) + .. method:: StateMachine.get(buf=None, shift=0) Pull a word from the state machine's RX FIFO. diff --git a/ports/rp2/rp2_pio.c b/ports/rp2/rp2_pio.c index 3ece26bd41..2e30475257 100644 --- a/ports/rp2/rp2_pio.c +++ b/ports/rp2/rp2_pio.c @@ -684,16 +684,19 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(rp2_state_machine_restart_obj, rp2_state_machin // StateMachine.exec(instr) STATIC mp_obj_t rp2_state_machine_exec(mp_obj_t self_in, mp_obj_t instr_in) { rp2_state_machine_obj_t *self = MP_OBJ_TO_PTR(self_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; - 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); + mp_int_t encoded = 0; + if (!mp_obj_get_int_maybe(instr_in, &encoded)) { + 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; + 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); + encoded = mp_obj_get_int(encoded_obj); + } pio_sm_exec(self->pio, self->sm, encoded); return mp_const_none; }