From 51852b167fd388536d6f81dd115a9ea69dd3a42d Mon Sep 17 00:00:00 2001 From: Patric Aeberhard <55001046+Simplycissmus@users.noreply.github.com> Date: Fri, 28 Aug 2026 08:20:31 +0200 Subject: [PATCH 1/2] fix(rp2040): run the blocking CYW43 WiFi join in a task and retry failed joins --- src/mesh/wifi/WiFiAPClient.cpp | 37 ++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index 8bb80cd96a9..78c9a9d06c1 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -29,11 +29,13 @@ #include static void WiFiEvent(WiFiEvent_t event); #elif defined(ARCH_RP2040) +#include #include +#include #endif -#ifndef DISABLE_NTP #include "Throttle.h" +#ifndef DISABLE_NTP #include #endif @@ -61,6 +63,31 @@ unsigned long lastrun_ntp = 0; bool needReconnect = true; // If we create our reconnector, run it once at the beginning bool isReconnecting = false; // If we are currently reconnecting + +#ifdef ARCH_RP2040 +// On the CYW43 under FreeRTOS even WiFi.beginNoBlock() holds the caller for several seconds (up to the WiFi timeout, +// 15 s); from the main loop that trips the 8 s hardware watchdog. Join from a short-lived task and poll for the link. +static TaskHandle_t wifiJoinTask = nullptr; + +static void wifiJoinTaskFn(void *) +{ + const char *psk = config.network.wifi_psk[0] ? config.network.wifi_psk : NULL; + WiFi.beginNoBlock(config.network.wifi_ssid, psk); + wifiJoinTask = nullptr; + vTaskDelete(NULL); +} + +static bool startWifiJoin() +{ + if (wifiJoinTask) + return true; // previous join still in progress + if (xTaskCreate(wifiJoinTaskFn, "wifijoin", 1536, NULL, uxTaskPriorityGet(NULL), &wifiJoinTask) != pdPASS) { + LOG_ERROR("Could not start WiFi join task"); + return false; + } + return true; +} +#endif #if defined(USE_WS5500) || defined(USE_CH390D) static volatile bool ethNetworkConnectedPending = false; #endif @@ -281,7 +308,11 @@ static int32_t reconnectWiFi() WiFi.useStaticBuffers(true); WiFi.mode(WIFI_STA); #endif +#ifdef ARCH_RP2040 + startWifiJoin(); +#else WiFi.begin(wifiName, wifiPsw); +#endif } isReconnecting = false; wifiReconnectPending = false; @@ -311,7 +342,9 @@ static int32_t reconnectWiFi() if (config.network.wifi_enabled && !WiFi.isConnected()) { #ifdef ARCH_RP2040 // (ESP32 handles this in WiFiEvent) - needReconnect = APStartupComplete; + // Lost the link, or a join that has not come up within 30 s: start the join over once the join task is done. + needReconnect = !wifiJoinTask && (APStartupComplete || (!isReconnecting && !Throttle::isWithinTimespanMs( + wifiReconnectStartMillis, 30000))); #endif return 1000; // check once per second } else { From 6735d354fe6128a2b574c811231d6a8b8447f29d Mon Sep 17 00:00:00 2001 From: Patric Aeberhard <55001046+Simplycissmus@users.noreply.github.com> Date: Sun, 30 Aug 2026 23:12:10 +0200 Subject: [PATCH 2/2] refactor: use Throttle::hasElapsed for the WiFi join retry deadline --- src/mesh/wifi/WiFiAPClient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index 78c9a9d06c1..1d08d9bebad 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -343,8 +343,8 @@ static int32_t reconnectWiFi() if (config.network.wifi_enabled && !WiFi.isConnected()) { #ifdef ARCH_RP2040 // (ESP32 handles this in WiFiEvent) // Lost the link, or a join that has not come up within 30 s: start the join over once the join task is done. - needReconnect = !wifiJoinTask && (APStartupComplete || (!isReconnecting && !Throttle::isWithinTimespanMs( - wifiReconnectStartMillis, 30000))); + needReconnect = + !wifiJoinTask && (APStartupComplete || (!isReconnecting && Throttle::hasElapsed(wifiReconnectStartMillis, 30000))); #endif return 1000; // check once per second } else {