mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
fix(esp_hw_support): disable mpll before sleep to avoid mspi module entering an error state
This commit is contained in:
parent
f3d963a93b
commit
8f33c69c30
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -32,7 +32,7 @@ void rtc_clk_cpu_set_to_default_config(void);
|
||||
* Currently, this function is only used for tracking whether USB Serial/JTAG is using the 48MHz PHY clock
|
||||
*
|
||||
* Note: Calling this function only helps to not disable the BBPLL clock in `rtc_clk_cpu_freq_set_config`.
|
||||
* For light and deep sleep, whether to disable the BBPLL in the interal call to `rtc_clk_cpu_freq_set_xtal`
|
||||
* For light and deep sleep, whether to disable the BBPLL in the internal call to `rtc_clk_cpu_freq_set_xtal`
|
||||
* varies for targets.
|
||||
* On ESP32C3/S3, USB CDC device can not function properly during sleep due to the lack of APB clock. Therefore.
|
||||
* `rtc_clk_cpu_freq_set_xtal` will always disable BBPLL, no matter whether BBPLL has any consumer.
|
||||
@ -65,6 +65,13 @@ void rtc_clk_mpll_disable(void);
|
||||
* @param[in] mpll_freq MPLL frequency
|
||||
*/
|
||||
void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq);
|
||||
|
||||
/**
|
||||
* Get the MPLL frequency
|
||||
* @return the value of MPLL frequency in MHz
|
||||
*/
|
||||
uint32_t rtc_clk_mpll_get_freq(void);
|
||||
|
||||
#endif //#if SOC_CLK_MPLL_SUPPORTED
|
||||
|
||||
/**
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "esp32p4/rom/rtc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_private/rtc_clk.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_hw_log.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
@ -26,6 +27,9 @@ static const char *TAG = "rtc_clk";
|
||||
// CPLL frequency option, in 360/400MHz. Zero if CPLL is not enabled.
|
||||
static int s_cur_cpll_freq = 0;
|
||||
|
||||
// MPLL frequency option, 400MHz. Zero if MPLL is not enabled.
|
||||
static DRAM_ATTR uint32_t s_cur_mpll_freq = 0;
|
||||
|
||||
void rtc_clk_32k_enable(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
@ -483,6 +487,7 @@ bool rtc_dig_8m_enabled(void)
|
||||
void rtc_clk_mpll_disable(void)
|
||||
{
|
||||
clk_ll_mpll_disable();
|
||||
s_cur_mpll_freq = 0;
|
||||
}
|
||||
|
||||
void rtc_clk_mpll_enable(void)
|
||||
@ -500,4 +505,10 @@ void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq)
|
||||
while(!regi2c_ctrl_ll_mpll_calibration_is_done());
|
||||
/* MPLL calibration stop */
|
||||
regi2c_ctrl_ll_mpll_calibration_stop();
|
||||
s_cur_mpll_freq = mpll_freq;
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_mpll_get_freq(void)
|
||||
{
|
||||
return s_cur_mpll_freq;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "esp_private/esp_sleep_internal.h"
|
||||
#include "esp_private/esp_timer_private.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/rtc_clk.h"
|
||||
#include "esp_private/sleep_event.h"
|
||||
#include "esp_private/system_internal.h"
|
||||
#include "esp_log.h"
|
||||
@ -27,6 +28,7 @@
|
||||
#include "soc/soc_caps.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "hal/rtc_io_hal.h"
|
||||
#include "hal/clk_tree_hal.h"
|
||||
|
||||
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
|
||||
#include "esp_private/pm_impl.h"
|
||||
@ -924,6 +926,13 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SOC_CLK_MPLL_SUPPORTED
|
||||
uint32_t mpll_freq_mhz = rtc_clk_mpll_get_freq();
|
||||
if (mpll_freq_mhz) {
|
||||
rtc_clk_mpll_disable();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_DCDC_SUPPORTED
|
||||
uint64_t ldo_increased_us = rtc_time_slowclk_to_us(rtc_time_get() - s_config.rtc_ticks_at_ldo_prepare, s_config.rtc_clk_cal_period);
|
||||
if (ldo_increased_us < LDO_POWER_TAKEOVER_PREPARATION_TIME_US) {
|
||||
@ -951,6 +960,13 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
|
||||
result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep);
|
||||
#endif
|
||||
|
||||
#if SOC_CLK_MPLL_SUPPORTED
|
||||
if (mpll_freq_mhz) {
|
||||
rtc_clk_mpll_enable();
|
||||
rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), mpll_freq_mhz);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Unhold the SPI CS pin */
|
||||
#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND)
|
||||
#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet
|
||||
|
@ -78,7 +78,6 @@ TEST_CASE_MULTIPLE_STAGES("enter deep sleep on APP CPU and wake up using timer",
|
||||
|
||||
#endif
|
||||
|
||||
#if !(CONFIG_SPIRAM && CONFIG_IDF_TARGET_ESP32P4) // TODO: IDF-9569
|
||||
static void do_deep_sleep_timer(void)
|
||||
{
|
||||
esp_sleep_enable_timer_wakeup(2000000);
|
||||
@ -111,7 +110,6 @@ TEST_CASE("wake up from light sleep using timer", "[deepsleep]")
|
||||
(tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f;
|
||||
TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt);
|
||||
}
|
||||
#endif
|
||||
|
||||
//NOTE: Explained in IDF-1445 | MR !14996
|
||||
#if !(CONFIG_SPIRAM) || (CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL >= 16384)
|
||||
@ -253,7 +251,6 @@ TEST_CASE("light sleep and frequency switching", "[deepsleep]")
|
||||
}
|
||||
}
|
||||
|
||||
#if !(CONFIG_SPIRAM && CONFIG_IDF_TARGET_ESP32P4) // TODO: IDF-9569
|
||||
static void do_deep_sleep(void)
|
||||
{
|
||||
esp_sleep_enable_timer_wakeup(100000);
|
||||
@ -289,7 +286,6 @@ TEST_CASE_MULTIPLE_STAGES("enter deep sleep after abort", "[deepsleep][reset=abo
|
||||
do_abort,
|
||||
check_abort_reset_and_sleep,
|
||||
check_sleep_reset);
|
||||
#endif
|
||||
|
||||
#if ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB
|
||||
static RTC_DATA_ATTR uint32_t s_wake_stub_var;
|
||||
@ -331,7 +327,7 @@ TEST_CASE_MULTIPLE_STAGES("can set sleep wake stub", "[deepsleep][reset=DEEPSLEE
|
||||
trigger a CRC calculation (done in hardware) for the entire RTC FAST memory
|
||||
before going to deep sleep and if it's invalid then the stub is not
|
||||
run. Also, while the CRC is being calculated the RTC FAST memory is not
|
||||
accesible by the CPU (reads all zeros).
|
||||
accessible by the CPU (reads all zeros).
|
||||
*/
|
||||
|
||||
static void increment_rtc_memory_cb(void *arg)
|
||||
@ -491,7 +487,7 @@ static void trigger_deepsleep(void)
|
||||
struct timeval start;
|
||||
|
||||
// Use NVS instead of RTC mem to store the start time of deep sleep
|
||||
// Beacuse not all esp chips support RTC mem(such as esp32c2)
|
||||
// Because not all esp chips support RTC mem(such as esp32c2)
|
||||
// Initialize NVS
|
||||
esp_err_t err = nvs_flash_init();
|
||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
|
@ -24,3 +24,5 @@ entries:
|
||||
spi_flash_hal_gpspi (noflash)
|
||||
if SOC_PMU_SUPPORTED = y:
|
||||
pmu_hal (noflash)
|
||||
if SOC_CLK_MPLL_SUPPORTED = y:
|
||||
clk_tree_hal: clk_hal_xtal_get_freq_mhz (noflash)
|
||||
|
Loading…
x
Reference in New Issue
Block a user