Merge branch 'bugfix/wait_tvsl_after_non_pd_top_lightsleep_for_esp32c6' into 'master'

fix(esp_hw_support/sleep): wait flash ready after non-pd_top lightsleep for esp32c6

Closes IDF-6930

See merge request espressif/esp-idf!27726
This commit is contained in:
Jiang Jiang Jian 2023-12-19 14:01:45 +08:00
commit 73de93d55e
10 changed files with 70 additions and 34 deletions

View File

@ -141,24 +141,34 @@ menu "Hardware Settings"
This option provides a software workaround for this issue. Configure to isolate all
GPIO pins in sleep state.
config ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY
int "Extra delay in deep sleep wake stub (in us)"
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3
default 2000
config ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY
int "Extra delay (in us) after flash powerdown sleep wakeup to wait flash ready"
default 2000 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3
default 0
range 0 5000
help
When the chip exits deep sleep, the CPU and the flash chip are powered on
at the same time. CPU will run deep sleep stub first, and then
proceed to load code from flash. Some flash chips need sufficient
time to pass between power on and first read operation. By default,
without any extra delay, this time is approximately 900us, although
When the chip exits sleep, the CPU and the flash chip are powered on at the same time.
CPU will run rom code (deepsleep) or ram code (lightsleep) first, and then load or execute
code from flash.
Some flash chips need sufficient time to pass between power on and first read operation.
By default, without any extra delay, this time is approximately 900us, although
some flash chip types need more than that.
By default extra delay is set to 2000us. When optimizing startup time
(!!! Please adjust this value according to the Data Sheet of SPI Flash used in your project.)
In Flash Data Sheet, the parameters that define the Flash ready timing after power-up (minimum
time from Vcc(min) to CS activeare) usually named tVSL in ELECTRICAL CHARACTERISTICS chapter,
and the configuration value here should be:
ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY = tVSL - 900
For esp32 and esp32s3, the default extra delay is set to 2000us. When optimizing startup time
for applications which require it, this value may be reduced.
If you are seeing "flash read err, 1000" message printed to the
console after deep sleep reset, try increasing this value.
If you are seeing "flash read err, 1000" message printed to the console after deep sleep reset
on esp32, or triggered RTC_WDT/LP_WDT after lightsleep wakeup, try increasing this value.
(For esp32, the delay will be executed in both deep sleep and light sleep wake up flow.
For chips after esp32, the delay will be executed only in light sleep flow, the delay
controlled by the EFUSE_FLASH_TPUW in ROM will be executed in deepsleep wake up flow.)
config ESP_SLEEP_CACHE_SAFE_ASSERTION
bool "Check the cache safety of the sleep wakeup code in sleep process"

View File

@ -291,6 +291,11 @@ void pmu_init(void);
*/
void pmu_sleep_enable_hp_sleep_sysclk(bool enable);
/**
* Get the time overhead used by regdma to work on the retention link during the hardware wake-up process
* @return regdma time cost during hardware wake-up stage in microseconds
*/
uint32_t pmu_sleep_get_wakup_retention_cost(void);
#endif //#if SOC_PMU_SUPPORTED

View File

@ -286,3 +286,8 @@ void pmu_sleep_enable_hp_sleep_sysclk(bool enable)
{
pmu_ll_hp_set_icg_sysclk_enable(PMU_instance()->hal->dev, HP(SLEEP), enable);
}
uint32_t pmu_sleep_get_wakup_retention_cost(void)
{
return PMU_REGDMA_S2A_WORK_TIME_US;
}

View File

