adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.11k stars 1.22k forks source link

Pico W pin names and functions need tweaking? #7017

Closed anecdata closed 2 years ago

anecdata commented 2 years ago

CircuitPython version

Adafruit CircuitPython 8.0.0-beta.1-13-ge0517c737 on 2022-10-06; Raspberry Pi Pico W with rp2040

Code/REPL

Adafruit CircuitPython 8.0.0-beta.1-13-ge0517c737 on 2022-10-06; Raspberry Pi Pico W with rp2040
>>> import board
>>> import digitalio
>>> 
>>> vs = digitalio.DigitalInOut(board.VBUS_SENSE)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: VBUS_SENSE in use
>>> 
>>> import analogio
>>> vm_a = analogio.AnalogIn(board.VOLTAGE_MONITOR)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: A3 in use

Behavior

Pin names and functions from p.8: https://datasheets.raspberrypi.com/picow/pico-w-datasheet.pdf

GPIO23 OP wireless power on signal Not in microcontroller. Not sure if it's intended to be read-only, or if it could be used to hard-reset the wifi module from user code.

GPIO24 IP wireless SPI data/IRQ microcontroller.pin.GPIO24 board.GP24 board.VBUS_SENSE This doesn't seem right. ValueError: VBUS_SENSE in use. It isn't VBUS_SENSE. Also, user code probably shouldn't have access to this pin?

GPIO25 OP wireless SPI CS- when high also enables GPIO29 ADC pin to read VSYS OP Not in microcontroller. Not sure how to use this to read VSYS since we don't want to mess up wireless SPI.

GPIO29 OP/IP wireless SPI CLK/ADC mode (ADC3) to measure VSYS/3 microcontroller.pin.GPIO29 board.A3 board.VOLTAGE_MONITOR Yes, but "ValueError: A3 in use" and we can't read it directly w/o prior use of GPIO25

edit: (p.12)

VSYS divided by 3 (by R5, R6 in the Pico W schematic) and can be monitored on ADC channel 3 when a wireless transmission isn’t in progress. This can be used for example as a crude battery voltage monitor.

Then, we also have these pins exposed (to the SDK) from the wifi processor:

WL_GPIO0 OP connected to user LED Exposed to user and works great!

WL_GPIO1 OP controls the on-board SMPS power save pin (Section 3.4) This is not exposed to user directly. I suspect it's used in the driver via cyw43.set_power_management()

WL_GPIO2 IP VBUS sense - high if VBUS is present, else low This seems to be our VBUS_SENSE, but it's not exposed to user code.

Description

Additional information

WL_GPIO1 also potentially useful for ADC:

Driving the SMPS mode pin (WL_GPIO1) high forces the power supply into PWM mode. This can greatly reduce the inherent ripple of the SMPS at light load, and therefore reduces the ripple on the ADC supply. This does reduce the power efficiency of the Pico W at light load, so at the end of an ADC conversation PFM mode can be re-enabled by driving WIFI_GPIO1 low once more. See Section 3.4.

I didn't spot this in analogio common-hal, perhaps as a later enhancement, if needed.

jepler commented 2 years ago

WL_GPIO1 OP controls the on-board SMPS power save pin (Section 3.4) This is not exposed to user directly. I suspect it's used in the driver via cyw43.set_power_management()

As far as I understand it, that's incorrect.

    { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_CYW1) },
    { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_CYW1) },

SMPS mode should be referring to CYW GPIO 1 already. I think this was a part of #6960.

It would be good to fix up the remaining items you mention. I would be happy to see someone else take it on, micropython should have good code to study.

anecdata commented 2 years ago

As far as I understand it, that's incorrect.

You're absolutely right, sorry, I completely missed it this time around. It's right there in board and it's a settable digitalio output.

anecdata commented 2 years ago

...but I think the second line: { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_CYW1) }, should be: { MP_ROM_QSTR(MP_QSTR_CYW1), MP_ROM_PTR(&pin_CYW1) }, like CYW0, to free up GP23 for its other function

jepler commented 2 years ago

Gp23 is not for use of CP code. But old code that used this name to refer to the function will work if this name is provided. If it's better to remove this name that's fine by me.

anecdata commented 2 years ago

I'm not sure, the docs say GPIO23 OP wireless power on signal. If that lets me toggle the wifi chip power from user code cleanly, then awesome! But if it's a read-only or has some more complex behavior, then we probably want non-W Pico code to break if they try to use it on a W? It doesn't seem like it's the same function as SMPS_MODE.

Non-W Pico code that references special pins by number, (e.g., GP23, GP24) may collide with different special functions on a W board. GP23 is SMPS_MODE on a non-W, and GP24 is VBUS_SENSE on a non-W, but it's all jumbled around for the W.

jepler commented 2 years ago

No, you'd just crash things if you could externally reset the wifi chip.

anecdata commented 2 years ago

That's unfortunate. So we probably want to enforce using these special pins by name only on both boards, so code for one runs on the other? Use the named aliases for the pins, and they will (in future) map to the correct non-W pin number, or W pin number or CywPin number.

jepler commented 2 years ago

I've created a separate issue for the vsys measurement (board.VOLTAGE_MONITOR) aspect: https://github.com/adafruit/circuitpython/issues/7020