diff --git a/components/esp32/include/esp_phy_init.h b/components/esp32/include/esp_phy_init.h index 2dfb7447da..63e19f1840 100644 --- a/components/esp32/include/esp_phy_init.h +++ b/components/esp32/include/esp_phy_init.h @@ -190,6 +190,18 @@ esp_err_t esp_phy_rf_deinit(phy_rf_module_t module); */ void esp_phy_load_cal_and_init(phy_rf_module_t module); +/** +* @brief Enable WiFi/BT common clock +* +*/ +void esp_phy_common_clock_enable(void); + +/** +* @brief Disable WiFi/BT common clock +* +*/ +void esp_phy_common_clock_disable(void); + /** * @brief Module requires to enter modem sleep */ diff --git a/components/esp32/include/esp_wifi_os_adapter.h b/components/esp32/include/esp_wifi_os_adapter.h index ba7c2d06ad..88dbc2720a 100644 --- a/components/esp32/include/esp_wifi_os_adapter.h +++ b/components/esp32/include/esp_wifi_os_adapter.h @@ -84,6 +84,8 @@ typedef struct { int32_t (* _phy_rf_init)(const void * init_data, uint32_t mode, void * calibration_data, uint32_t module); int32_t (* _phy_rf_deinit)(uint32_t module); void (* _phy_load_cal_and_init)(uint32_t module); + void (* _phy_common_clock_enable)(void); + void (* _phy_common_clock_disable)(void); int32_t (* _read_mac)(uint8_t* mac, uint32_t type); void (* _timer_init)(void); void (* _timer_deinit)(void); diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index b8e791f7fd..330a52dca8 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -51,6 +51,12 @@ static uint32_t s_module_phy_rf_init = 0; /* Whether modem sleep is turned on */ static volatile bool s_is_phy_rf_en = false; +/* Whether WiFi/BT common clock enabled reference */ +static volatile int32_t s_common_clock_enable_ref = 0; + +/* PHY spinlock mux */ +static portMUX_TYPE s_phy_spin_lock = portMUX_INITIALIZER_UNLOCKED; + /* Bit mask of modules needing to enter modem sleep mode */ static uint32_t s_modem_sleep_module_enter = 0; @@ -112,6 +118,56 @@ static inline void phy_update_wifi_mac_time(bool en_clock_stopped, int64_t now) } } +IRAM_ATTR static inline void phy_spin_lock(void) +{ + if (xPortInIsrContext()) { + portENTER_CRITICAL_ISR(&s_phy_spin_lock); + } else { + portENTER_CRITICAL(&s_phy_spin_lock); + } +} + +IRAM_ATTR static inline void phy_spin_unlock(void) +{ + if (xPortInIsrContext()) { + portEXIT_CRITICAL_ISR(&s_phy_spin_lock); + } else { + portEXIT_CRITICAL(&s_phy_spin_lock); + } +} + +IRAM_ATTR void esp_phy_common_clock_enable(void) +{ + phy_spin_lock(); + + if (s_common_clock_enable_ref == 0) { + // Enable WiFi/BT common clock + periph_module_enable(PERIPH_WIFI_BT_COMMON_MODULE); + } + + s_common_clock_enable_ref++; + phy_spin_unlock(); +} + +IRAM_ATTR void esp_phy_common_clock_disable(void) +{ + phy_spin_lock(); + + if (s_common_clock_enable_ref > 0) { + s_common_clock_enable_ref --; + + if (s_common_clock_enable_ref == 0) { + // Disable WiFi/BT common clock + periph_module_disable(PERIPH_WIFI_BT_COMMON_MODULE); + } + } else { + abort(); + } + + phy_spin_unlock(); +} + + esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data, phy_rf_module_t module) { @@ -160,7 +216,8 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, esp_phy_calibrat // Update WiFi MAC time before WiFi/BT common clock is enabled phy_update_wifi_mac_time(false, s_phy_rf_en_ts); // Enable WiFi/BT common peripheral clock - periph_module_enable(PERIPH_WIFI_BT_COMMON_MODULE); + //periph_module_enable(PERIPH_WIFI_BT_COMMON_MODULE); + esp_phy_common_clock_enable(); phy_set_wifi_mode_only(0); if (ESP_CAL_DATA_CHECK_FAIL == register_chipv7_phy(init_data, calibration_data, mode)) { @@ -253,7 +310,8 @@ esp_err_t esp_phy_rf_deinit(phy_rf_module_t module) // Update WiFi MAC time before disalbe WiFi/BT common peripheral clock phy_update_wifi_mac_time(true, esp_timer_get_time()); // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG - periph_module_disable(PERIPH_WIFI_BT_COMMON_MODULE); + //periph_module_disable(PERIPH_WIFI_BT_COMMON_MODULE); + esp_phy_common_clock_disable(); } } diff --git a/components/esp32/wifi_os_adapter.c b/components/esp32/wifi_os_adapter.c index cfe3d29239..28316e6a83 100644 --- a/components/esp32/wifi_os_adapter.c +++ b/components/esp32/wifi_os_adapter.c @@ -489,6 +489,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._phy_rf_init = phy_rf_init_wrapper, ._phy_rf_deinit = esp_phy_rf_deinit, ._phy_load_cal_and_init = esp_phy_load_cal_and_init, + ._phy_common_clock_enable = esp_phy_common_clock_enable, + ._phy_common_clock_disable = esp_phy_common_clock_disable, ._read_mac = esp_read_mac, ._timer_init = ets_timer_init, ._timer_deinit = ets_timer_deinit,