Procházet zdrojové kódy

Merge branch 'feature/refactor_phy_access_v4.1' into 'release/v4.1'

esp_wifi: refactor PHY access (Backport v4.1)

See merge request espressif/esp-idf!16985
Jiang Jiang Jian před 3 roky
rodič
revize
e604f638c7

+ 24 - 53
components/bt/controller/bt.c

@@ -902,8 +902,7 @@ static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
 static void btdm_sleep_enter_phase2_wrapper(void)
 {
     if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
-        esp_modem_sleep_enter(MODEM_BLE_MODULE);
-        esp_modem_sleep_enter(MODEM_CLASSIC_BT_MODULE);
+        esp_phy_disable();
 #ifdef CONFIG_PM_ENABLE
         if (s_pm_lock_acquired) {
             esp_pm_lock_release(s_pm_lock);
@@ -911,7 +910,7 @@ static void btdm_sleep_enter_phase2_wrapper(void)
         }
 #endif
     } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
-        esp_modem_sleep_enter(MODEM_BLE_MODULE);
+        esp_phy_disable();
         // pause bluetooth baseband
         periph_module_disable(PERIPH_BT_BASEBAND_MODULE);
     }
@@ -927,8 +926,7 @@ static void btdm_sleep_exit_phase3_wrapper(void)
 #endif
 
     if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
-        esp_modem_sleep_exit(MODEM_BLE_MODULE);
-        esp_modem_sleep_exit(MODEM_CLASSIC_BT_MODULE);
+        esp_phy_enable();
         btdm_check_and_init_bb();
 #ifdef CONFIG_PM_ENABLE
         esp_timer_stop(s_btdm_slp_tmr);
@@ -936,7 +934,7 @@ static void btdm_sleep_exit_phase3_wrapper(void)
     } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
         // resume bluetooth baseband
         periph_module_enable(PERIPH_BT_BASEBAND_MODULE);
-        esp_modem_sleep_exit(MODEM_BLE_MODULE);
+        esp_phy_enable();
     }
 }
 
@@ -1560,7 +1558,7 @@ static void bt_shutdown(void)
     }
 
     esp_bt_controller_shutdown();
-    esp_phy_rf_deinit(PHY_BT_MODULE);
+    esp_phy_disable();
 
     return;
 }
@@ -1586,21 +1584,11 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
     esp_pm_lock_acquire(s_pm_lock);
 #endif
 
-    esp_phy_load_cal_and_init(PHY_BT_MODULE);
-
-    if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_NONE) {
-        //Just register to sleep module, make the modem sleep modules check BT sleep status when sleep enter.
-        //Thus, it will prevent WIFI from disabling RF when BT is not in sleep but is using RF.
-        esp_modem_sleep_register(MODEM_BLE_MODULE);
-        esp_modem_sleep_register(MODEM_CLASSIC_BT_MODULE);
-        esp_modem_sleep_exit(MODEM_BLE_MODULE);
-        esp_modem_sleep_exit(MODEM_CLASSIC_BT_MODULE);
-    } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
-        esp_modem_sleep_register(MODEM_BLE_MODULE);
-        esp_modem_sleep_register(MODEM_CLASSIC_BT_MODULE);
-    } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
-        esp_modem_sleep_register(MODEM_BLE_MODULE);
-    }
+    esp_phy_enable();
+
+#if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
+    coex_init();
+#endif
 
     if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
         btdm_controller_enable_sleep(true);
@@ -1610,15 +1598,11 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
     btdm_check_and_init_bb();
 
     ret = btdm_controller_enable(mode);
-    if (ret) {
-        if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_NONE
-                || btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
-            esp_modem_sleep_deregister(MODEM_BLE_MODULE);
-            esp_modem_sleep_deregister(MODEM_CLASSIC_BT_MODULE);
-        } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
-            esp_modem_sleep_deregister(MODEM_BLE_MODULE);
-        }
-        esp_phy_rf_deinit(PHY_BT_MODULE);
+    if (ret != 0) {
+#if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
+        coex_deinit();
+#endif
+        esp_phy_disable();
 #ifdef CONFIG_PM_ENABLE
         if (!s_btdm_allow_light_sleep) {
             esp_pm_lock_release(s_light_sleep_pm_lock);
@@ -1654,14 +1638,11 @@ esp_err_t esp_bt_controller_disable(void)
 
     btdm_controller_disable();
 
-    if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_NONE
-            || btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
-        esp_modem_sleep_deregister(MODEM_BLE_MODULE);
-        esp_modem_sleep_deregister(MODEM_CLASSIC_BT_MODULE);
-    } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
-        esp_modem_sleep_deregister(MODEM_BLE_MODULE);
-    }
-    esp_phy_rf_deinit(PHY_BT_MODULE);
+#if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
+    coex_deinit();
+#endif
+
+    esp_phy_disable();
     btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
     esp_unregister_shutdown_handler(bt_shutdown);
 
