fix(ulp): fix lp uart keep wakeup triggered

This commit is contained in:
hebinglin
2026-06-05 20:01:15 +08:00
parent a0688c6e32
commit f088b73ea8
12 changed files with 80 additions and 25 deletions

View File

@@ -1682,3 +1682,7 @@ config SOC_LP_CORE_SUPPORT_ETM
config SOC_LP_CORE_SUPPORT_STORE_LOAD_EXCEPTIONS
bool
default y
config SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED
bool
default y

View File

@@ -673,3 +673,4 @@
#define SOC_LP_CORE_SINGLE_INTERRUPT_VECTOR (1) /*!< LP Core interrupts all map to a single entry in vector table */
#define SOC_LP_CORE_SUPPORT_ETM (1) /*!< LP Core supports ETM */
#define SOC_LP_CORE_SUPPORT_STORE_LOAD_EXCEPTIONS (1) /*!< LP Core will raise exceptions if accessing invalid addresses */
#define SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED (1) /*!< LP UART wakeup source is kept triggered */

View File

@@ -1431,6 +1431,10 @@ config SOC_LP_CORE_SUPPORT_ETM
bool
default y
config SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED
bool
default y
config SOC_DEBUG_HAVE_OCD_STUB_BINS
bool
default y

View File

@@ -588,6 +588,7 @@
/*------------------------------------- ULP CAPS -------------------------------------*/
#define SOC_LP_CORE_SINGLE_INTERRUPT_VECTOR (1) /*!< LP Core interrupts all map to a single entry in vector table */
#define SOC_LP_CORE_SUPPORT_ETM (1) /*!< LP Core supports ETM */
#define SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED (1) /*!< LP UART wakeup source is kept triggered */
/*------------------------------------- DEBUG CAPS -------------------------------------*/
#define SOC_DEBUG_HAVE_OCD_STUB_BINS (1)

View File

@@ -1986,3 +1986,7 @@ config SOC_LP_CORE_SUPPORT_LP_ADC
config SOC_LP_CORE_SUPPORT_STORE_LOAD_EXCEPTIONS
bool
default y
config SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED
bool
default y

View File

@@ -769,3 +769,4 @@
#define SOC_LP_CORE_SUPPORT_ETM (1) /*!< LP Core supports ETM */
#define SOC_LP_CORE_SUPPORT_LP_ADC (1) /*!< LP ADC can be accessed from the LP-Core */
#define SOC_LP_CORE_SUPPORT_STORE_LOAD_EXCEPTIONS (1) /*!< LP Core will raise exceptions if accessing invalid addresses */
#define SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED (1) /*!< LP UART wakeup source is kept triggered */

View File

