mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
fix(ulp): fix lp uart keep wakeup triggered
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
禁用睡眠模式唤醒源
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user