rp2: No support for external pins in Pico W build
The named pins feature for supporting external pins requires the definition of machine_pin_ext_init and various other functions for configuring, setting and getting external pins.
This feature is entirely monopolized by the Pico W build, in such a way that it's impossible to add additional external pins on top of those defined for Pico W.
There should be no reason why we can't take a copy of machine_pin_cyw43.c , and extend it as necessary.
This would require moving the hard-coded exception for Pico W in CMakeLists.txt into the board config -
https://github.com/micropython/micropython/blob/3637252b7bc3e85ea92038161e008a550991d1f4/ports/rp2/CMakeLists.txt#L300-L302
ESP32 handles additional sources with the MICROPY_SOURCE_BOARD variable, I think the RP2 port should mirror this behavior, and this is how machine_pin_cyw43.c should be included - https://github.com/micropython/micropython/blob/3637252b7bc3e85ea92038161e008a550991d1f4/ports/esp32/esp32_common.cmake#L105
rp2: Add support for named pins and alternate functions.
This PR adds named pins and alternate functions support in the rp2 port, something that's been missing for a very long time, and is more important now especially with recent changes that added support for CYW43-controlled pins, which made pin management (in machine_pin.c) much more complex.
- The first commit refactors
machine_pin.cto handle externally controlled GPIO pins more generically, by removing all CYW43-specific code frommachine_pin.ctomachine_pin_cyw43.c, and adding hooks to initialise, configure, read and write external pins, that can be implemented by any driver that controls external pins. External pin control is enabled by defining the number of external GPIOs inMICROPY_HW_PIN_EXT_COUNT, otherwise only CPU pins are used. - The following commit adds support for generating named pin mappings for all pins including the CPU pins, board-defined pins (in
pins.csv), LED pin and externally controlled pins (again enabled byMICROPY_HW_PIN_EXT_COUNT). CPU pins are mapped topin_GPIO<n>, externally-controlled pins are mapped topin_WL_GPIO<n>, and defined conditionally (up to 10 pins, and can be expanded in the future), and they are non-const to allowmachine_pin_xxx.cto write the pin fields. Both CPU and external pins are generated even if there's no board CSV file, if one exists it will just be added to board pins. Note the prefix for external pinsWL_is fixed for now (very hard to generate that with macros, probably should useEXT_and use custom naming inpins.csv). - The last 2 commits, implement external pin control for Nina module as en example (in addition to the CYW43 controls, which I left in the
rp2port, for now, but can be moved to the cyw43 driver). - There's special handling for the LED pin (if one is defined), by default "LED" is mapped to a CPU pin (default pico pin), and on CYW43 builds, "LED" is mapped to a CYW43 pin (if defined). However, the LED, and any externally controlled pin, can also be mapped in
pins.csvsame as CPU pins, for example:LEDR,WL_GPIO0. It's possible to remove this special case, if all boards addLED,<pin>to theirpins.csv.
For testing, I used the following simple script:
from machine import Pin
def print_pin(*args, **kwargs):
try:
print(Pin(*args, **kwargs))
except Exception as e:
print (e)
print_pin("LED", Pin.OUT) # On Pico-W this WL_GPIO0, on Pico this GPIO6
print_pin("RESET", Pin.OUT) # board pin defined for Nano
print_pin("WL_GPIO2", Pin.OUT) # Works on PICO-W
print_pin("GPIO9", Pin.ALT, alt=Pin.AF_PWM) # PWM AF
print_pin("GPIO10", Pin.ALT, alt=Pin.AF_CLOCK) # Should fail, no CLOCK AF on GPIO10
Running this on Nano-RP2040 board (non-cyw43 build), with a custom board pin (RESET) and LED pin on GPIO6, I get the following output:
Pin(GPIO6, mode=OUT, ext_pin=false)
Pin(GPIO3, mode=OUT, ext_pin=false)
Unknown named pin "WL_GPIO2".
Pin(GPIO9, mode=ALT, alt=PWM, ext_pin=false)
Invalid pin af: 8.
Running on the Pico-W ( no board reset pin, LED controlled by WL_GPIO0):
Pin(WL_GPIO0, mode=OUT, ext_pin=true)
Unknown named pin "RESET".
Pin(WL_GPIO2, mode=OUT, ext_pin=true)
Pin(GPIO9, mode=ALT, alt=PWM, ext_pin=false)
Invalid pin af: 8.
Note: even though AF unit is not really needed/used, I kept them around for future boards (re-adding them will be a lot of work).