rp2: Make rp2_state_machine_exec accept integers.
Currently rp2.StateMachine.exec(instr_in) requires that the instr_in parameter be a string representing the PIO assembly language instruction to be encoded by rp2.asm_pio_encode(). This commit allows the parameter to also be of integral type. This is useful if the exec() method is being called often where the use of pre-encoded machine code is desireable. This commit still supports calls like: sm.exec("set(0, 1)") It also now supports calls like: # Performed once earlier, maybe in __init__() assembled_instr = rp2.asm_pio_encode("out(y, 8)", 0) # Performed multiple times later as the PIO state machine is # configured for its next run. sm.exec(assembled_instr) The existing examples/rp2/pio_exec.py and examples/rp2/pio_pwm.py that exercise the rp2.StateMachine.exec() method still work with this change. Signed-off-by: Adam Green <adamgrym@yahoo.com>
This commit is contained in:
parent
3229791b60
commit
f9958417d8
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user