adafruit / circuitpython

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

7.2.4 Feather RP2040 GPIO0 board.UART() problem #6219

Closed dhalbert closed 2 years ago

dhalbert commented 2 years ago

7.2.4 and some earlier versions have a problem with GPIO0 being used for board.UART() on the Feather RP2040. The following program will hang and then USB will disconnect after 10 iterations, due to the gc.collect().,

This is related to #6213 and was found after fixing that bug by setting ringbuf->buf to NULL in ringbuf_free().

import board
import gc
import time

time.sleep(5)
uart = board.UART()
uart.baudrate = 115200

i = 0
while True:
    if i % 10 == 0:
        gc.collect()
    data = f"abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz: {i}\n"
    print(data, end="")
    uart.write(bytes(data, "utf-8"))
    i += 1
    time.sleep(0.0)

If you remove the early gc.collect(), it hangs later, when a gc is necessary, after about 867 iterations or something like that.

import board
import gc
import time

time.sleep(5)
uart = board.UART()
uart.baudrate = 115200

i = 0
while True:
    if i % 10 == 0:
        gc.collect()
    data = f"abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz: {i}\n"
    print(data, end="")
    uart.write(bytes(data, "utf-8"))
    i += 1
    time.sleep(0.0)

The default pins for board.UART() are (from mpconfigboard.h):

#define DEFAULT_UART_BUS_RX (&pin_GPIO1)
#define DEFAULT_UART_BUS_TX (&pin_GPIO0)

If GPIO0 is changed to another TX-capable UART0 pin, then the problem does not happen. I have looked for some issue about the pin->number being zero being treated specially, but haven't found it yet.

dhalbert commented 2 years ago

This is affected by whether or not the TX and/or RX pins are connected to another board. I was testing with them connected to a QT Py RP2040 that was not powered. TX->RX, RX->TX, and common ground. Without the connection, I don't see the failure. To be continued.

So I don't think it's GPIO0 per se, it's that GPIO was connected to something.

dhalbert commented 2 years ago

Closing in favor of #6237.