From 7f86d8108344587d844d4591f14a29161b9f40f6 Mon Sep 17 00:00:00 2001 From: dongyou Date: Thu, 6 Aug 2020 15:20:43 +0800 Subject: [PATCH] Replace periph_module_enable/disable by periph_wifi_bt_common_module_enable which are in IRAM. AddIRAM_ATTR periph_ll_wifi_bt_module_enable_clk_clear_rstandIRAM_ATTR periph_ll_wifi_bt_module_disable_clk_set_rstto fit O0 optimization level. Delete duplicated spinlock and counter. --- .../driver/include/driver/periph_ctrl.h | 23 +++++++++ components/driver/periph_ctrl.c | 23 +++++++++ components/esp32/phy_init.c | 49 +------------------ .../freertos/include/freertos/portmacro.h | 16 ++++++ 4 files changed, 64 insertions(+), 47 deletions(-) diff --git a/components/driver/include/driver/periph_ctrl.h b/components/driver/include/driver/periph_ctrl.h index 9689a8cb21..1d010c0c2c 100644 --- a/components/driver/include/driver/periph_ctrl.h +++ b/components/driver/include/driver/periph_ctrl.h @@ -62,6 +62,29 @@ void periph_module_disable(periph_module_t periph); */ void periph_module_reset(periph_module_t periph); +/** + * @brief enable wifi bt common module + * + * @note If wifi_bt_common_module_enable is called a number of times, + * wifi_bt_common_module_disable has to be called the same number of times + * in order to put the peripheral into disabled state. + * + * @return NULL + * + */ +void wifi_bt_common_module_enable(void); + +/** + * @brief disable wifi bt common module + * + * @note If wifi_bt_common_module_enable is called a number of times, + * wifi_bt_common_module_disable has to be called the same number of times + * in order to put the peripheral into disabled state. + * + * @return NULL + * + */ +void wifi_bt_common_module_disable(void); #ifdef __cplusplus } diff --git a/components/driver/periph_ctrl.c b/components/driver/periph_ctrl.c index 0b06ed1bc7..cd57f53e38 100644 --- a/components/driver/periph_ctrl.c +++ b/components/driver/periph_ctrl.c @@ -20,6 +20,7 @@ #include "driver/periph_ctrl.h" static portMUX_TYPE periph_spinlock = portMUX_INITIALIZER_UNLOCKED; +static uint8_t ref_counts = 0; /* Static functions to return register address & mask for clk_en / rst of each peripheral */ static uint32_t get_clk_en_mask(periph_module_t periph); @@ -257,4 +258,26 @@ static uint32_t get_rst_en_reg(periph_module_t periph) } } +IRAM_ATTR void wifi_bt_common_module_enable(void) +{ + portENTER_CRITICAL_SAFE(&periph_spinlock); + if (ref_counts == 0) { + DPORT_SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG,DPORT_WIFI_CLK_WIFI_BT_COMMON_M); + DPORT_CLEAR_PERI_REG_MASK(DPORT_CORE_RST_EN_REG,0); + } + + ref_counts++; + portEXIT_CRITICAL_SAFE(&periph_spinlock); +} +IRAM_ATTR void wifi_bt_common_module_disable(void) +{ + portENTER_CRITICAL_SAFE(&periph_spinlock); + ref_counts--; + if (ref_counts == 0) { + DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG,DPORT_WIFI_CLK_WIFI_BT_COMMON_M); + DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG,0); + } + + portEXIT_CRITICAL_SAFE(&periph_spinlock); +} diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index 76ba149539..42e910bf78 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -52,12 +52,6 @@ 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; @@ -121,53 +115,14 @@ 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(); + wifi_bt_common_module_enable(); } 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(); + wifi_bt_common_module_disable(); } diff --git a/components/freertos/include/freertos/portmacro.h b/components/freertos/include/freertos/portmacro.h index adeb3bb009..774993f4d2 100644 --- a/components/freertos/include/freertos/portmacro.h +++ b/components/freertos/include/freertos/portmacro.h @@ -235,6 +235,22 @@ void vPortCPUReleaseMutex(portMUX_TYPE *mux); #define portEXIT_CRITICAL_ISR(mux) vTaskExitCritical(mux) #endif +#define portENTER_CRITICAL_SAFE(mux) do { \ + if (xPortInIsrContext()) { \ + portENTER_CRITICAL_ISR(mux); \ + } else { \ + portENTER_CRITICAL(mux); \ + } \ + } while(0) + +#define portEXIT_CRITICAL_SAFE(mux) do { \ + if (xPortInIsrContext()) { \ + portEXIT_CRITICAL_ISR(mux); \ + } else { \ + portEXIT_CRITICAL(mux); \ + } \ + } while(0) + // Critical section management. NW-TODO: replace XTOS_SET_INTLEVEL with more efficient version, if any? // These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level. //