@@ -1728,13 +1709,8 @@ esp_err_t esp_bt_sleep_enable (void)
     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
         return ESP_ERR_INVALID_STATE;
     }
-    if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
-        esp_modem_sleep_register(MODEM_BLE_MODULE);
-        esp_modem_sleep_register(MODEM_CLASSIC_BT_MODULE);
-        btdm_controller_enable_sleep (true);
-        status = ESP_OK;
-    } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
-        esp_modem_sleep_register(MODEM_BLE_MODULE);
+    if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG ||
+            btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
         btdm_controller_enable_sleep (true);
         status = ESP_OK;
     } else {
@@ -1750,13 +1726,8 @@ esp_err_t esp_bt_sleep_disable (void)
     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
         return ESP_ERR_INVALID_STATE;
     }
-    if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
-        esp_modem_sleep_deregister(MODEM_BLE_MODULE);
-        esp_modem_sleep_deregister(MODEM_CLASSIC_BT_MODULE);
-        btdm_controller_enable_sleep (false);
-        status = ESP_OK;
-    } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
-        esp_modem_sleep_deregister(MODEM_BLE_MODULE);
+    if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG ||
+            btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
         btdm_controller_enable_sleep (false);
         status = ESP_OK;
     } else {

+ 41 - 8
components/esp_wifi/esp32/esp_adapter.c

@@ -38,6 +38,8 @@
 #include "esp_private/wifi_os_adapter.h"
 #include "esp_private/wifi.h"
 #include "esp_phy_init.h"
+#include "soc/dport_reg.h"
+#include "soc/syscon_reg.h"
 #include "driver/periph_ctrl.h"
 #include "nvs.h"
 #include "os.h"
@@ -408,6 +410,22 @@ static void IRAM_ATTR timer_arm_us_wrapper(void *ptimer, uint32_t us, bool repea
     ets_timer_arm_us(ptimer, us, repeat);
 }
 
+static void wifi_reset_mac_wrapper(void)
+{
+    DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST);
+    DPORT_CLEAR_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST);
+}
+
+static void wifi_clock_enable_wrapper(void)
+{
+    periph_module_enable(PERIPH_WIFI_MODULE);
+}
+
+static void wifi_clock_disable_wrapper(void)
+{
+    periph_module_disable(PERIPH_WIFI_MODULE);
+}
+
 static int get_time_wrapper(void *t)
 {
     return os_get_time(t);
@@ -437,6 +455,22 @@ static void * IRAM_ATTR zalloc_internal_wrapper(size_t size)
     return ptr;
 }
 
+static int coex_init_wrapper(void)
+{
+#if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
+    return coex_init();
+#else
+    return 0;
+#endif
+}
+
+static void coex_deinit_wrapper(void)
+{
+#if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
+    coex_deinit();
+#endif
+}
+
 static uint32_t coex_status_get_wrapper(void)
 {
 #if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
@@ -600,8 +634,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
     ._rand = esp_random,
     ._dport_access_stall_other_cpu_start_wrap = s_esp_dport_access_stall_other_cpu_start,
     ._dport_access_stall_other_cpu_end_wrap = s_esp_dport_access_stall_other_cpu_end,
-    ._phy_rf_deinit = esp_phy_rf_deinit,
-    ._phy_load_cal_and_init = esp_phy_load_cal_and_init,
+    ._phy_disable = esp_phy_disable,
+    ._phy_enable = esp_phy_enable,
     ._phy_common_clock_enable = esp_phy_common_clock_enable,
     ._phy_common_clock_disable = esp_phy_common_clock_disable,
     ._read_mac = esp_read_mac,
@@ -610,8 +644,9 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
     ._timer_done = timer_done_wrapper,
     ._timer_setfn = timer_setfn_wrapper,
     ._timer_arm_us = timer_arm_us_wrapper,
-    ._periph_module_enable = periph_module_enable,
-    ._periph_module_disable = periph_module_disable,
+    ._wifi_reset_mac = wifi_reset_mac_wrapper,
+    ._wifi_clock_enable = wifi_clock_enable_wrapper,
+    ._wifi_clock_disable = wifi_clock_disable_wrapper,
     ._esp_timer_get_time = esp_timer_get_time,
     ._nvs_set_i8 = nvs_set_i8,
     ._nvs_get_i8 = nvs_get_i8,
@@ -641,10 +676,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
     ._wifi_zalloc = wifi_zalloc_wrapper,
     ._wifi_create_queue = wifi_create_queue_wrapper,
     ._wifi_delete_queue = wifi_delete_queue_wrapper,
-    ._modem_sleep_enter = esp_modem_sleep_enter,
-    ._modem_sleep_exit = esp_modem_sleep_exit,
-    ._modem_sleep_register = esp_modem_sleep_register,
-    ._modem_sleep_deregister = esp_modem_sleep_deregister,
+    ._coex_init = coex_init_wrapper,
+    ._coex_deinit = coex_deinit_wrapper,
     ._coex_status_get = coex_status_get_wrapper,
     ._coex_condition_set = coex_condition_set_wrapper,
     ._coex_wifi_request = coex_wifi_request_wrapper,

+ 0 - 12
components/esp_wifi/include/esp_coexist_internal.h

@@ -53,18 +53,6 @@ esp_err_t coex_init(void);
  */
 void coex_deinit(void);
 
-/**
- * @brief Pause software coexist
- *        extern function for internal use.
- */
-void coex_pause(void);
-
-/**
- * @brief Resume software coexist
- *        extern function for internal use.
- */
-void coex_resume(void);
-
 /**
  * @brief Get software coexist version string
  *        extern function for internal use.

+ 9 - 81
components/esp_wifi/include/esp_phy_init.h

@@ -48,45 +48,6 @@ typedef enum {
     PHY_RF_CAL_FULL    = 0x00000002         /*!< Do full RF calibration. Produces best results, but also consumes a lot of time and current. Suggested to be used once. */
 } esp_phy_calibration_mode_t;
 
