Skip to content

PIO does not work on RP2350B with GPIO pin >=32 #16199

@sfe-SparkFro

Description

@sfe-SparkFro

Port, board and/or hardware

rp2 port with RP2350B

MicroPython version

v1.24.0-preview.461.gb8227a3f7.dirty

Reproduction

Connect a quadrature encoder to any pair of GPIO pins. Then create an instance of this class, which implements a quadrature decoder using PIO: https://github.com/Open-STEM/XRP_MicroPython/blob/main/XRPLib/encoder.py

Then run the following while rotating the encoder:

pinA = 0
pinB = 1

myEncoder = Encoder(0, pinA, pinB)

while True:
    print(myEncoder.get_position_counts())
    time.sleep(0.1)

Expected behaviour

A PIO encoder should work on any pair of pins, and the printed output should change as the encoder rotates.

Observed behaviour

A PIO encoder only works if pinA and pinB are <32. If they're >=32, the printed output is fixed at 0.

Additional Information

I'm not super familiar with MicroPython, but this appears to be where the state machine is created:

// StateMachine(id, ...)
static mp_obj_t rp2_state_machine_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
// Get the StateMachine object.
mp_int_t sm_id = mp_obj_get_int(args[0]);
const rp2_state_machine_obj_t *self = rp2_state_machine_get_object(sm_id);
if (n_args > 1 || n_kw > 0) {
// Configuration arguments given so init this StateMachine.
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
rp2_state_machine_init_helper(self, n_args - 1, args + 1, &kw_args);
}
// Return the StateMachine object.
return MP_OBJ_FROM_PTR(self);
}

Which eventually calls this Pico SDK function:

// Configure in pin base, if needed.
if (args[ARG_in_base].u_obj != mp_const_none) {
sm_config_set_in_pins(&config, mp_hal_get_pin_obj(args[ARG_in_base].u_obj));
}

Not sure whether the root problem is with MicroPython or the Pico SDK, but I suspect it may be related to raspberrypi/pico-sdk#2030 TLDR; need to set pio->gpiobase to 16 if the pin is >=32.

Edit: Just realized that sm_config_set_in_pins() only accepts pins 0-31, so that's likely the root problem. Not sure what the solution would be.

Code of Conduct

Yes, I agree

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions