feat(psram): allow PSRAM to enter halfsleep mode during light sleep

This commit is contained in:
Song Ruo Jing
2026-01-22 17:21:18 +08:00
parent b3b348c650
commit 69def0c3ea
15 changed files with 291 additions and 26 deletions
@@ -1,3 +1,5 @@
CONFIG_SPIRAM=y
CONFIG_SPIRAM_MODE_HEX=y
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0
# Disable PSRAM halfsleep feature, otherwise P4 tcm section overflows with COMPILER_OPTIMIZATION_NONE=y
CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED=n
@@ -1,3 +1,5 @@
CONFIG_SPIRAM=y
CONFIG_SPIRAM_MODE_HEX=y
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0
# Disable PSRAM halfsleep feature, otherwise P4 tcm section overflows with COMPILER_OPTIMIZATION_NONE=y
CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED=n
@@ -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
*/
@@ -263,6 +263,20 @@ static inline void psram_ctrlr_ll_enable_hex_data_line_mode(uint32_t mspi_id, bo
SPIMEM2.mem_sram_cmd.mem_sdout_hex = en;
}
/**
* @brief Get PSRAM hex data line mode enable status
*
* @param mspi_id mspi_id
*
* @return true if hex data line mode is enabled, false otherwise
*/
__attribute__((always_inline))
static inline bool psram_ctrlr_ll_is_hex_data_line_mode(uint32_t mspi_id)
{
(void)mspi_id;
return (SPIMEM2.mem_sram_cmd.mem_sdin_hex & SPIMEM2.mem_sram_cmd.mem_sdout_hex);
}
/**
* @brief Enable PSRAM AXI master access
*
@@ -39,6 +39,7 @@
#if CONFIG_SPIRAM
#include "hal/ldo_ll.h"
#include "hal/mspi_ll.h"
#include "esp_private/esp_psram_impl.h"
#endif
#if (CONFIG_ESP_REV_MIN_FULL == 300)
@@ -195,7 +196,7 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
// Get light sleep analog default
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(sleep_flags);
#if CONFIG_SPIRAM
#if CONFIG_SPIRAM && CONFIG_ESP32P4_SELECTS_REV_LESS_V3
// Adjust analog parameters to keep EXT_LDO PSRAM channel volt outputting during light-sleep.
analog_default.hp_sys.analog.pd_cur = PMU_PD_CUR_SLEEP_ON;
analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = PMU_PD_CUR_SLEEP_ON;
@@ -408,11 +409,15 @@ TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt,
// to be written back so that regdma can get the correct link.
// 3. We cannot use the API provided by ROM to invalidate the cache, since it is a function calling that writes data to the stack during
// the return process, which results in dirty cachelines in L1 Cache again.
pmu_sleep_cache_sync_items(SMMU_GID_DEFAULT, CACHE_SYNC_WRITEBACK, CACHE_MAP_L1_DCACHE, 0, 0);
pmu_sleep_cache_sync_items(SMMU_GID_DEFAULT, CACHE_SYNC_WRITEBACK, CACHE_MAP_L1_DCACHE, 0, 0); // No PSRAM dirty data after this time write back
if (!dslp) {
#if CONFIG_SPIRAM
psram_ctrlr_ll_wait_all_transaction_done();
#if CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED
esp_psram_impl_enter_halfsleep_mode();
#endif
mspi_ll_hold_all_psram_pins();
#endif
s_mpll_freq_mhz_before_sleep = rtc_clk_mpll_get_freq();
if (s_mpll_freq_mhz_before_sleep) {
@@ -426,10 +431,10 @@ TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt,
_psram_ctrlr_ll_enable_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, false);
_psram_ctrlr_ll_enable_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2, false);
}
mspi_ll_hold_all_psram_pins();
#endif
rtc_clk_mpll_disable();
}
pmu_sleep_cache_sync_items(SMMU_GID_DEFAULT, CACHE_SYNC_WRITEBACK, CACHE_MAP_L1_DCACHE, 0, 0); // No L2 MEM dirty data after this time write back
} else {
#if CONFIG_P4_REV3_MSPI_CRASH_AFTER_POWER_UP_WORKAROUND
if (efuse_hal_chip_revision() == 300) {
@@ -493,19 +498,26 @@ TCM_IRAM_ATTR bool pmu_sleep_finish(bool dslp)
// Wait eFuse memory update done.
while(efuse_ll_get_controller_state() != EFUSE_CONTROLLER_STATE_IDLE);
if (s_mpll_freq_mhz_before_sleep && !dslp) {
rtc_clk_mpll_enable();
rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), s_mpll_freq_mhz_before_sleep, true);
if (!dslp) {
if (s_mpll_freq_mhz_before_sleep) {
rtc_clk_mpll_enable();
rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), s_mpll_freq_mhz_before_sleep, true);
#if CONFIG_SPIRAM
if (!s_pmu_sleep_regdma_backup_enabled) {
// MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here.
// If it's a PD_TOP sleep, psram MSPI core clock will be enabled by REGDMA
_psram_ctrlr_ll_enable_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true);
_psram_ctrlr_ll_enable_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true);
if (!s_pmu_sleep_regdma_backup_enabled) {
// MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here.
// If it's a PD_TOP sleep, psram MSPI core clock will be enabled by REGDMA
_psram_ctrlr_ll_enable_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true);
_psram_ctrlr_ll_enable_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true);
}
_psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_2, PSRAM_CLK_SRC_MPLL);
_psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_3, PSRAM_CLK_SRC_MPLL);
#endif
}
_psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_2, PSRAM_CLK_SRC_MPLL);
_psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_3, PSRAM_CLK_SRC_MPLL);
#if CONFIG_SPIRAM
mspi_ll_unhold_all_psram_pins();
#if CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED
esp_psram_impl_exit_halfsleep_mode();
#endif
#endif
}
@@ -15,6 +15,7 @@
#include "soc/timer_group_reg.h"
#include "esp_rom_sys.h"
#include "esp_private/periph_ctrl.h"
#include "esp_attr.h"
ESP_LOG_ATTR_TAG(TAG, "rtc_time");
@@ -211,7 +212,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
return (rtc_cycles * period) >> RTC_CLK_CAL_FRACT;
}
uint64_t rtc_time_get(void)
TCM_IRAM_ATTR uint64_t rtc_time_get(void)
{
return rtc_timer_hal_get_cycle_count(0);
}
+8
View File
@@ -161,6 +161,10 @@
#include "esp_private/sleep_retention.h"
#endif
#if CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED
#include "esp_private/esp_psram_impl.h"
#endif
// If light sleep time is less than that, don't power down flash
#define FLASH_PD_MIN_SLEEP_TIME_US 2000
@@ -1382,6 +1386,10 @@ static SLEEP_FN_ATTR esp_err_t esp_light_sleep_inner(uint32_t sleep_flags, uint3
#endif
}
#if CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED
esp_psram_impl_resume_from_halfsleep_mode(s_config.rtc_clk_cal_period);
#endif
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION
if (sleep_flags & RTC_SLEEP_PD_VDDSDIO) {
/* Cache Resume 2: flash is ready now, we can resume the cache and access flash safely after */
+24
View File
@@ -287,4 +287,28 @@ menu "Power Management"
Only enabled when SPI_FLASH_FREQ_LIMIT_C5_240MHZ is enabled.
This is an internal configuration, automatically set based on SPI Flash configuration.
config PM_SLP_SPIRAM_HALFSLEEP_ENABLED
bool "Enable halfsleep mode for PSRAM in light sleep"
depends on SPIRAM
default y
help
Enable PSRAM halfsleep mode feature to reduce power consumption during light sleep, if the PSRAM used
support halfsleep mode.
When enabled, the PSRAM chip will be configured to enter halfsleep mode (if applicable) before entering
light sleep. This reduces power consumption by:
1. Setting refresh rate to 0.5x
2. Setting PSRAM to halfsleep mode
The PSRAM will automatically exit halfsleep mode after waking up from light sleep.
config PM_SLP_SPIRAM_HALFSLEEP_EXIT_WAIT_DELAY
int "The time to wait for PSRAM to be able to access after exiting halfsleep mode (in us)"
depends on SPIRAM
default 150
range 50 250
help
Configure the delay time between waking up PSRAM halfsleep mode and the first access to PSRAM.
Refer to the tXHS parameter in datasheet of the used PSRAM to configure this option.
endmenu # "Power Management"
+1 -2
View File
@@ -4,7 +4,7 @@ if(${target} STREQUAL "linux")
return() # This component is not supported by the POSIX/Linux simulator
endif()
set(includes "include")
set(includes "include" "device/include")
if(CONFIG_SOC_SPIRAM_XIP_SUPPORTED)
list(APPEND includes xip_impl/include)
@@ -37,7 +37,6 @@ endif()
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ${includes}
PRIV_INCLUDE_DIRS device/include
PRIV_REQUIRES ${priv_requires}
LDFRAGMENTS linker.lf)
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -14,6 +14,7 @@
#include "hal/psram_ctrlr_ll.h"
#include "hal/mspi_ll.h"
#include "clk_ctrl_os.h"
#include "soc/rtc.h"
#define AP_HEX_PSRAM_SYNC_READ 0x0000
#define AP_HEX_PSRAM_SYNC_WRITE 0x8080
@@ -62,6 +63,8 @@
#define AP_HEX_PSRAM_REF_DATA 0x5a6b7c8d
#define AP_HEX_PSRAM_ULP_MODE_HALFSLEEP 0xF0
typedef struct {
union {
struct {
@@ -76,7 +79,7 @@ typedef struct {
union {
struct {
uint8_t vendor_id: 5;
uint8_t rsvd0_2: 2;
uint8_t rsvd5_7: 3;
uint8_t ulp: 1;
};
uint8_t val;
@@ -91,9 +94,9 @@ typedef struct {
} mr2;
union {
struct {
uint8_t rsvd3_7: 4;
uint8_t rsvd0_3: 4;
uint8_t srf: 2;
uint8_t rsvd0: 1;
uint8_t rsvd6: 1;
uint8_t rbx_en: 1;
};
uint8_t val;
@@ -106,6 +109,13 @@ typedef struct {
};
uint8_t val;
} mr4;
union {
struct {
uint8_t rsvd0_3: 4;
uint8_t halfsleep: 4;
};
uint8_t val;
} mr6;
union {
struct {
uint8_t bl: 2;
@@ -507,3 +517,83 @@ esp_err_t esp_psram_impl_get_available_size(uint32_t *out_size_bytes)
#endif
return (s_psram_size ? ESP_OK : ESP_ERR_INVALID_STATE);
}
/******************************* Halfsleep Mode *******************************/
static PSRAM_HALFSLEEP_DATA_ATTR struct {
uint8_t mr4;
bool is_hex_line_mode;
uint64_t halfsleep_wakeup_tick;
} s_halfsleep_ctx = {0};
PSRAM_HALFSLEEP_SLEEP_CODE_ATTR void esp_psram_impl_enter_halfsleep_mode(void)
{
// Backup line mode configuration and set to 8-line mode (MR registers R/W not support in hex line mode)
s_halfsleep_ctx.is_hex_line_mode = psram_ctrlr_ll_is_hex_data_line_mode(PSRAM_CTRLR_LL_MSPI_ID_3);
psram_ctrlr_ll_enable_hex_data_line_mode(PSRAM_CTRLR_LL_MSPI_ID_3, false);
// Backup MR4
psram_ctrlr_ll_common_transaction(PSRAM_CTRLR_LL_MSPI_ID_3,
AP_HEX_PSRAM_REG_READ, AP_HEX_PSRAM_RD_CMD_BITLEN,
0x4, AP_HEX_PSRAM_ADDR_BITLEN,
AP_HEX_PSRAM_RD_REG_DUMMY_BITLEN,
NULL, 0,
&s_halfsleep_ctx.mr4, 16,
false);
// Set refresh rate to 0.5x
hex_psram_mode_reg_t mode_reg;
mode_reg.mr4.val = s_halfsleep_ctx.mr4;
mode_reg.mr4.rf = 3; // (0:4x 1:1x 3:0.5x)
psram_ctrlr_ll_common_transaction(PSRAM_CTRLR_LL_MSPI_ID_3,
AP_HEX_PSRAM_REG_WRITE, AP_HEX_PSRAM_RD_CMD_BITLEN,
0x4, AP_HEX_PSRAM_ADDR_BITLEN,
0,
&mode_reg.mr4.val, 16,
NULL, 0,
false);
// Set halfsleep mode
uint8_t halfsleep_cmd = AP_HEX_PSRAM_ULP_MODE_HALFSLEEP;
psram_ctrlr_ll_common_transaction(PSRAM_CTRLR_LL_MSPI_ID_3,
AP_HEX_PSRAM_REG_WRITE, AP_HEX_PSRAM_RD_CMD_BITLEN,
0x6, AP_HEX_PSRAM_ADDR_BITLEN,
0,
&halfsleep_cmd, 16,
NULL, 0,
false);
}
PSRAM_HALFSLEEP_SLEEP_CODE_ATTR void esp_psram_impl_exit_halfsleep_mode(void)
{
// Record the tick exiting halfsleep mode
s_halfsleep_ctx.halfsleep_wakeup_tick = rtc_time_get();
// Do a SPI dummy write transmission to invalid address to wake up from halfsleep mode
uint8_t null = 0;
psram_ctrlr_ll_common_transaction(PSRAM_CTRLR_LL_MSPI_ID_3,
AP_HEX_PSRAM_REG_WRITE, AP_HEX_PSRAM_WR_CMD_BITLEN,
0xFF, AP_HEX_PSRAM_ADDR_BITLEN,
0,
&null, 0,
NULL, 0,
false);
}
PSRAM_HALFSLEEP_RESUME_CODE_ATTR void esp_psram_impl_resume_from_halfsleep_mode(uint32_t slowclk_period)
{
uint64_t halfsleep_exit_tick = s_halfsleep_ctx.halfsleep_wakeup_tick + rtc_time_us_to_slowclk(CONFIG_PM_SLP_SPIRAM_HALFSLEEP_EXIT_WAIT_DELAY, slowclk_period);
while (rtc_time_get() < halfsleep_exit_tick) {
// Busy wait for PSRAM to exit halfsleep mode
}
// Restore MR4 configuration (restore refresh rate)
psram_ctrlr_ll_common_transaction(PSRAM_CTRLR_LL_MSPI_ID_3,
AP_HEX_PSRAM_REG_WRITE, AP_HEX_PSRAM_WR_CMD_BITLEN,
0x4, AP_HEX_PSRAM_ADDR_BITLEN,
0,
&s_halfsleep_ctx.mr4, 16,
NULL, 0,
false);
// Restore hex line mode if it was enabled before
if (s_halfsleep_ctx.is_hex_line_mode) {
psram_ctrlr_ll_enable_hex_data_line_mode(PSRAM_CTRLR_LL_MSPI_ID_3, true);
}
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -433,6 +433,20 @@ static void config_psram_spi_phases(void)
psram_ctrlr_ll_set_cs_pin(PSRAM_CTRLR_LL_MSPI_ID_0, PSRAM_LL_CS_ID_1);
}
/******************************* Halfsleep Mode *******************************/
// This PSRAM device does not support halfsleep mode
PSRAM_HALFSLEEP_SLEEP_CODE_ATTR void esp_psram_impl_enter_halfsleep_mode(void)
{
}
PSRAM_HALFSLEEP_SLEEP_CODE_ATTR void esp_psram_impl_exit_halfsleep_mode(void)
{
}
PSRAM_HALFSLEEP_RESUME_CODE_ATTR void esp_psram_impl_resume_from_halfsleep_mode(uint32_t slowclk_period)
{
}
/*---------------------------------------------------------------------------------
* Following APIs are not required to be IRAM-Safe
*
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -8,6 +8,7 @@
#include "esp_err.h"
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
@@ -20,6 +21,21 @@ extern "C" {
#define PSRAM_SIZE_32MB (32 * 1024 * 1024)
#define PSRAM_SIZE_64MB (64 * 1024 * 1024)
#if CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
#define PSRAM_HALFSLEEP_DATA_ATTR TCM_DRAM_ATTR
#define PSRAM_HALFSLEEP_SLEEP_CODE_ATTR TCM_IRAM_ATTR
#else
#define PSRAM_HALFSLEEP_DATA_ATTR DRAM_ATTR
#define PSRAM_HALFSLEEP_SLEEP_CODE_ATTR IRAM_ATTR
#endif
#define PSRAM_HALFSLEEP_RESUME_CODE_ATTR IRAM_ATTR
#else
#define PSRAM_HALFSLEEP_DATA_ATTR
#define PSRAM_HALFSLEEP_SLEEP_CODE_ATTR
#define PSRAM_HALFSLEEP_RESUME_CODE_ATTR
#endif
/**
* @brief To get the physical psram size in bytes.
*
@@ -51,6 +67,29 @@ esp_err_t esp_psram_impl_enable(void);
*/
uint8_t esp_psram_impl_get_cs_io(void);
/**
* @brief Set psram to halfsleep mode to save power consumption
*
* It will also set refresh rate to 0.5x.
*/
void esp_psram_impl_enter_halfsleep_mode(void);
/**
* @brief Make psram exit halfsleep mode (no wait, wait is done in esp_psram_impl_resume_from_halfsleep_mode)
*/
void esp_psram_impl_exit_halfsleep_mode(void);
/**
* @brief Resume psram from halfsleep mode (also restore refresh rate)
*
* @param slowclk_period RTC slow clock period, calibration value obtained using rtc_clk_cal
*
* @note PSRAM requires some time (tHSPU) to fully recover from halfsleep mode.
* This function examines the time between exiting halfsleep mode and current time, and busy wait if the time is not long enough.
* This shortens the overall busy loop time if wait is done inside esp_psram_impl_exit_halfsleep_mode.
*/
void esp_psram_impl_resume_from_halfsleep_mode(uint32_t slowclk_period);
#ifdef __cplusplus
}
#endif
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2013-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2013-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1175,4 +1175,19 @@ esp_err_t esp_psram_impl_get_available_size(uint32_t *out_size_bytes)
{
return esp_psram_impl_get_physical_size(out_size_bytes);
}
/******************************* Halfsleep Mode *******************************/
// This PSRAM device does not support halfsleep mode
PSRAM_HALFSLEEP_SLEEP_CODE_ATTR void esp_psram_impl_enter_halfsleep_mode(void)
{
}
PSRAM_HALFSLEEP_SLEEP_CODE_ATTR void esp_psram_impl_exit_halfsleep_mode(void)
{
}
PSRAM_HALFSLEEP_RESUME_CODE_ATTR void esp_psram_impl_resume_from_halfsleep_mode(uint32_t slowclk_period)
{
}
#endif // CONFIG_SPIRAM
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2013-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2013-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -577,3 +577,17 @@ esp_err_t esp_psram_impl_get_available_size(uint32_t *out_size_bytes)
{
return esp_psram_impl_get_physical_size(out_size_bytes);
}
/******************************* Halfsleep Mode *******************************/
// This PSRAM device does not support halfsleep mode
PSRAM_HALFSLEEP_SLEEP_CODE_ATTR void esp_psram_impl_enter_halfsleep_mode(void)
{
}
PSRAM_HALFSLEEP_SLEEP_CODE_ATTR void esp_psram_impl_exit_halfsleep_mode(void)
{
}
PSRAM_HALFSLEEP_RESUME_CODE_ATTR void esp_psram_impl_resume_from_halfsleep_mode(uint32_t slowclk_period)
{
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -456,3 +456,17 @@ esp_err_t esp_psram_impl_get_available_size(uint32_t *out_size_bytes)
#endif
return (s_psram_size ? ESP_OK : ESP_ERR_INVALID_STATE);
}
/******************************* Halfsleep Mode *******************************/
// This PSRAM supports halfsleep mode, but not implemented yet
PSRAM_HALFSLEEP_SLEEP_CODE_ATTR void esp_psram_impl_enter_halfsleep_mode(void)
{
}
PSRAM_HALFSLEEP_SLEEP_CODE_ATTR void esp_psram_impl_exit_halfsleep_mode(void)
{
}
PSRAM_HALFSLEEP_RESUME_CODE_ATTR void esp_psram_impl_resume_from_halfsleep_mode(uint32_t slowclk_period)
{
}
@@ -17,8 +17,10 @@
#include "esp_private/esp_psram_io.h"
#include "esp_psram.h"
#include "esp_private/esp_psram_extram.h"
#include "esp_private/esp_psram_impl.h"
#include "esp_flash.h"
#include "esp_partition.h"
#include "soc/rtc.h"
__attribute__((unused)) const static char *TAG = "PSRAM";
@@ -58,6 +60,21 @@ TEST_CASE("stress test psram heap allocable", "[psram][manual][ignore]")
}
}
#if !CONFIG_SPIRAM_XIP_FROM_PSRAM
TEST_CASE("test psram halfsleep mode (if applicable)", "[psram]")
{
uint32_t rtc_slow_clk_period = rtc_clk_cal(CLK_CAL_RTC_SLOW, CONFIG_RTC_CLK_CAL_CYCLES);
s_test_psram_heap_allocable();
for (int i = 0; i < 5; i++) {
esp_psram_impl_enter_halfsleep_mode();
vTaskDelay(pdMS_TO_TICKS(1000));
esp_psram_impl_exit_halfsleep_mode();
esp_psram_impl_resume_from_halfsleep_mode(rtc_slow_clk_period);
s_test_psram_heap_allocable();
}
}
#endif
#if CONFIG_SPIRAM_XIP_FROM_PSRAM
/*---------------------------------------------------------------
SPI1 with XIP