diff --git a/components/bt/controller/lib_esp32h4/esp32h4-bt-lib b/components/bt/controller/lib_esp32h4/esp32h4-bt-lib index 2b03d4afe9d..f4ce5d581a2 160000 --- a/components/bt/controller/lib_esp32h4/esp32h4-bt-lib +++ b/components/bt/controller/lib_esp32h4/esp32h4-bt-lib @@ -1 +1 @@ -Subproject commit 2b03d4afe9de0abd8bce61df34e68a85b75be9d4 +Subproject commit f4ce5d581a264fb5bf4c1b6ed473c45ad91f9db7 diff --git a/components/bt/controller/lib_esp32s31/esp32s31-bt-lib b/components/bt/controller/lib_esp32s31/esp32s31-bt-lib index 4c572fb7839..f4f26856d78 160000 --- a/components/bt/controller/lib_esp32s31/esp32s31-bt-lib +++ b/components/bt/controller/lib_esp32s31/esp32s31-bt-lib @@ -1 +1 @@ -Subproject commit 4c572fb78395098cfabd808159e6a51f54274bdf +Subproject commit f4f26856d7898b4846b5a6c26a1ad27edabe516f diff --git a/components/bt/controller/linker_esp_ble_controller.lf b/components/bt/controller/linker_esp_ble_controller.lf index b9b9b124b9d..f3acf0f710c 100644 --- a/components/bt/controller/linker_esp_ble_controller.lf +++ b/components/bt/controller/linker_esp_ble_controller.lf @@ -10,6 +10,24 @@ entries: entries: .adv_fast_execute_code_iram1+ +[sections:sleep_text] +entries: + .iram_sleep+ + .iram_btslp+ + +[sections:sleep_text_adv] +entries: + .iram_sleep_adv+ + +[sections:sleep_text_conn] +entries: + .iram_sleep_conn+ + +[sections:sleep_single_sleep] +entries: + .iram_single_sleep+ + + [scheme:bt_default] entries: bt_bss -> dram0_bss @@ -27,6 +45,26 @@ entries: else: adv_fast_execute_code_iram_text -> flash_text + if BT_CTRL_SLEEP_RELATED_CODE_IN_IRAM = y: + sleep_text -> iram0_text + else: + sleep_text -> flash_text + + if BT_CTRL_LE_ADV_SLEEP_CODE_IN_IRAM = y: + sleep_text_adv->iram0_text + else: + sleep_text_adv->flash_text + + if BT_CTRL_LE_CONN_SLEEP_CODE_IN_IRAM = y: + sleep_text_conn->iram0_text + else: + sleep_text_conn->flash_text + + if BT_CTRL_SLEEP_RELATED_CODE_IN_IRAM = y || BT_CTRL_RUN_IN_FLASH_ONLY = n: + sleep_single_sleep->iram0_text + else: + sleep_single_sleep->flash_text + # For the following fragments, order matters for # 'ALIGN(4) ALIGN(4, post) SURROUND(sym)', which generates: # diff --git a/components/bt/controller/linker_esp_btdm_controller.lf b/components/bt/controller/linker_esp_btdm_controller.lf index 7602b6a06b3..d8547abb520 100644 --- a/components/bt/controller/linker_esp_btdm_controller.lf +++ b/components/bt/controller/linker_esp_btdm_controller.lf @@ -10,6 +10,23 @@ entries: entries: .adv_fast_execute_code_iram1+ +[sections:sleep_text] +entries: + .iram_sleep+ + .iram_btslp+ + +[sections:sleep_text_adv] +entries: + .iram_sleep_adv+ + +[sections:sleep_text_conn] +entries: + .iram_sleep_conn+ + +[sections:sleep_single_sleep] +entries: + .iram_single_sleep+ + [scheme:bt_default] entries: bt_bss -> dram0_bss @@ -27,6 +44,26 @@ entries: else: adv_fast_execute_code_iram_text -> flash_text + if BT_CTRL_SLEEP_RELATED_CODE_IN_IRAM = y: + sleep_text -> iram0_text + else: + sleep_text -> flash_text + + if BT_CTRL_LE_ADV_SLEEP_CODE_IN_IRAM = y: + sleep_text_adv->iram0_text + else: + sleep_text_adv->flash_text + + if BT_CTRL_LE_CONN_SLEEP_CODE_IN_IRAM = y: + sleep_text_conn->iram0_text + else: + sleep_text_conn->flash_text + + if BT_CTRL_SLEEP_RELATED_CODE_IN_IRAM = y || BT_CTRL_RUN_IN_FLASH_ONLY = n: + sleep_single_sleep->iram0_text + else: + sleep_single_sleep->flash_text + # For the following fragments, order matters for # 'ALIGN(4) ALIGN(4, post) SURROUND(sym)', which generates: # diff --git a/components/bt/porting_btdm/Kconfig.in b/components/bt/porting_btdm/Kconfig.in index 896800d20ab..f6c44fe8643 100644 --- a/components/bt/porting_btdm/Kconfig.in +++ b/components/bt/porting_btdm/Kconfig.in @@ -27,7 +27,7 @@ config BT_CTRL_TASK_STACK_SIZE help This configures stack size of NimBLE controller task -config BT_CTRL_SLEEP_ENABLE +menuconfig BT_CTRL_SLEEP_ENABLE bool "Enable Bluetooth Controller sleep" default n help @@ -55,6 +55,30 @@ choice BT_CTRL_LP_CLK_SRC endchoice +config BT_CTRL_SLEEP_RELATED_CODE_IN_IRAM + bool "Put sleep related code into IRAM to optimize power consumption" + default n + depends on BT_CTRL_SLEEP_ENABLE + help + Put frequently-executed sleep functions into IRAM for faster execution + and lower power consumption. Occupies extra 3 KB RAM. + +config BT_CTRL_LE_ADV_SLEEP_CODE_IN_IRAM + bool "Put BLE advertising sleep code into IRAM" + default y + depends on BT_CTRL_SLEEP_RELATED_CODE_IN_IRAM && BT_CTRL_BLE_ENABLE + help + Put frequently-executed advertising functions into IRAM. + Occupies extra 8 KB RAM. + +config BT_CTRL_LE_CONN_SLEEP_CODE_IN_IRAM + bool "Put BLE connection sleep code into IRAM" + default y + depends on BT_CTRL_SLEEP_RELATED_CODE_IN_IRAM && BT_CTRL_BLE_ENABLE + help + Put frequently-executed connection functions into IRAM. + Occupies extra 8 KB RAM. + config BT_DUAL_MODE_ARCH bool default y diff --git a/components/bt/porting_btdm/controller/btdm_common/src/btdm_lp.c b/components/bt/porting_btdm/controller/btdm_common/src/btdm_lp.c index 7046b2f5698..a5b21fe533b 100644 --- a/components/bt/porting_btdm/controller/btdm_common/src/btdm_lp.c +++ b/components/bt/porting_btdm/controller/btdm_common/src/btdm_lp.c @@ -37,15 +37,26 @@ */ #define BTDM_LOG_TAG "BTDM_SLEEP" -#define BTDM_RTC_DELAY_US_LIGHT_SLEEP (2000) +#define BTDM_RTC_DELAY_US_LIGHT_SLEEP (1800) #define BTDM_RTC_DELAY_US_MODEM_SLEEP (1500) +typedef union { + struct { + uint32_t rsv:31; + uint32_t bt_wakeup:1; + }; + uint32_t val; +} btdm_lp_wakeup_params_t; + /* *************************************************************************************************** * External Functions *************************************************************************************************** */ #if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if UC_BT_CTRL_SLEEP_ENABLE +static bool btdm_lp_check_wakeup_by_bt(void); +#endif // UC_BT_CTRL_SLEEP_ENABLE extern bool r_btdm_sleep_should_skip_light_sleep_check(void); extern const sleep_retention_entries_config_t *r_btdm_mac_retention_link_get(uint8_t *size); extern void r_btdm_sleep_wake_up_overhead_set(uint32_t overhead); @@ -73,6 +84,7 @@ static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL; #endif // CONFIG_PM_ENABLE static uint32_t s_bt_xtal_lpclk_freq = 100000; static uint32_t s_bt_lpclk_freq = 0; +static uint8_t s_btdm_lp_modem_clk_en = 0; /* *************************************************************************************************** @@ -197,6 +209,21 @@ btdm_lp_timer_clk_deinit(void) modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); } +void IRAM_ATTR e_btdm_lp_modem_clock_set(bool enable) +{ + if (enable) { + if (!s_btdm_lp_modem_clk_en) { + modem_clock_module_enable(PERIPH_BT_MODULE); + s_btdm_lp_modem_clk_en = 1; + } + } else { + if (!s_bt_active && s_btdm_lp_modem_clk_en) { + modem_clock_module_disable(PERIPH_BT_MODULE); + s_btdm_lp_modem_clk_en = 0; + } + } +} + void btdm_lp_sleep_cb(uint32_t enable_tick, void *arg) { @@ -213,17 +240,33 @@ btdm_lp_sleep_cb(uint32_t enable_tick, void *arg) void btdm_lp_wake_up_cb(void *arg) { + btdm_lp_wakeup_params_t *params; + if (s_bt_active) { return; } #ifdef CONFIG_PM_ENABLE esp_pm_lock_acquire(s_pm_lock); #endif // CONFIG_PM_ENABLE + params = (btdm_lp_wakeup_params_t *)arg; + if (params) { + params->bt_wakeup = 0; + } esp_phy_enable(PHY_MODEM_BT); +#if UC_BT_CTRL_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE + if (params) { + params->bt_wakeup = btdm_lp_check_wakeup_by_bt(); + } +#endif // UC_BT_CTRL_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE s_bt_active = true; } #if UC_BT_CTRL_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE +static bool btdm_lp_check_wakeup_by_bt(void) +{ + return (esp_sleep_get_wakeup_causes() & BIT(ESP_SLEEP_WAKEUP_BT)); +} + static esp_err_t btdm_lp_modem_retention_create(void) { @@ -307,7 +350,11 @@ btdm_lp_modem_state_deinit(void) void btdm_lp_enable_clock(esp_btdm_controller_config_t *cfg) { - modem_clock_module_enable(PERIPH_BT_MODULE); + if (!s_btdm_lp_modem_clk_en) { + modem_clock_module_enable(PERIPH_BT_MODULE); + s_btdm_lp_modem_clk_en = 1; + } + modem_clock_module_enable(PERIPH_BT_APB_MODULE); modem_clock_module_mac_reset(PERIPH_BT_MODULE); btdm_lp_timer_clk_init(cfg); } @@ -316,7 +363,11 @@ void btdm_lp_disable_clock(void) { btdm_lp_timer_clk_deinit(); - modem_clock_module_disable(PERIPH_BT_MODULE); + modem_clock_module_disable(PERIPH_BT_APB_MODULE); + if (s_btdm_lp_modem_clk_en) { + modem_clock_module_disable(PERIPH_BT_MODULE); + s_btdm_lp_modem_clk_en = 0; + } } int