@ -44,6 +44,8 @@ extern "C" {
#define PMU_HP_XPD_DEEPSLEEP 0
#define PMU_LP_DRVB_DEEPSLEEP 0
#define PMU_REGDMA_S2A_WORK_TIME_US 480
#define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 12
#define PMU_LP_DBIAS_DEEPSLEEP_0V7 23
@ -456,7 +458,7 @@ typedef struct pmu_sleep_machine_constant {
.power_supply_wait_time_us = 2, \
.power_up_wait_time_us = 2, \
.regdma_s2m_work_time_us = 172, \
.regdma_s2a_work_time_us = 480, \
.regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_US, \
.regdma_m2a_work_time_us = 278, \
.regdma_a2s_work_time_us = 382, \
.regdma_rf_on_work_time_us = 70, \

View File

@ -228,3 +228,8 @@ bool pmu_sleep_finish(void)
{
return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev);
}
uint32_t pmu_sleep_get_wakup_retention_cost(void)
{
return PMU_REGDMA_S2A_WORK_TIME_US;
}

View File

@ -41,6 +41,8 @@ extern "C" {
#define PMU_HP_DBIAS_LIGHTSLEEP_0V6 1
#define PMU_LP_DBIAS_LIGHTSLEEP_0V7 6
#define PMU_REGDMA_S2A_WORK_TIME_US 0
// FOR DEEPSLEEP
#define PMU_HP_XPD_DEEPSLEEP 0
#define PMU_LP_DRVB_DEEPSLEEP 7
@ -438,7 +440,7 @@ typedef struct pmu_sleep_machine_constant {
.analog_wait_time_us = 154, \
.power_supply_wait_time_us = 2, \
.power_up_wait_time_us = 2, \
.regdma_s2a_work_time_us = 0, \
.regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_US, \
.regdma_a2s_work_time_us = 0, \
.xtal_wait_stable_time_us = 250, \
.pll_wait_stable_time_us = 1 \

View File

@ -21,7 +21,8 @@ CONFIG_SPIRAM_SUPPORT CONFIG_SPIRAM
CONFIG_ESP32_SPIRAM_SUPPORT CONFIG_SPIRAM
CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP
CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY
CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY
CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY
CONFIG_ESP32_XTAL_FREQ_26 CONFIG_XTAL_FREQ_26
CONFIG_ESP32_XTAL_FREQ_40 CONFIG_XTAL_FREQ_40

View File

@ -10,4 +10,5 @@ CONFIG_ESP32S3_RTC_XTAL_CAL_RETRY CONFIG_RTC_XTAL_CAL_RE
CONFIG_ESP32S3_SPIRAM_SUPPORT CONFIG_SPIRAM
CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY
CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY
CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY

View File

@ -106,8 +106,8 @@
// If light sleep time is less than that, don't power down flash
#define FLASH_PD_MIN_SLEEP_TIME_US 2000
// Time from VDD_SDIO power up to first flash read in ROM code
#define VDD_SDIO_POWERUP_TO_FLASH_READ_US 700
// Default waiting time for the software to wait for Flash ready after waking up from sleep
#define ESP_SLEEP_WAIT_FLASH_READY_DEFAULT_DELAY_US 700
// Cycles for RTC Timer clock source (internal oscillator) calibrate
#define RTC_CLK_SRC_CAL_CYCLES (10)
@ -156,12 +156,6 @@
#define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ)
#endif
#if CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY
#define DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY
#else
#define DEEP_SLEEP_WAKEUP_DELAY 0
#endif
// Minimal amount of time we can sleep for
#define LIGHT_SLEEP_MIN_TIME_US 200
@ -358,13 +352,16 @@ void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void)
_DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) | DPORT_PRO_CACHE_MMU_IA_CLR);
_DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG,
_DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) & (~DPORT_PRO_CACHE_MMU_IA_CLR));
#if DEEP_SLEEP_WAKEUP_DELAY > 0
#if CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY > 0
// ROM code has not started yet, so we need to set delay factor
// used by esp_rom_delay_us first.
ets_update_cpu_frequency_rom(ets_get_detected_xtal_freq() / 1000000);
// This delay is configured in menuconfig, it can be used to give
// the flash chip some time to become ready.
esp_rom_delay_us(DEEP_SLEEP_WAKEUP_DELAY);
// Time from VDD_SDIO power up to first flash read in ROM code is 700 us,
// for some flash chips is not sufficient, this delay is configured in menuconfig,
// it can be used to give the flash chip some extra time to become ready.
// For later chips, we have EFUSE_FLASH_TPUW field to configure it and do
// this delay in the ROM.
esp_rom_delay_us(CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY);
#endif
#elif CONFIG_IDF_TARGET_ESP32S2
REG_SET_BIT(EXTMEM_CACHE_DBG_INT_ENA_REG, EXTMEM_CACHE_DBG_EN);
@ -1043,6 +1040,18 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags,
// If SPI flash was powered down, wait for it to become ready
if (pd_flags & RTC_SLEEP_PD_VDDSDIO) {
#if SOC_PM_SUPPORT_TOP_PD
if (pd_flags & PMU_SLEEP_PD_TOP) {
uint32_t flash_ready_hw_waited_time_us = pmu_sleep_get_wakup_retention_cost();
uint32_t flash_ready_sw_waited_time_us = (esp_cpu_get_cycle_count() - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / MHZ);
uint32_t flash_ready_waited_time_us = flash_ready_hw_waited_time_us + flash_ready_sw_waited_time_us;
if (flash_enable_time_us > flash_ready_waited_time_us){
flash_enable_time_us -= flash_ready_waited_time_us;
} else {
flash_enable_time_us = 0;
}
}
#endif
// Wait for the flash chip to start up
esp_rom_delay_us(flash_enable_time_us);
}
@ -1155,12 +1164,9 @@ esp_err_t esp_light_sleep_start(void)
+ rtc_time_slowclk_to_us(rtc_cntl_xtl_buf_wait_slp_cycles + RTC_CNTL_CK8M_WAIT_SLP_CYCLES + RTC_CNTL_WAKEUP_DELAY_CYCLES, s_config.rtc_clk_cal_period);
#endif
#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-6930
const uint32_t flash_enable_time_us = 0;
#else
// Decide if VDD_SDIO needs to be powered down;
// If it needs to be powered down, adjust sleep time.
const uint32_t flash_enable_time_us = VDD_SDIO_POWERUP_TO_FLASH_READ_US + DEEP_SLEEP_WAKEUP_DELAY;
const uint32_t flash_enable_time_us = ESP_SLEEP_WAIT_FLASH_READY_DEFAULT_DELAY_US + CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY;
/**
* If VDD_SDIO power domain is requested to be turned off, bit `RTC_SLEEP_PD_VDDSDIO`
@ -1199,7 +1205,6 @@ esp_err_t esp_light_sleep_start(void)
}
}
}
#endif
periph_inform_out_light_sleep_overhead(s_config.sleep_time_adjustment - sleep_time_overhead_in);

View File

@ -184,7 +184,7 @@ CONFIG_RTC_CLK_SRC_INT_RC=y
CONFIG_RTC_CLK_SRC_EXT_CRYS=
CONFIG_RTC_CLK_CAL_CYCLES=1024
CONFIG_RTC_XTAL_BOOTSTRAP_CYCLES=100
CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000
CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000
CONFIG_XTAL_FREQ_40=y
CONFIG_XTAL_FREQ_26=
CONFIG_XTAL_FREQ_AUTO=