mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
Merge branch 'bugfix/esp_idf_ulp_wakeupcauses_record' into 'master'
fix(ulp): record wakeup causes before lp core request sleep Closes PM-677 and IDFCI-8878 See merge request espressif/esp-idf!46467
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -519,6 +519,11 @@ FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_intr_status(pmu_dev_t *hw)
|
||||
hw->hp_ext.int_clr.reject = 1;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void pmu_ll_hp_clear_lp_cpu_exc_intr_status(pmu_dev_t *hw)
|
||||
{
|
||||
hw->hp_ext.int_clr.lp_cpu_exc = 1;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void pmu_ll_hp_enable_sw_intr(pmu_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->hp_ext.int_ena.sw = enable;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -519,6 +519,11 @@ FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_intr_status(pmu_dev_t *hw)
|
||||
hw->hp_ext.int_clr.reject = 1;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void pmu_ll_hp_clear_lp_cpu_exc_intr_status(pmu_dev_t *hw)
|
||||
{
|
||||
hw->hp_ext.int_clr.lp_cpu_exc = 1;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void pmu_ll_hp_enable_sw_intr(pmu_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->hp_ext.int_ena.sw = enable;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -567,6 +567,11 @@ FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_intr_status(pmu_dev_t *hw)
|
||||
hw->hp_ext.int_clr.reject = 1;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void pmu_ll_hp_clear_lp_cpu_exc_intr_status(pmu_dev_t *hw)
|
||||
{
|
||||
hw->hp_ext.int_clr.lp_exception = 1;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_wakeup_cause(pmu_dev_t *hw)
|
||||
{
|
||||
return hw->wakeup.status0;
|
||||
|
||||
@@ -595,6 +595,11 @@ FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_intr_status(pmu_dev_t *hw)
|
||||
hw->hp_ext.int_clr.soc_sleep_reject = 1;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void pmu_ll_hp_clear_lp_cpu_exc_intr_status(pmu_dev_t *hw)
|
||||
{
|
||||
hw->hp_ext.int_clr.lp_cpu_exc = 1;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void pmu_ll_hp_enable_sw_intr(pmu_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->hp_ext.int_ena.sw = enable;
|
||||
|
||||
@@ -81,6 +81,9 @@
|
||||
#endif
|
||||
#include "hal/temperature_sensor_hal.h"
|
||||
#include "hal/mspi_ll.h"
|
||||
#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
#include "hal/lp_aon_hal.h"
|
||||
#endif
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_serial_output.h"
|
||||
@@ -1098,6 +1101,7 @@ static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t cl
|
||||
#if CONFIG_ULP_COPROC_TYPE_LP_CORE
|
||||
if (s_config.wakeup_triggers & (RTC_LP_CORE_TRIG_EN | RTC_LP_CORE_TRAP_TRIG_EN)) {
|
||||
pmu_ll_hp_clear_sw_intr_status(&PMU);
|
||||
pmu_ll_hp_clear_lp_cpu_exc_intr_status(&PMU);
|
||||
}
|
||||
#endif
|
||||
#endif // CONFIG_ULP_COPROC_ENABLED
|
||||
@@ -2533,6 +2537,15 @@ uint32_t esp_sleep_get_wakeup_causes(void)
|
||||
uint32_t wakeup_cause_raw = rtc_cntl_ll_get_wakeup_cause();
|
||||
#endif
|
||||
|
||||
#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
/* LP store register to read wakeup cause saved by LP core.
|
||||
* Must match the register used in lp_core_utils.c */
|
||||
uint32_t lp_core_wakeup_cause_status0 = lp_aon_hal_load_wakeup_cause();
|
||||
if ((wakeup_cause_raw == 0) && (lp_core_wakeup_cause_status0 != 0)) {
|
||||
wakeup_cause_raw = lp_core_wakeup_cause_status0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (wakeup_cause_raw & RTC_TIMER_TRIG_EN) {
|
||||
wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_TIMER);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,8 @@ extern "C" {
|
||||
* LP_AON_STORE6_REG FAST_RTC_MEMORY_ENTRY
|
||||
* LP_AON_STORE7_REG FAST_RTC_MEMORY_CRC
|
||||
* LP_AON_STORE8_REG Store light sleep wake stub addr
|
||||
* LP_AON_STORE9_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep)
|
||||
* LP_AON_STORE8_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep)
|
||||
* LP_AON_STORE9_REG LP core store wakeup cause
|
||||
*************************************************************************************
|
||||
*/
|
||||
|
||||
@@ -64,6 +65,7 @@ extern "C" {
|
||||
#define RTC_MEMORY_CRC_REG LP_AON_STORE7_REG
|
||||
#define RTC_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG
|
||||
#define RTC_SLEEP_MODE_REG LP_AON_STORE8_REG
|
||||
#define RTC_LP_CORE_STORE_WAKEUP_REG LP_AON_STORE9_REG
|
||||
|
||||
#define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code.
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ extern "C" {
|
||||
* LP_AON_STORE7_REG FAST_RTC_MEMORY_CRC
|
||||
* LP_AON_STORE8_REG Store light sleep wake stub addr
|
||||
* LP_AON_STORE9_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep)
|
||||
* LP_AON_STORE9_REG LP core store wakeup cause at bit[31:2]
|
||||
*************************************************************************************
|
||||
*/
|
||||
|
||||
@@ -66,6 +67,7 @@ extern "C" {
|
||||
#define RTC_MEMORY_CRC_REG LP_AON_STORE7_REG
|
||||
#define RTC_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG
|
||||
#define RTC_SLEEP_MODE_REG LP_AON_STORE9_REG
|
||||
#define RTC_LP_CORE_STORE_WAKEUP_REG LP_AON_STORE9_REG
|
||||
|
||||
#define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -53,17 +53,19 @@ extern "C" {
|
||||
* LP_SYS_LP_STORE8_REG sleep mode and wake stub address
|
||||
* LP_SYS_LP_STORE9_REG LP_UART_INIT_CTRL
|
||||
* LP_SYS_LP_STORE10_REG LP_ROM_LOG_CTRL
|
||||
* LP_SYS_LP_STORE11_REG LP core store wakeup cause
|
||||
*************************************************************************************
|
||||
*/
|
||||
|
||||
#define RTC_SLOW_CLK_CAL_REG LP_SYSTEM_REG_LP_STORE1_REG
|
||||
#define RTC_BOOT_TIME_LOW_REG LP_SYSTEM_REG_LP_STORE2_REG
|
||||
#define RTC_BOOT_TIME_HIGH_REG LP_SYSTEM_REG_LP_STORE3_REG
|
||||
#define RTC_XTAL_FREQ_REG LP_SYSTEM_REG_LP_STORE4_REG
|
||||
#define RTC_APB_FREQ_REG LP_SYSTEM_REG_LP_STORE5_REG
|
||||
#define RTC_ENTRY_ADDR_REG LP_SYSTEM_REG_LP_STORE6_REG
|
||||
#define RTC_RESET_CAUSE_REG LP_SYSTEM_REG_LP_STORE6_REG
|
||||
#define RTC_MEMORY_CRC_REG LP_SYSTEM_REG_LP_STORE7_REG
|
||||
#define RTC_SLOW_CLK_CAL_REG LP_SYSTEM_REG_LP_STORE1_REG
|
||||
#define RTC_BOOT_TIME_LOW_REG LP_SYSTEM_REG_LP_STORE2_REG
|
||||
#define RTC_BOOT_TIME_HIGH_REG LP_SYSTEM_REG_LP_STORE3_REG
|
||||
#define RTC_XTAL_FREQ_REG LP_SYSTEM_REG_LP_STORE4_REG
|
||||
#define RTC_APB_FREQ_REG LP_SYSTEM_REG_LP_STORE5_REG
|
||||
#define RTC_ENTRY_ADDR_REG LP_SYSTEM_REG_LP_STORE6_REG
|
||||
#define RTC_RESET_CAUSE_REG LP_SYSTEM_REG_LP_STORE6_REG
|
||||
#define RTC_MEMORY_CRC_REG LP_SYSTEM_REG_LP_STORE7_REG
|
||||
#define RTC_LP_CORE_STORE_WAKEUP_REG LP_SYSTEM_REG_LP_STORE11_REG
|
||||
|
||||
#define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code.
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ extern "C" {
|
||||
* RTC_CNTL_STORE5_REG FAST_RTC_MEMORY_LENGTH
|
||||
* RTC_CNTL_STORE6_REG FAST_RTC_MEMORY_ENTRY
|
||||
* RTC_CNTL_STORE7_REG FAST_RTC_MEMORY_CRC
|
||||
* RTC_CNTL_STORE9_REG LP core store wakeup cause
|
||||
*************************************************************************************
|
||||
*/
|
||||
|
||||
@@ -56,6 +57,7 @@ extern "C" {
|
||||
#define RTC_ENTRY_ADDR_REG LP_SYSTEM_REG_LP_STORE6_REG
|
||||
#define RTC_RESET_CAUSE_REG LP_SYSTEM_REG_LP_STORE6_REG
|
||||
#define RTC_MEMORY_CRC_REG LP_SYSTEM_REG_LP_STORE7_REG
|
||||
#define RTC_LP_CORE_STORE_WAKEUP_REG LP_SYSTEM_REG_LP_STORE9_REG
|
||||
|
||||
// light sleep
|
||||
/* use LP_SYS_LP_STORE8_REG to store light sleep wake stub addr and sleep mode for dualcore
|
||||
|
||||
@@ -15,3 +15,6 @@
|
||||
#define rtc_hal_ext1_get_wakeup_pins() lp_aon_ll_ext1_get_wakeup_pins()
|
||||
|
||||
#define lp_aon_hal_inform_wakeup_type(dslp) lp_aon_ll_inform_wakeup_type(dslp)
|
||||
|
||||
#define lp_aon_hal_store_wakeup_cause(wakeup_cause) lp_aon_ll_store_wakeup_cause(wakeup_cause)
|
||||
#define lp_aon_hal_load_wakeup_cause() lp_aon_ll_load_wakeup_cause()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -85,6 +85,24 @@ static inline void lp_aon_ll_inform_wakeup_type(bool dslp)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the wakeup cause stored by LP core
|
||||
* @param wakeup_cause The wakeup cause in PMU register
|
||||
*/
|
||||
static inline void lp_aon_ll_store_wakeup_cause(uint32_t wakeup_cause)
|
||||
{
|
||||
REG_WRITE(RTC_LP_CORE_STORE_WAKEUP_REG, wakeup_cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the wakeup cause stored by LP core
|
||||
* @return The wakeup cause cleared before LP core sleep
|
||||
*/
|
||||
static inline uint32_t lp_aon_ll_load_wakeup_cause(void)
|
||||
{
|
||||
return REG_READ(RTC_LP_CORE_STORE_WAKEUP_REG);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define lp_aon_hal_inform_wakeup_type(dslp) lp_aon_ll_inform_wakeup_type(dslp)
|
||||
#define lp_aon_hal_store_wakeup_cause(wakeup_cause) lp_aon_ll_store_wakeup_cause(wakeup_cause)
|
||||
#define lp_aon_hal_load_wakeup_cause() lp_aon_ll_load_wakeup_cause()
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -85,6 +85,24 @@ static inline void lp_aon_ll_inform_wakeup_type(bool dslp)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the wakeup cause stored by LP core
|
||||
* @param wakeup_cause The wakeup cause in PMU register
|
||||
*/
|
||||
static inline void lp_aon_ll_store_wakeup_cause(uint32_t wakeup_cause)
|
||||
{
|
||||
REG_WRITE(RTC_LP_CORE_STORE_WAKEUP_REG, (REG_READ(RTC_LP_CORE_STORE_WAKEUP_REG) & 0x1) | ((wakeup_cause << 1) & 0xFFFFFFFE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the wakeup cause stored by LP core
|
||||
* @return The wakeup cause cleared before LP core sleep
|
||||
*/
|
||||
static inline uint32_t lp_aon_ll_load_wakeup_cause(void)
|
||||
{
|
||||
return (REG_READ(RTC_LP_CORE_STORE_WAKEUP_REG) & 0xFFFFFFFE) >> 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define lp_aon_hal_inform_wakeup_type(dslp) lp_sys_ll_inform_wakeup_type(dslp)
|
||||
#define lp_aon_hal_store_wakeup_cause(wakeup_cause) lp_sys_ll_store_wakeup_cause(wakeup_cause)
|
||||
#define lp_aon_hal_load_wakeup_cause() lp_sys_ll_load_wakeup_cause()
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -81,6 +81,25 @@ FORCE_INLINE_ATTR void lp_sys_ll_set_lp_mem_lowpower_mode(uint32_t mode)
|
||||
LP_SYS.lp_mem_aux_ctrl.lp_mem_lowpower_mode = mode;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set the wakeup cause stored by LP core
|
||||
* @param wakeup_cause The wakeup cause in PMU register
|
||||
*/
|
||||
static inline void lp_sys_ll_store_wakeup_cause(uint32_t wakeup_cause)
|
||||
{
|
||||
REG_WRITE(RTC_LP_CORE_STORE_WAKEUP_REG, wakeup_cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the wakeup cause stored by LP core
|
||||
* @return The wakeup cause cleared before LP core sleep
|
||||
*/
|
||||
static inline uint32_t lp_sys_ll_load_wakeup_cause(void)
|
||||
{
|
||||
return REG_READ(RTC_LP_CORE_STORE_WAKEUP_REG);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define lp_aon_hal_inform_wakeup_type(dslp) lp_sys_ll_inform_wakeup_type(dslp)
|
||||
#define lp_aon_hal_store_wakeup_cause(wakeup_cause) lp_sys_ll_store_wakeup_cause(wakeup_cause)
|
||||
#define lp_aon_hal_load_wakeup_cause() lp_sys_ll_load_wakeup_cause()
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -65,6 +65,24 @@ static inline void lp_sys_set_regdma_link_count(int count)
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_SYS.backup_dma_cfg1, branch_link_length_aon, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the wakeup cause stored by LP core
|
||||
* @param wakeup_cause The wakeup cause in PMU register
|
||||
*/
|
||||
static inline void lp_sys_ll_store_wakeup_cause(uint32_t wakeup_cause)
|
||||
{
|
||||
REG_WRITE(RTC_LP_CORE_STORE_WAKEUP_REG, wakeup_cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the wakeup cause stored by LP core
|
||||
* @return The wakeup cause cleared before LP core sleep
|
||||
*/
|
||||
static inline uint32_t lp_sys_ll_load_wakeup_cause(void)
|
||||
{
|
||||
return REG_READ(RTC_LP_CORE_STORE_WAKEUP_REG);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1614,3 +1614,7 @@ config SOC_LP_CORE_SUPPORT_STORE_LOAD_EXCEPTIONS
|
||||
config SOC_LP_CORE_SUPPORT_I2C
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -645,3 +645,4 @@
|
||||
#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_SUPPORT_I2C (1) /*!< LP Core supports I2C */
|
||||
#define SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE (1) /*!< LP core requests sleep, PMU clears both HP and LP wakeup causes */
|
||||
|
||||
@@ -1363,6 +1363,10 @@ config SOC_LP_CORE_SUPPORT_I2C
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_DEBUG_HAVE_OCD_STUB_BINS
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -554,6 +554,7 @@
|
||||
#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_I2C (1) /*!< LP Core supports I2C */
|
||||
#define SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE (1) /*!< LP core requests sleep, PMU clears both HP and LP wakeup causes */
|
||||
|
||||
/*------------------------------------- DEBUG CAPS -------------------------------------*/
|
||||
#define SOC_DEBUG_HAVE_OCD_STUB_BINS (1)
|
||||
|
||||
@@ -1922,3 +1922,7 @@ config SOC_LP_CORE_SUPPORT_STORE_LOAD_EXCEPTIONS
|
||||
config SOC_LP_CORE_SUPPORT_I2C
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -736,3 +736,4 @@
|
||||
#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_SUPPORT_I2C (1) /*!< LP Core supports I2C */
|
||||
#define SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE (1) /*!< LP core requests sleep, PMU clears both HP and LP wakeup causes */
|
||||
|
||||
@@ -1095,6 +1095,10 @@ config SOC_LP_CORE_CONFIGURABLE_BOOT_ADDR
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LP_TIMER_BIT_WIDTH_LO
|
||||
int
|
||||
default 32
|
||||
|
||||
@@ -458,6 +458,7 @@
|
||||
#define SOC_LP_CORE_SUPPORT_ETM (1) /*!< LP Core supports ETM wakeup */
|
||||
#define SOC_LP_CORE_CONFIGURABLE_BOOT_ADDR (1) /*!< LP Core has no LP ROM; HP must write the reset_vector address (LP_RAM_BASE+0x80) to LP_SYS.lp_core_boot_addr before triggering LP wake */
|
||||
//#define SOC_LP_CORE_SUPPORT_I2C (1) /*!< LP Core supports I2C */ TODO IDF-14635
|
||||
#define SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE (1) /*!< LP core requests sleep, PMU clears both HP and LP wakeup causes */
|
||||
|
||||
/*-------------------------- LP_TIMER CAPS ----------------------------------*/
|
||||
#define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part
|
||||
|
||||
@@ -30,6 +30,11 @@
|
||||
extern uint8_t _rtc_ulp_memory_start[];
|
||||
#endif //ESP_ROM_HAS_LP_ROM
|
||||
|
||||
#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
#include "hal/lp_aon_hal.h"
|
||||
#include "rom/rtc.h"
|
||||
#endif
|
||||
|
||||
const static char* TAG = "ulp-lp-core";
|
||||
|
||||
#define WAKEUP_SOURCE_MAX_NUMBER 6
|
||||
@@ -178,6 +183,19 @@ esp_err_t ulp_lp_core_load_binary(const uint8_t* program_binary, size_t program_
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void ulp_lp_core_sleep_start(void)
|
||||
{
|
||||
#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
/* LP store register to save wakeup cause for HP core to query.
|
||||
* Using a hardware register avoids symbol linking issues between
|
||||
* the independently compiled HP and LP core binaries.
|
||||
* Save PMU wakeup cause to LP store register for HP core to query */
|
||||
lp_aon_hal_store_wakeup_cause(pmu_ll_hp_get_wakeup_cause(&PMU));
|
||||
#endif
|
||||
|
||||
lp_core_ll_request_sleep();
|
||||
}
|
||||
|
||||
void ulp_lp_core_stop(void)
|
||||
{
|
||||
if (esp_cpu_dbgr_is_attached()) {
|
||||
@@ -191,7 +209,7 @@ void ulp_lp_core_stop(void)
|
||||
}
|
||||
/* Disable wake-up source and put lp core to sleep */
|
||||
lp_core_ll_set_wakeup_source(0);
|
||||
lp_core_ll_request_sleep();
|
||||
ulp_lp_core_sleep_start();
|
||||
}
|
||||
|
||||
void ulp_lp_core_sw_intr_to_lp_trigger(void)
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
|
||||
#include "esp_cpu.h"
|
||||
#include "ulp_lp_core_cpu_freq_shared.h"
|
||||
#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
#include "hal/lp_aon_hal.h"
|
||||
#include "rom/rtc.h"
|
||||
#endif
|
||||
|
||||
static uint32_t lp_wakeup_cause = 0;
|
||||
|
||||
@@ -142,9 +146,22 @@ void ulp_lp_core_lp_uart_reset_wakeup_en(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
void ulp_lp_core_sleep_start_lp_core(void)
|
||||
{
|
||||
#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
/* LP store register to save wakeup cause for HP core to query.
|
||||
* Using a hardware register avoids symbol linking issues between
|
||||
* the independently compiled HP and LP core binaries.
|
||||
* Save PMU wakeup cause to LP store register for HP core to query */
|
||||
lp_aon_hal_store_wakeup_cause(pmu_ll_hp_get_wakeup_cause(&PMU));
|
||||
#endif
|
||||
|
||||
lp_core_ll_request_sleep();
|
||||
}
|
||||
|
||||
void ulp_lp_core_halt(void)
|
||||
{
|
||||
lp_core_ll_request_sleep();
|
||||
ulp_lp_core_sleep_start_lp_core();
|
||||
|
||||
while (1);
|
||||
}
|
||||
@@ -153,7 +170,7 @@ void ulp_lp_core_stop_lp_core(void)
|
||||
{
|
||||
/* Disable wake-up source and put lp core to sleep */
|
||||
lp_core_ll_set_wakeup_source(0);
|
||||
lp_core_ll_request_sleep();
|
||||
ulp_lp_core_sleep_start_lp_core();
|
||||
}
|
||||
|
||||
void __attribute__((noreturn)) abort(void)
|
||||
|
||||
@@ -59,6 +59,10 @@ if(CONFIG_SOC_LP_VAD_SUPPORTED)
|
||||
set(lp_core_sources_vad "lp_core/test_main_vad.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE)
|
||||
set(lp_core_sources_halt "lp_core/test_main_halt.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "lp_core"
|
||||
REQUIRES ulp unity esp_timer test_utils
|
||||
@@ -105,3 +109,7 @@ ulp_embed_binary(lp_core_test_app_prefix1 "lp_core/test_main_prefix1.c" "${lp_c
|
||||
ulp_embed_binary(lp_core_test_app_prefix2 "lp_core/test_main_prefix2.c" "${lp_core_exp_dep_srcs}" PREFIX "ulp2_")
|
||||
|
||||
ulp_embed_binary(lp_core_test_app_exception "lp_core/test_main_exception.c" "${lp_core_exp_dep_srcs}")
|
||||
|
||||
if(CONFIG_SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE)
|
||||
ulp_embed_binary(lp_core_test_app_halt "lp_core/test_main_halt.c" "${lp_core_exp_dep_srcs}")
|
||||
endif()
|
||||
|
||||
+7
-1
@@ -1,10 +1,16 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "ulp_lp_core_utils.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Wait for 1 second to ensure the HP Core enters deep sleep
|
||||
ulp_lp_core_delay_us(1000000);
|
||||
|
||||
// Trigger an exception to wake up the HP Core
|
||||
asm volatile("unimp");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ulp_lp_core_utils.h"
|
||||
#include "hal/lp_core_ll.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Wait for 1 second to ensure the HP Core enters deep sleep
|
||||
ulp_lp_core_delay_us(1000000);
|
||||
|
||||
ulp_lp_core_wakeup_main_processor();
|
||||
/* Disable wake-up source and put lp core to sleep */
|
||||
lp_core_ll_set_wakeup_source(0);
|
||||
ulp_lp_core_halt();
|
||||
}
|
||||
@@ -22,6 +22,7 @@ typedef enum {
|
||||
LP_CORE_DELAY_US_CALIBRATION_TEST,
|
||||
LP_CORE_DEEP_SLEEP_WAKEUP_SHORT_DELAY_TEST,
|
||||
LP_CORE_DEEP_SLEEP_WAKEUP_LONG_DELAY_TEST,
|
||||
LP_CORE_HALT_TEST,
|
||||
LP_CORE_LP_UART_WRITE_TEST,
|
||||
LP_CORE_LP_UART_READ_TEST,
|
||||
LP_CORE_LP_UART_MULTI_BYTE_READ_TEST,
|
||||
|
||||
@@ -40,6 +40,12 @@
|
||||
#include "hal/lp_core_ll.h"
|
||||
#include "hal/rtc_io_ll.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
#include "rom/rtc.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
#include "lp_core_test_app_halt.h"
|
||||
#include "hal/lp_aon_hal.h"
|
||||
#endif
|
||||
|
||||
extern const uint8_t lp_core_main_bin_start[] asm("_binary_lp_core_test_app_bin_start");
|
||||
extern const uint8_t lp_core_main_bin_end[] asm("_binary_lp_core_test_app_bin_end");
|
||||
@@ -64,6 +70,11 @@ extern const uint8_t lp_core_main_isr_bin_end[] asm("_binary_lp_core_test_app_
|
||||
extern const uint8_t lp_core_main_exception_bin_start[] asm("_binary_lp_core_test_app_exception_bin_start");
|
||||
extern const uint8_t lp_core_main_exception_bin_end[] asm("_binary_lp_core_test_app_exception_bin_end");
|
||||
|
||||
#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
extern const uint8_t lp_core_main_halt_bin_start[] asm("_binary_lp_core_test_app_halt_bin_start");
|
||||
extern const uint8_t lp_core_main_halt_bin_end[] asm("_binary_lp_core_test_app_halt_bin_end");
|
||||
#endif
|
||||
|
||||
static void load_and_start_lp_core_firmware(ulp_lp_core_cfg_t* cfg, const uint8_t* firmware_start, const uint8_t* firmware_end)
|
||||
{
|
||||
TEST_ASSERT(ulp_lp_core_load_binary(firmware_start,
|
||||
@@ -648,4 +659,43 @@ static void check_reset_reason_ulp_trap_wakeup(void)
|
||||
TEST_CASE_MULTIPLE_STAGES("LP-core exception can wakeup main cpu", "[ulp]",
|
||||
lp_core_prep_exception_wakeup,
|
||||
check_reset_reason_ulp_trap_wakeup);
|
||||
|
||||
#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
static void do_ulp_wakeup_with_lp_timer_deepsleep_and_halt(void)
|
||||
{
|
||||
/* Load ULP firmware and start the coprocessor */
|
||||
ulp_lp_core_cfg_t cfg = {
|
||||
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER,
|
||||
.lp_timer_sleep_duration_us = 1000000, // 1 second
|
||||
#if ESP_ROM_HAS_LP_ROM
|
||||
/* ROM Boot takes quite a bit longer, which skews the numbers of wake-ups. skip rom boot to keep the calculation simple */
|
||||
.skip_lp_rom_boot = true,
|
||||
#endif
|
||||
};
|
||||
|
||||
load_and_start_lp_core_firmware(&cfg, lp_core_main_halt_bin_start, lp_core_main_halt_bin_end);
|
||||
|
||||
/* Setup wakeup triggers */
|
||||
TEST_ASSERT(esp_sleep_enable_ulp_wakeup() == ESP_OK);
|
||||
|
||||
/* Enter Deep Sleep */
|
||||
esp_deep_sleep_start();
|
||||
|
||||
UNITY_TEST_FAIL(__LINE__, "Should not get here!");
|
||||
}
|
||||
|
||||
static void check_hp_core_wakeup_cause_saved(void)
|
||||
{
|
||||
uint32_t lp_core_wakeup_cause_status0 = lp_aon_hal_load_wakeup_cause();
|
||||
TEST_ASSERT_EQUAL(RTC_LP_CORE_TRIG_EN, lp_core_wakeup_cause_status0 & RTC_LP_CORE_TRIG_EN);
|
||||
TEST_ASSERT_EQUAL(BIT(ESP_SLEEP_WAKEUP_ULP), esp_sleep_get_wakeup_causes() & BIT(ESP_SLEEP_WAKEUP_ULP));
|
||||
|
||||
clear_test_cmds();
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_STAGES("HP core wakeup causes are saved after LP core halt", "[ulp]",
|
||||
do_ulp_wakeup_with_lp_timer_deepsleep_and_halt,
|
||||
check_hp_core_wakeup_cause_saved);
|
||||
#endif //SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE
|
||||
|
||||
#endif //SOC_DEEP_SLEEP_SUPPORTED
|
||||
|
||||
Reference in New Issue
Block a user