]> granicus.if.org Git - esp-idf/commitdiff
disable PHY and RF when stop WiFi and disable BT
authorXiaXiaotian <xiaxiaotian@espressif.com>
Thu, 16 Feb 2017 11:05:07 +0000 (19:05 +0800)
committerXiaXiaotian <xiaxiaotian@espressif.com>
Fri, 17 Feb 2017 02:24:54 +0000 (10:24 +0800)
1. Add disable PHY and RF when WiFi and BT are both disabled(including call sniffer disable API).

2. Do not init PHY and RF when cpu start. Init PHY and RF when call Wifi or BT start APIs(including sniffer enable API).

3. Add a temporary lib: librtc_clk.a and will delete it when CPU frequency switching function is done.

4. Add an function to get OS tick rate.

5. Do not put the whole pp.a in iram0, only put lmac.o, ieee80211_misc.o, ets_time.o and wdev.o in iram0.

13 files changed:
components/bootloader/src/main/component.mk
components/bt/bluedroid/api/esp_bt_main.c
components/bt/bt.c
components/esp32/Kconfig
components/esp32/component.mk
components/esp32/cpu_start.c
components/esp32/include/esp_phy_init.h
components/esp32/ld/esp32.common.ld
components/esp32/lib
components/esp32/phy_init.c
components/esp32/rtc.h
components/freertos/include/freertos/portable.h
components/freertos/port.c

index 73cd9287dff70e005f12b9777e767e482e18772c..2069665d1a80242ec82d725fca9f35477dcbb1fe 100644 (file)
@@ -18,6 +18,6 @@ ifdef IS_BOOTLOADER_BUILD
 # following lines are a workaround to link librtc into the
 # bootloader, until clock setting code is in a source-based esp-idf
 # component. See also rtc_printf() in bootloader_start.c
-COMPONENT_ADD_LDFLAGS += -L $(IDF_PATH)/components/esp32/lib/ -lrtc
+COMPONENT_ADD_LDFLAGS += -L $(IDF_PATH)/components/esp32/lib/ -lrtc_clk -lrtc
 COMPONENT_EXTRA_INCLUDES += $(IDF_PATH)/components/esp32/
 endif
index c9fe4fc060e97a96c99526a9d9ad572825d33835..f96cae1b3bfa6b50b6400e5cd5b89e3d33abf3c0 100644 (file)
@@ -21,6 +21,8 @@
 static bool esp_already_enable = false;
 static bool esp_already_init = false;
 
+extern esp_err_t esp_phy_deinit(void);
+
 esp_bluedroid_status_t esp_bluedroid_get_status(void)
 {
     if (esp_already_init) {
@@ -164,6 +166,8 @@ esp_err_t esp_bluedroid_deinit(void)
 
     esp_already_init = false;
 
+    esp_phy_deinit();
+
     return ESP_OK;
 }
 
index 5bad45ea2c2a0c7a90e81cd21ff06329264cf986..4378b4da6ce281d25a3f5298f2e816cbbd2a0249 100644 (file)
@@ -31,6 +31,8 @@
 
 #if CONFIG_BT_ENABLED
 
+extern void do_phy_init(void);
+
 /* not for user call, so don't put to include file */
 extern void btdm_osi_funcs_register(void *osi_funcs);
 extern void btdm_controller_init(void);
@@ -145,6 +147,9 @@ void esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback)
 static void bt_controller_task(void *pvParam)
 {
     btdm_osi_funcs_register(&osi_funcs);
+
+    do_phy_init();
+
     btdm_controller_init();
 }
 
index db9bb2539fd71e27060e1c77fc6023fde09ccea2..5338e5f459c9fd3875474aedfeec2c2dbdf8b2ad 100644 (file)
@@ -508,21 +508,6 @@ config PHY_ENABLED
 menu PHY
        visible if PHY_ENABLED
 
-config ESP32_PHY_AUTO_INIT
-    bool "Initialize PHY in startup code"
-    depends on PHY_ENABLED
-    default y
-    help
-        If enabled, PHY will be initialized in startup code, before
-        app_main function runs.
-        If this is undesired, disable this option and call esp_phy_init
-        from the application before enabling WiFi or BT.
-
-        If this option is enabled, startup code will also initialize
-        NVS prior to initializing PHY.
-
-        If unsure, choose 'y'.
-
 config ESP32_PHY_INIT_DATA_IN_PARTITION
     bool "Use a partition to store PHY init data"
     depends on PHY_ENABLED