-
-/**
- * @brief Modules for modem sleep 
- */
-typedef enum{
-    MODEM_BLE_MODULE,              //!< BLE controller used
-    MODEM_CLASSIC_BT_MODULE,       //!< Classic BT controller used
-    MODEM_WIFI_STATION_MODULE,     //!< Wi-Fi Station used
-    MODEM_WIFI_SOFTAP_MODULE,      //!< Wi-Fi SoftAP used
-    MODEM_WIFI_SNIFFER_MODULE,     //!< Wi-Fi Sniffer used
-    MODEM_WIFI_NULL_MODULE,        //!< Wi-Fi Null mode used
-    MODEM_USER_MODULE,             //!< User used
-    MODEM_MODULE_COUNT             //!< Number of items
-}modem_sleep_module_t;
-
-/**
- * @brief Module WIFI mask for medem sleep
- */
-#define MODEM_BT_MASK   ((1<<MODEM_BLE_MODULE)          |   \
-                         (1<<MODEM_CLASSIC_BT_MODULE))
-
-/**
- * @brief Module WIFI mask for medem sleep
- */
-#define MODEM_WIFI_MASK ((1<<MODEM_WIFI_STATION_MODULE) |   \
-                         (1<<MODEM_WIFI_SOFTAP_MODULE)  |   \
-                         (1<<MODEM_WIFI_SNIFFER_MODULE) |   \
-                         (1<<MODEM_WIFI_NULL_MODULE))
-
-/**
- * @brief Modules needing to call phy_rf_init
- */
-typedef enum{
-    PHY_BT_MODULE,          //!< Bluetooth used
-    PHY_WIFI_MODULE,        //!< Wi-Fi used
-    PHY_MODEM_MODULE,       //!< Modem sleep used
-    PHY_MODULE_COUNT        //!< Number of items
-}phy_rf_module_t;
-
 /**
  * @brief Get PHY init data
  *
@@ -169,38 +130,29 @@ esp_err_t esp_phy_store_cal_data_to_nvs(const esp_phy_calibration_data_t* cal_da
 esp_err_t esp_phy_erase_cal_data_in_nvs(void);
 
 /**
- * @brief Initialize PHY and RF module
+ * @brief Enable PHY and RF module
  *
- * PHY and RF module should be initialized in order to use WiFi or BT.
- * Now PHY and RF initializing job is done automatically when start WiFi or BT. Users should not
+ * PHY and RF module should be enabled in order to use WiFi or BT.
+ * Now PHY and RF enabling job is done automatically when start WiFi or BT. Users should not
  * call this API in their application.
  *
- * @param init_data  PHY parameters. Default set of parameters can
- *                   be obtained by calling esp_phy_get_default_init_data
- *                   function.
- * @param mode  Calibration mode (Full, partial, or no calibration)
- * @param[inout] calibration_data
- * @return ESP_OK on success.
- * @return ESP_FAIL on fail.
  */
-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);
+void esp_phy_enable(void);
 
 /**
- * @brief De-initialize PHY and RF module
+ * @brief Disable PHY and RF module
  *
- * PHY module should be de-initialized in order to shutdown WiFi or BT.
- * Now PHY and RF de-initializing job is done automatically when stop WiFi or BT. Users should not
+ * PHY module should be disabled in order to shutdown WiFi or BT.
+ * Now PHY and RF disabling job is done automatically when stop WiFi or BT. Users should not
  * call this API in their application.
  *
- * @return ESP_OK on success.
  */
-esp_err_t esp_phy_rf_deinit(phy_rf_module_t module);
+void esp_phy_disable(void);
 
 /**
  * @brief Load calibration data from NVS and initialize PHY and RF module
  */
