forked from espressif/esp-idf
feat(esp_driver_uart): support hp uarts wakeup modes 1 2 3 during light sleep
This commit is contained in:
@@ -67,6 +67,16 @@ typedef struct {
|
||||
*/
|
||||
esp_err_t uart_wakeup_setup(uart_port_t uart_num, const uart_wakeup_cfg_t *cfg);
|
||||
|
||||
/**
|
||||
* @brief Clear the UART wakeup configuration.
|
||||
*
|
||||
* This function will clear the UART wakeup behavior and set to its default configuration.
|
||||
*
|
||||
* @param uart_num The UART port to initialize for wakeup (e.g., UART_NUM_0, UART_NUM_1, etc.).
|
||||
* @param wakeup_mode The UART wakeup mode set in `uart_wakeup_setup`.
|
||||
*/
|
||||
void uart_wakeup_clear(uart_port_t uart_num, uart_wakeup_mode_t wakeup_mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -13,6 +13,10 @@
|
||||
|
||||
#include "driver/uart_wakeup.h"
|
||||
#include "hal/uart_hal.h"
|
||||
#include "esp_private/esp_sleep_internal.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
const __attribute__((unused)) static char *TAG = "uart_wakeup";
|
||||
|
||||
#if SOC_UART_WAKEUP_SUPPORT_CHAR_SEQ_MODE
|
||||
static esp_err_t uart_char_seq_wk_configure(uart_dev_t *hw, const char* phrase)
|
||||
@@ -59,6 +63,26 @@ esp_err_t uart_wakeup_setup(uart_port_t uart_num, const uart_wakeup_cfg_t *cfg)
|
||||
// This should be mocked at ll level if the selection of the UART wakeup mode is not supported by this SOC.
|
||||
uart_ll_set_wakeup_mode(hw, cfg->wakeup_mode);
|
||||
|
||||
#if SOC_PM_SUPPORT_PMU_CLK_ICG
|
||||
// When hp uarts are utilized, the main XTAL need to be PU and UARTx & IOMX ICG need to be ungate
|
||||
bool __attribute__((unused)) is_hp_uart = (uart_num < SOC_UART_HP_NUM);
|
||||
uart_hal_context_t hal = {
|
||||
.dev = hw,
|
||||
};
|
||||
soc_module_clk_t src_clk;
|
||||
uart_hal_get_sclk(&hal, &src_clk);
|
||||
|
||||
if (is_hp_uart && cfg->wakeup_mode != UART_WK_MODE_ACTIVE_THRESH) {
|
||||
if (src_clk != SOC_MOD_CLK_XTAL) {
|
||||
ESP_LOGE(TAG, "Failed to setup uart wakeup due to the clock source is not XTAL!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
|
||||
esp_sleep_clock_config(UART_LL_SLEEP_CLOCK(uart_num), ESP_SLEEP_CLOCK_OPTION_UNGATE);
|
||||
esp_sleep_clock_config(ESP_SLEEP_CLOCK_IOMUX, ESP_SLEEP_CLOCK_OPTION_UNGATE);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (cfg->wakeup_mode) {
|
||||
#if SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE
|
||||
case UART_WK_MODE_ACTIVE_THRESH:
|
||||
@@ -89,3 +113,18 @@ esp_err_t uart_wakeup_setup(uart_port_t uart_num, const uart_wakeup_cfg_t *cfg)
|
||||
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
void uart_wakeup_clear(uart_port_t uart_num, uart_wakeup_mode_t wakeup_mode)
|
||||
{
|
||||
#if SOC_PM_SUPPORT_PMU_CLK_ICG
|
||||
// When hp uarts are utilized, the main XTAL need to be PU and UARTx & IOMX ICG need to be ungate
|
||||
bool __attribute__((unused)) is_hp_uart = (uart_num < SOC_UART_HP_NUM);
|
||||
|
||||
if (is_hp_uart && wakeup_mode != UART_WK_MODE_ACTIVE_THRESH) {
|
||||
esp_sleep_clock_config(UART_LL_SLEEP_CLOCK(uart_num), ESP_SLEEP_CLOCK_OPTION_GATE);
|
||||
esp_sleep_clock_config(ESP_SLEEP_CLOCK_IOMUX, ESP_SLEEP_CLOCK_OPTION_GATE);
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -86,9 +86,15 @@ typedef enum {
|
||||
#if SOC_UART_SUPPORT_WAKEUP_INT
|
||||
#define RTC_UART0_TRIG_EN PMU_UART0_WAKEUP_EN //!< UART0 wakeup (light sleep only)
|
||||
#define RTC_UART1_TRIG_EN PMU_UART1_WAKEUP_EN //!< UART1 wakeup (light sleep only)
|
||||
#if SOC_UART_HP_NUM > 2
|
||||
#define RTC_UART2_TRIG_EN PMU_UART2_WAKEUP_EN //!< UART2 wakeup (light sleep only)
|
||||
#else
|
||||
#define RTC_UART2_TRIG_EN 0
|
||||
#endif
|
||||
#else
|
||||
#define RTC_UART0_TRIG_EN 0
|
||||
#define RTC_UART1_TRIG_EN 0
|
||||
#define RTC_UART2_TRIG_EN 0
|
||||
#endif
|
||||
|
||||
#if SOC_BT_SUPPORTED
|
||||
@@ -130,6 +136,7 @@ typedef enum {
|
||||
RTC_WIFI_TRIG_EN | \
|
||||
RTC_UART0_TRIG_EN | \
|
||||
RTC_UART1_TRIG_EN | \
|
||||
RTC_UART2_TRIG_EN | \
|
||||
RTC_BT_TRIG_EN | \
|
||||
RTC_LP_CORE_TRIG_EN | \
|
||||
RTC_TOUCH_TRIG_EN | \
|
||||
|
@@ -92,6 +92,9 @@ typedef enum {
|
||||
ESP_SLEEP_CLOCK_LEDC, //!< The clock ICG cell mapping of LEDC
|
||||
ESP_SLEEP_CLOCK_UART0, //!< The clock ICG cell mapping of UART0
|
||||
ESP_SLEEP_CLOCK_UART1, //!< The clock ICG cell mapping of UART1
|
||||
#if SOC_UART_HP_NUM > 2
|
||||
ESP_SLEEP_CLOCK_UART2, //!< The clock ICG cell mapping of UART2
|
||||
#endif
|
||||
ESP_SLEEP_CLOCK_MAX //!< Number of ICG cells
|
||||
} esp_sleep_clock_t;
|
||||
|
||||
|
@@ -18,6 +18,7 @@ extern "C" {
|
||||
#define PMU_WIFI_SOC_WAKEUP_EN BIT(5)
|
||||
#define PMU_UART0_WAKEUP_EN BIT(6)
|
||||
#define PMU_UART1_WAKEUP_EN BIT(7)
|
||||
#define PMU_UART2_WAKEUP_EN BIT(9)
|
||||
#define PMU_BLE_SOC_WAKEUP_EN BIT(10)
|
||||
// #define PMU_LP_CORE_WAKEUP_EN BIT(11)
|
||||
#define PMU_USB_WAKEUP_EN BIT(14)
|
||||
|
@@ -1601,9 +1601,15 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
|
||||
#endif
|
||||
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_GPIO, RTC_GPIO_TRIG_EN)) {
|
||||
s_config.wakeup_triggers &= ~RTC_GPIO_TRIG_EN;
|
||||
#if SOC_PMU_SUPPORTED && (SOC_UART_HP_NUM > 2)
|
||||
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN | RTC_UART2_TRIG_EN))) {
|
||||
s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN | RTC_UART2_TRIG_EN);
|
||||
}
|
||||
#else
|
||||
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) {
|
||||
s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN);
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_ULP_COPROC_TYPE_FSM
|
||||
else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) {
|
||||
s_config.wakeup_triggers &= ~RTC_ULP_TRIG_EN;
|
||||
@@ -2082,6 +2088,10 @@ esp_err_t esp_sleep_enable_uart_wakeup(int uart_num)
|
||||
s_config.wakeup_triggers |= RTC_UART0_TRIG_EN;
|
||||
} else if (uart_num == UART_NUM_1) {
|
||||
s_config.wakeup_triggers |= RTC_UART1_TRIG_EN;
|
||||
#if SOC_PMU_SUPPORTED && (SOC_UART_HP_NUM > 2)
|
||||
} else if (uart_num == UART_NUM_2) {
|
||||
s_config.wakeup_triggers |= RTC_UART2_TRIG_EN;
|
||||
#endif
|
||||
} else {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
@@ -2165,7 +2175,11 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void)
|
||||
return ESP_SLEEP_WAKEUP_TIMER;
|
||||
} else if (wakeup_cause & RTC_GPIO_TRIG_EN) {
|
||||
return ESP_SLEEP_WAKEUP_GPIO;
|
||||
#if SOC_PMU_SUPPORTED && (SOC_UART_HP_NUM > 2)
|
||||
} else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN | RTC_UART2_TRIG_EN)) {
|
||||
#else
|
||||
} else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN)) {
|
||||
#endif
|
||||
return ESP_SLEEP_WAKEUP_UART;
|
||||
#if SOC_PM_SUPPORT_EXT0_WAKEUP
|
||||
} else if (wakeup_cause & RTC_EXT0_TRIG_EN) {
|
||||
@@ -2571,6 +2585,11 @@ static uint32_t get_sleep_clock_icg_flags(void)
|
||||
if (s_config.clock_icg_refs[ESP_SLEEP_CLOCK_UART1] > 0) {
|
||||
clk_flags |= BIT(PMU_ICG_FUNC_ENA_UART1);
|
||||
}
|
||||
#if SOC_UART_HP_NUM > 2
|
||||
if (s_config.clock_icg_refs[ESP_SLEEP_CLOCK_UART2] > 0) {
|
||||
clk_flags |= BIT(PMU_ICG_FUNC_ENA_UART2);
|
||||
}
|
||||
#endif
|
||||
#endif /* SOC_PM_SUPPORT_PMU_CLK_ICG */
|
||||
return clk_flags;
|
||||
}
|
||||
|
@@ -30,6 +30,8 @@ extern "C" {
|
||||
#define LP_UART_LL_FIFO_DEF_LEN (SOC_LP_UART_FIFO_LEN)
|
||||
// Get UART hardware instance with giving uart num
|
||||
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (((num) == UART_NUM_1) ? (&UART1) : (&LP_UART)))
|
||||
// Get UART sleep clock with giving uart num
|
||||
#define UART_LL_SLEEP_CLOCK(num) (((num) == UART_NUM_0) ? (ESP_SLEEP_CLOCK_UART0) : (ESP_SLEEP_CLOCK_UART1))
|
||||
|
||||
#define UART_LL_REG_FIELD_BIT_SHIFT(hw) (((hw) == &LP_UART) ? 3 : 0)
|
||||
|
||||
|
@@ -30,6 +30,8 @@ extern "C" {
|
||||
#define LP_UART_LL_FIFO_DEF_LEN (SOC_LP_UART_FIFO_LEN)
|
||||
// Get UART hardware instance with giving uart num
|
||||
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (((num) == UART_NUM_1) ? (&UART1) : (&LP_UART)))
|
||||
// Get UART sleep clock with giving uart num
|
||||
#define UART_LL_SLEEP_CLOCK(num) (((num) == UART_NUM_0) ? (ESP_SLEEP_CLOCK_UART0) : (ESP_SLEEP_CLOCK_UART1))
|
||||
|
||||
#define UART_LL_REG_FIELD_BIT_SHIFT(hw) (((hw) == &LP_UART) ? 3 : 0)
|
||||
|
||||
|
@@ -29,6 +29,8 @@ extern "C" {
|
||||
#define UART_LL_FIFO_DEF_LEN (SOC_UART_FIFO_LEN)
|
||||
// Get UART hardware instance with giving uart num
|
||||
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (((num) == UART_NUM_1) ? (&UART1) : (&UART2)))
|
||||
// Get UART sleep clock with giving uart num
|
||||
#define UART_LL_SLEEP_CLOCK(num) (((num) == UART_NUM_0) ? (ESP_SLEEP_CLOCK_UART0) : (((num) == UART_NUM_1) ? (ESP_SLEEP_CLOCK_UART1) : (ESP_SLEEP_CLOCK_UART2)))
|
||||
|
||||
#define UART_LL_PULSE_TICK_CNT_MAX UART_LOWPULSE_MIN_CNT_V
|
||||
|
||||
|
@@ -28,6 +28,8 @@ extern "C" {
|
||||
#define UART_LL_FIFO_DEF_LEN (SOC_UART_FIFO_LEN)
|
||||
// Get UART hardware instance with giving uart num
|
||||
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (&UART1))
|
||||
// Get UART sleep clock with giving uart num
|
||||
#define UART_LL_SLEEP_CLOCK(num) (((num) == UART_NUM_0) ? (ESP_SLEEP_CLOCK_UART0) : (ESP_SLEEP_CLOCK_UART1))
|
||||
|
||||
#define UART_LL_PULSE_TICK_CNT_MAX UART_LOWPULSE_MIN_CNT_V
|
||||
|
||||
|
Reference in New Issue
Block a user