mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-11-04 06:11:06 +00:00 
			
		
		
		
	fix(esp_hw_support): move deepsleep phy callback before PLL disable
This commit is contained in:
		@@ -7,6 +7,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include "sdkconfig.h"
 | 
			
		||||
#include "esp_sleep.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
@@ -47,6 +48,29 @@ void esp_sleep_enable_adc_tsens_monitor(bool enable);
 | 
			
		||||
void esp_sleep_isolate_digital_gpio(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * Register a callback to be called from the deep sleep prepare for maintain the PHY state
 | 
			
		||||
  *          CPU is equal to min_freq_mhz (if DFS is enabled) when running this callback,
 | 
			
		||||
  *          and PLL clock is exists)
 | 
			
		||||
  *
 | 
			
		||||
  * @warning deepsleep PHY callbacks should without parameters, and MUST NOT,
 | 
			
		||||
  *          UNDER ANY CIRCUMSTANCES, CALL A FUNCTION THAT MIGHT BLOCK.
 | 
			
		||||
  *
 | 
			
		||||
  * @param new_dslp_cb     Callback to be called to close PHY related modules
 | 
			
		||||
  *
 | 
			
		||||
  * @return
 | 
			
		||||
  *     - ESP_OK:         PHY callback registered to the phy modules deepsleep prepare
 | 
			
		||||
  *     - ESP_ERR_NO_MEM: No more hook space for register the callback
 | 
			
		||||
  */
 | 
			
		||||
esp_err_t esp_deep_sleep_register_phy_hook(esp_deep_sleep_cb_t new_dslp_cb);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Unregister an PHY deepsleep callback
 | 
			
		||||
  *
 | 
			
		||||
  * @param old_dslp_cb     Callback to be unregistered
 | 
			
		||||
  */
 | 
			
		||||
void esp_deep_sleep_deregister_phy_hook(esp_deep_sleep_cb_t old_dslp_cb);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -173,7 +173,8 @@
 | 
			
		||||
 | 
			
		||||
#define MAX_DSLP_HOOKS      3
 | 
			
		||||
 | 
			
		||||
static esp_deep_sleep_cb_t s_dslp_cb[MAX_DSLP_HOOKS]={0};
 | 
			
		||||
static esp_deep_sleep_cb_t s_dslp_cb[MAX_DSLP_HOOKS] = {0};
 | 
			
		||||
static esp_deep_sleep_cb_t s_dslp_phy_cb[MAX_DSLP_HOOKS] = {0};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Internal structure which holds all requested deep sleep parameters
 | 
			
		||||
@@ -390,12 +391,12 @@ esp_err_t esp_deep_sleep_try(uint64_t time_in_us)
 | 
			
		||||
    return esp_deep_sleep_try_to_start();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t esp_deep_sleep_register_hook(esp_deep_sleep_cb_t new_dslp_cb)
 | 
			
		||||
