Merge branch 'feat/esp_idf_lp_uart_wakeup_v6.0' into 'release/v6.0'

feat(esp_hw_support): support lp uart wakeup during sleep (v6.0)

See merge request espressif/esp-idf!43151
This commit is contained in:
Jiang Jiang Jian
2025-11-11 19:22:19 +08:00
13 changed files with 237 additions and 29 deletions
+65 -16
View File
@@ -17,6 +17,10 @@
#include "esp_private/esp_sleep_internal.h"
#include "esp_log.h"
#if (SOC_UART_LP_NUM >= 1)
#include "soc/rtc.h"
#endif
const __attribute__((unused)) static char *TAG = "uart_wakeup";
#if SOC_UART_WAKEUP_SUPPORT_CHAR_SEQ_MODE
@@ -62,24 +66,48 @@ esp_err_t uart_wakeup_setup(uart_port_t uart_num, const uart_wakeup_cfg_t *cfg)
};
soc_module_clk_t src_clk;
uart_hal_get_sclk(&hal, &src_clk);
if (uart_num < SOC_UART_HP_NUM && cfg->wakeup_mode != UART_WK_MODE_ACTIVE_THRESH) {
// For wakeup modes except ACTIVE_THRESH, the function clock needs to be exist to trigger wakeup
ESP_RETURN_ON_FALSE(src_clk == SOC_MOD_CLK_XTAL, ESP_ERR_NOT_SUPPORTED, TAG, "failed to setup uart wakeup due to the clock source is not XTAL!");
}
esp_err_t ret = ESP_OK;
// 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);
// When uarts are utilized, the src clk(hp_uart: main XTAL, lp_uart: RTC_FAST or XTAL_D2) need to be PU and ungateand for hp uart UARTx & IOMX ICG need to be ungate
if (cfg->wakeup_mode != UART_WK_MODE_ACTIVE_THRESH) {
if (uart_num < SOC_UART_HP_NUM) {
// For wakeup modes except ACTIVE_THRESH, the function clock needs to be exist to trigger wakeup
ESP_RETURN_ON_FALSE(src_clk == SOC_MOD_CLK_XTAL, ESP_ERR_NOT_SUPPORTED, TAG, "failed to setup uart wakeup due to the clock source is not XTAL!");
#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
if (uart_num < SOC_UART_HP_NUM && cfg->wakeup_mode != UART_WK_MODE_ACTIVE_THRESH) {
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);
}
esp_sleep_sub_mode_config(ESP_SLEEP_DIG_USE_XTAL_MODE, true);
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
#if (SOC_UART_LP_NUM >= 1)
} else {
// When lp uarts are utilized, the src clk need to be power up and lp clock need to be ungate
if ((src_clk == SOC_MOD_CLK_RTC_FAST && rtc_clk_fast_src_get() == SOC_RTC_FAST_CLK_SRC_RC_FAST) || (src_clk == SOC_MOD_CLK_RC_FAST)) {
esp_sleep_sub_mode_config(ESP_SLEEP_LP_USE_RC_FAST_MODE, true);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
} else if (src_clk == SOC_MOD_CLK_XTAL_D2) {
#if SOC_XTAL_CLOCK_PATH_DEPENDS_ON_TOP_DOMAIN
// TODO: PM-533
// Currently, ESP32C5 and ESP32C6 don't support this feature temporarily.
ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "Not support when the source clock of the LP UART is XTAL_D2, and lp uart will be powered down.");
#else
// ESP32P4 supports this feature.
esp_sleep_acquire_lp_use_xtal();
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
ESP_LOGW(TAG, "Not support When the source clock of the LP UART is XTAL_D2 during deep sleep.");
#endif
#if SOC_CLK_LP_FAST_SUPPORT_LP_PLL
} else if (src_clk == SOC_MOD_CLK_LP_PLL) {
ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "Not support When the source clock of the LP UART is lp_pll, and lp uart will be powered down.");
#endif
}
#endif
}
}
switch (cfg->wakeup_mode) {
#if SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE
@@ -119,13 +147,34 @@ esp_err_t uart_wakeup_setup(uart_port_t uart_num, const uart_wakeup_cfg_t *cfg)
esp_err_t uart_wakeup_clear(uart_port_t uart_num, uart_wakeup_mode_t wakeup_mode)
{
if (wakeup_mode != UART_WK_MODE_ACTIVE_THRESH) {
// When hp uarts are utilized, the main XTAL need to be PU and UARTx & IOMX ICG need to be ungate
if (uart_num < SOC_UART_HP_NUM) {
#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
if (uart_num < SOC_UART_HP_NUM && 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);
}
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);
esp_sleep_sub_mode_config(ESP_SLEEP_DIG_USE_XTAL_MODE, false);
#endif
#if (SOC_UART_LP_NUM >= 1)
} else {
uart_dev_t *hw = UART_LL_GET_HW(uart_num);
uart_hal_context_t hal = {
.dev = hw,
};
soc_module_clk_t src_clk;
uart_hal_get_sclk(&hal, &src_clk);
if ((src_clk == SOC_MOD_CLK_RTC_FAST && rtc_clk_fast_src_get() == SOC_RTC_FAST_CLK_SRC_RC_FAST) || (src_clk == SOC_MOD_CLK_RC_FAST)) {
esp_sleep_sub_mode_config(ESP_SLEEP_LP_USE_RC_FAST_MODE, false);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
} else if (src_clk == SOC_MOD_CLK_XTAL_D2) {
#if !SOC_XTAL_CLOCK_PATH_DEPENDS_ON_TOP_DOMAIN
esp_sleep_release_lp_use_xtal();
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
#endif
}
#endif
}
}
return ESP_OK;
}
@@ -47,6 +47,7 @@ typedef enum {
#define RTC_SLEEP_PD_MODEM PMU_SLEEP_PD_MODEM //!< Power down modem(include wifi, ble and 15.4)
//These flags are not power domains, but will affect some sleep parameters
#define RTC_SLEEP_LP_PERIPH_USE_RC_FAST BIT(25)
#define RTC_SLEEP_POWER_BY_VBAT BIT(26)
#define RTC_SLEEP_DIG_USE_8M BIT(27)
#define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(28)
@@ -39,6 +39,7 @@ typedef enum {
ESP_SLEEP_RTC_FAST_USE_XTAL_MODE, //!< The mode in which the crystal is used as the RTC_FAST clock source, need keep XTAL on in HP_SLEEP mode when ULP is working.
ESP_SLEEP_DIG_USE_XTAL_MODE, //!< The mode requested by digital peripherals to keep XTAL clock on during sleep (both HP_SLEEP and LP_SLEEP mode). (!!! Only valid for lightsleep, will override the XTAL domain config by esp_sleep_pd_config)
ESP_SLEEP_LP_USE_XTAL_MODE, //!< The mode requested by lp peripherals to keep XTAL clock on during sleep. Only valid for lightsleep.
ESP_SLEEP_LP_USE_RC_FAST_MODE, //!< The mode requested by lp peripherals to keep FOSC clock on during sleep.
ESP_SLEEP_VBAT_POWER_DEEPSLEEP_MODE, //!< The mode to switch power supply to VBAT during deep sleep.
#if CONFIG_IDF_TARGET_ESP32
ESP_SLEEP_ANALOG_LOW_POWER_MODE, //!< If analog-related peripherals(ADC, TSENS, TOUCH) is not used in monitor mode, analog low power mode can be enabled to reduce power consumption (~300uA) in monitor state.
@@ -78,6 +79,24 @@ esp_err_t esp_sleep_sub_mode_force_disable(esp_sleep_sub_mode_t mode);
*/
int32_t* esp_sleep_sub_mode_dump_config(FILE *stream);
#if SOC_PM_SUPPORT_RTC_PERIPH_PD
/**
* @brief Enable LP peripherals to use XTAL during sleep
*
* @return
* - ESP_OK on success
*/
esp_err_t esp_sleep_acquire_lp_use_xtal(void);
/**
* @brief Disable LP peripherals to use XTAL during sleep
*
* @return
* - ESP_OK on success
*/
esp_err_t esp_sleep_release_lp_use_xtal(void);
#endif
#if SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP && !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
/**
* @brief Isolate all digital IOs except those that are held during deep sleep
@@ -285,6 +285,12 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
config->analog.hp_sys.analog.dbias = get_act_hp_dbias();
}
if (sleep_flags & RTC_SLEEP_LP_PERIPH_USE_RC_FAST) {
config->analog.hp_sys.analog.dbias = get_act_hp_dbias();
config->analog.lp_sys[LP(SLEEP)].analog.dbg_atten = 0;
config->analog.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias();
}
config->power = power_default;
pmu_sleep_param_config_t param_default = PMU_SLEEP_PARAM_CONFIG_DEFAULT(sleep_flags);
config->param = *pmu_sleep_param_config_default(&param_default, &power_default, sleep_flags, adjustment, slowclk_src, slowclk_period, fastclk_period);
@@ -241,6 +241,7 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(sleep_flags);
analog_default.lp_sys[LP(SLEEP)].analog.dbg_atten = get_dslp_dbg();
analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_dslp_lp_dbias();
config->analog = analog_default;
} else {
pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(sleep_flags, clk_flags);
@@ -279,6 +280,12 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
config->analog.hp_sys.analog.dbias = get_act_hp_dbias();
}
if (sleep_flags & RTC_SLEEP_LP_PERIPH_USE_RC_FAST) {
config->analog.hp_sys.analog.dbias = get_act_hp_dbias();
config->analog.lp_sys[LP(SLEEP)].analog.dbg_atten = PMU_DBG_ATTEN_LIGHTSLEEP_NODROP;
config->analog.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias();
}
return config;
}
@@ -30,7 +30,6 @@
#include "hal/pmu_hal.h"
#include "hal/psram_ctrlr_ll.h"
#include "hal/lp_sys_ll.h"
#include "hal/clk_gate_ll.h"
#include "esp_private/esp_pmu.h"
#include "pmu_param.h"
#include "esp_rom_sys.h"
@@ -224,8 +223,10 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
config->analog.hp_sys.analog.dbias = HP_CALI_ACTIVE_DBIAS_DEFAULT;
}
if (sleep_flags & RTC_SLEEP_LP_PERIPH_USE_XTAL) {
_clk_gate_ll_xtal_to_lp_periph_en(true);
if (sleep_flags & RTC_SLEEP_LP_PERIPH_USE_RC_FAST) {
config->analog.hp_sys.analog.dbias = get_act_hp_dbias();
config->analog.lp_sys[LP(SLEEP)].analog.dbg_atten = 0;
config->analog.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias();
}
config->power = power_default;
+86 -10
View File
@@ -101,9 +101,11 @@
#elif CONFIG_IDF_TARGET_ESP32C6
#include "esp32c6/rom/rtc.h"
#include "hal/gpio_ll.h"
#include "hal/clk_gate_ll.h"
#elif CONFIG_IDF_TARGET_ESP32C5
#include "esp32c5/rom/rtc.h"
#include "hal/gpio_ll.h"
#include "hal/clk_gate_ll.h"
#elif CONFIG_IDF_TARGET_ESP32C61
#include "esp32c61/rom/rtc.h"
#include "hal/gpio_ll.h"
@@ -123,6 +125,7 @@
#elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/rtc.h"
#include "hal/gpio_ll.h"
#include "hal/clk_gate_ll.h"
#endif
#if SOC_PM_SUPPORT_PMU_CLK_ICG
@@ -710,6 +713,33 @@ static SLEEP_FN_ATTR bool light_sleep_uart_prepare(uint32_t sleep_flags, int64_t
return should_skip_sleep;
}
/**
* LP peripherals prepare XTAL, FOSC or other clocks as the clock source for sleep.
*/
static SLEEP_FN_ATTR void lp_periph_use_clk_sleep_prepare(uint32_t sleep_flags, bool deep_sleep)
{
#if SOC_PMU_SUPPORTED
#if CONFIG_IDF_TARGET_ESP32P4
if (sleep_flags & RTC_SLEEP_LP_PERIPH_USE_XTAL) {
/* Force the xtal clk pass lp clock gate */
_clk_gate_ll_xtal_to_lp_periph_en(true);
} else {
/* Set xtal lp clock gate controlled by hardware fsm */
_clk_gate_ll_xtal_to_lp_periph_en(false);
}
#endif
#if SOC_LP_PERIPHERALS_SUPPORTED
if (sleep_flags & RTC_SLEEP_LP_PERIPH_USE_RC_FAST) {
/* Force the rtc_fast clk pass lp clock gate */
_clk_gate_ll_rtc_fast_to_lp_periph_en(true);
} else {
/* Lp clock gate of rtc_fast clk is decided by FSM(PMU state)*/
_clk_gate_ll_rtc_fast_to_lp_periph_en(false);
}
#endif
#endif
}
/**
* These save-restore workaround should be moved to lower layer
*/
@@ -1107,6 +1137,9 @@ static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t cl
}
#endif
/* Prepare for LP peripherals to select a clock source. */
lp_periph_use_clk_sleep_prepare(sleep_flags, deep_sleep);
// Enter sleep
esp_err_t result;
#if SOC_PMU_SUPPORTED
@@ -1769,31 +1802,61 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)
return ESP_OK;
}
#if SOC_LP_VAD_SUPPORTED
esp_err_t esp_sleep_enable_vad_wakeup(void)
#if SOC_PM_SUPPORT_RTC_PERIPH_PD
esp_err_t esp_sleep_acquire_lp_use_xtal(void)
{
esp_err_t ret = ESP_FAIL;
ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "fail to keep rtc periph power on");
return ret;
}
ret = esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "fail to keep xtal power on");
return ret;
}
ret = esp_sleep_sub_mode_config(ESP_SLEEP_LP_USE_XTAL_MODE, true);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "fail to set to ESP_SLEEP_LP_USE_XTAL_MODE mode");
return ret;
}
s_config.wakeup_triggers |= RTC_LP_VAD_TRIG_EN;
return ESP_OK;
}
esp_err_t esp_sleep_release_lp_use_xtal(void)
{
esp_err_t ret = ESP_FAIL;
ret = esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "fail to keep xtal power off");
return ret;
}
ret = esp_sleep_sub_mode_config(ESP_SLEEP_LP_USE_XTAL_MODE, false);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "fail to disable ESP_SLEEP_LP_USE_XTAL_MODE mode");
return ret;
}
return ESP_OK;
}
#endif
#if SOC_LP_VAD_SUPPORTED
esp_err_t esp_sleep_enable_vad_wakeup(void)
{
esp_err_t ret = ESP_FAIL;
ret = esp_sleep_acquire_lp_use_xtal();
ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "fail to keep rtc periph power on");
return ret;
}
s_config.wakeup_triggers |= RTC_LP_VAD_TRIG_EN;
return ret;
}
#endif
#if SOC_VBAT_SUPPORTED
@@ -2210,6 +2273,10 @@ esp_err_t esp_sleep_enable_uart_wakeup(int uart_num)
#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
#if SOC_PM_SUPPORT_LP_UART_WAKEUP
} else if (uart_num == LP_UART_NUM_0) {
s_config.wakeup_triggers |= PMU_LP_UART_WAKEUP_EN;
#endif
} else {
return ESP_ERR_INVALID_ARG;
@@ -2503,6 +2570,7 @@ static const char* s_submode2str[] = {
[ESP_SLEEP_RTC_FAST_USE_XTAL_MODE] = "ESP_SLEEP_RTC_FAST_USE_XTAL_MODE",
[ESP_SLEEP_DIG_USE_XTAL_MODE] = "ESP_SLEEP_DIG_USE_XTAL_MODE",
[ESP_SLEEP_LP_USE_XTAL_MODE] = "ESP_SLEEP_LP_USE_XTAL_MODE",
[ESP_SLEEP_LP_USE_RC_FAST_MODE] = "ESP_SLEEP_LP_USE_RC_FAST_MODE",
[ESP_SLEEP_VBAT_POWER_DEEPSLEEP_MODE] = "ESP_SLEEP_VBAT_POWER_DEEPSLEEP_MODE",
#if CONFIG_IDF_TARGET_ESP32
[ESP_SLEEP_ANALOG_LOW_POWER_MODE] = "ESP_SLEEP_ANALOG_LOW_POWER_MODE",
@@ -2812,11 +2880,19 @@ static SLEEP_FN_ATTR uint32_t get_sleep_flags(uint32_t sleep_flags, bool deepsle
sleep_flags |= RTC_SLEEP_XTAL_AS_RTC_FAST;
}
#if SOC_LP_VAD_SUPPORTED
#if SOC_PMU_SUPPORTED
#if CONFIG_IDF_TARGET_ESP32P4
if (s_sleep_sub_mode_ref_cnt[ESP_SLEEP_LP_USE_XTAL_MODE] && !deepsleep) {
sleep_flags |= RTC_SLEEP_LP_PERIPH_USE_XTAL;
}
#endif
#if SOC_LP_PERIPHERALS_SUPPORTED
if (s_sleep_sub_mode_ref_cnt[ESP_SLEEP_LP_USE_RC_FAST_MODE]) {
sleep_flags &= ~RTC_SLEEP_PD_INT_8M;
sleep_flags |= RTC_SLEEP_LP_PERIPH_USE_RC_FAST;
}
#endif
#endif
#if SOC_VBAT_SUPPORTED
if (s_sleep_sub_mode_ref_cnt[ESP_SLEEP_VBAT_POWER_DEEPSLEEP_MODE] && deepsleep) {
@@ -14,6 +14,7 @@ extern "C" {
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/pcr_struct.h"
#include "soc/lp_clkrst_struct.h"
/**
* Enable or disable the clock gate for ref_12m.
@@ -123,6 +124,18 @@ FORCE_INLINE_ATTR void _clk_gate_ll_ref_240m_clk_en(bool enable)
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define clk_gate_ll_ref_240m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_240m_clk_en(__VA_ARGS__)
/**
* Enable or disable the clock gate for rtc_fast to lp periph
* @param enable Enable / disable
*/
FORCE_INLINE_ATTR void _clk_gate_ll_rtc_fast_to_lp_periph_en(bool enable)
{
LP_CLKRST.lp_clk_en.fast_ori_gate = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define clk_gate_ll_rtc_fast_to_lp_periph_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_rtc_fast_to_lp_periph_en(__VA_ARGS__)
#ifdef __cplusplus
}
#endif
@@ -14,6 +14,7 @@
#include "soc/soc.h"
#include "soc/soc_caps.h"
#include "esp_attr.h"
#include "soc/lp_clkrst_struct.h"
#ifdef __cplusplus
extern "C" {
@@ -194,6 +195,18 @@ static inline bool IRAM_ATTR periph_ll_periph_enabled(shared_periph_module_t per
REG_GET_BIT(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph)) != 0;
}
/**
* Enable or disable the clock gate for rtc_fast to lp periph
* @param enable Enable / disable
*/
FORCE_INLINE_ATTR void _clk_gate_ll_rtc_fast_to_lp_periph_en(bool enable)
{
LP_CLKRST.lp_clk_en.fast_ori_gate = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define clk_gate_ll_rtc_fast_to_lp_periph_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_rtc_fast_to_lp_periph_en(__VA_ARGS__)
#ifdef __cplusplus
}
#endif
@@ -121,6 +121,21 @@ FORCE_INLINE_ATTR void _clk_gate_ll_xtal_to_lp_periph_en(bool enable)
_clk_gate_ll_xtal_to_lp_periph_en(__VA_ARGS__); \
} while(0)
/**
* Enable or disable the clock gate for rtc fast to lp periph
* @param enable Enable / disable
*/
FORCE_INLINE_ATTR void _clk_gate_ll_rtc_fast_to_lp_periph_en(bool enable)
{
LP_AON_CLKRST.lp_clk_en.fosc_clk_force_on = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define clk_gate_ll_rtc_fast_to_lp_periph_en(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_clk_gate_ll_rtc_fast_to_lp_periph_en(__VA_ARGS__); \
} while(0)
/**
* Enable or disable the clock gate for ref_50m.
* @param enable Enable / disable
@@ -1879,6 +1879,10 @@ config SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP
bool
default y
config SOC_PM_SUPPORT_LP_UART_WAKEUP
bool
default y
config SOC_PM_SUPPORT_CPU_PD
bool
default y
@@ -708,6 +708,7 @@
#define SOC_PM_EXT1_WAKEUP_BY_PMU (1)
#define SOC_PM_SUPPORT_WIFI_WAKEUP (1)
#define SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP (1) /*!<Supports waking up from touch pad trigger */
#define SOC_PM_SUPPORT_LP_UART_WAKEUP (1)
#define SOC_PM_SUPPORT_CPU_PD (1)
#define SOC_PM_SUPPORT_XTAL32K_PD (1)
#define SOC_PM_SUPPORT_RC32K_PD (1)
@@ -1 +1,4 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
Information about this test app can be found [here](../README.md#application-under-test).