index a8109a0f5ee8e1ceee17c8c8c840aea6dd4cf3ca..e7a88571ff8b2848d131077d463a1f31f7293f79 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 COMPONENT_SRCDIRS := . hwcrypto
-LIBS := core rtc
+LIBS := core rtc rtc_clk
 ifdef CONFIG_PHY_ENABLED # BT || WIFI
 LIBS += phy coexist
 endif
index 5278f9b166a2f54e9ef0e1c89c17303740ccade3..bc7ed6a71cab045c537b8b93aa84fab664737007 100644 (file)
@@ -73,9 +73,6 @@ static bool app_cpu_started = false;
 static void do_global_ctors(void);
 static void main_task(void* args);
 extern void app_main(void);
-#if CONFIG_ESP32_PHY_AUTO_INIT
-static void do_phy_init();
-#endif
 
 extern int _bss_start;
 extern int _bss_end;
@@ -214,11 +211,6 @@ void start_cpu0_default(void)
     esp_core_dump_init();
 #endif
 
-#if CONFIG_ESP32_PHY_AUTO_INIT
-    nvs_flash_init();
-    do_phy_init();
-#endif
-
 #if CONFIG_SW_COEXIST_ENABLE
     if (coex_init() == ESP_OK) {
         coexist_set_enable(true);
@@ -268,39 +260,3 @@ static void main_task(void* args)
     vTaskDelete(NULL);
 }
 
