ESP32-S3: UART Interrupt Missed for Data Arriving ~90µs After Waking from Light Sleep via GPIO
Posted: Tue Dec 16, 2025 10:09 am
I'm developing a firmware for the ESP32-S3 using ESP-IDF and have encountered a precise timing issue related to waking from Light Sleep and UART communication.
Hardware & Software Environment
Chip: ESP32-S3
ESP-IDF Version: v5.4.2
Problem Description
The system enters Light Sleep mode via esp_light_sleep_start() and is configured to be woken up by a falling edge on an external GPIO pin. Approximately 90 microseconds (µs) after the GPIO wakeup signal occurs, an external device sends a data packet over UART.
The problem is that this first UART packet is completely lost by the system. We have installed the UART driver using uart_driver_install with an event queue, but this queue receives no UART_DATA event in this scenario.
If we wait for a longer period after wakeup (e.g., a few milliseconds) before sending the UART data, communication works perfectly.
Steps to Reproduce
Configure UART: Initialize the UART driver using uart_param_config and uart_driver_install, providing an event queue.
Configure GPIO: Configure a GPIO pin as a wakeup source from Light Sleep.
Enter Sleep: Call esp_light_sleep_start().
External Trigger: An external device pulls the GPIO pin low, waking up the ESP32-S3.
Send Data: 90µs after the GPIO falling edge, the external device sends data via UART.
Observed Result: The ESP32-S3 wakes up successfully, but the event queue provided to uart_driver_install does not receive a UART_DATA event, and the data is lost.
Investigation and Analysis
To isolate the problem, we have dug directly into the driver's lower layers:
Event Queue Confirmation: We confirmed that the UART driver's event queue remains empty in the scenario described above.
Low-Level Hardware Interrupt Confirmation: We located the UART driver source code at uart.c and placed a debug log (e.g., using ESP_DRAM_LOGI) directly inside the lowest-level hardware interrupt service routine (ISR), uart_rx_intr_handler_default.
Key Finding: Our tests show that within this 90µs window, the low-level hardware ISR uart_rx_intr_handler_default is never executed at all.
Since the hardware ISR itself is not being triggered, it strongly suggests that the UART peripheral's receiving logic is not yet operational
Our Questions
1.In general, what is the official or typical wakeup time for the ESP32-S3 to resume normal operation (i.e., CPU running at full speed and system clocks stable) after exiting Light Sleep?
2.Is our hypothesis (that the total recovery time, especially clock stabilization, exceeds 90µs) likely correct? If so, which part of the wakeup process is the primary contributor to this delay?
Hardware & Software Environment
Chip: ESP32-S3
ESP-IDF Version: v5.4.2
Problem Description
The system enters Light Sleep mode via esp_light_sleep_start() and is configured to be woken up by a falling edge on an external GPIO pin. Approximately 90 microseconds (µs) after the GPIO wakeup signal occurs, an external device sends a data packet over UART.
The problem is that this first UART packet is completely lost by the system. We have installed the UART driver using uart_driver_install with an event queue, but this queue receives no UART_DATA event in this scenario.
If we wait for a longer period after wakeup (e.g., a few milliseconds) before sending the UART data, communication works perfectly.
Steps to Reproduce
Configure UART: Initialize the UART driver using uart_param_config and uart_driver_install, providing an event queue.
Configure GPIO: Configure a GPIO pin as a wakeup source from Light Sleep.
Enter Sleep: Call esp_light_sleep_start().
External Trigger: An external device pulls the GPIO pin low, waking up the ESP32-S3.
Send Data: 90µs after the GPIO falling edge, the external device sends data via UART.
Observed Result: The ESP32-S3 wakes up successfully, but the event queue provided to uart_driver_install does not receive a UART_DATA event, and the data is lost.
Investigation and Analysis
To isolate the problem, we have dug directly into the driver's lower layers:
Event Queue Confirmation: We confirmed that the UART driver's event queue remains empty in the scenario described above.
Low-Level Hardware Interrupt Confirmation: We located the UART driver source code at uart.c and placed a debug log (e.g., using ESP_DRAM_LOGI) directly inside the lowest-level hardware interrupt service routine (ISR), uart_rx_intr_handler_default.
Key Finding: Our tests show that within this 90µs window, the low-level hardware ISR uart_rx_intr_handler_default is never executed at all.
Since the hardware ISR itself is not being triggered, it strongly suggests that the UART peripheral's receiving logic is not yet operational
Our Questions
1.In general, what is the official or typical wakeup time for the ESP32-S3 to resume normal operation (i.e., CPU running at full speed and system clocks stable) after exiting Light Sleep?
2.Is our hypothesis (that the total recovery time, especially clock stabilization, exceeds 90µs) likely correct? If so, which part of the wakeup process is the primary contributor to this delay?