← index #17515PR #3952
Off-topic · high · value 1.901
QUERY · ISSUE

Add Pin.mode() and Pin.alt() support for all applicable ports

openby sfe-SparkFroopened 2025-06-17updated 2025-06-19
enhancement

Description

Request

Pin.mode() is currently only supported on cc3200 and stm32 ports, according to the current docs. The first part of this request is to implement that method on all other applicable ports (eg. rp2).

The second part of this request is to implement a similar Pin.alt() method for all applicable ports (eg. rp2), that can be used to either get or set the alt value of the Pin object.


Motivation

I'm writing an ST7789 display driver. Yes, there are many out there, but none fit the needs of my application perfectly.

For example, many ST7789 breakout boards include an SD card slot that shares the same SPI bus, but none of the existing ST7789 MicroPython drivers (that I know of) allow both the display and SD card to be used simultaneously. The DC pin of the ST7789 typically shares the MISO pin. The DC pin has to be driven by the host microcontroller, meaning its mode must be set to OUT. However for the SD card, the mode must be set to ALT, and the alt must be set to ALT_SPI (at least, in the case of the rp2 port); having the mode changed to OUT causes the SD card to stop functioning.

My solution is to have my ST7789 driver save the DC pin's mode and alt values before communicating with the ST7789, then restore them after. However, there is no built-in way to get the mode and alt values of the pin directly. Instead, I convert the pin to a string and parse/extract the mode and alt values from there. This works, but the string parsing isn't an efficient solution. Having direct access to the values would be very helpful.

For reference, here's a snippet of my code that saves and restores the mode and alt values:

# There's no way to get the mode and alt of a pin directly, so we
# convert the pin to a string and parse it. Example formats:
# "Pin(GPIO16, mode=OUT)"
# "Pin(GPIO16, mode=ALT, alt=SPI)"
pinStr = str(pin)

# Extract the "mode" parameter from the pin string
if "mode=" in pinStr:
    # Split between "mode=" and the next comma or closing parenthesis
    modeStr = pinStr.split("mode=")[1].split(",")[0].split(")")[0]

    # Look up the mode in Pin class dictionary
    mode = Pin.__dict__[modeStr]
else:
    # No mode specified, just set to None
    mode = None

# Extrct the "alt" parameter from the pin string
if "alt=" in pinStr:
    # Split between "alt=" and the next comma or closing parenthesis
    altStr = pinStr.split("alt=")[1].split(",")[0].split(")")[0]

    # Look up the alt in Pin class dictionary (with "ALT_" prefix)
    alt = Pin.__dict__["ALT_" + altStr]
else:
    # No alt specified, just set to None
    alt = None

#########################
# Communicate with ST7789
#########################

# Restore the pin to its original mode and alt
pin.init(mode=mode, alt=alt)

Code Size

This feature should be always enabled for all ports that support it, to ensure compatibility with drivers that make use of it. I do not expect this to have a significant impact on code size.

Implementation

I hope the MicroPython maintainers or community will implement this feature

Code of Conduct

Yes, I agree

CANDIDATE · PULL REQUEST

stm32: Add method for statically configuring pin alternate function

closedby andrewleechopened 2018-07-17updated 2018-07-20

Works with pins declared normally in mpconfigboard.h, eg. (pin_XX)

Provides new mp_hal_pin_config_alt_static(pin_obj, mode, pull, fn, type) function
declared in pin_static_af.h to allow configuring pin alternate functions by name
eg.

mp_hal_pin_config_alt_static(MICROPY_HW_FMC_SDCLK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, FMC, SDCLK);

For a full usage example see: #3940

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied