Skip to content

Commit d115a3d

Browse files
committed
feat(esp_driver_uart): support hp uarts wakeup modes 1 2 3 during light sleep
1 parent ea57c1b commit d115a3d

File tree

10 files changed

+88
-1
lines changed

10 files changed

+88
-1
lines changed

components/esp_driver_uart/include/driver/uart_wakeup.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ typedef struct {
6767
*/
6868
esp_err_t uart_wakeup_setup(uart_port_t uart_num, const uart_wakeup_cfg_t *cfg);
6969

70+
/**
71+
* @brief Clear the UART wakeup configuration.
72+
*
73+
* This function will clear the UART wakeup behavior and set to its default configuration.
74+
*
75+
* @param uart_num The UART port to initialize for wakeup (e.g., UART_NUM_0, UART_NUM_1, etc.).
76+
* @param wakeup_mode The UART wakeup mode set in `uart_wakeup_setup`.
77+
*/
78+
void uart_wakeup_clear(uart_port_t uart_num, uart_wakeup_mode_t wakeup_mode);
79+
7080
#ifdef __cplusplus
7181
}
7282
#endif

components/esp_driver_uart/src/uart_wakeup.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313

1414
#include "driver/uart_wakeup.h"
1515
#include "hal/uart_hal.h"
16+
#include "esp_private/esp_sleep_internal.h"
17+
#include "esp_log.h"
18+
19+
const __attribute__((unused)) static char *TAG = "uart_wakeup";
1620

1721
#if SOC_UART_WAKEUP_SUPPORT_CHAR_SEQ_MODE
1822
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)
5963
// This should be mocked at ll level if the selection of the UART wakeup mode is not supported by this SOC.
6064
uart_ll_set_wakeup_mode(hw, cfg->wakeup_mode);
6165

66+
#if SOC_PM_SUPPORT_PMU_CLK_ICG
67+
// When hp uarts are utilized, the main XTAL need to be PU and UARTx & IOMX ICG need to be ungate
68+
bool __attribute__((unused)) is_hp_uart = (uart_num < SOC_UART_HP_NUM);
69+
uart_hal_context_t hal = {
70+
.dev = hw,
71+
};
72+
soc_module_clk_t src_clk;
73+
uart_hal_get_sclk(&hal, &src_clk);
74+
75+
if (is_hp_uart && cfg->wakeup_mode != UART_WK_MODE_ACTIVE_THRESH) {
76+
if (src_clk != SOC_MOD_CLK_XTAL) {
77+
ESP_LOGE(TAG, "Failed to setup uart wakeup due to the clock source is not XTAL!");
78+
return ESP_ERR_NOT_SUPPORTED;
79+
}
80+
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
81+
esp_sleep_clock_config(UART_LL_SLEEP_CLOCK(uart_num), ESP_SLEEP_CLOCK_OPTION_UNGATE);
82+
esp_sleep_clock_config(ESP_SLEEP_CLOCK_IOMUX, ESP_SLEEP_CLOCK_OPTION_UNGATE);
83+
}
84+
#endif
85+
6286
switch (cfg->wakeup_mode) {
6387
#if SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE
6488
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)
89113

90114
return ESP_ERR_INVALID_ARG;
91115
}
116+
117+
void uart_wakeup_clear(uart_port_t uart_num, uart_wakeup_mode_t wakeup_mode)
118+
{
119+
#if SOC_PM_SUPPORT_PMU_CLK_ICG
120+
// When hp uarts are utilized, the main XTAL need to be PU and UARTx & IOMX ICG need to be ungate
121+
bool __attribute__((unused)) is_hp_uart = (uart_num < SOC_UART_HP_NUM);
122+
123+
if (is_hp_uart && wakeup_mode != UART_WK_MODE_ACTIVE_THRESH) {
124+
esp_sleep_clock_config(UART_LL_SLEEP_CLOCK(uart_num), ESP_SLEEP_CLOCK_OPTION_GATE);
125+
esp_sleep_clock_config(ESP_SLEEP_CLOCK_IOMUX, ESP_SLEEP_CLOCK_OPTION_GATE);
126+
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF);
127+
}
128+
#endif
129+
130+
}

