From 60642e580c3a77956adf7ed45af7900c4eae834a Mon Sep 17 00:00:00 2001 From: xiehang Date: Thu, 11 Mar 2021 11:46:28 +0800 Subject: [PATCH 1/3] esp_wifi: Fix the second distribution network failure of ESPTouch v2 --- components/esp_wifi/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index d21608a505..536393a4a9 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit d21608a505f8000ba3a7cce696985fb3b4cd8e81 +Subproject commit 536393a4a91afc1f03714c677aac6befbfef4dfd From 2b7a3f6d85ef21224a8df9bf72593bc09ad2ce39 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Tue, 23 Feb 2021 10:17:27 +0800 Subject: [PATCH 2/3] light sleep: some default parameters optimization --- components/esp_pm/Kconfig | 4 ++ .../esp_pm/include/esp_private/pm_impl.h | 29 +++++++++++ components/esp_pm/pm_impl.c | 49 ++++++++++++++++++- components/esp_wifi/Kconfig | 18 +++++++ .../esp_wifi/include/esp_private/wifi.h | 26 ++++++++-- components/esp_wifi/src/wifi_init.c | 18 ++++++- 6 files changed, 138 insertions(+), 6 deletions(-) diff --git a/components/esp_pm/Kconfig b/components/esp_pm/Kconfig index 1ce8e6af4f..d06018213f 100644 --- a/components/esp_pm/Kconfig +++ b/components/esp_pm/Kconfig @@ -90,4 +90,8 @@ menu "Power Management" Waring: If you want to enable this option on ESP32, you should enable `GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL` at first, otherwise you will not be able to switch pullup/pulldown mode. + config PM_SLP_DEFAULT_PARAMS_OPT + bool + default n + endmenu # "Power Management" diff --git a/components/esp_pm/include/esp_private/pm_impl.h b/components/esp_pm/include/esp_private/pm_impl.h index 50e459fc77..e208d2bcf5 100644 --- a/components/esp_pm/include/esp_private/pm_impl.h +++ b/components/esp_pm/include/esp_private/pm_impl.h @@ -49,6 +49,13 @@ typedef enum { */ pm_mode_t esp_pm_impl_get_mode(esp_pm_lock_type_t type, int arg); +/** + * @brief Get CPU clock frequency by power mode + * @param mode power mode + * @return CPU clock frequency + */ +int esp_pm_impl_get_cpu_freq(pm_mode_t mode); + /** * If profiling is enabled, this data type will be used to store microsecond * timestamps. @@ -172,6 +179,28 @@ esp_err_t esp_pm_register_inform_out_light_sleep_overhead_callback(inform_out_li */ esp_err_t esp_pm_unregister_inform_out_light_sleep_overhead_callback(inform_out_light_sleep_overhead_cb_t cb); +/** + * @brief Callback function type for peripherals to know light sleep default parameters + */ +typedef void (* update_light_sleep_default_params_config_cb_t)(int, int); + +/** + * @brief Register peripherals light sleep default parameters configure callback + * + * This function allows you to register a callback that configure the peripherals + * of default parameters of light sleep + * @param cb function to update default parameters + */ +void esp_pm_register_light_sleep_default_params_config_callback(update_light_sleep_default_params_config_cb_t cb); + +/** + * @brief Unregister peripherals light sleep default parameters configure Callback + * + * This function allows you to unregister a callback that configure the peripherals + * of default parameters of light sleep + */ +void esp_pm_unregister_light_sleep_default_params_config_callback(void); + #ifdef CONFIG_PM_PROFILING #define WITH_PROFILING #endif diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index 3b02cc64b0..760b813e1b 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -152,7 +152,7 @@ static esp_pm_lock_handle_t s_rtos_lock_handle[portNUM_PROCESSORS]; /* Lookup table of CPU frequency configs to be used in each mode. * Initialized by esp_pm_impl_init and modified by esp_pm_configure. */ -rtc_cpu_freq_config_t s_cpu_freq_by_mode[PM_MODE_COUNT]; +static rtc_cpu_freq_config_t s_cpu_freq_by_mode[PM_MODE_COUNT]; /* Whether automatic light sleep is enabled */ static bool s_light_sleep_en = false; @@ -198,6 +198,9 @@ static const char* TAG = "pm"; static void do_switch(pm_mode_t new_mode); static void leave_idle(void); static void on_freq_update(uint32_t old_ticks_per_us, uint32_t ticks_per_us); +#if CONFIG_PM_SLP_DEFAULT_PARAMS_OPT +static void esp_pm_light_sleep_default_params_config(int min_freq_mhz, int max_freq_mhz); +#endif pm_mode_t esp_pm_impl_get_mode(esp_pm_lock_type_t type, int arg) { @@ -311,6 +314,12 @@ esp_err_t esp_pm_configure(const void* vconfig) } #endif +#if CONFIG_PM_SLP_DEFAULT_PARAMS_OPT + if (config->light_sleep_enable) { + esp_pm_light_sleep_default_params_config(min_freq_mhz, max_freq_mhz); + } +#endif + return ESP_OK; } @@ -660,6 +669,19 @@ void esp_pm_impl_dump_stats(FILE* out) } #endif // WITH_PROFILING +int esp_pm_impl_get_cpu_freq(pm_mode_t mode) +{ + int freq_mhz; + if (mode >= PM_MODE_LIGHT_SLEEP && mode < PM_MODE_COUNT) { + portENTER_CRITICAL(&s_switch_lock); + freq_mhz = s_cpu_freq_by_mode[mode].freq_mhz; + portEXIT_CRITICAL(&s_switch_lock); + } else { + abort(); + } + return freq_mhz; +} + void esp_pm_impl_init(void) { #if defined(CONFIG_ESP_CONSOLE_UART) @@ -816,3 +838,28 @@ void periph_inform_out_light_sleep_overhead(uint32_t out_light_sleep_time) } } } + +static update_light_sleep_default_params_config_cb_t s_light_sleep_default_params_config_cb = NULL; + +void esp_pm_register_light_sleep_default_params_config_callback(update_light_sleep_default_params_config_cb_t cb) +{ + if (s_light_sleep_default_params_config_cb == NULL) { + s_light_sleep_default_params_config_cb = cb; + } +} + +void esp_pm_unregister_light_sleep_default_params_config_callback(void) +{ + if (s_light_sleep_default_params_config_cb) { + s_light_sleep_default_params_config_cb = NULL; + } +} + +#if CONFIG_PM_SLP_DEFAULT_PARAMS_OPT +static void esp_pm_light_sleep_default_params_config(int min_freq_mhz, int max_freq_mhz) +{ + if (s_light_sleep_default_params_config_cb) { + (*s_light_sleep_default_params_config_cb)(min_freq_mhz, max_freq_mhz); + } +} +#endif diff --git a/components/esp_wifi/Kconfig b/components/esp_wifi/Kconfig index 37386ee7f8..6fd5846eff 100644 --- a/components/esp_wifi/Kconfig +++ b/components/esp_wifi/Kconfig @@ -323,6 +323,8 @@ menu "Wi-Fi" config ESP_WIFI_SLP_IRAM_OPT bool "WiFi SLP IRAM speed optimization" + depends on FREERTOS_USE_TICKLESS_IDLE + select PM_SLP_DEFAULT_PARAMS_OPT help Select this option to place called Wi-Fi library TBTT process and receive beacon functions in IRAM. Some functions can be put in IRAM either by ESP32_WIFI_IRAM_OPT and ESP32_WIFI_RX_IRAM_OPT, or this one. @@ -331,6 +333,22 @@ menu "Wi-Fi" If neither of them are enabled, the other 7.4KB IRAM memory would be taken by this option. Wi-Fi power-save mode average current would be reduced if this option is enabled. + config ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME + int "Minimum active time" + range 8 60 + default 8 + depends on ESP_WIFI_SLP_IRAM_OPT + help + The minimum timeout for waiting to receive data, unit: milliseconds. + + config ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME + int "Maximum keep alive time" + range 10 60 + default 60 + depends on ESP_WIFI_SLP_IRAM_OPT + help + The maximum time that wifi keep alive, unit: seconds. + config ESP_WIFI_FTM_INITIATOR_SUPPORT bool "FTM Initiator support" default y diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index 9ae3003994..3c5a93a106 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -575,10 +575,28 @@ esp_err_t esp_wifi_set_tx_done_cb(wifi_tx_done_cb_t cb); esp_err_t esp_wifi_internal_set_spp_amsdu(wifi_interface_t ifidx, bool spp_cap, bool spp_req); /** - * @brief Apply WiFi sleep optimization parameters - * - */ -void esp_wifi_internal_optimize_wake_ahead_time(void); + * @brief Update WIFI light sleep default parameters + * + * @param min_freq_mhz: minimum frequency of DFS + * @param max_freq_mhz: maximum frequency of DFS + */ +void esp_wifi_internal_update_light_sleep_default_params(int min_freq_mhz, int max_freq_mhz); + +/** + * @brief Set the delay time for wifi to enter the sleep state when light sleep + * + * @param return_to_sleep_delay: minimum timeout time for waiting to receive + * data, when no data is received during the timeout period, + * the wifi enters the sleep process. + */ +void esp_wifi_set_sleep_delay_time(uint32_t return_to_sleep_delay); + +/** + * @brief Set wifi keep alive time + * + * @param keep_alive_time: keep alive time + */ +void esp_wifi_set_keep_alive_time(uint32_t keep_alive_time); /** * @brief Set FTM Report log level diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index 4569277105..73284f5514 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -151,6 +151,9 @@ esp_err_t esp_wifi_deinit(void) esp_pm_unregister_skip_light_sleep_callback(esp_wifi_internal_is_tsf_active); esp_pm_unregister_inform_out_light_sleep_overhead_callback(esp_wifi_internal_update_light_sleep_wake_ahead_time); #endif +#if CONFIG_ESP_WIFI_SLP_IRAM_OPT + esp_pm_unregister_light_sleep_default_params_config_callback(); +#endif #endif #if CONFIG_MAC_BB_PD esp_unregister_mac_bb_pd_callback(pm_mac_sleep); @@ -186,7 +189,6 @@ static void esp_wifi_config_info(void) #endif #ifdef CONFIG_ESP_WIFI_SLP_IRAM_OPT - esp_wifi_internal_optimize_wake_ahead_time(); ESP_LOGI(TAG, "WiFi SLP IRAM OP enabled"); #endif @@ -222,6 +224,20 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) } #endif +#if CONFIG_ESP_WIFI_SLP_IRAM_OPT + esp_pm_register_light_sleep_default_params_config_callback(esp_wifi_internal_update_light_sleep_default_params); + + int min_freq_mhz = esp_pm_impl_get_cpu_freq(PM_MODE_LIGHT_SLEEP); + int max_freq_mhz = esp_pm_impl_get_cpu_freq(PM_MODE_CPU_MAX); + esp_wifi_internal_update_light_sleep_default_params(min_freq_mhz, max_freq_mhz); + + uint32_t sleep_delay_us = CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME * 1000; + esp_wifi_set_sleep_delay_time(sleep_delay_us); + + uint32_t keep_alive_time_us = CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME * 1000 * 1000; + esp_wifi_set_keep_alive_time(keep_alive_time_us); +#endif + #if SOC_WIFI_HW_TSF esp_err_t ret = esp_pm_register_skip_light_sleep_callback(esp_wifi_internal_is_tsf_active); if (ret != ESP_OK) { From 37946ab300f3d5d5c91822f3ea027387f78f98d5 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Tue, 9 Mar 2021 17:04:13 +0800 Subject: [PATCH 3/3] deep sleep: power down wifi and bt during deep sleep --- components/esp_system/sleep_modes.c | 12 +++++++++++- components/soc/esp32c3/include/soc/soc_caps.h | 4 ++++ components/soc/esp32s2/include/soc/soc_caps.h | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index 8c8e9dd6b4..633b656f4c 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -622,8 +622,18 @@ void IRAM_ATTR esp_deep_sleep_start(void) // Correct the sleep time s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US; + uint32_t force_pd_flags = RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO; + +#if SOC_PM_SUPPORT_WIFI_PD + force_pd_flags |= RTC_SLEEP_PD_WIFI; +#endif + +#if SOC_PM_SUPPORT_BT_PD + force_pd_flags |= RTC_SLEEP_PD_BT; +#endif + // Enter sleep - esp_sleep_start(RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | pd_flags); + esp_sleep_start(force_pd_flags | pd_flags); // Because RTC is in a slower clock domain than the CPU, it // can take several CPU cycles for the sleep mode to start. diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index d74aab972d..fdda99cf0b 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -135,3 +135,7 @@ #define SOC_PM_SUPPORT_BT_WAKEUP (1) #define SOC_PM_SUPPORT_CPU_PD (1) + +#define SOC_PM_SUPPORT_WIFI_PD (1) + +#define SOC_PM_SUPPORT_BT_PD (1) diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 1a15baf29d..c6262a39a3 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -314,5 +314,7 @@ #define SOC_PM_SUPPORT_WIFI_WAKEUP (1) +#define SOC_PM_SUPPORT_WIFI_PD (1) + /* ---------------------------- Compatibility ------------------------------- */ // No contents