-#if CONFIG_ESP32_PHY_AUTO_INIT
-static void do_phy_init()
-{
-    esp_phy_calibration_mode_t calibration_mode = PHY_RF_CAL_PARTIAL;
-    if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) {
-        calibration_mode = PHY_RF_CAL_NONE;
-    }
-    const esp_phy_init_data_t* init_data = esp_phy_get_init_data();
-    if (init_data == NULL) {
-        ESP_LOGE(TAG, "failed to obtain PHY init data");
-        abort();
-    }
-    esp_phy_calibration_data_t* cal_data =
-            (esp_phy_calibration_data_t*) calloc(sizeof(esp_phy_calibration_data_t), 1);
-    if (cal_data == NULL) {
-        ESP_LOGE(TAG, "failed to allocate memory for RF calibration data");
-        abort();
-    }
-    esp_err_t err = esp_phy_load_cal_data_from_nvs(cal_data);
-    if (err != ESP_OK) {
-        ESP_LOGW(TAG, "failed to load RF calibration data, falling back to full calibration");
-        calibration_mode = PHY_RF_CAL_FULL;
-    }
-
-    esp_phy_init(init_data, calibration_mode, cal_data);
-
-    if (calibration_mode != PHY_RF_CAL_NONE && err != ESP_OK) {
-        err = esp_phy_store_cal_data_to_nvs(cal_data);
-    } else {
-        err = ESP_OK;
-    }
-    esp_phy_release_init_data(init_data);
-    free(cal_data); // PHY maintains a copy of calibration data, so we can free this
-}
-#endif //CONFIG_ESP32_PHY_AUTO_INIT
-
index e669a44151d980da9287ac5203af5b97e8482538..55ce145e9d6f9cd300241274060782729a1106a5 100644 (file)
@@ -223,25 +223,31 @@ esp_err_t esp_phy_store_cal_data_to_nvs(const esp_phy_calibration_data_t* cal_da
  * @brief Initialize PHY module
  *
  * PHY module should be initialized in order to use WiFi or BT.
- * If "Initialize PHY in startup code" option is set in menuconfig,
- * this function will be called automatically before app_main is called,
- * using parameters obtained from esp_phy_get_init_data.
- *
- * Applications which don't need to enable PHY on every start up should
- * disable this menuconfig option and call esp_phy_init before calling
- * esp_wifi_init or esp_bt_controller_init. See do_phy_init function in
- * cpu_start.c for an example of using this function.
+ * Now PHY initializing 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
+ * @param WiFi is_Waked up from sleep or not
  * @return ESP_OK on success.
+ * @return ESP_FAIL on fail.
  */
-esp_err_t esp_phy_init(const esp_phy_init_data_t* init_data,
-        esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data);
+esp_err_t esp_phy_init(const void* init_data,
+        int mode, void* calibration_data, bool is_sleep);
 
+/**
+ * @brief De-initialize PHY module
+ *
+ * PHY module should be de-initialized in order to shutdown WiFi or BT.
+ * Now PHY de-initializing 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_deinit(void);
 
 #ifdef __cplusplus
 }
index ac04c07d57b2634d7c7912c2eabefd42c6661cf1..43775a6c49ccbfe6d4fdcc99409db0746f860523 100644 (file)
@@ -83,7 +83,11 @@ SECTIONS
     *libesp32.a:core_dump.o(.literal .text .literal.* .text.*)
     *libphy.a:(.literal .text .literal.* .text.*)
     *librtc.a:(.literal .text .literal.* .text.*)
-    *libpp.a:(.literal .text .literal.* .text.*)
+    *librtc_clk.a:(.literal .text .literal.* .text.*)
+    *libpp.a:lmac.o(.literal .text .literal.* .text.*)
+    *libpp.a:wdev.o(.literal .text .literal.* .text.*)
+    *libcore.a:ets_timer.o(.literal .text .literal.* .text.*)
+    *libnet80211.a:ieee80211_misc.o(.literal .text .literal.* .text.*)
     *libhal.a:(.literal .text .literal.* .text.*)
     *libcoexist.a:(.literal .text .literal.* .text.*)
     _iram_text_end = ABSOLUTE(.);
index 1627461bf2fc2ec8a090b30cddae2118d542c454..c0d94203602f7dd3d755bb1180a1640c3715c3ae 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 1627461bf2fc2ec8a090b30cddae2118d542c454
+Subproject commit c0d94203602f7dd3d755bb1180a1640c3715c3ae
index 5b130eaf7aa4cf7c8e06efe6099d5a2826a6c385..6026da6acd5bc3dc87a2b407177a3561561bf627 100644 (file)
 #include <string.h>
 #include <stdbool.h>
 
+#include "freertos/FreeRTOS.h"
+#include "freertos/semphr.h"
+#include "freertos/xtensa_api.h"
+#include "freertos/task.h"
+#include "freertos/ringbuf.h"
+
 #include "rom/ets_sys.h"
+#include "rom/rtc.h"
 #include "soc/dport_reg.h"
 
 #include "esp_err.h"
 #include "esp_system.h"
 #include "esp_log.h"
 #include "nvs.h"
+#include "nvs_flash.h"
 #include "sdkconfig.h"
 
 #ifdef CONFIG_PHY_ENABLED
 #include "phy.h"
 #include "phy_init_data.h"
+#include "rtc.h"
 
 static const char* TAG = "phy_init";
 
+/* Count value to indicate if there is peripheral that has initialized PHY and RF */
+int g_phy_rf_init_count = 0;
+
+static xSemaphoreHandle g_phy_rf_init_mux = NULL;
+
+esp_err_t esp_phy_init(const void* init_data,
+        int mode, void* calibration_data, bool is_sleep)
+{
+    esp_phy_init_data_t* data = (esp_phy_init_data_t *)init_data;
+    esp_phy_calibration_mode_t cal_mode = (esp_phy_calibration_mode_t)mode;
+    esp_phy_calibration_data_t* cal_data = (esp_phy_calibration_data_t *)calibration_data;
+
+    assert((g_phy_rf_init_count <= 1) && (g_phy_rf_init_count >= 0));
+
+    if (g_phy_rf_init_mux == NULL) {
+        g_phy_rf_init_mux = xSemaphoreCreateMutex();
+        if (g_phy_rf_init_mux == NULL) {
+            ESP_LOGE(TAG, "Create PHY RF mutex fail");
+            return ESP_FAIL;
+        }
+    }
+
+    xSemaphoreTake(g_phy_rf_init_mux, portMAX_DELAY);
+    if (g_phy_rf_init_count == 0) {
+       if (is_sleep == false) {
+           REG_SET_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST);
+           REG_CLR_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST);
+       }
+       // Enable WiFi peripheral clock
+       SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf);
+        ESP_LOGV(TAG, "register_chipv7_phy, init_data=%p, cal_data=%p, mode=%d",
+                init_data, calibration_data, mode);
+        phy_set_wifi_mode_only(0);
+        register_chipv7_phy(data, cal_data, cal_mode);
+        coex_bt_high_prio();
+    }
+    g_phy_rf_init_count++;
+    xSemaphoreGive(g_phy_rf_init_mux);
+    return ESP_OK;
+}
 
