GPIO API Clearification

There are a few things that are not clearly specified in the GPIO API. I’d like to gather some feedback on this:

Interaction with IRQs

If a GPIO IRQ is configured on a given pin and then gpio_init() is called on that pin:

  • gpio_init() should reset IRQ settings on the specified pin
  • gpio_init() should keep IRQ settings unchanged
  • this is implementation defined, e.g. behavior can be different on different MCUs
0 voters

Interaction with Multiplexing/Peripherals

If a GPIO pin is routed to a peripheral (e.g. SPI/I2C/UART/…) and then gpio_init() is called on that pin:

  • gpio_init() should detach the specified pin from any peripheral
  • gpio_init() should keep the specified pin connected to a peripheral
  • this is implementation defined, e.g. behavior can be different on different MCUs
0 voters

There might be some implications that are non-obvious but worth pointing out: gpio_init_int() cannot keep the mux settings. E.g. on SAM0 the GPIO is routed to the IRQ controller in the same way it is routed to every other peripheral. Enabling an IRQ will force it to route the pin to the IRQ controller and therefore detach it from another peripheral, if it was connected before.

So for compatibility with SAM0, gpio_init_int() behavior regarding the mux can only be “implementation defined” or “must detach from peripheral”.

I’d argue it would be less surprising to have the same policy for gpio_init().

I say implementation defined, because there are some drivers which call gpio_init() to change a pin’s I/O direction. So adding extra work inside of that function may add extra overhead to those drivers.

Hmm, if it is just for changing the I/O direction, gpio_init() is already pretty much overhead. For that gpio_ll_switch_dir_input() and ..._output() would probably be the right tool.

But I do get the point: There is little reason in not reusing the code of the GPIO driver for configuring pins for e.g. SPI/UART/I2C/PWM/ADC/…

I believe that resetting the mux from gpio_init() does not rule out code reuse. E.g. there could be an MCU specific API such as gpio_init_with_mux(gpio_t pin, gpio_mode_t mode, gpio_mux_t mux) or so, and gpio_init() would just all that with, say, GPIO_MUX_NONE for mux.

Fair enough. Those other drivers should probably just be converted to gpio_ll then.