WiFi.disconnect() sets _wifiHWInitted=false and _mode=WIFI_OFF, which
causes beginAP to run in AP-only mode (_mode=WIFI_AP). In AP-only mode,
subsequent beginNoBlock() calls hit the ESP8266 compatibility hack in
_beginInternal that redirects to beginAP() instead of starting a STA
connection, creating a connect/disconnect loop.
Without WiFi.disconnect(), _wifiHWInitted stays true and beginAP
correctly enters AP_STA mode, allowing STA reconnection attempts to
work properly alongside the fallback AP.
The wifi_sta_connected() helper from the previous commit is sufficient
to prevent false CONNECTED reports by checking WiFi.localIP() instead
of the AP-contaminated WiFi.status().
Two bugs combined to make the RP2040 Pico W immediately think it was
connected to WiFi after starting the fallback AP, causing it to disable
the AP and stop retrying:
1. wifi_mode_(false, {}) was a no-op for STA disable — restart_adapter()
calls this to tear down STA, but the implementation only handled
sta=true. The CYW43 STA link state remained CYW43_LINK_JOIN from
the timed-out connection attempt.
2. wifi_ap_ip_config_() called WiFi.config(192.168.4.1) which configured
the STA interface's IP (not the AP's). When wifi_sta_connect_status_()
checked WiFi.status(), CYW43lwIP::status() saw CYW43_LINK_JOIN +
localIP().isSet() and returned WL_CONNECTED.
Fix wifi_mode_() to call WiFi.disconnect() when sta=false to clear stale
link state. Remove the WiFi.config() call from wifi_ap_ip_config_() since
WiFi.beginAP() already configures the AP IP internally. Also fix
wifi_soft_ap_ip() to use WiFi.softAPIP() instead of WiFi.localIP().
Enable instant wake on socket activity for RP2040 using ARM WFE/SEV
hardware instructions, matching ESP8266's esp_delay/esp_schedule pattern.
Previously, RP2040 used plain delay() in the main loop which could not
be interrupted by incoming socket data. Now LWIP recv/accept callbacks
call socket_wake() which sets a flag and sends a hardware event (__sev)
to wake the main loop from __wfe() sleep immediately.
The implementation uses a one-shot pico-sdk timer alarm for timeout
(same pattern as ESP8266's os_timer_arm) combined with __wfe() for
true hardware sleep between events.
Move signed bin creation from post_build script to upload_using_platformio.
The post_build AddPostAction only runs during build, not during nobuild
upload, so the file was missing when PlatformIO tried to upload.
Now create firmware.bin.signed before calling PlatformIO upload.