From 40f5755a7c765862fb48b8f6d9c2675298f7935b Mon Sep 17 00:00:00 2001 From: muhaidong Date: Mon, 24 Nov 2025 15:02:16 +0800 Subject: [PATCH] fix(wifi): fix external coexistence depends on wifi connect issue --- components/esp_coex/src/coexist.c | 15 ++----- components/esp_coex/src/coexist_debug.c | 22 +++------- .../include/esp_private/periph_ctrl.h | 20 +++++++++ components/esp_hw_support/periph_ctrl.c | 44 +++++++++++++++++++ .../hal/esp32c2/include/hal/clk_gate_ll.h | 11 +++++ .../soc/esp32c2/include/soc/periph_defs.h | 1 + .../soc/esp32c2/include/soc/syscon_reg.h | 8 ++-- 7 files changed, 91 insertions(+), 30 deletions(-) diff --git a/components/esp_coex/src/coexist.c b/components/esp_coex/src/coexist.c index c990a071f7..da83b47a94 100644 --- a/components/esp_coex/src/coexist.c +++ b/components/esp_coex/src/coexist.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,9 +17,7 @@ #include "esp_private/gpio.h" #endif -#if SOC_MODEM_CLOCK_IS_INDEPENDENT -#include "esp_private/esp_modem_clock.h" -#endif +#include "esp_private/periph_ctrl.h" #if SOC_EXTERNAL_COEX_ADVANCE #define EXTERNAL_COEX_SIGNAL_I0_IDX EXTERN_ACTIVE_I_IDX @@ -263,16 +261,11 @@ esp_err_t esp_enable_extern_coex_gpio_pin(external_coex_wire_t wire_type, esp_ex return ESP_ERR_INVALID_ARG; #endif /* SOC_EXTERNAL_COEX_ADVANCE */ } -#if SOC_MODEM_CLOCK_IS_INDEPENDENT - modem_clock_module_enable(PERIPH_COEX_MODULE); -#endif + coex_module_enable(); #if SOC_EXTERNAL_COEX_ADVANCE esp_coex_external_params(g_external_coex_params, 0, 0); #endif esp_err_t ret = esp_coex_external_set(EXTERN_COEX_PTI_MID, EXTERN_COEX_PTI_MID, EXTERN_COEX_PTI_HIGH); -#if SOC_MODEM_CLOCK_IS_INDEPENDENT - modem_clock_module_disable(PERIPH_COEX_MODULE); -#endif if (ESP_OK != ret) { return ESP_FAIL; } @@ -282,7 +275,7 @@ esp_err_t esp_enable_extern_coex_gpio_pin(external_coex_wire_t wire_type, esp_ex esp_err_t esp_disable_extern_coex_gpio_pin(void) { esp_coex_external_stop(); - + coex_module_disable(); return ESP_OK; } #endif /* External Coex */ diff --git a/components/esp_coex/src/coexist_debug.c b/components/esp_coex/src/coexist_debug.c index b0cc341313..6d91447cac 100644 --- a/components/esp_coex/src/coexist_debug.c +++ b/components/esp_coex/src/coexist_debug.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,9 +18,7 @@ #include "soc/gpio_sig_map.h" #include "esp_rom_gpio.h" #include "soc/soc.h" -#if SOC_MODEM_CLOCK_IS_INDEPENDENT -#include "esp_private/esp_modem_clock.h" -#endif +#include "esp_private/periph_ctrl.h" #if CONFIG_ESP_COEX_GPIO_DEBUG static char* TAG = "coexist debug"; @@ -191,13 +189,9 @@ esp_err_t esp_coexist_debug_matrix_init(int evt, int sig, bool rev) esp_err_t esp_coexist_gpio_debug_matrix_config(int event) { -#if SOC_MODEM_CLOCK_IS_INDEPENDENT - modem_clock_module_enable(PERIPH_COEX_MODULE); -#endif + coex_module_enable(); esp_err_t ret = coex_gpio_debug_matrix_config(event); -#if SOC_MODEM_CLOCK_IS_INDEPENDENT - modem_clock_module_disable(PERIPH_COEX_MODULE); -#endif + coex_module_disable(); return ret; } @@ -264,14 +258,10 @@ esp_err_t esp_coexist_debug_init(void) gpio_set_level(s_io_nums[i], false); } -#if SOC_MODEM_CLOCK_IS_INDEPENDENT - modem_clock_module_enable(PERIPH_COEX_MODULE); -#endif + coex_module_enable(); /* Init coexist hardware signal */ ESP_ERROR_CHECK(coex_gpio_debug_matrix_init()); -#if SOC_MODEM_CLOCK_IS_INDEPENDENT - modem_clock_module_disable(PERIPH_COEX_MODULE); -#endif + coex_module_disable(); return ESP_OK; } diff --git a/components/esp_hw_support/include/esp_private/periph_ctrl.h b/components/esp_hw_support/include/esp_private/periph_ctrl.h index d46229b03b..c53effde7d 100644 --- a/components/esp_hw_support/include/esp_private/periph_ctrl.h +++ b/components/esp_hw_support/include/esp_private/periph_ctrl.h @@ -153,6 +153,26 @@ void phy_module_disable(void); */ bool phy_module_has_clock_bits(uint32_t mask); +/** + * @brief Enable coex module + * + * @note Calling this function will only enable coex module. + * @note For ESP32S2, ESP32S3, and ESP32C3, this function has no effect because + * the coex module clock is controlled by the modem clock. On these chips, + * you must call esp_wifi_init() to enable the modem clock before using + * external coexistence features. + */ +void coex_module_enable(void); + +/** + * @brief Disable coex module + * + * @note Calling this function will only disable coex module. + * @note For ESP32S2, ESP32S3, and ESP32C3, this function has no effect because + * the coex module clock is controlled by the modem clock. + */ +void coex_module_disable(void); + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/periph_ctrl.c b/components/esp_hw_support/periph_ctrl.c index cf1e428c7b..089d7d293f 100644 --- a/components/esp_hw_support/periph_ctrl.c +++ b/components/esp_hw_support/periph_ctrl.c @@ -96,6 +96,12 @@ IRAM_ATTR void wifi_bt_common_module_enable(void) periph_ll_wifi_bt_module_enable_clk(); } ref_counts[PERIPH_WIFI_BT_COMMON_MODULE]++; +#if CONFIG_IDF_TARGET_ESP32C2 + if (ref_counts[PERIPH_COEX_MODULE] == 0) { + periph_ll_coex_module_enable_clk_clear_rst(); + } + ref_counts[PERIPH_COEX_MODULE]++; +#endif portEXIT_CRITICAL_SAFE(&periph_spinlock); #endif } @@ -110,6 +116,12 @@ IRAM_ATTR void wifi_bt_common_module_disable(void) if (ref_counts[PERIPH_WIFI_BT_COMMON_MODULE] == 0) { periph_ll_wifi_bt_module_disable_clk(); } +#if CONFIG_IDF_TARGET_ESP32C2 + ref_counts[PERIPH_COEX_MODULE]--; + if (ref_counts[PERIPH_COEX_MODULE] == 0) { + periph_ll_coex_module_disable_clk_set_rst(); + } +#endif portEXIT_CRITICAL_SAFE(&periph_spinlock); #endif } @@ -222,4 +234,36 @@ IRAM_ATTR bool phy_module_has_clock_bits(uint32_t mask) } return true; } + +IRAM_ATTR void coex_module_enable(void) +{ +#if SOC_MODEM_CLOCK_IS_INDEPENDENT + modem_clock_module_enable(PERIPH_COEX_MODULE); +#else + portENTER_CRITICAL_SAFE(&periph_spinlock); +#if CONFIG_IDF_TARGET_ESP32C2 + if (ref_counts[PERIPH_COEX_MODULE] == 0) { + periph_ll_coex_module_enable_clk_clear_rst(); + } + ref_counts[PERIPH_COEX_MODULE]++; +#endif + portEXIT_CRITICAL_SAFE(&periph_spinlock); +#endif +} + +IRAM_ATTR void coex_module_disable(void) +{ +#if SOC_MODEM_CLOCK_IS_INDEPENDENT + modem_clock_module_disable(PERIPH_COEX_MODULE); +#else + portENTER_CRITICAL_SAFE(&periph_spinlock); +#if CONFIG_IDF_TARGET_ESP32C2 + ref_counts[PERIPH_COEX_MODULE]--; + if (ref_counts[PERIPH_COEX_MODULE] == 0) { + periph_ll_coex_module_disable_clk_set_rst(); + } +#endif + portEXIT_CRITICAL_SAFE(&periph_spinlock); +#endif +} #endif //#if SOC_BT_SUPPORTED || SOC_WIFI_SUPPORTED || SOC_IEEE802154_SUPPORTED diff --git a/components/hal/esp32c2/include/hal/clk_gate_ll.h b/components/hal/esp32c2/include/hal/clk_gate_ll.h index f91522ebf9..0a8dea6d3b 100644 --- a/components/hal/esp32c2/include/hal/clk_gate_ll.h +++ b/components/hal/esp32c2/include/hal/clk_gate_ll.h @@ -226,6 +226,17 @@ static inline void periph_ll_phy_calibration_module_disable_clk_set_rst(void) DPORT_SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); } +static inline void periph_ll_coex_module_enable_clk_clear_rst(void) +{ + DPORT_SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_COEX_EN_M); + DPORT_CLEAR_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); +} + +static inline void periph_ll_coex_module_disable_clk_set_rst(void) +{ + DPORT_CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_COEX_EN_M); + DPORT_SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); +} #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c2/include/soc/periph_defs.h b/components/soc/esp32c2/include/soc/periph_defs.h index e3ee27848c..03eeb20775 100644 --- a/components/soc/esp32c2/include/soc/periph_defs.h +++ b/components/soc/esp32c2/include/soc/periph_defs.h @@ -38,6 +38,7 @@ typedef enum { PERIPH_MODEM_RPA_MODULE, PERIPH_ASSIST_DEBUG_MODULE, PERIPH_PHY_CALIBRATION_MODULE, + PERIPH_COEX_MODULE, PERIPH_MODULE_MAX } periph_module_t; diff --git a/components/soc/esp32c2/include/soc/syscon_reg.h b/components/soc/esp32c2/include/soc/syscon_reg.h index 2744edd2d1..e0a783b14b 100644 --- a/components/soc/esp32c2/include/soc/syscon_reg.h +++ b/components/soc/esp32c2/include/soc/syscon_reg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -178,8 +178,10 @@ extern "C" { #define SYSTEM_WIFI_CLK_BT_EN_S 0 /* Mask for clock bits used by both WIFI and Bluetooth, 0, 1, 2, 3, 7, 8, 9, 10, 19, 20, 21, 22, 23 */ #define SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M 0x78078F -/* Mask for clock bits used by phy calibration, bit 22, 29, 30, 31 */ -#define SYSTEM_WIFI_CLK_PHY_EN_M 0xE0400000 +/* Mask for clock bits used by phy calibration, bit 22, 30, 31 */ +#define SYSTEM_WIFI_CLK_PHY_EN_M 0xC0400000 +/* Mask for clock bits used by coex, bit 29 */ +#define SYSTEM_WIFI_CLK_COEX_EN_M 0x20000000 /* Digital team to check */ //bluetooth baseband bit11