components/esp_hw_support/include/esp_private/esp_pmu.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -86,9 +86,15 @@ typedef enum {
8686
#if SOC_UART_SUPPORT_WAKEUP_INT
8787
#define RTC_UART0_TRIG_EN PMU_UART0_WAKEUP_EN //!< UART0 wakeup (light sleep only)
8888
#define RTC_UART1_TRIG_EN PMU_UART1_WAKEUP_EN //!< UART1 wakeup (light sleep only)
89+
#if SOC_UART_HP_NUM > 2
90+
#define RTC_UART2_TRIG_EN PMU_UART2_WAKEUP_EN //!< UART2 wakeup (light sleep only)
91+
#else
92+
#define RTC_UART2_TRIG_EN 0
93+
#endif
8994
#else
9095
#define RTC_UART0_TRIG_EN 0
9196
#define RTC_UART1_TRIG_EN 0
97+
#define RTC_UART2_TRIG_EN 0
9298
#endif
9399

94100
#if SOC_BT_SUPPORTED
@@ -130,6 +136,7 @@ typedef enum {
130136
RTC_WIFI_TRIG_EN | \
131137
RTC_UART0_TRIG_EN | \
132138
RTC_UART1_TRIG_EN | \
139+
RTC_UART2_TRIG_EN | \
133140
RTC_BT_TRIG_EN | \
134141
RTC_LP_CORE_TRIG_EN | \
135142
RTC_TOUCH_TRIG_EN | \

components/esp_hw_support/include/esp_private/esp_sleep_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ typedef enum {
9292
ESP_SLEEP_CLOCK_LEDC, //!< The clock ICG cell mapping of LEDC
9393
ESP_SLEEP_CLOCK_UART0, //!< The clock ICG cell mapping of UART0
9494
ESP_SLEEP_CLOCK_UART1, //!< The clock ICG cell mapping of UART1
95+
#if SOC_UART_HP_NUM > 2
96+
ESP_SLEEP_CLOCK_UART2, //!< The clock ICG cell mapping of UART2
97+
#endif
9598
ESP_SLEEP_CLOCK_MAX //!< Number of ICG cells
9699
} esp_sleep_clock_t;
97100

components/esp_hw_support/port/esp32c61/private_include/pmu_bit_defs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ extern "C" {
1818
#define PMU_WIFI_SOC_WAKEUP_EN BIT(5)
1919
#define PMU_UART0_WAKEUP_EN BIT(6)
2020
#define PMU_UART1_WAKEUP_EN BIT(7)
21+
#define PMU_UART2_WAKEUP_EN BIT(9)
2122
#define PMU_BLE_SOC_WAKEUP_EN BIT(10)
2223
// #define PMU_LP_CORE_WAKEUP_EN BIT(11)
2324
#define PMU_USB_WAKEUP_EN BIT(14)

components/esp_hw_support/sleep_modes.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,9 +1601,15 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
16011601
#endif
16021602
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_GPIO, RTC_GPIO_TRIG_EN)) {
16031603
s_config.wakeup_triggers &= ~RTC_GPIO_TRIG_EN;
1604+
#if SOC_PMU_SUPPORTED && (SOC_UART_HP_NUM > 2)
1605+
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN | RTC_UART2_TRIG_EN))) {
1606+
s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN | RTC_UART2_TRIG_EN);
1607+
}
1608+
#else
16041609
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) {
16051610
s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN);
16061611
}
1612+
#endif
16071613
#if CONFIG_ULP_COPROC_TYPE_FSM
16081614
else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) {
16091615
s_config.wakeup_triggers &= ~RTC_ULP_TRIG_EN;
@@ -2082,6 +2088,10 @@ esp_err_t esp_sleep_enable_uart_wakeup(int uart_num)
20822088
s_config.wakeup_triggers |= RTC_UART0_TRIG_EN;
20832089
} else if (uart_num == UART_NUM_1) {
20842090
s_config.wakeup_triggers |= RTC_UART1_TRIG_EN;
2091+
#if SOC_PMU_SUPPORTED && (SOC_UART_HP_NUM > 2)
2092+
} else if (uart_num == UART_NUM_2) {
2093+
s_config.wakeup_triggers |= RTC_UART2_TRIG_EN;
2094+
#endif
20852095
} else {
20862096
return ESP_ERR_INVALID_ARG;
20872097
}
@@ -2165,7 +2175,11 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void)
21652175
return ESP_SLEEP_WAKEUP_TIMER;
21662176
} else if (wakeup_cause & RTC_GPIO_TRIG_EN) {
21672177
return ESP_SLEEP_WAKEUP_GPIO;
2178+
#if SOC_PMU_SUPPORTED && (SOC_UART_HP_NUM > 2)
2179+
} else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN | RTC_UART2_TRIG_EN)) {
2180+
#else
21682181
} else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN)) {
2182+
#endif
21692183
return ESP_SLEEP_WAKEUP_UART;
21702184
#if SOC_PM_SUPPORT_EXT0_WAKEUP
21712185
} else if (wakeup_cause & RTC_EXT0_TRIG_EN) {
@@ -2571,6 +2585,11 @@ static uint32_t get_sleep_clock_icg_flags(void)
25712585
if (s_config.clock_icg_refs[ESP_SLEEP_CLOCK_UART1] > 0) {
25722586
clk_flags |= BIT(PMU_ICG_FUNC_ENA_UART1);
25732587
}
2588+
#if SOC_UART_HP_NUM > 2
2589+
if (s_config.clock_icg_refs[ESP_SLEEP_CLOCK_UART2] > 0) {
2590+
clk_flags |= BIT(PMU_ICG_FUNC_ENA_UART2);
2591+
}
2592+
#endif
25742593
#endif /* SOC_PM_SUPPORT_PMU_CLK_ICG */
25752594
return clk_flags;
25762595
}