-esp_err_t esp_phy_init(const esp_phy_init_data_t* init_data,
-        esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data)
+esp_err_t esp_phy_deinit(void)
 {
-    assert(init_data);
-    assert(calibration_data);
-
-    REG_SET_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST);
-    REG_CLR_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST);
-    // Enable WiFi peripheral clock
-    SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf);
-    ESP_LOGV(TAG, "register_chipv7_phy, init_data=%p, cal_data=%p, mode=%d",
-            init_data, calibration_data, mode);
-    phy_set_wifi_mode_only(0);
-    register_chipv7_phy(init_data, calibration_data, mode);
-    coex_bt_high_prio();
+    assert((g_phy_rf_init_count <= 2) && (g_phy_rf_init_count >= 1));
+
+    xSemaphoreTake(g_phy_rf_init_mux, portMAX_DELAY);
+    if (g_phy_rf_init_count == 1) {
+       // Disable PHY and RF. This is a teporary function.
+        pm_close_rf();
+       // Disable WiFi peripheral clock
+       CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf);
+    }
+    g_phy_rf_init_count--;
+    xSemaphoreGive(g_phy_rf_init_mux);
     return ESP_OK;
 }
 
@@ -220,4 +267,39 @@ static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle,
     return err;
 }
 
+void do_phy_init(void)
+{
+    esp_phy_calibration_mode_t calibration_mode = PHY_RF_CAL_PARTIAL;
+    nvs_flash_init();
+    if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) {
+        calibration_mode = PHY_RF_CAL_NONE;
+    }
+    const esp_phy_init_data_t* init_data = esp_phy_get_init_data();
+    if (init_data == NULL) {
+        ESP_LOGE(TAG, "failed to obtain PHY init data");
+        abort();
+    }
+    esp_phy_calibration_data_t* cal_data =
+            (esp_phy_calibration_data_t*) calloc(sizeof(esp_phy_calibration_data_t), 1);
+    if (cal_data == NULL) {
+        ESP_LOGE(TAG, "failed to allocate memory for RF calibration data");
+        abort();
+    }
+    esp_err_t err = esp_phy_load_cal_data_from_nvs(cal_data);
+    if (err != ESP_OK) {
+        ESP_LOGW(TAG, "failed to load RF calibration data, falling back to full calibration");
+        calibration_mode = PHY_RF_CAL_FULL;
+    }
+
+    esp_phy_init(init_data, calibration_mode, cal_data, false);
+
+    if (calibration_mode != PHY_RF_CAL_NONE) {
+        err = esp_phy_store_cal_data_to_nvs(cal_data);
+    } else {
+        err = ESP_OK;
+    }
+    esp_phy_release_init_data(init_data);
+    free(cal_data); // PHY maintains a copy of calibration data, so we can free this
+}
+
 #endif // CONFIG_PHY_ENABLED
index e1cf33522d1ca2a9920f471603a2cf8b6f6ce1cd..48272259fa53da4336513c7d86002bcf032d5724 100644 (file)
@@ -135,6 +135,10 @@ void rtc_slp_prep_lite(uint32_t deep_slp, uint32_t cpu_lp_mode);
  */
 uint32_t rtc_sleep(uint32_t cycles_h, uint32_t cycles_l, uint32_t wakeup_opt, uint32_t reject_opt);
 
+/**
+ * @brief Shutdown PHY and RF. This is a temporary function.
+ */
+void pm_close_rf(void);
 
 #ifdef __cplusplus
 }
index b05755da40c85bf821e4bd90568566229f5241e0..0c10ac36eb3116406bb710285aa598d1c2cc7f12 100644 (file)
@@ -216,6 +216,9 @@ static inline uint32_t xPortGetCoreID() {
     return id;
 }
 
+/* Get tick rate per second */
+uint32_t xPortGetTickRateHz(void);
+
 #ifdef __cplusplus
 }
 #endif
index c778950d6d4e5992e0227403d9d5ff4d0c8c6318..ba4da3e284eb7c9a59da41c6d268c30d501a9b5b 100644 (file)
@@ -406,7 +406,9 @@ void vPortSetStackWatchpoint( void* pxStackStart ) {
        esp_set_watchpoint(1, (char*)addr, 32, ESP_WATCHPOINT_STORE);
 }
 
-
+uint32_t xPortGetTickRateHz(void) {
+    return (uint32_t)configTICK_RATE_HZ;
+}