-void esp_phy_load_cal_and_init(phy_rf_module_t module);
+void esp_phy_load_cal_and_init(void);
 
 /**
  * @brief Enable WiFi/BT common clock
@@ -214,30 +166,6 @@ void esp_phy_common_clock_enable(void);
  */
 void esp_phy_common_clock_disable(void);
 
-/**
- * @brief Module requires to enter modem sleep
- */
-esp_err_t esp_modem_sleep_enter(modem_sleep_module_t module);
-
-/**
- * @brief Module requires to exit modem sleep
- */
-esp_err_t esp_modem_sleep_exit(modem_sleep_module_t module);
-
-/**
- * @brief Register module to make it be able to require to enter/exit modem sleep
- *        Although the module has no sleep function, as long as the module use RF,
- *        it must call esp_modem_sleep_regsiter. Otherwise, other modules with sleep
- *        function will disable RF without checking the module which doesn't call
- *        esp_modem_sleep_regsiter.
- */
-esp_err_t esp_modem_sleep_register(modem_sleep_module_t module);
-
-/**
- * @brief De-register module from modem sleep list 
- */
-esp_err_t esp_modem_sleep_deregister(modem_sleep_module_t module);
-
 /**
  * @brief            Get the time stamp when PHY/RF was switched on
  * @return           return 0 if PHY/RF is never switched on. Otherwise return time in

+ 7 - 8
components/esp_wifi/include/esp_private/wifi_os_adapter.h

@@ -77,8 +77,8 @@ typedef struct {
     uint32_t (* _rand)(void);
     void (* _dport_access_stall_other_cpu_start_wrap)(void);
     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_disable)(void);
+    void (* _phy_enable)(void);
     void (* _phy_common_clock_enable)(void);
     void (* _phy_common_clock_disable)(void);
     int32_t (* _read_mac)(uint8_t* mac, uint32_t type);
@@ -87,8 +87,9 @@ typedef struct {
     void (* _timer_done)(void *ptimer);
     void (* _timer_setfn)(void *ptimer, void *pfunction, void *parg);
     void (* _timer_arm_us)(void *ptimer, uint32_t us, bool repeat);
-    void (* _periph_module_enable)(uint32_t periph);
-    void (* _periph_module_disable)(uint32_t periph);
+    void (* _wifi_reset_mac)(void);
+    void (* _wifi_clock_enable)(void);
+    void (* _wifi_clock_disable)(void);
     int64_t (* _esp_timer_get_time)(void);
     int32_t (* _nvs_set_i8)(uint32_t handle, const char* key, int8_t value);
     int32_t (* _nvs_get_i8)(uint32_t handle, const char* key, int8_t* out_value);
@@ -118,10 +119,8 @@ typedef struct {
     void * (* _wifi_zalloc)(size_t size);
     void * (* _wifi_create_queue)(int32_t queue_len, int32_t item_size);
     void (* _wifi_delete_queue)(void * queue);
-    int32_t (* _modem_sleep_enter)(uint32_t module);
-    int32_t (* _modem_sleep_exit)(uint32_t module);
-    int32_t (* _modem_sleep_register)(uint32_t module);
-    int32_t (* _modem_sleep_deregister)(uint32_t module);
+    int (* _coex_init)(void);
+    void (* _coex_deinit)(void);
     uint32_t (* _coex_status_get)(void);
     void (* _coex_condition_set)(uint32_t type, bool dissatisfy);
     int32_t (* _coex_wifi_request)(uint32_t event, uint32_t latency, uint32_t duration);

+ 10 - 2
components/esp_wifi/include/phy.h

@@ -59,18 +59,26 @@ void phy_set_wifi_mode_only(bool wifi_only);
  */
 void coex_bt_high_prio(void);
 
-#if CONFIG_IDF_TARGET_ESP32S2BETA
 /**
  * @brief Open PHY and RF.
  */
 void phy_wakeup_init(void);
-#endif
 
 /**
  * @brief Shutdown PHY and RF.
  */
 void phy_close_rf(void);
 
+/**
+ * @brief Store and load PHY digital registers.
+ *
+ * @param     backup_en  if backup_en is true, store PHY digital registers to memory. Otherwise load PHY digital registers from memory
+ * @param     mem_addr   Memory address to store and load PHY digital registers
+ *
+ * @return    memory size
+ */
+uint8_t phy_dig_reg_backup(bool backup_en, uint32_t *mem_addr);
+
 #ifdef __cplusplus
 }
 #endif

+ 1 - 1
components/esp_wifi/lib

@@ -1 +1 @@
-Subproject commit 2d8942782c28a3621e6d73eb4dab20e8635569f1
+Subproject commit a16da2079608f5d30bd759a94d56a3adf81ee1c8

+ 59 - 276
components/esp_wifi/src/phy_init.c

@@ -34,6 +34,7 @@
 #include "esp_coexist_internal.h"
 #include "driver/periph_ctrl.h"
 #include "esp_private/wifi.h"
+#include "soc/soc_caps.h"
 
 #if CONFIG_IDF_TARGET_ESP32
 #include "esp32/rom/ets_sys.h"
