feat(esp_hw_support): support esp32s31 lightsleep/deepsleep example

This commit is contained in:
wuzhenghui
2026-05-06 20:15:01 +08:00
parent 54fed4c1c3
commit f1f3f204fe
29 changed files with 132 additions and 71 deletions
@@ -36,7 +36,7 @@
#elif CONFIG_IDF_TARGET_ESP32C61
#define DEFAULT_UART1_TX_IO_NUM GPIO_NUM_4
#define DEFAULT_UART1_RX_IO_NUM GPIO_NUM_5
#elif CONFIG_IDF_TARGET_ESP32C5
#elif CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32S31
#define DEFAULT_UART1_TX_IO_NUM GPIO_NUM_2
#define DEFAULT_UART1_RX_IO_NUM GPIO_NUM_3
#elif CONFIG_IDF_TARGET_ESP32H21
@@ -0,0 +1,38 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "esp_attr.h"
#include "soc/soc.h"
#include "soc/reset_reasons.h"
#include "soc/lp_clkrst_struct.h"
#include "soc/lp_clkrst_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* 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.root_clk_conf.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)
#ifdef __cplusplus
}
#endif
@@ -795,6 +795,7 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_ext1_get_wakeup_status(void)
FORCE_INLINE_ATTR void pmu_ll_ext1_clear_wakeup_status(void)
{
REG_SET_BIT(PMU_EXT_WAKEUP_CNTL_REG, PMU_EXT_WAKEUP_STATUS_CLR);
REG_CLR_BIT(PMU_EXT_WAKEUP_CNTL_REG, PMU_EXT_WAKEUP_STATUS_CLR);
}
/**
@@ -15,6 +15,7 @@
#include "esp_private/rtc_clk.h"
#include "esp_hw_log.h"
#include "esp_rom_sys.h"
#include "esp_sleep.h"
#include "hal/clk_tree_ll.h"
#include "esp_private/sleep_event.h"
#include "esp_private/regi2c_ctrl.h"
@@ -87,19 +88,13 @@ void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
{
clk_ll_rtc_slow_set_src(clk_src);
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
// TODO: IDF-14645
// #ifndef BOOTLOADER_BUILD
// if (clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
// esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL32K, ESP_PD_OPTION_ON);
// } else {
// esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL32K, ESP_PD_OPTION_AUTO);
// }
// if (clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
// esp_sleep_pd_config(ESP_PD_DOMAIN_RC32K, ESP_PD_OPTION_ON);
// } else {
// esp_sleep_pd_config(ESP_PD_DOMAIN_RC32K, ESP_PD_OPTION_AUTO);
// }
// #endif
#ifndef BOOTLOADER_BUILD
if (clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL32K, ESP_PD_OPTION_ON);
} else {
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL32K, ESP_PD_OPTION_AUTO);
}
#endif
}
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
+1 -1
View File
@@ -225,7 +225,7 @@ uint32_t sleep_modem_reject_triggers(void)
{
uint32_t reject_triggers = 0;
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
reject_triggers = (s_sleep_modem.wifi.phy_link != NULL) ? BIT(16) : 0;
reject_triggers = (s_sleep_modem.wifi.phy_link != NULL) ? PMU_MODEM_WAKEUP_PROTECT : 0;
#endif
return reject_triggers;
}
+13 -2
View File
@@ -146,6 +146,10 @@
#include "esp32p4/rom/rtc.h"
#include "hal/gpio_ll.h"
#include "hal/clk_gate_ll.h"
#elif CONFIG_IDF_TARGET_ESP32S31
#include "esp32s31/rom/rtc.h"
#include "hal/gpio_ll.h"
#include "hal/clk_gate_ll.h"
#endif
#if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
@@ -245,6 +249,9 @@
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (324)
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (240)
#define LDO_POWER_TAKEOVER_PREPARATION_TIME_US (185)
#elif CONFIG_IDF_TARGET_ESP32S31
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (324)
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (240)
#endif
// Actually costs 80us, using the fastest slow clock 150K calculation takes about 16 ticks
@@ -694,7 +701,7 @@ static SLEEP_FN_ATTR void misc_modules_sleep_prepare(uint32_t sleep_flags, bool
// Only avoid USJ pad leakage here, USB OTG pad leakage is prevented through USB Host driver.
sleep_console_usj_pad_backup_and_disable();
#endif
#if SOC_USB_OTG_SUPPORTED && SOC_PM_SUPPORT_CNNT_PD
#if SOC_USB_OTG_SUPPORTED && SOC_PM_SUPPORT_CNNT_PD && SOC_USB_OTG_NEED_SOFTWARE_SUSPEND_BEFORE_SLEEP
if (!(sleep_flags & PMU_SLEEP_PD_CNNT)) {
sleep_usb_otg_phy_backup_and_disable();
}
@@ -715,7 +722,11 @@ static SLEEP_FN_ATTR void misc_modules_sleep_prepare(uint32_t sleep_flags, bool
/* When using SPIRAM on the ESP32-C5, we need to use Cache_WriteBack_All to protect SPIRAM data
because the cache powers down when we power down the CPU */
if(sleep_flags & PMU_SLEEP_PD_CPU) {
#if SOC_SHARED_IDCACHE_SUPPORTED || CONFIG_IDF_TARGET_ESP32H4
Cache_WriteBack_All();
#else
Cache_WriteBack_All(CACHE_MAP_L1_DCACHE);
#endif
}
#endif
#if ADC_LL_ANA_CALI_REG_PD_WORKAROUND
@@ -762,7 +773,7 @@ static SLEEP_FN_ATTR void misc_modules_wake_prepare(uint32_t sleep_flags)
#if SOC_USB_SERIAL_JTAG_SUPPORTED && !SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP
sleep_console_usj_pad_restore();
#endif
#if SOC_USB_OTG_SUPPORTED && SOC_PM_SUPPORT_CNNT_PD
#if SOC_USB_OTG_SUPPORTED && SOC_PM_SUPPORT_CNNT_PD && SOC_USB_OTG_NEED_SOFTWARE_SUSPEND_BEFORE_SLEEP
if (!(sleep_flags & PMU_SLEEP_PD_CNNT)) {
sleep_usb_otg_phy_restore();
}
+8 -6
View File
@@ -20,18 +20,20 @@ void sleep_usb_otg_phy_backup_and_disable(void)
if (!s_usb_utmi_bus_clock_state) {
_usb_utmi_ll_enable_bus_clock(true);
}
usb_dwc_dev_t *hw = USB_DWC_LL_GET_HW(0);
// Forcing BVALID low to ignore the hardware-detected VBUS BVALID signal to suppress USB leakage.
s_usb_dwc_bvalid_override = usb_dwc_ll_get_bvalid_override(&USB_DWC_HS);
usb_dwc_ll_enable_bvalid_override(&USB_DWC_HS, true);
s_usb_utmi_stoppclk_state = usb_dwc_ll_get_stoppclk_st(&USB_DWC_HS);
usb_dwc_ll_set_stoppclk(&USB_DWC_HS, true);
s_usb_dwc_bvalid_override = usb_dwc_ll_get_bvalid_override(hw);
usb_dwc_ll_enable_bvalid_override(hw, true);
s_usb_utmi_stoppclk_state = usb_dwc_ll_get_stoppclk_st(hw);
usb_dwc_ll_set_stoppclk(hw, true);
}
void sleep_usb_otg_phy_restore(void)
{
_usb_utmi_ll_enable_bus_clock(true);
usb_dwc_ll_enable_bvalid_override(&USB_DWC_HS, s_usb_dwc_bvalid_override);
usb_dwc_ll_set_stoppclk(&USB_DWC_HS, s_usb_utmi_stoppclk_state);
usb_dwc_dev_t *hw = USB_DWC_LL_GET_HW(0);
usb_dwc_ll_enable_bvalid_override(hw, s_usb_dwc_bvalid_override);
usb_dwc_ll_set_stoppclk(hw, s_usb_utmi_stoppclk_state);
if (!s_usb_utmi_bus_clock_state) {
_usb_utmi_ll_enable_bus_clock(false);
}
@@ -1,2 +1,2 @@
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 |
| ----------------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- |
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S31 |
| ----------------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | --------- |
@@ -1,2 +1,2 @@
| 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 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
| 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 | ESP32-S31 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
+1 -1
View File
@@ -40,7 +40,7 @@ entries:
esp_clk:esp_clk_private_unlock (noflash)
if SOC_SYSTIMER_SUPPORTED = y:
systimer (noflash)
if IDF_TARGET_ESP32H21 != y && IDF_TARGET_ESP32H4 != y:
if SOC_ADC_SUPPORTED = y:
sar_periph_ctrl:sar_periph_ctrl_power_disable (noflash)
sar_periph_ctrl:adc_reset_lock_acquire (noflash)
sar_periph_ctrl:adc_reset_lock_release (noflash)
+6 -5
View File
@@ -569,14 +569,15 @@ FORCE_INLINE_ATTR IRAM_ATTR void ext_mem_init(void)
MSPI_INIT_ATTR void sys_rtc_init(const soc_reset_reason_t *rst_reas)
{
#if SOC_RTC_WDT_SUPPORTED
#if CONFIG_IDF_TARGET_ESP32P4
#if CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32S31
#define RWDT_RESET RESET_REASON_CORE_RWDT
#define MWDT_RESET RESET_REASON_CORE_MWDT
#elif CONFIG_IDF_TARGET_ESP32S31
#define RWDT_RESET RESET_REASON_CORE_RWDT
#define MWDT_RESET RESET_REASON_CORE_MWDT0
#else
#define RWDT_RESET RESET_REASON_CORE_RTC_WDT
#endif
#if CONFIG_IDF_TARGET_ESP32P4
#define MWDT_RESET RESET_REASON_CORE_MWDT
#else
#define MWDT_RESET RESET_REASON_CORE_MWDT0
#endif
@@ -1171,6 +1171,10 @@ config SOC_USB_FSLS_PHY_NUM
int
default 1
config SOC_USB_OTG_NEED_SOFTWARE_SUSPEND_BEFORE_SLEEP
bool
default y
config SOC_USB_UTMI_PHY_NUM
int
default 1
@@ -432,6 +432,7 @@
// USB OTG Caps
#define SOC_USB_OTG_PERIPH_NUM (2U)
#define SOC_USB_FSLS_PHY_NUM (1U)
#define SOC_USB_OTG_NEED_SOFTWARE_SUSPEND_BEFORE_SLEEP (1)
// USB PHY Caps
#define SOC_USB_UTMI_PHY_NUM (1U)
@@ -235,6 +235,14 @@ config SOC_PPA_SUPPORTED
bool
default y
config SOC_LIGHT_SLEEP_SUPPORTED
bool
default y
config SOC_DEEP_SLEEP_SUPPORTED
bool
default y
config SOC_MODEM_CLOCK_SUPPORTED
bool
default y
@@ -303,6 +311,10 @@ config SOC_XTAL_SUPPORT_40M
bool
default y
config SOC_XTAL_CLOCK_PATH_DEPENDS_ON_TOP_DOMAIN
bool
default y
config SOC_ADC_MAX_CHANNEL_NUM
int
default 10
@@ -443,6 +455,10 @@ config SOC_GPIO_SUPPORT_ETM
bool
default y
config SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP
bool
default y
config SOC_LP_IO_HAS_INDEPENDENT_WAKEUP_SOURCE
bool
default y
@@ -459,14 +475,10 @@ config SOC_GPIO_OUT_RANGE_MAX
int
default 61
config SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK
config SOC_GPIO_HP_PERIPH_PD_SLEEP_WAKEABLE_MASK
int
default 0
config SOC_GPIO_DEEP_SLEEP_WAKE_SUPPORTED_PIN_CNT
int
default 8
config SOC_GPIO_SUPPORT_FORCE_HOLD
bool
default y
@@ -715,10 +727,6 @@ config SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR
bool
default y
config SOC_MSPI_HAS_INDEPENT_IOMUX
bool
default y
config SOC_MEMSPI_IS_INDEPENDENT
bool
default y
@@ -97,8 +97,8 @@
#define SOC_TOUCH_SENSOR_SUPPORTED 1
// #define SOC_RNG_SUPPORTED 1 // TODO: [ESP32S31] IDF-14632
#define SOC_PPA_SUPPORTED 1
// #define SOC_LIGHT_SLEEP_SUPPORTED 1 // TODO: [ESP32S31] IDF-14645
// #define SOC_DEEP_SLEEP_SUPPORTED 1 // TODO: [ESP32S31] IDF-14643
#define SOC_LIGHT_SLEEP_SUPPORTED 1
#define SOC_DEEP_SLEEP_SUPPORTED 1
#define SOC_MODEM_CLOCK_SUPPORTED 1
// #define SOC_PM_SUPPORTED 1 // TODO: [ESP32S31] IDF-14648
#define SOC_BITSCRAMBLER_SUPPORTED 1
@@ -122,7 +122,8 @@
#define SOC_BT_SUPPORTED 1
#define SOC_PHY_CALIBRATION_CLOCK_IS_INDEPENDENT 1
/*-------------------------- XTAL CAPS ---------------------------------------*/
#define SOC_XTAL_SUPPORT_40M 1
#define SOC_XTAL_SUPPORT_40M 1
#define SOC_XTAL_CLOCK_PATH_DEPENDS_ON_TOP_DOMAIN 1
/*-------------------------- ADC CAPS ----------------------------------------*/
/*!< SAR ADC Module*/
@@ -185,7 +186,7 @@
#define SOC_GPIO_SUPPORT_ETM 1
// GPIO0~7 on ESP32S31 can support chip deep sleep wakeup
// #define SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP (1) // TODO: [ESP32S31] IDF-14643
#define SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP (1)
#define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP
#define SOC_LP_IO_HAS_INDEPENDENT_WAKEUP_SOURCE (1)
@@ -198,8 +199,7 @@
#define SOC_GPIO_IN_RANGE_MAX 61
#define SOC_GPIO_OUT_RANGE_MAX 61
#define SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK (0ULL | 0xFF)
#define SOC_GPIO_DEEP_SLEEP_WAKE_SUPPORTED_PIN_CNT (8)
#define SOC_GPIO_HP_PERIPH_PD_SLEEP_WAKEABLE_MASK (0ULL | 0xFF)
// digital I/O pad powered by VDD3V3_CPU or VDD_SPI(GPIO_NUM_8~GPIO_NUM_61, excluding GPIO29/41 which are not bonded)
#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK (SOC_GPIO_VALID_GPIO_MASK & ~((1ULL << SOC_RTCIO_PIN_COUNT) - 1))
@@ -298,7 +298,6 @@
#define SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP (1)
#define SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR (1)
#define SOC_MSPI_HAS_INDEPENT_IOMUX 1
#define SOC_MEMSPI_IS_INDEPENDENT 1
#define SOC_MEMSPI_ENCRYPTION_ALIGNMENT 16 /*!< 16-byte alignment restriction to mem addr and size if encryption is enabled */