From eb14284c92a79ccbe41647600c565f162a1b78fb Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Thu, 16 Feb 2017 19:05:07 +0800 Subject: [PATCH 1/7] disable PHY and RF when stop WiFi and disable BT 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. --- components/bootloader/src/main/component.mk | 2 +- components/bt/bluedroid/api/esp_bt_main.c | 4 + components/bt/bt.c | 5 + components/esp32/Kconfig | 15 --- components/esp32/component.mk | 2 +- components/esp32/cpu_start.c | 44 ------- components/esp32/include/esp_phy_init.h | 28 +++-- components/esp32/ld/esp32.common.ld | 6 +- components/esp32/lib | 2 +- components/esp32/phy_init.c | 108 +++++++++++++++--- components/esp32/rtc.h | 4 + .../freertos/include/freertos/portable.h | 3 + components/freertos/port.c | 4 +- 13 files changed, 139 insertions(+), 88 deletions(-) diff --git a/components/bootloader/src/main/component.mk b/components/bootloader/src/main/component.mk index 73cd9287df..2069665d1a 100644 --- a/components/bootloader/src/main/component.mk +++ b/components/bootloader/src/main/component.mk @@ -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 diff --git a/components/bt/bluedroid/api/esp_bt_main.c b/components/bt/bluedroid/api/esp_bt_main.c index c9fe4fc060..f96cae1b3b 100644 --- a/components/bt/bluedroid/api/esp_bt_main.c +++ b/components/bt/bluedroid/api/esp_bt_main.c @@ -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; } diff --git a/components/bt/bt.c b/components/bt/bt.c index 5bad45ea2c..4378b4da6c 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -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(); } diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index db9bb2539f..5338e5f459 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -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 diff --git a/components/esp32/component.mk b/components/esp32/component.mk index a8109a0f5e..e7a88571ff 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -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 diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 5278f9b166..bc7ed6a71c 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -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 - diff --git a/components/esp32/include/esp_phy_init.h b/components/esp32/include/esp_phy_init.h index e669a44151..55ce145e9d 100644 --- a/components/esp32/include/esp_phy_init.h +++ b/components/esp32/include/esp_phy_init.h @@ -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 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_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); #ifdef __cplusplus } diff --git a/components/esp32/ld/esp32.common.ld b/components/esp32/ld/esp32.common.ld index ac04c07d57..43775a6c49 100644 --- a/components/esp32/ld/esp32.common.ld +++ b/components/esp32/ld/esp32.common.ld @@ -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(.); diff --git a/components/esp32/lib b/components/esp32/lib index 1627461bf2..c0d9420360 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 1627461bf2fc2ec8a090b30cddae2118d542c454 +Subproject commit c0d94203602f7dd3d755bb1180a1640c3715c3ae diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index 5b130eaf7a..6026da6acd 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -17,7 +17,14 @@ #include #include +#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" @@ -25,30 +32,70 @@ #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; -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) +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) { - assert(init_data); - assert(calibration_data); + 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; - 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 <= 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_deinit(void) +{ + 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 diff --git a/components/esp32/rtc.h b/components/esp32/rtc.h index e1cf33522d..48272259fa 100644 --- a/components/esp32/rtc.h +++ b/components/esp32/rtc.h @@ -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 } diff --git a/components/freertos/include/freertos/portable.h b/components/freertos/include/freertos/portable.h index b05755da40..0c10ac36eb 100644 --- a/components/freertos/include/freertos/portable.h +++ b/components/freertos/include/freertos/portable.h @@ -216,6 +216,9 @@ static inline uint32_t xPortGetCoreID() { return id; } +/* Get tick rate per second */ +uint32_t xPortGetTickRateHz(void); + #ifdef __cplusplus } #endif diff --git a/components/freertos/port.c b/components/freertos/port.c index c778950d6d..ba4da3e284 100644 --- a/components/freertos/port.c +++ b/components/freertos/port.c @@ -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; +} From cd13c9e95d24724aac77a40270546e1c8fd04822 Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Thu, 16 Feb 2017 22:06:02 +0800 Subject: [PATCH 2/7] disable phy and rf 1. add a macro in menuconfig for users to choose whether store phy calibration data into NVS or not. 2. rename some disable phy and rf APIs so that existing code which calls old APIS will fail to compile. --- components/bt/bluedroid/api/esp_bt_main.c | 5 +- components/bt/bt.c | 5 +- components/esp32/Kconfig | 10 +++ components/esp32/include/esp_phy_init.h | 25 +++++--- components/esp32/lib | 2 +- components/esp32/phy_init.c | 78 ++++++++++------------- components/freertos/port.c | 2 +- 7 files changed, 64 insertions(+), 63 deletions(-) diff --git a/components/bt/bluedroid/api/esp_bt_main.c b/components/bt/bluedroid/api/esp_bt_main.c index f96cae1b3b..612a9e020a 100644 --- a/components/bt/bluedroid/api/esp_bt_main.c +++ b/components/bt/bluedroid/api/esp_bt_main.c @@ -17,12 +17,11 @@ #include "btc_task.h" #include "btc_main.h" #include "future.h" +#include "esp_phy_init.h" 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) { @@ -166,7 +165,7 @@ esp_err_t esp_bluedroid_deinit(void) esp_already_init = false; - esp_phy_deinit(); + esp_phy_rf_deinit(); return ESP_OK; } diff --git a/components/bt/bt.c b/components/bt/bt.c index 4378b4da6c..2390456afb 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -27,12 +27,11 @@ #include "esp_task.h" #include "esp_intr.h" #include "esp_attr.h" +#include "esp_phy_init.h" #include "bt.h" #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); @@ -148,7 +147,7 @@ static void bt_controller_task(void *pvParam) { btdm_osi_funcs_register(&osi_funcs); - do_phy_init(); + esp_phy_load_cal_and_init(); btdm_controller_init(); } diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 5338e5f459..d3441fa017 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -507,6 +507,16 @@ config PHY_ENABLED menu PHY visible if PHY_ENABLED + +config ESP32_STORE_PHY_CAL_DATA_INTO_NVS + bool "Store PHY calibration data into NVS" + depends on PHY_ENABLED + default y + help + If this option is enabled, PHY initialization will also calibrate PHY data, and + store it into NVS. + + If unsure, choose 'y'. config ESP32_PHY_INIT_DATA_IN_PARTITION bool "Use a partition to store PHY init data" diff --git a/components/esp32/include/esp_phy_init.h b/components/esp32/include/esp_phy_init.h index 55ce145e9d..5ad06ee896 100644 --- a/components/esp32/include/esp_phy_init.h +++ b/components/esp32/include/esp_phy_init.h @@ -192,7 +192,7 @@ void esp_phy_release_init_data(const esp_phy_init_data_t* data); * mechanism for loading calibration data, disable * "Initialize PHY in startup code" option in menuconfig and call esp_phy_init * function from the application. For an example usage of esp_phy_init and - * this function, see do_phy_init function in cpu_start.c + * this function, see esp_phy_store_cal_data_to_nvs function in cpu_start.c * * @param out_cal_data pointer to calibration data structure to be filled with * loaded data. @@ -220,10 +220,10 @@ esp_err_t esp_phy_load_cal_data_from_nvs(esp_phy_calibration_data_t* out_cal_dat esp_err_t esp_phy_store_cal_data_to_nvs(const esp_phy_calibration_data_t* cal_data); /** - * @brief Initialize PHY module + * @brief Initialize PHY and RF module * - * PHY module should be initialized in order to use WiFi or BT. - * Now PHY initializing job is done automatically when start WiFi or BT. Users should not + * 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 * call this API in their application. * * @param init_data PHY parameters. Default set of parameters can @@ -231,23 +231,28 @@ esp_err_t esp_phy_store_cal_data_to_nvs(const esp_phy_calibration_data_t* cal_da * function. * @param mode Calibration mode (Full, partial, or no calibration) * @param[inout] calibration_data - * @param WiFi is_Waked up from sleep or not + * @param is_sleep WiFi wakes up from sleep or not * @return ESP_OK on success. * @return ESP_FAIL on fail. */ -esp_err_t esp_phy_init(const void* init_data, - int mode, void* calibration_data, bool is_sleep); +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, bool is_sleep); /** - * @brief De-initialize PHY module + * @brief De-initialize PHY and RF 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 + * Now PHY and RF 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); +esp_err_t esp_phy_rf_deinit(void); + +/** + * @brief Load calibration data from NVS and initialize PHY and RF module + */ +void esp_phy_load_cal_and_init(void); #ifdef __cplusplus } diff --git a/components/esp32/lib b/components/esp32/lib index c0d9420360..bc16e8c074 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit c0d94203602f7dd3d755bb1180a1640c3715c3ae +Subproject commit bc16e8c0749adefcd5bf44c9024849a504b8e839 diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index 6026da6acd..1c67a404ab 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -17,11 +17,7 @@ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "freertos/xtensa_api.h" -#include "freertos/task.h" -#include "freertos/ringbuf.h" +#include #include "rom/ets_sys.h" #include "rom/rtc.h" @@ -43,59 +39,47 @@ 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 int s_phy_rf_init_count = 0; -static xSemaphoreHandle g_phy_rf_init_mux = NULL; +static _lock_t s_phy_rf_init_lock; -esp_err_t esp_phy_init(const void* init_data, - int mode, void* calibration_data, bool is_sleep) +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, 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((s_phy_rf_init_count <= 1) && (s_phy_rf_init_count >= 0)); - 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; + _lock_acquire(&s_phy_rf_init_lock); + if (s_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); } - } - - 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); + // 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); + register_chipv7_phy(init_data, calibration_data, mode); coex_bt_high_prio(); } - g_phy_rf_init_count++; - xSemaphoreGive(g_phy_rf_init_mux); + s_phy_rf_init_count++; + _lock_release(&s_phy_rf_init_lock); return ESP_OK; } -esp_err_t esp_phy_deinit(void) +esp_err_t esp_phy_rf_deinit(void) { - assert((g_phy_rf_init_count <= 2) && (g_phy_rf_init_count >= 1)); + assert((s_phy_rf_init_count <= 2) && (s_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. + _lock_acquire(&s_phy_rf_init_lock); + if (s_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); + // 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); + s_phy_rf_init_count--; + _lock_release(&s_phy_rf_init_lock); return ESP_OK; } @@ -267,10 +251,11 @@ static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle, return err; } -void do_phy_init(void) +void esp_phy_load_cal_and_init(void) { - esp_phy_calibration_mode_t calibration_mode = PHY_RF_CAL_PARTIAL; +#ifdef CONFIG_ESP32_STORE_PHY_CAL_DATA_INTO_NVS nvs_flash_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; } @@ -291,15 +276,18 @@ void do_phy_init(void) calibration_mode = PHY_RF_CAL_FULL; } - esp_phy_init(init_data, calibration_mode, cal_data, false); + esp_phy_rf_init(init_data, calibration_mode, cal_data, false); - if (calibration_mode != PHY_RF_CAL_NONE) { + 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 +#else + esp_phy_rf_init(NULL, PHY_RF_CAL_NONE, NULL, false); +#endif } #endif // CONFIG_PHY_ENABLED diff --git a/components/freertos/port.c b/components/freertos/port.c index ba4da3e284..3c26edfabf 100644 --- a/components/freertos/port.c +++ b/components/freertos/port.c @@ -407,7 +407,7 @@ void vPortSetStackWatchpoint( void* pxStackStart ) { } uint32_t xPortGetTickRateHz(void) { - return (uint32_t)configTICK_RATE_HZ; + return (uint32_t)configTICK_RATE_HZ; } From 8f3d1d3184496f3ca9952fa762c0fd69bc027d33 Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Fri, 17 Feb 2017 15:29:11 +0800 Subject: [PATCH 3/7] fix compile error that if enable CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION compile fail --- components/esp32/include/esp_phy_init.h | 1 + 1 file changed, 1 insertion(+) diff --git a/components/esp32/include/esp_phy_init.h b/components/esp32/include/esp_phy_init.h index 5ad06ee896..9990957e2c 100644 --- a/components/esp32/include/esp_phy_init.h +++ b/components/esp32/include/esp_phy_init.h @@ -14,6 +14,7 @@ #pragma once #include +#include #include "esp_err.h" #ifdef __cplusplus From 4bd5b0c91af842a6a612e1c9e8d50edf6a7835cd Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Fri, 17 Feb 2017 19:24:58 +0800 Subject: [PATCH 4/7] component/bt : add bt enable/disable for power save 1. add new APIs bt controller enable/disab/deinit 2. make bt controller work need to call two APIs of esp_bt_controller_init and enable 3. modify phy init to make mac reset once --- components/bt/bluedroid/api/esp_bt_main.c | 3 - components/bt/bt.c | 62 ++++++++++++++++++- components/bt/include/bt.h | 35 ++++++++++- components/bt/lib | 2 +- components/esp32/phy_init.c | 8 ++- docs/api/bluetooth/controller_vhci.rst | 4 ++ examples/bluetooth/ble_adv/main/app_bt.c | 5 ++ examples/bluetooth/blufi/main/blufi_main.c | 6 ++ .../bluetooth/gatt_client/main/gattc_demo.c | 2 + .../bluetooth/gatt_server/main/gatts_demo.c | 5 ++ .../main/gatts_table_creat_demo.c | 30 +++++---- 11 files changed, 141 insertions(+), 21 deletions(-) diff --git a/components/bt/bluedroid/api/esp_bt_main.c b/components/bt/bluedroid/api/esp_bt_main.c index 612a9e020a..c9fe4fc060 100644 --- a/components/bt/bluedroid/api/esp_bt_main.c +++ b/components/bt/bluedroid/api/esp_bt_main.c @@ -17,7 +17,6 @@ #include "btc_task.h" #include "btc_main.h" #include "future.h" -#include "esp_phy_init.h" static bool esp_already_enable = false; static bool esp_already_init = false; @@ -165,8 +164,6 @@ esp_err_t esp_bluedroid_deinit(void) esp_already_init = false; - esp_phy_rf_deinit(); - return ESP_OK; } diff --git a/components/bt/bt.c b/components/bt/bt.c index 2390456afb..440c960e64 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -35,6 +35,10 @@ /* 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); +extern void btdm_controller_deinit(void); +extern int btdm_controller_enable(esp_bt_mode_t mode); +extern int btdm_controller_disable(esp_bt_mode_t mode); +extern void btdm_rf_bb_init(void); /* VHCI function interface */ typedef struct vhci_host_callback { @@ -71,6 +75,11 @@ struct osi_funcs_t { esp_err_t (* _read_efuse_mac)(uint8_t mac[6]); }; +/* Static variable declare */ +static bool btdm_bb_init_flag = false; + +static xTaskHandle btControllerTaskHandle; + static portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED; static void IRAM_ATTR interrupt_disable(void) @@ -147,16 +156,63 @@ static void bt_controller_task(void *pvParam) { btdm_osi_funcs_register(&osi_funcs); - esp_phy_load_cal_and_init(); - btdm_controller_init(); } +static bool bb_inited; void esp_bt_controller_init() { + bb_inited = false; xTaskCreatePinnedToCore(bt_controller_task, "btController", ESP_TASK_BT_CONTROLLER_STACK, NULL, - ESP_TASK_BT_CONTROLLER_PRIO, NULL, 0); + ESP_TASK_BT_CONTROLLER_PRIO, &btControllerTaskHandle, 0); +} + +void esp_bt_controller_deinit(void) +{ + vTaskDelete(btControllerTaskHandle); + bb_inited = false; +} + +esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) +{ + int ret; + + if (mode != ESP_BT_MODE_BTDM) { + return ESP_ERR_INVALID_ARG; + } + + esp_phy_load_cal_and_init(); + + if (btdm_bb_init_flag == false) { + btdm_bb_init_flag = true; + btdm_rf_bb_init(); /* only initialise once */ + } + + ret = btdm_controller_enable(mode); + if (ret) { + return ESP_ERR_INVALID_STATE; + } + + return ESP_OK; +} + +esp_err_t esp_bt_controller_disable(esp_bt_mode_t mode) +{ + int ret; + + if (mode != ESP_BT_MODE_BTDM) { + return ESP_ERR_INVALID_ARG; + } + + ret = btdm_controller_disable(mode); + if (ret) { + return ESP_ERR_INVALID_STATE; + } + + esp_phy_rf_deinit(); + + return ESP_OK; } #endif diff --git a/components/bt/include/bt.h b/components/bt/include/bt.h index 926ecfadcd..91617a28f4 100644 --- a/components/bt/include/bt.h +++ b/components/bt/include/bt.h @@ -23,14 +23,47 @@ extern "C" { #endif +/** + * @brief Bluetooth mode for controller enable/disable + */ +typedef enum { + ESP_BT_MODE_ILDE = 0x00, /*!< Bluetooth is not run */ + ESP_BT_MODE_BLE = 0x01, /*!< Run BLE mode */ + ESP_BT_MODE_CLASSIC_BT = 0x02, /*!< Run Classic BT mode */ + ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */ +} esp_bt_mode_t; /** - * @brief Initialize BT controller + * @brief Initialize BT controller to allocate task and other resource. * * This function should be called only once, before any other BT functions are called. */ void esp_bt_controller_init(void); +/** + * @brief De-initialize BT controller to free resource and delete task. + * + * This function should be called only once, after any other BT functions are called. + * This function is not whole completed, esp_bt_controller_init cannot called after this function. + */ +void esp_bt_controller_deinit(void); + +/** + * @brief Enable BT controller + * @param mode : the mode(BLE/BT/BTDM) to enable. + * Now only support BTDM. + */ +esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode); + +/** + * @brief Disable BT controller + * @param mode : the mode(BLE/BT/BTDM) to disable. + * Now only support BTDM. + */ +esp_err_t esp_bt_controller_disable(esp_bt_mode_t mode); + + + /** @brief esp_vhci_host_callback * used for vhci call host function to notify what host need to do */ diff --git a/components/bt/lib b/components/bt/lib index 9c1eea6bb0..69616af765 160000 --- a/components/bt/lib +++ b/components/bt/lib @@ -1 +1 @@ -Subproject commit 9c1eea6bb03adc3b3847fff79c3f017652840a46 +Subproject commit 69616af7653f4de6e3b78f475dc10e73f0a20ece diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index 1c67a404ab..340bd7ee72 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -40,6 +40,7 @@ static const char* TAG = "phy_init"; /* Count value to indicate if there is peripheral that has initialized PHY and RF */ static int s_phy_rf_init_count = 0; +static bool s_mac_rst_flag = false; static _lock_t s_phy_rf_init_lock; @@ -51,8 +52,11 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, _lock_acquire(&s_phy_rf_init_lock); if (s_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); + if (s_mac_rst_flag == false) { + s_mac_rst_flag = true; + 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); diff --git a/docs/api/bluetooth/controller_vhci.rst b/docs/api/bluetooth/controller_vhci.rst index 35248cbb1e..108a9f678d 100644 --- a/docs/api/bluetooth/controller_vhci.rst +++ b/docs/api/bluetooth/controller_vhci.rst @@ -33,6 +33,7 @@ Type Definitions Enumerations ^^^^^^^^^^^^ +.. doxygenenum:: esp_bt_mode_t Structures ^^^^^^^^^^ @@ -45,6 +46,9 @@ Functions ^^^^^^^^^ .. doxygenfunction:: esp_bt_controller_init +.. doxygenfunction:: esp_bt_controller_deinit +.. doxygenfunction:: esp_bt_controller_enable +.. doxygenfunction:: esp_bt_controller_disable .. doxygenfunction:: esp_vhci_host_check_send_available .. doxygenfunction:: esp_vhci_host_send_packet .. doxygenfunction:: esp_vhci_host_register_callback diff --git a/examples/bluetooth/ble_adv/main/app_bt.c b/examples/bluetooth/ble_adv/main/app_bt.c index f0780c950c..67ab2c8fe0 100644 --- a/examples/bluetooth/ble_adv/main/app_bt.c +++ b/examples/bluetooth/ble_adv/main/app_bt.c @@ -215,6 +215,11 @@ void bleAdvtTask(void *pvParameters) void app_main() { esp_bt_controller_init(); + + if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK) { + return; + } + xTaskCreatePinnedToCore(&bleAdvtTask, "bleAdvtTask", 2048, NULL, 5, NULL, 0); } diff --git a/examples/bluetooth/blufi/main/blufi_main.c b/examples/bluetooth/blufi/main/blufi_main.c index a95db66eb5..b46ffb4648 100644 --- a/examples/bluetooth/blufi/main/blufi_main.c +++ b/examples/bluetooth/blufi/main/blufi_main.c @@ -317,6 +317,12 @@ void app_main() esp_bt_controller_init(); + ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); + if (ret) { + BLUFI_ERROR("%s enable bt controller failed\n", __func__); + return; + } + ret = esp_bluedroid_init(); if (ret) { BLUFI_ERROR("%s init bluedroid failed\n", __func__); diff --git a/examples/bluetooth/gatt_client/main/gattc_demo.c b/examples/bluetooth/gatt_client/main/gattc_demo.c index e6ee867293..4a2fa0051d 100644 --- a/examples/bluetooth/gatt_client/main/gattc_demo.c +++ b/examples/bluetooth/gatt_client/main/gattc_demo.c @@ -397,6 +397,8 @@ void gattc_client_test(void) void app_main() { esp_bt_controller_init(); + esp_bt_controller_enable(ESP_BT_MODE_BTDM); + gattc_client_test(); } diff --git a/examples/bluetooth/gatt_server/main/gatts_demo.c b/examples/bluetooth/gatt_server/main/gatts_demo.c index 0afa1630ba..acbf9195a0 100644 --- a/examples/bluetooth/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/gatt_server/main/gatts_demo.c @@ -394,6 +394,11 @@ void app_main() esp_bt_controller_init(); + ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); + if (ret) { + ESP_LOGE(GATTS_TAG, "%s enable controller failed\n", __func__); + return; + } ret = esp_bluedroid_init(); if (ret) { ESP_LOGE(GATTS_TAG, "%s init bluetooth failed\n", __func__); diff --git a/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c b/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c index 024362c5b7..71baf1842c 100644 --- a/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c +++ b/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c @@ -29,6 +29,7 @@ #include "esp_bt_main.h" #include "gatts_table_creat_demo.h" +#define GATTS_TABLE_TAG "GATTS_TABLE_DEMO" #define HEART_PROFILE_NUM 1 #define HEART_PROFILE_APP_IDX 0 @@ -196,7 +197,7 @@ static const esp_gatts_attr_db_t heart_rate_gatt_db[HRS_IDX_NB] = static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { - LOG_ERROR("GAP_EVT, event %d\n", event); + ESP_LOGE(GATTS_TABLE_TAG, "GAP_EVT, event %d\n", event); switch (event) { case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: @@ -210,15 +211,15 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { - LOG_ERROR("event = %x\n",event); + ESP_LOGE(GATTS_TABLE_TAG, "event = %x\n",event); switch (event) { case ESP_GATTS_REG_EVT: - LOG_INFO("%s %d\n", __func__, __LINE__); + ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); esp_ble_gap_set_device_name(SAMPLE_DEVICE_NAME); - LOG_INFO("%s %d\n", __func__, __LINE__); + ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); esp_ble_gap_config_adv_data(&heart_rate_adv_config); - LOG_INFO("%s %d\n", __func__, __LINE__); + ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); esp_ble_gatts_create_attr_tab(heart_rate_gatt_db, gatts_if, HRS_IDX_NB, HEART_RATE_SVC_INST_ID); break; @@ -256,7 +257,7 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, case ESP_GATTS_CONGEST_EVT: break; case ESP_GATTS_CREAT_ATTR_TAB_EVT:{ - LOG_ERROR("The number handle =%x\n",param->add_attr_tab.num_handle); + ESP_LOGE(GATTS_TABLE_TAG, "The number handle =%x\n",param->add_attr_tab.num_handle); if(param->add_attr_tab.num_handle == HRS_IDX_NB){ memcpy(heart_rate_handle_table, param->add_attr_tab.handles, sizeof(heart_rate_handle_table)); @@ -275,14 +276,14 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { - LOG_INFO("EVT %d, gatts if %d\n", event, gatts_if); + ESP_LOGI(GATTS_TABLE_TAG, "EVT %d, gatts if %d\n", event, gatts_if); /* If event is register event, store the gatts_if for each profile */ if (event == ESP_GATTS_REG_EVT) { if (param->reg.status == ESP_GATT_OK) { heart_rate_profile_tab[HEART_PROFILE_APP_IDX].gatts_if = gatts_if; } else { - LOG_INFO("Reg app failed, app_id %04x, status %d\n", + ESP_LOGI(GATTS_TABLE_TAG, "Reg app failed, app_id %04x, status %d\n", param->reg.app_id, param->reg.status); return; @@ -307,15 +308,22 @@ void app_main() esp_err_t ret; esp_bt_controller_init(); - LOG_INFO("%s init bluetooth\n", __func__); + + ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); + if (ret) { + ESP_LOGE(GATTS_TABLE_TAG, "%s enable controller failed\n", __func__); + return; + } + + ESP_LOGI(GATTS_TABLE_TAG, "%s init bluetooth\n", __func__); ret = esp_bluedroid_init(); if (ret) { - LOG_ERROR("%s init bluetooth failed\n", __func__); + ESP_LOGE(GATTS_TABLE_TAG, "%s init bluetooth failed\n", __func__); return; } ret = esp_bluedroid_enable(); if (ret) { - LOG_ERROR("%s enable bluetooth failed\n", __func__); + ESP_LOGE(GATTS_TABLE_TAG, "%s enable bluetooth failed\n", __func__); return; } From 770c2ade05a91f9e0d924d7edc7a499a4cd0df56 Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Mon, 20 Feb 2017 10:23:56 +0800 Subject: [PATCH 5/7] phy init: modify some comments --- components/esp32/Kconfig | 9 +++++---- components/esp32/phy_init.c | 4 ++-- components/esp32/rtc.h | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index d3441fa017..8aa0ed3b5f 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -508,13 +508,14 @@ config PHY_ENABLED menu PHY visible if PHY_ENABLED -config ESP32_STORE_PHY_CAL_DATA_INTO_NVS - bool "Store PHY calibration data into NVS" +config ESP32_PHY_CALIBRATION_AND_DATA_STORAGE + bool "Do phy calibration and store calibration data in NVS" depends on PHY_ENABLED default y help - If this option is enabled, PHY initialization will also calibrate PHY data, and - store it into NVS. + If this option is enabled, NVS will be initialized and calibration data will be loaded from there. + PHY calibration will be skipped on deep sleep wakeup. If calibration data is not found, full calibration + will be performed and stored in NVS. In all other cases, only partial calibration will be performed. If unsure, choose 'y'. diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index 340bd7ee72..8ec518bac0 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -77,7 +77,7 @@ esp_err_t esp_phy_rf_deinit(void) _lock_acquire(&s_phy_rf_init_lock); if (s_phy_rf_init_count == 1) { - // Disable PHY and RF. This is a teporary function. + // Disable PHY and RF. TODO: convert this function to another one. pm_close_rf(); // Disable WiFi peripheral clock CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf); @@ -257,7 +257,7 @@ static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle, void esp_phy_load_cal_and_init(void) { -#ifdef CONFIG_ESP32_STORE_PHY_CAL_DATA_INTO_NVS +#ifdef CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE nvs_flash_init(); esp_phy_calibration_mode_t calibration_mode = PHY_RF_CAL_PARTIAL; if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) { diff --git a/components/esp32/rtc.h b/components/esp32/rtc.h index 48272259fa..f21d0da83e 100644 --- a/components/esp32/rtc.h +++ b/components/esp32/rtc.h @@ -136,7 +136,7 @@ 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. + * @brief Shutdown PHY and RF. TODO: convert this function to another one. */ void pm_close_rf(void); From bb0298bc715a2444a6822f4e04e9c188085bf862 Mon Sep 17 00:00:00 2001 From: XiaXiaotian Date: Mon, 20 Feb 2017 23:53:25 +0800 Subject: [PATCH 6/7] coexist: enable coexist when wifi&bt are enabled, disable coexist when one of wifi&bt is disabled. --- components/esp32/cpu_start.c | 6 ------ components/esp32/include/esp_coexist.h | 5 +++++ components/esp32/include/esp_wifi.h | 1 + components/esp32/lib | 2 +- components/esp32/phy_init.c | 9 +++++++++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index bc7ed6a71c..cf20083508 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -211,12 +211,6 @@ void start_cpu0_default(void) esp_core_dump_init(); #endif -#if CONFIG_SW_COEXIST_ENABLE - if (coex_init() == ESP_OK) { - coexist_set_enable(true); - } -#endif - xTaskCreatePinnedToCore(&main_task, "main", ESP_TASK_MAIN_STACK, NULL, ESP_TASK_MAIN_PRIO, NULL, 0); diff --git a/components/esp32/include/esp_coexist.h b/components/esp32/include/esp_coexist.h index f58d2ef949..872b5e5ab7 100644 --- a/components/esp32/include/esp_coexist.h +++ b/components/esp32/include/esp_coexist.h @@ -25,6 +25,11 @@ extern "C" { */ esp_err_t coex_init(void); +/** + * @brief De-init software coexist + */ +void coex_deinit(void); + /** * @brief Get software coexist enable or not * diff --git a/components/esp32/include/esp_wifi.h b/components/esp32/include/esp_wifi.h index 8d4fa17bb7..0f7e2996e8 100755 --- a/components/esp32/include/esp_wifi.h +++ b/components/esp32/include/esp_wifi.h @@ -130,6 +130,7 @@ esp_err_t esp_wifi_init(wifi_init_config_t *config); * Free all resource allocated in esp_wifi_init and stop WiFi task * * @attention 1. This API should be called if you want to remove WiFi driver from the system + * @attention 2. This API can not be called yet and will be done in the future. * * @return ESP_OK: succeed */ diff --git a/components/esp32/lib b/components/esp32/lib index bc16e8c074..ed85cf9156 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit bc16e8c0749adefcd5bf44c9024849a504b8e839 +Subproject commit ed85cf9156f2ef358c29d07fb849a73c5758eecb diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index 8ec518bac0..34e1a9f00e 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -35,6 +35,7 @@ #include "phy.h" #include "phy_init_data.h" #include "rtc.h" +#include "esp_coexist.h" static const char* TAG = "phy_init"; @@ -65,6 +66,10 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, phy_set_wifi_mode_only(0); register_chipv7_phy(init_data, calibration_data, mode); coex_bt_high_prio(); + } else { +#if CONFIG_SW_COEXIST_ENABLE + coex_init(); +#endif } s_phy_rf_init_count++; _lock_release(&s_phy_rf_init_lock); @@ -81,6 +86,10 @@ esp_err_t esp_phy_rf_deinit(void) pm_close_rf(); // Disable WiFi peripheral clock CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf); + } else { +#if CONFIG_SW_COEXIST_ENABLE + coex_deinit(); +#endif } s_phy_rf_init_count--; _lock_release(&s_phy_rf_init_lock); From 12a7293b312d410be73e0da912f0bb55a8b13149 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Tue, 21 Feb 2017 01:05:37 +0800 Subject: [PATCH 7/7] component/bt : add bluetooth status check 1. add bluetooth controller/host initialize status check 2. separate bluetooth controller task schedule loop from controller init --- components/bt/bluedroid/api/esp_bt_main.c | 6 +++++ components/bt/bt.c | 31 ++++++++++++++++++++--- components/bt/include/bt.h | 18 ++++++++++++- components/bt/lib | 2 +- docs/api/bluetooth/controller_vhci.rst | 1 + 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/components/bt/bluedroid/api/esp_bt_main.c b/components/bt/bluedroid/api/esp_bt_main.c index c9fe4fc060..5f7265e99c 100644 --- a/components/bt/bluedroid/api/esp_bt_main.c +++ b/components/bt/bluedroid/api/esp_bt_main.c @@ -16,6 +16,7 @@ #include "esp_bt_main.h" #include "btc_task.h" #include "btc_main.h" +#include "bt.h" #include "future.h" static bool esp_already_enable = false; @@ -103,6 +104,11 @@ esp_err_t esp_bluedroid_init(void) btc_msg_t msg; future_t **future_p; + if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { + LOG_ERROR("%s conroller not init\n", __func__); + return ESP_ERR_INVALID_STATE; + } + if (esp_already_init) { LOG_ERROR("%s already init\n", __func__); return ESP_ERR_INVALID_STATE; diff --git a/components/bt/bt.c b/components/bt/bt.c index 440c960e64..6a81d11acc 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -35,6 +35,7 @@ /* 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); +extern void btdm_controller_schedule(void); extern void btdm_controller_deinit(void); extern int btdm_controller_enable(esp_bt_mode_t mode); extern int btdm_controller_disable(esp_bt_mode_t mode); @@ -77,6 +78,7 @@ struct osi_funcs_t { /* Static variable declare */ static bool btdm_bb_init_flag = false; +static esp_bt_controller_status_t btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; static xTaskHandle btControllerTaskHandle; @@ -157,12 +159,18 @@ static void bt_controller_task(void *pvParam) btdm_osi_funcs_register(&osi_funcs); btdm_controller_init(); + btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; + + /* Loop */ + btdm_controller_schedule(); } -static bool bb_inited; void esp_bt_controller_init() { - bb_inited = false; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return; + } + xTaskCreatePinnedToCore(bt_controller_task, "btController", ESP_TASK_BT_CONTROLLER_STACK, NULL, ESP_TASK_BT_CONTROLLER_PRIO, &btControllerTaskHandle, 0); @@ -171,13 +179,17 @@ void esp_bt_controller_init() void esp_bt_controller_deinit(void) { vTaskDelete(btControllerTaskHandle); - bb_inited = false; + btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; } esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) { int ret; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) { + return ESP_ERR_INVALID_STATE; + } + if (mode != ESP_BT_MODE_BTDM) { return ESP_ERR_INVALID_ARG; } @@ -194,6 +206,8 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) return ESP_ERR_INVALID_STATE; } + btdm_controller_status = ESP_BT_CONTROLLER_STATUS_ENABLED; + return ESP_OK; } @@ -201,6 +215,10 @@ esp_err_t esp_bt_controller_disable(esp_bt_mode_t mode) { int ret; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (mode != ESP_BT_MODE_BTDM) { return ESP_ERR_INVALID_ARG; } @@ -212,7 +230,14 @@ esp_err_t esp_bt_controller_disable(esp_bt_mode_t mode) esp_phy_rf_deinit(); + btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; + return ESP_OK; } +esp_bt_controller_status_t esp_bt_controller_get_status(void) +{ + return btdm_controller_status; +} + #endif diff --git a/components/bt/include/bt.h b/components/bt/include/bt.h index 91617a28f4..2c652466bd 100644 --- a/components/bt/include/bt.h +++ b/components/bt/include/bt.h @@ -33,6 +33,16 @@ typedef enum { ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */ } esp_bt_mode_t; +/** + * @brief Bluetooth controller enable/disable/initialised/de-initialised status + */ +typedef enum { + ESP_BT_CONTROLLER_STATUS_IDLE = 0, + ESP_BT_CONTROLLER_STATUS_INITED, + ESP_BT_CONTROLLER_STATUS_ENABLED, + ESP_BT_CONTROLLER_STATUS_NUM, +} esp_bt_controller_status_t; + /** * @brief Initialize BT controller to allocate task and other resource. * @@ -52,6 +62,7 @@ void esp_bt_controller_deinit(void); * @brief Enable BT controller * @param mode : the mode(BLE/BT/BTDM) to enable. * Now only support BTDM. + * @return ESP_OK - success, other - failed */ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode); @@ -59,10 +70,15 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode); * @brief Disable BT controller * @param mode : the mode(BLE/BT/BTDM) to disable. * Now only support BTDM. + * @return ESP_OK - success, other - failed */ esp_err_t esp_bt_controller_disable(esp_bt_mode_t mode); - +/** + * @brief Get BT controller is initialised/de-initialised/enabled/disabled + * @return status value + */ +esp_bt_controller_status_t esp_bt_controller_get_status(void); /** @brief esp_vhci_host_callback * used for vhci call host function to notify what host need to do diff --git a/components/bt/lib b/components/bt/lib index 69616af765..dbac82b5c2 160000 --- a/components/bt/lib +++ b/components/bt/lib @@ -1 +1 @@ -Subproject commit 69616af7653f4de6e3b78f475dc10e73f0a20ece +Subproject commit dbac82b5c2694f2639161b0a2b3c0bd8c7d3efc5 diff --git a/docs/api/bluetooth/controller_vhci.rst b/docs/api/bluetooth/controller_vhci.rst index 108a9f678d..9fc5910c25 100644 --- a/docs/api/bluetooth/controller_vhci.rst +++ b/docs/api/bluetooth/controller_vhci.rst @@ -49,6 +49,7 @@ Functions .. doxygenfunction:: esp_bt_controller_deinit .. doxygenfunction:: esp_bt_controller_enable .. doxygenfunction:: esp_bt_controller_disable +.. doxygenfunction:: esp_bt_controller_get_status .. doxygenfunction:: esp_vhci_host_check_send_available .. doxygenfunction:: esp_vhci_host_send_packet .. doxygenfunction:: esp_vhci_host_register_callback