@@ -49,34 +50,25 @@ extern wifi_mac_time_update_cb_t s_wifi_mac_time_update_cb;
 
 static const char* TAG = "phy_init";
 
-static _lock_t s_phy_rf_init_lock;
+static _lock_t s_phy_access_lock;
 
-/* Bit mask of modules needing to call phy_rf_init */
-static uint32_t s_module_phy_rf_init = 0;
+/* Indicate PHY is calibrated or not */
+static bool s_is_phy_calibrated = false;
 
-/* Whether modem sleep is turned on */
-static volatile bool s_is_phy_rf_en = false;
-
-/* Bit mask of modules needing to enter modem sleep mode */
-static uint32_t s_modem_sleep_module_enter = 0;
-
-/* Bit mask of modules which might use RF, system can enter modem
- * sleep mode only when all modules registered require to enter
- * modem sleep*/
-static uint32_t s_modem_sleep_module_register = 0;
-
-/* Whether modern sleep is turned on */
-static volatile bool s_is_modem_sleep_en = false;
-
-static _lock_t s_modem_sleep_lock;
+/* Reference count of enabling PHY */
+static uint8_t s_phy_access_ref = 0;
 
 #if CONFIG_IDF_TARGET_ESP32
 /* time stamp updated when the PHY/RF is turned on */
 static int64_t s_phy_rf_en_ts = 0;
 #endif
 
+/* PHY spinlock for libphy.a */
 static DRAM_ATTR portMUX_TYPE s_phy_int_mux = portMUX_INITIALIZER_UNLOCKED;
 