@@ -25,9 +25,19 @@
#include "esp_cpu.h"
#include "ulp_lp_core_cpu_freq_shared.h"
#include "ulp_lp_core_lp_uart_shared.h"
#include "ulp_lp_core_uart.h"
static uint32_t lp_wakeup_cause = 0;
#if SOC_ULP_LP_UART_SUPPORTED
void ulp_lp_core_lp_uart_reset_wakeup_en(void)
{
lp_core_ll_enable_lp_uart_wakeup(false);
lp_core_ll_enable_lp_uart_wakeup(true);
}
#endif
void ulp_lp_core_update_wakeup_cause(void)
{
lp_wakeup_cause = 0;
@@ -42,6 +52,13 @@ void ulp_lp_core_update_wakeup_cause(void)
&& (uart_ll_get_intraw_mask(&LP_UART) & LP_UART_WAKEUP_INT_RAW)) {
lp_wakeup_cause |= LP_CORE_LL_WAKEUP_SOURCE_LP_UART;
uart_ll_clr_intsts_mask(&LP_UART, LP_UART_WAKEUP_INT_CLR);
#if SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED
// In these chips, the LP UART wakeup source is kept triggered, so we need to
// reset the wakeup register and flush the UART buffer manually after waking up.
lp_core_uart_tx_flush(LP_UART_NUM_0);
lp_core_uart_clear_buf();
ulp_lp_core_lp_uart_reset_wakeup_en();
#endif
}
#endif
@@ -133,15 +150,6 @@ void ulp_lp_core_delay_cycles(uint32_t cycles)
}
}
#if SOC_ULP_LP_UART_SUPPORTED
void ulp_lp_core_lp_uart_reset_wakeup_en(void)
{
lp_core_ll_enable_lp_uart_wakeup(false);
lp_core_ll_enable_lp_uart_wakeup(true);
}
#endif
void ulp_lp_core_halt(void)
{
lp_core_ll_request_sleep();

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -18,9 +18,10 @@ extern "C" {
*
* @note This function configures the LP UART wakeup mode. Ensure that the UART has already been initialized
* with the lp_core_uart_init() call.
* Once the LP Core wakes up due to the LP UART, the wakeup feature is disabled.
* To re-enable the wakeup from the LP UART, you must call
* ulp_lp_core_lp_uart_reset_wakeup_en() again before the LP core goes to sleep.
* Once the LP Core wakes up due to the LP UART, the wakeup will be kept triggered in the chips with
* SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED. You need to call ulp_lp_core_lp_uart_reset_wakeup_en()
* to reset the wakeup signal and the UART buffer manually after waking up, which is done in ulp
* startup phase.
* Also be aware of limitations in different modes mentioned in the uart_wakeup_cfg_t struct.
*
*

View File

@@ -1,19 +1,17 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "ulp_lp_core_utils.h"
#include "ulp_lp_core_print.h"
#include "ulp_lp_core_lp_uart_shared.h"
#include "lp_core_uart.h"
#include "ulp_lp_core_uart.h"
int main(void)
{
lp_core_printf("Hello world\r\n");
ulp_lp_core_delay_us(5000);
lp_core_uart_clear_buf();
ulp_lp_core_lp_uart_reset_wakeup_en();
lp_core_uart_tx_flush(LP_UART_NUM_0);
return 0;
}

View File

@@ -365,6 +365,24 @@ After waking-up from UART, you should send some extra data through the UART port
In Light-sleep mode, setting Kconfig option :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP` will invalidate UART wakeup.
.. only:: SOC_ULP_LP_UART_SUPPORTED
LP_UART can wake up the ULP LP core coprocessor. LP_UART supports the same wakeup modes as the HP UART described above, including active edge threshold wakeup, RX FIFO threshold wakeup, start bit detection wakeup, and character sequence detection wakeup.
To use LP_UART to wake up the ULP LP core, follow these steps:
#. Set the :c:macro:`ULP_LP_CORE_WAKEUP_SOURCE_LP_UART` flag in the ``wakeup_source`` field of the :cpp:type:`ulp_lp_core_cfg_t` structure.
#. Initialize the LP UART (call :cpp:func:`lp_core_uart_init`).
#. Configure the LP_UART wakeup mode using the :cpp:func:`lp_core_uart_wakeup_setup` function with a :cpp:type:`uart_wakeup_cfg_t` structure, using the same configuration method as HP UART.
.. only:: SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED
.. note::
On chips with ``SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED``, the LP UART wakeup signal remains triggered after a wakeup event. The LP core startup flow (:cpp:func:`ulp_lp_core_update_wakeup_cause`) automatically calls :cpp:func:`ulp_lp_core_lp_uart_reset_wakeup_en` and :cpp:func:`lp_core_uart_clear_buf` to clear this state. If the standard startup flow is not used, you must handle this manually; otherwise, repeated wakeups will occur.
For example code on LP_UART wakeup, refer to :example:`system/ulp/lp_core/lp_uart/lp_uart_char_seq_wakeup`.
.. _disable_sleep_wakeup_source:
Disable Sleep Wakeup Source

View File

@@ -365,6 +365,24 @@ UART 唤醒(仅适用于 Light-sleep 模式)
在 Light-sleep 模式下,设置 Kconfig 选项 :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP` 将使 UART 唤醒失效。
.. only:: SOC_ULP_LP_UART_SUPPORTED
LP_UART 可以将 ULP LP 内核协处理器唤醒。LP_UART 支持的唤醒模式与上述 HP UART 唤醒模式相同包括边沿阈值唤醒、RX FIFO 阈值唤醒、起始位检测唤醒和字符序列检测唤醒。
要使用 LP_UART 唤醒 ULP LP 内核,需要执行以下步骤:
#.:cpp:type:`ulp_lp_core_cfg_t` 结构体的 ``wakeup_source`` 字段中设置 :c:macro:`ULP_LP_CORE_WAKEUP_SOURCE_LP_UART` 标志位。
#. 初始化 LP UART调用 :cpp:func:`lp_core_uart_init`)。
#. 使用 :cpp:func:`lp_core_uart_wakeup_setup` 函数配置 LP_UART 的唤醒模式,参数使用 :cpp:type:`uart_wakeup_cfg_t` 结构体,配置方式与 HP UART 相同。
.. only:: SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED
.. note::
在支持 ``SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED`` 的芯片上LP UART 唤醒后唤醒信号会保持触发状态。LP 核启动流程(:cpp:func:`ulp_lp_core_update_wakeup_cause`)会自动调用 :cpp:func:`ulp_lp_core_lp_uart_reset_wakeup_en`:cpp:func:`lp_core_uart_clear_buf` 清除该状态。若未走标准启动流程,则需手动处理,否则会被重复唤醒。
有关 LP_UART 唤醒的示例代码,请参考 :example:`system/ulp/lp_core/lp_uart/lp_uart_char_seq_wakeup`
.. _disable_sleep_wakeup_source:
禁用睡眠模式唤醒源

View File

@@ -1,20 +1,17 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "ulp_lp_core_utils.h"
#include "ulp_lp_core_print.h"
#include "ulp_lp_core_lp_uart_shared.h"
#include "ulp_lp_core_uart.h"
int main (void)
{
lp_core_printf("Hello world\r\n");
lp_core_uart_tx_flush(LP_UART_NUM_0);
// If you want to make it possible to wake up from UART after sleep,
// you have to reset the wakeup register and the UART buffer manually.
// ulp_lp_core_lp_uart_reset_wakeup_en();
// lp_core_uart_clear_buf();
return 0;
}