This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch releases/13.1
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/releases/13.1 by this push:
new 77254a13843 boards/esp32s3-xiao: wire up Wi-Fi, guarding PM light
sleep during radio init
77254a13843 is described below
commit 77254a13843851da6bc4f29d376f5a649c25a099
Author: Felipe Moura <[email protected]>
AuthorDate: Wed Sep 9 14:59:16 2026 -0300
boards/esp32s3-xiao: wire up Wi-Fi, guarding PM light sleep during radio
init
The in-tree esp32s3-xiao board bringup never wires up Wi-Fi at all --
unlike esp32s3-devkit/esp32s3-eye, it has no
`#ifdef CONFIG_ESPRESSIF_WIFI` include of esp32s3_board_wlan.h and no
call to board_wlan_init(). Add both, mirroring those boards' pattern
and placement exactly.
On its own this is not enough for a board that also uses CONFIG_PM:
Wi-Fi's PHY/RF calibration inside board_wlan_init() cannot tolerate
the clock gating of PM_STANDBY (light sleep). If the idle task enters
light sleep while phy_init's calibration is still running -- which the
greedy governor is free to do the moment the CPU goes idle during
driver init -- the calibration hangs forever waiting on a clock that
just stopped. Confirmed on real XIAO ESP32-S3 hardware: with
CONFIG_PM + CONFIG_ESPRESSIF_WIFI both enabled and no guard, boot got
stuck 100% of the time right after the "net80211 rom version" line,
before phy_init ever printed, and never reached NSH -- reproducible
across repeated flashes, 50s+ waits, not even responding to a UART
wakeup keypress (a genuine hang, not quiet sleep).
Fixed by holding a stronger PM lock than PM_STANDBY for the duration
of board_wlan_init(): pm_stay(PM_IDLE_DOMAIN, PM_IDLE) blocks
PM_STANDBY/PM_SLEEP while still allowing normal CPU idle, and
pm_relax() releases it immediately after, restoring whatever floor the
board's own PM policy holds otherwise. Confirmed fixed on the same
hardware: boots clean to NSH with Wi-Fi + PM enabled together, `ps`
shows the wifi/netdev-wlan0 kernel threads running, and `wapi scan`/
`ifup wlan0` work normally.
esp32c3-devkit and esp32c6-devkit also combine CONFIG_PM with Wi-Fi,
but don't need this guard today: both call board_wlan_init() well
before esp_pmconfigure() (which is what actually arms the PM governor)
runs near the end of bringup, so PM isn't active yet during their
Wi-Fi init. This board's PM handling begins earlier in bringup, so the
two can race here.
Signed-off-by: Felipe Moura <[email protected]>
Assisted-by: Claude:claude-sonnet-5
---
.../esp32s3/esp32s3-xiao/src/esp32s3_bringup.c | 24 ++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/boards/xtensa/esp32s3/esp32s3-xiao/src/esp32s3_bringup.c
b/boards/xtensa/esp32s3/esp32s3-xiao/src/esp32s3_bringup.c
index 5aac91128a8..f2818899e60 100644
--- a/boards/xtensa/esp32s3/esp32s3-xiao/src/esp32s3_bringup.c
+++ b/boards/xtensa/esp32s3/esp32s3-xiao/src/esp32s3_bringup.c
@@ -38,6 +38,7 @@
#include <errno.h>
#include <nuttx/fs/fs.h>
#include <nuttx/himem/himem.h>
+#include <nuttx/power/pm.h>
#include <arch/board/board.h>
#include "espressif/esp_gpio.h"
@@ -47,6 +48,10 @@
# include "espressif/esp_hr_timer.h"
#endif
+#ifdef CONFIG_ESPRESSIF_WIFI
+# include "esp32s3_board_wlan.h"
+#endif
+
#ifdef CONFIG_ESP32S3_I2C
# include "esp32s3_i2c.h"
#endif
@@ -157,6 +162,25 @@ int esp32s3_bringup(void)
}
#endif
+#ifdef CONFIG_ESPRESSIF_WIFI
+# ifdef CONFIG_PM
+ /* Wi-Fi radio calibration can't tolerate PM_STANDBY light sleep. */
+
+ pm_stay(PM_IDLE_DOMAIN, PM_IDLE);
+# endif
+
+ ret = board_wlan_init();
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to initialize wlan subsystem=%d\n",
+ ret);
+ }
+
+# ifdef CONFIG_PM
+ pm_relax(PM_IDLE_DOMAIN, PM_IDLE);
+# endif
+#endif
+
/* If we got here then perhaps not all initialization was successful, but
* at least enough succeeded to bring-up NSH with perhaps reduced
* capabilities.