+/* Memory to store PHY digital registers */
+static uint32_t* s_phy_digital_regs_mem = NULL;
+
 uint32_t IRAM_ATTR phy_enter_critical(void)
 {
     if (xPortInIsrContext()) {
@@ -134,288 +126,75 @@ IRAM_ATTR void esp_phy_common_clock_disable(void)
     wifi_bt_common_module_disable();
 }
 
-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)
+static inline void phy_digital_regs_store(void)
 {
-    /* 3 modules may call phy_init: Wi-Fi, BT, Modem Sleep */
-    if (module >= PHY_MODULE_COUNT){
-        ESP_LOGE(TAG, "%s, invalid module parameter(%d), should be smaller than \
-                 module count(%d)", __func__, module, PHY_MODULE_COUNT);
-        return ESP_ERR_INVALID_ARG;
+    if (s_phy_digital_regs_mem == NULL) {
+        s_phy_digital_regs_mem = (uint32_t *)malloc(SOC_PHY_DIG_REGS_MEM_SIZE);
     }
 
-    _lock_acquire(&s_phy_rf_init_lock);
-    uint32_t s_module_phy_rf_init_old = s_module_phy_rf_init;
-    bool is_wifi_or_bt_enabled = !!(s_module_phy_rf_init_old & (BIT(PHY_BT_MODULE) | BIT(PHY_WIFI_MODULE)));
-    esp_err_t status = ESP_OK;
-    s_module_phy_rf_init |= BIT(module);
-
-    if ((is_wifi_or_bt_enabled == false) && (module == PHY_MODEM_MODULE)){
-        status = ESP_FAIL;
-    }
-    else if (s_is_phy_rf_en == true) {
-    }
-    else {
-        /* If Wi-Fi, BT all disabled, modem sleep should not take effect;
-         * If either Wi-Fi or BT is enabled, should allow modem sleep requires
-         * to enter sleep;
-         * If Wi-Fi, BT co-exist, it is disallowed that only one module
-         * support modem sleep, E,g. BT support modem sleep but Wi-Fi not
-         * support modem sleep;
-         */
-        if (is_wifi_or_bt_enabled == false){
-            if ((module == PHY_BT_MODULE) || (module == PHY_WIFI_MODULE)){
-                s_is_phy_rf_en = true;
-            }
-        }
-        else {
-            if (module == PHY_MODEM_MODULE){
-                s_is_phy_rf_en = true;
-            }
-            else if ((module == PHY_BT_MODULE) || (module == PHY_WIFI_MODULE)){
-                /* New module (BT or Wi-Fi) can init RF according to modem_sleep_exit */
-            }
-        }
-        if (s_is_phy_rf_en == true){
-#if CONFIG_IDF_TARGET_ESP32
-            // Update time stamp
-            s_phy_rf_en_ts = esp_timer_get_time();
-            // Update WiFi MAC time before WiFi/BT common clock is enabled
-            phy_update_wifi_mac_time(false, s_phy_rf_en_ts);
-#endif
-            esp_phy_common_clock_enable();
-            phy_set_wifi_mode_only(0);
-
-#if CONFIG_IDF_TARGET_ESP32S2BETA
-            if (module == PHY_MODEM_MODULE) {
-                phy_wakeup_init();
-            }
-            else
-#endif
-            if (ESP_CAL_DATA_CHECK_FAIL == register_chipv7_phy(init_data, calibration_data, mode)) {
-                ESP_LOGW(TAG, "saving new calibration data because of checksum failure, mode(%d)", mode);
-#ifdef CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE
-                if (mode != PHY_RF_CAL_FULL) {
-                    esp_phy_store_cal_data_to_nvs(calibration_data);
-                }
-#endif
-            }
-
-#if CONFIG_IDF_TARGET_ESP32
-            coex_bt_high_prio();
-#endif
-        }
+    if (s_phy_digital_regs_mem != NULL) {
+        phy_dig_reg_backup(true, s_phy_digital_regs_mem);
     }
+}
 
-#if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
-    if ((module == PHY_BT_MODULE) || (module == PHY_WIFI_MODULE)){
-        uint32_t phy_bt_wifi_mask = BIT(PHY_BT_MODULE) | BIT(PHY_WIFI_MODULE);
-        if ((s_module_phy_rf_init & phy_bt_wifi_mask) == phy_bt_wifi_mask) { //both wifi & bt enabled
-            coex_init();
-            coex_resume();
-        }
+static inline void phy_digital_regs_load(void)
+{
+    if (s_phy_digital_regs_mem != NULL) {
+        phy_dig_reg_backup(false, s_phy_digital_regs_mem);
     }
-#endif
-
-    _lock_release(&s_phy_rf_init_lock);
-    return status;
 }
 
-esp_err_t esp_phy_rf_deinit(phy_rf_module_t module)
+void esp_phy_enable(void)
 {
-    /* 3 modules may call phy_init: Wi-Fi, BT, Modem Sleep */
-    if (module >= PHY_MODULE_COUNT){
-        ESP_LOGE(TAG, "%s, invalid module parameter(%d), should be smaller than \
-                 module count(%d)", __func__, module, PHY_MODULE_COUNT);
-        return ESP_ERR_INVALID_ARG;
-    }
-
-    _lock_acquire(&s_phy_rf_init_lock);
-    uint32_t s_module_phy_rf_init_old = s_module_phy_rf_init;
-    uint32_t phy_bt_wifi_mask = BIT(PHY_BT_MODULE) | BIT(PHY_WIFI_MODULE);
-    bool is_wifi_or_bt_enabled = !!(s_module_phy_rf_init_old & phy_bt_wifi_mask);
-    bool is_both_wifi_bt_enabled = ((s_module_phy_rf_init_old & phy_bt_wifi_mask) == phy_bt_wifi_mask);
-    s_module_phy_rf_init &= ~BIT(module);
-    esp_err_t status = ESP_OK;
-
-#if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
-    if ((module == PHY_BT_MODULE) || (module == PHY_WIFI_MODULE)){
-        if (is_both_wifi_bt_enabled == true) {
-            coex_deinit();
-        }
-    }
+    _lock_acquire(&s_phy_access_lock);
+
+    if (s_phy_access_ref == 0) {
+#if CONFIG_IDF_TARGET_ESP32
+        // Update time stamp
+        s_phy_rf_en_ts = esp_timer_get_time();
+        // Update WiFi MAC time before WiFi/BT common clock is enabled
+        phy_update_wifi_mac_time(false, s_phy_rf_en_ts);
 #endif
+        esp_phy_common_clock_enable();
 
-    if ((is_wifi_or_bt_enabled == false) && (module == PHY_MODEM_MODULE)){
-        /* Modem sleep should not take effect in this case */
-        status = ESP_FAIL;
-    }
-    else if (s_is_phy_rf_en == false) {
-        //do nothing
-    }
-    else {
-        if (is_wifi_or_bt_enabled == false){
-            if ((module == PHY_BT_MODULE) || (module == PHY_WIFI_MODULE)){
-                s_is_phy_rf_en = false;
-                ESP_LOGE(TAG, "%s, RF should not be in enabled state if both Wi-Fi and BT are disabled", __func__);
-            }
+        if (s_is_phy_calibrated == false) {
+            esp_phy_load_cal_and_init();
+            s_is_phy_calibrated = true;
         }
         else {
-            if (module == PHY_MODEM_MODULE){
-                s_is_phy_rf_en = false;
-            }
-            else if ((module == PHY_BT_MODULE) || (module == PHY_WIFI_MODULE)){
-                s_is_phy_rf_en = is_both_wifi_bt_enabled ? true : false;
-            }
+            phy_wakeup_init();
+            phy_digital_regs_load();
         }
 
-        if (s_is_phy_rf_en == false) {
-            // Disable PHY and RF.
-            phy_close_rf();
 #if CONFIG_IDF_TARGET_ESP32
-            // Update WiFi MAC time before disalbe WiFi/BT common peripheral clock
-            phy_update_wifi_mac_time(true, esp_timer_get_time());
+        coex_bt_high_prio();
 #endif
-            // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG
-            esp_phy_common_clock_disable();
-        }
     }
+    s_phy_access_ref++;
 
-    _lock_release(&s_phy_rf_init_lock);
-    return status;
-}
-
-
-
-esp_err_t esp_modem_sleep_enter(modem_sleep_module_t module)
-{
-#if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
-    uint32_t phy_bt_wifi_mask = BIT(PHY_BT_MODULE) | BIT(PHY_WIFI_MODULE);
-#endif
-
-    if (module >= MODEM_MODULE_COUNT){
-        ESP_LOGE(TAG, "%s, invalid module parameter(%d), should be smaller than \
-                 module count(%d)", __func__, module, MODEM_MODULE_COUNT);
-        return ESP_ERR_INVALID_ARG;
-    }
-    else if (!(s_modem_sleep_module_register & BIT(module))){
-        ESP_LOGW(TAG, "%s, module (%d) has not been registered", __func__, module);
-        return ESP_ERR_INVALID_ARG;
-    }
-    else {
-        _lock_acquire(&s_modem_sleep_lock);
-        s_modem_sleep_module_enter |= BIT(module);
-#if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
-        _lock_acquire(&s_phy_rf_init_lock);
-        if (((s_module_phy_rf_init & phy_bt_wifi_mask) == phy_bt_wifi_mask)  //both wifi & bt enabled
-                && (s_modem_sleep_module_enter & (MODEM_BT_MASK | MODEM_WIFI_MASK)) != 0){
-            coex_pause();
-        }
-        _lock_release(&s_phy_rf_init_lock);
-#endif
-        if (!s_is_modem_sleep_en && (s_modem_sleep_module_enter == s_modem_sleep_module_register)){
-            esp_err_t status = esp_phy_rf_deinit(PHY_MODEM_MODULE);
-            if (status == ESP_OK){
-                s_is_modem_sleep_en = true;
-            }
-        }
-        _lock_release(&s_modem_sleep_lock);
-        return ESP_OK;
-    }
+    _lock_release(&s_phy_access_lock);
 }
 
-esp_err_t esp_modem_sleep_exit(modem_sleep_module_t module)
+void esp_phy_disable(void)
 {
-#if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
-    uint32_t phy_bt_wifi_mask = BIT(PHY_BT_MODULE) | BIT(PHY_WIFI_MODULE);
-#endif
+    _lock_acquire(&s_phy_access_lock);
 
-    if (module >= MODEM_MODULE_COUNT){
-        ESP_LOGE(TAG, "%s, invalid module parameter(%d), should be smaller than \
-                 module count(%d)", __func__, module, MODEM_MODULE_COUNT);
-        return ESP_ERR_INVALID_ARG;
-    }
-    else if (!(s_modem_sleep_module_register & BIT(module))){
-        ESP_LOGW(TAG, "%s, module (%d) has not been registered", __func__, module);
-        return ESP_ERR_INVALID_ARG;
-    }
-    else {
-        _lock_acquire(&s_modem_sleep_lock);
-        s_modem_sleep_module_enter &= ~BIT(module);
-        if (s_is_modem_sleep_en){
-            esp_err_t status = esp_phy_rf_init(NULL,PHY_RF_CAL_NONE,NULL, PHY_MODEM_MODULE);
-            if (status == ESP_OK){
-                s_is_modem_sleep_en = false;
-            }
-        }
-#if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
-        _lock_acquire(&s_phy_rf_init_lock);
-        if (((s_module_phy_rf_init & phy_bt_wifi_mask) == phy_bt_wifi_mask)  //both wifi & bt enabled
-                && (s_modem_sleep_module_enter & (MODEM_BT_MASK | MODEM_WIFI_MASK)) == 0){
-            coex_resume();
-        }
-        _lock_release(&s_phy_rf_init_lock);
+    s_phy_access_ref--;
+    if (s_phy_access_ref == 0) {
+        phy_digital_regs_store();
+        // Disable PHY and RF.
+        phy_close_rf();
+#if CONFIG_IDF_TARGET_ESP32
+        // Update WiFi MAC time before disalbe WiFi/BT common peripheral clock
+        phy_update_wifi_mac_time(true, esp_timer_get_time());
 #endif
-        _lock_release(&s_modem_sleep_lock);
-        return ESP_OK;
+        // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG
+        esp_phy_common_clock_disable();
     }
-    return ESP_OK;
-}
 
-esp_err_t esp_modem_sleep_register(modem_sleep_module_t module)
-{
-    if (module >= MODEM_MODULE_COUNT){
-        ESP_LOGE(TAG, "%s, invalid module parameter(%d), should be smaller than \
-                 module count(%d)", __func__, module, MODEM_MODULE_COUNT);
-        return ESP_ERR_INVALID_ARG;
-    }
-    else if (s_modem_sleep_module_register & BIT(module)){
-        ESP_LOGI(TAG, "%s, multiple registration of module (%d)", __func__, module);
-        return ESP_OK;
-    }
-    else{
-        _lock_acquire(&s_modem_sleep_lock);
-        s_modem_sleep_module_register |= BIT(module);
-        /* The module is set to enter modem sleep by default, otherwise will prevent
-         * other modules from entering sleep mode if this module never call enter sleep function
-         * in the future */
-        s_modem_sleep_module_enter |= BIT(module);
-        _lock_release(&s_modem_sleep_lock);
-        return ESP_OK;
-    }
+    _lock_release(&s_phy_access_lock);
 }
 
-esp_err_t esp_modem_sleep_deregister(modem_sleep_module_t module)
-{
-    if (module >= MODEM_MODULE_COUNT){
-        ESP_LOGE(TAG, "%s, invalid module parameter(%d), should be smaller than \
-                 module count(%d)", __func__, module, MODEM_MODULE_COUNT);
-        return ESP_ERR_INVALID_ARG;
-    }
-    else if (!(s_modem_sleep_module_register & BIT(module))){
-        ESP_LOGI(TAG, "%s, module (%d) has not been registered", __func__, module);
-        return ESP_OK;
-    }
-    else{
-        _lock_acquire(&s_modem_sleep_lock);
-        s_modem_sleep_module_enter &= ~BIT(module);
-        s_modem_sleep_module_register &= ~BIT(module);
-        if (s_modem_sleep_module_register == 0){
-            s_modem_sleep_module_enter = 0;
-            /* Once all module are de-registered and current state
-             * is modem sleep mode, we need to turn off modem sleep
-             */
-            if (s_is_modem_sleep_en == true){
-               s_is_modem_sleep_en = false;
-               esp_phy_rf_init(NULL,PHY_RF_CAL_NONE,NULL, PHY_MODEM_MODULE);
-            }
-        }
-        _lock_release(&s_modem_sleep_lock);
-        return ESP_OK;
-    }
-}
-
-
 // PHY init data handling functions
 #if CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
 #include "esp_partition.h"
@@ -638,7 +417,7 @@ static void __attribute((unused)) esp_phy_reduce_tx_power(esp_phy_init_data_t* i
 }
 #endif
 
-void esp_phy_load_cal_and_init(phy_rf_module_t module)
+void esp_phy_load_cal_and_init(void)
 {
 #if CONFIG_IDF_TARGET_ESP32
     char * phy_version = get_phy_version_str();
@@ -694,15 +473,19 @@ void esp_phy_load_cal_and_init(phy_rf_module_t module)
 
     esp_efuse_mac_get_default(sta_mac);
     memcpy(cal_data->mac, sta_mac, 6);
-    esp_phy_rf_init(init_data, calibration_mode, cal_data, module);
+    esp_err_t ret = register_chipv7_phy(init_data, cal_data, calibration_mode);
+    if (ret == ESP_CAL_DATA_CHECK_FAIL) {
+        ESP_LOGW(TAG, "saving new calibration data because of checksum failure, mode(%d)", calibration_mode);
+    }
 
-    if (calibration_mode != PHY_RF_CAL_NONE && err != ESP_OK) {
+    if ((calibration_mode != PHY_RF_CAL_NONE && err != ESP_OK) ||
+            (calibration_mode != PHY_RF_CAL_FULL && ret == ESP_CAL_DATA_CHECK_FAIL)) {
         err = esp_phy_store_cal_data_to_nvs(cal_data);
     } else {
         err = ESP_OK;
     }
 #else
-    esp_phy_rf_init(init_data, PHY_RF_CAL_FULL, cal_data, module);
+    register_chipv7_phy(init_data, cal_data, PHY_RF_CAL_FULL);
 #endif
 
 #if CONFIG_ESP32_REDUCE_PHY_TX_POWER

+ 2 - 5
components/esp_wifi/test/test_phy_rtc.c

@@ -45,10 +45,7 @@ static void test_phy_rtc_init(void)
     }
     TEST_ESP_OK(ret);
 
-#ifdef SOC_BT_SUPPORTED
-    esp_phy_load_cal_and_init(PHY_BT_MODULE);
-#endif
-    esp_phy_load_cal_and_init(PHY_WIFI_MODULE);
+    esp_phy_enable();
 
     //must run here, not blocking in above code
     TEST_ASSERT(1);
@@ -100,4 +97,4 @@ TEST_CASE("Test PHY/RTC functions called when cache is disabled", "[phy_rtc][cac
     vSemaphoreDelete(semphr_done);
 }
 
-#endif
+#endif

+ 4 - 0
components/soc/esp32/include/soc/soc_caps.h

@@ -10,3 +10,7 @@
 #define SOC_BT_SUPPORTED 1
 #define SOC_SDIO_SLAVE_SUPPORTED    1
 #define SOC_CAN_SUPPORTED 1
+
+/*--------------- PHY REGISTER AND MEMORY SIZE CAPS --------------------------*/
+#define SOC_PHY_DIG_REGS_MEM_SIZE       (21*4)
+