components/hal/esp32c5/include/hal/uart_ll.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ extern "C" {
3030
#define LP_UART_LL_FIFO_DEF_LEN (SOC_LP_UART_FIFO_LEN)
3131
// Get UART hardware instance with giving uart num
3232
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (((num) == UART_NUM_1) ? (&UART1) : (&LP_UART)))
33+
// Get UART sleep clock with giving uart num
34+
#define UART_LL_SLEEP_CLOCK(num) (((num) == UART_NUM_0) ? (ESP_SLEEP_CLOCK_UART0) : (ESP_SLEEP_CLOCK_UART1))
3335

3436
#define UART_LL_REG_FIELD_BIT_SHIFT(hw) (((hw) == &LP_UART) ? 3 : 0)
3537

components/hal/esp32c6/include/hal/uart_ll.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ extern "C" {
3030
#define LP_UART_LL_FIFO_DEF_LEN (SOC_LP_UART_FIFO_LEN)
3131
// Get UART hardware instance with giving uart num
3232
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (((num) == UART_NUM_1) ? (&UART1) : (&LP_UART)))
33+
// Get UART sleep clock with giving uart num
34+
#define UART_LL_SLEEP_CLOCK(num) (((num) == UART_NUM_0) ? (ESP_SLEEP_CLOCK_UART0) : (ESP_SLEEP_CLOCK_UART1))
3335

3436
#define UART_LL_REG_FIELD_BIT_SHIFT(hw) (((hw) == &LP_UART) ? 3 : 0)
3537

components/hal/esp32c61/include/hal/uart_ll.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ extern "C" {
2929
#define UART_LL_FIFO_DEF_LEN (SOC_UART_FIFO_LEN)
3030
// Get UART hardware instance with giving uart num
3131
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (((num) == UART_NUM_1) ? (&UART1) : (&UART2)))
32+
// Get UART sleep clock with giving uart num
33+
#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)))
3234

3335
#define UART_LL_PULSE_TICK_CNT_MAX UART_LOWPULSE_MIN_CNT_V
3436

components/hal/esp32h2/include/hal/uart_ll.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ extern "C" {
2828
#define UART_LL_FIFO_DEF_LEN (SOC_UART_FIFO_LEN)
2929
// Get UART hardware instance with giving uart num
3030
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (&UART1))
31+
// Get UART sleep clock with giving uart num
32+
#define UART_LL_SLEEP_CLOCK(num) (((num) == UART_NUM_0) ? (ESP_SLEEP_CLOCK_UART0) : (ESP_SLEEP_CLOCK_UART1))
3133

3234
#define UART_LL_PULSE_TICK_CNT_MAX UART_LOWPULSE_MIN_CNT_V
3335

0 commit comments

Comments
 (0)