diff --git a/components/esp32/esp_adapter.c b/components/esp32/esp_adapter.c index 2de293acd..c300fa09c 100644 --- a/components/esp32/esp_adapter.c +++ b/components/esp32/esp_adapter.c @@ -561,6 +561,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._dport_access_stall_other_cpu_end_wrap = esp_dport_access_stall_other_cpu_end_wrap, ._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_arm = timer_arm_wrapper, ._timer_disarm = timer_disarm_wrapper, diff --git a/components/esp32/include/esp_phy_init.h b/components/esp32/include/esp_phy_init.h index 6783ff54b..3402f197b 100644 --- a/components/esp32/include/esp_phy_init.h +++ b/components/esp32/include/esp_phy_init.h @@ -202,6 +202,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 c8b8766de..89778661a 100644 --- a/components/esp32/include/esp_wifi_os_adapter.h +++ b/components/esp32/include/esp_wifi_os_adapter.h @@ -78,6 +78,8 @@ typedef struct { void (* _dport_access_stall_other_cpu_end_wrap)(void); 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_arm)(void *timer, uint32_t tmout, bool repeat); void (* _timer_disarm)(void *timer); diff --git a/components/esp32/lib b/components/esp32/lib index b287033ff..3aa21ee5b 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit b287033ffd84608f555e48f9c538bcccba3395fe +Subproject commit 3aa21ee5be737121584c874a3188dd482163f30b diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index dc80971b8..35ca1cd0a 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -52,6 +52,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; @@ -115,6 +121,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) { @@ -163,7 +219,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)) { @@ -248,7 +305,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(); } }