raspberrypi / pico-sdk

BSD 3-Clause "New" or "Revised" License
3.63k stars 902 forks source link

using wifi on PicoW while using serial on UART0 via PicoProbe does not maintain connection on a chip reset #1895

Open gherlein opened 1 week ago

gherlein commented 1 week ago

This may be something I don't grok about how the UART and the wifi chip interact. Here's the setup NOT using wifi:

I have a PicoProbe connected to SWD and to UART0 (GP0 and GP1). Anything I printf comes across just great, and the serial connection survives a chip flash or reset. For example, I can do this:

openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "init ; reset halt ; rp2040.core1 arp_reset assert 0 ; rp2040.core0 arp_reset assert 0 ; exit"

it's magic - the board resets and I have serial maintained across the link.

UNLESS I also use anything in pico_cyw43_arch_lwip_threadsafe_background - even blinking the LED. What happens is that I have to kill and restart the serial connection to get it to work again.

I'm not deep enough into this all to understand, but it seems like something in that library is resetting the UART somehow?

Anyone able to explain this? The code is below

/**
 * Copyright (c) 2024 Gregory C Herlein
 * Derived from sample code at https://www.iopress.info/index.php/books/master-the-raspberry-pi-pico-in-c-wifi-with-lwip-mbedtls/9-programs/73-picocprogramswifi?showall=1
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "pico/stdlib.h"
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "pico/cyw43_arch.h"

#include "credentials.h"

int setup(uint32_t country, const char *ssid, const char *pass, uint32_t auth)
{
    if (cyw43_arch_init_with_country(country))
    {
        return 1;
    }
    cyw43_arch_enable_sta_mode();
    if (cyw43_arch_wifi_connect_blocking(ssid, pass, auth))
    {
        return 2;
    }
    printf("IP: %s\n",
           ip4addr_ntoa(netif_ip_addr4(netif_default)));
    printf("Mask: %s\n",
           ip4addr_ntoa(netif_ip_netmask4(netif_default)));
    printf("Gateway: %s\n",
           ip4addr_ntoa(netif_ip_gw4(netif_default)));
    printf("Host Name: %s\n",
           netif_get_hostname(netif_default));
}

int main()
{
    uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
    // workaround for a hardware debug problem
    // https://forums.raspberrypi.com/viewtopic.php?t=363914
    // also in openocd you need to us -c "set USE_CORE 0"  before rp2040.cfg is loaded per https://github.com/raspberrypi/debugprobe/issues/45
    timer_hw->dbgpause = 0;
    sleep_ms(150);

    stdio_init_all();
    setup(country, ssid, pass, auth);

    while (true)
    {
        printf("on\n");
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
        sleep_ms(500);
        printf("off\n");
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
        sleep_ms(500);
    }
}

cmake_minimum_required(VERSION 3.13)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

include(pico_sdk_import.cmake)

project(main C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(PICO_BOARD pico_w)

pico_sdk_init()

add_executable(main    
    main.c
)

pico_enable_stdio_usb(main 0)
pico_enable_stdio_uart(main 1)

target_include_directories(main PRIVATE
        ${CMAKE_CURRENT_LIST_DIR}
)

pico_add_extra_outputs(main)

target_link_libraries(main
    pico_stdlib
    pico_cyw43_arch_lwip_threadsafe_background 
    #pico_cyw43_arch_none
    # other libs as needed
)

add_custom_target(flash
    COMMAND /bin/bash ../flash main.elf
    DEPENDS main
)
add_custom_target(reset
    COMMAND /bin/bash ../reset
    DEPENDS main
)

(Edited by lurch to put the code inside triple-backticks)

lurch commented 1 week ago

Curious indeed...

I have to kill and restart the serial connection to get it to work again.

"kill and restart" from the Pico W side, from the Pico Probe side, or from the PC-side?

How are you powering the Pico W and Pico Probe? If they're both being powered from the same USB port, I wonder if the additional power draw from the WiFi chip is causing a brownout? (Perhaps https://github.com/raspberrypi/debugprobe/issues/148 is relevant here? )

peterharperuk commented 1 week ago

Does this happen with the standard pico-examples? I certainly never reset my serial connection. Are you using Windows or Linux? What does the "reset" command do?

gherlein commented 1 week ago

UPDATE: I don't see this from other test code, so this may be something weird in my setup or example code. If so, I really apologize. I'm capturing the state of things here just in case, but other test programs using the same libraries are NOT exhibiting this behavior. I hope I didn't waste your time.

I am on Linux, no Windows in my house. On the serial side, I use screen from a Linux terminal. When I say "reset" I mean "ctrl-a k y" to end the screen session, then restart screen at the Linux command line. NOT at the Pico.

The PicoProbe is on it's own USB port, separate from the Pico. I usually power the Pico from a USB power supply, not plugged into a computer.

My experience is that at least on Ubuntu if I connect the Pico and PicoProbe to the computer AND use the USB serial connection to the computer AND do a reset or flash the Pico over the probe THEN I have to restart screen (e.g. "ctrl-a k y" to end the screen session, then restart screen). That's no matter what I run.

IF I power the Pico from a USB power supply AND connect the PicoProbe to the computer AND use the UART serial connection to the computer AND do a reset or flash the Pico over the probe THEN serial just keeps on going, no restart of the screen session required.

EXCEPT for the test code I shared, which is also here: https://github.com/gherlein/picow-blink

AND, similar code, that uses the same library AND actually does useful WiFI stuff (sets up an AP) that is here: https://github.com/gherlein/pico-ap/tree/main works just fine.

Same exact configuration, computer, wiring, installation of the SDK, everything. I'll chase this a little later today and see if I can find something. I hate dangling unexplained things.