static esp_err_t s_sleep_hook_register(esp_deep_sleep_cb_t new_cb, esp_deep_sleep_cb_t s_cb_array[MAX_DSLP_HOOKS])
 | 
			
		||||
{
 | 
			
		||||
    portENTER_CRITICAL(&spinlock_rtc_deep_sleep);
 | 
			
		||||
    for(int n = 0; n < MAX_DSLP_HOOKS; n++){
 | 
			
		||||
        if (s_dslp_cb[n]==NULL || s_dslp_cb[n]==new_dslp_cb) {
 | 
			
		||||
            s_dslp_cb[n]=new_dslp_cb;
 | 
			
		||||
    for (int n = 0; n < MAX_DSLP_HOOKS; n++) {
 | 
			
		||||
        if (s_cb_array[n]==NULL || s_cb_array[n]==new_cb) {
 | 
			
		||||
            s_cb_array[n]=new_cb;
 | 
			
		||||
            portEXIT_CRITICAL(&spinlock_rtc_deep_sleep);
 | 
			
		||||
            return ESP_OK;
 | 
			
		||||
        }
 | 
			
		||||
@@ -405,17 +406,46 @@ esp_err_t esp_deep_sleep_register_hook(esp_deep_sleep_cb_t new_dslp_cb)
 | 
			
		||||
    return ESP_ERR_NO_MEM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void esp_deep_sleep_deregister_hook(esp_deep_sleep_cb_t old_dslp_cb)
 | 
			
		||||
static void s_sleep_hook_deregister(esp_deep_sleep_cb_t old_cb, esp_deep_sleep_cb_t s_cb_array[MAX_DSLP_HOOKS])
 | 
			
		||||
{
 | 
			
		||||
    portENTER_CRITICAL(&spinlock_rtc_deep_sleep);
 | 
			
		||||
    for(int n = 0; n < MAX_DSLP_HOOKS; n++){
 | 
			
		||||
        if(s_dslp_cb[n] == old_dslp_cb) {
 | 
			
		||||
            s_dslp_cb[n] = NULL;
 | 
			
		||||
    for (int n = 0; n < MAX_DSLP_HOOKS; n++) {
 | 
			
		||||
        if(s_cb_array[n] == old_cb) {
 | 
			
		||||
            s_cb_array[n] = NULL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    portEXIT_CRITICAL(&spinlock_rtc_deep_sleep);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t esp_deep_sleep_register_hook(esp_deep_sleep_cb_t new_dslp_cb)
 | 
			
		||||
{
 | 
			
		||||
    return s_sleep_hook_register(new_dslp_cb, s_dslp_cb);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void esp_deep_sleep_deregister_hook(esp_deep_sleep_cb_t old_dslp_cb)
 | 
			
		||||
{
 | 
			
		||||
    s_sleep_hook_deregister(old_dslp_cb, s_dslp_cb);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
esp_err_t esp_deep_sleep_register_phy_hook(esp_deep_sleep_cb_t new_dslp_cb)
 | 
			
		||||
{
 | 
			
		||||
    return s_sleep_hook_register(new_dslp_cb, s_dslp_phy_cb);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void esp_deep_sleep_deregister_phy_hook(esp_deep_sleep_cb_t old_dslp_cb)
 | 
			
		||||
{
 | 
			
		||||
    s_sleep_hook_deregister(old_dslp_cb, s_dslp_phy_cb);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void s_do_deep_sleep_phy_callback(void)
 | 
			
		||||
{
 | 
			
		||||
    for (int n = 0; n < MAX_DSLP_HOOKS; n++) {
 | 
			
		||||
        if (s_dslp_phy_cb[n] != NULL) {
 | 
			
		||||
            s_dslp_phy_cb[n]();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int s_cache_suspend_cnt = 0;
 | 
			
		||||
 | 
			
		||||
static void IRAM_ATTR suspend_cache(void) {
 | 
			
		||||
@@ -658,6 +688,12 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
 | 
			
		||||
        should_skip_sleep = light_sleep_uart_prepare(pd_flags, sleep_duration);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Do deep-sleep PHY related callback, which need to be executed when the PLL clock is exists.
 | 
			
		||||
    // For light-sleep, PHY state is managed by the upper layer of the wifi/bt protocol stack.
 | 
			
		||||
    if (deep_sleep) {
 | 
			
		||||
        s_do_deep_sleep_phy_callback();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA
 | 
			
		||||
    if (!deep_sleep && (pd_flags & PMU_SLEEP_PD_TOP)) {
 | 
			
		||||
        sleep_retention_do_system_retention(true);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
 | 
			
		||||
 * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 */
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
#include "nvs_flash.h"
 | 
			
		||||
#include "esp_efuse.h"
 | 
			
		||||
#include "esp_timer.h"
 | 
			
		||||
#include "esp_sleep.h"
 | 
			
		||||
#include "esp_private/esp_sleep_internal.h"
 | 
			
		||||
#include "sdkconfig.h"
 | 
			
		||||
#include "freertos/FreeRTOS.h"
 | 
			
		||||
#include "freertos/portmacro.h"
 | 
			
		||||
@@ -865,9 +865,9 @@ void esp_phy_load_cal_and_init(void)
 | 
			
		||||
    esp_phy_release_init_data(init_data);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    ESP_ERROR_CHECK(esp_deep_sleep_register_hook(&phy_close_rf));
 | 
			
		||||
    ESP_ERROR_CHECK(esp_deep_sleep_register_phy_hook(&phy_close_rf));
 | 
			
		||||
#if !CONFIG_IDF_TARGET_ESP32
 | 
			
		||||
    ESP_ERROR_CHECK(esp_deep_sleep_register_hook(&phy_xpd_tsens));
 | 
			
		||||
    ESP_ERROR_CHECK(esp_deep_sleep_register_phy_hook(&phy_xpd_tsens));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    free(cal_data); // PHY maintains a copy of calibration data, so we can free this
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user