|
|
@@ -72,7 +72,8 @@ typedef union {
|
|
|
uint32_t mac_bb_pd : 1; // whether hardware(MAC, BB) force-power-down is required during sleep
|
|
|
uint32_t wakeup_timer_required : 1; // whether system timer is needed
|
|
|
uint32_t no_light_sleep : 1; // do not allow system to enter light sleep after bluetooth is enabled
|
|
|
- uint32_t reserved : 26; // reserved
|
|
|
+ uint32_t main_xtal_pu : 1; // power up main XTAL
|
|
|
+ uint32_t reserved : 25; // reserved
|
|
|
};
|
|
|
uint32_t val;
|
|
|
} btdm_lpcntl_t;
|
|
|
@@ -1035,12 +1036,13 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
|
|
// set default values for global states or resources
|
|
|
s_lp_stat.val = 0;
|
|
|
s_lp_cntl.val = 0;
|
|
|
+ s_lp_cntl.main_xtal_pu = 0;
|
|
|
s_wakeup_req_sem = NULL;
|
|
|
s_btdm_slp_tmr = NULL;
|
|
|
|
|
|
// configure and initialize resources
|
|
|
s_lp_cntl.enable = (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) ? 1 : 0;
|
|
|
- s_lp_cntl.no_light_sleep = 1;
|
|
|
+ s_lp_cntl.no_light_sleep = 0;
|
|
|
|
|
|
if (s_lp_cntl.enable) {
|
|
|
#if CONFIG_MAC_BB_PD
|
|
|
@@ -1083,33 +1085,41 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
|
|
// check whether or not EXT_CRYS is working
|
|
|
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
|
|
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // External 32 kHz XTAL
|
|
|
- s_lp_cntl.no_light_sleep = 0;
|
|
|
} else {
|
|
|
- ESP_LOGW(BT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n"
|
|
|
- "light sleep mode will not be able to apply when bluetooth is enabled");
|
|
|
+ ESP_LOGW(BT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
|
|
|
+#if !CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
|
|
|
+ s_lp_cntl.no_light_sleep = 1;
|
|
|
+#endif
|
|
|
}
|
|
|
-#elif CONFIG_BT_CTRL_LPCLK_SEL_RTC_SLOW
|
|
|
- // check whether or not EXT_CRYS is working
|
|
|
+#elif (CONFIG_BT_CTRL_LPCLK_SEL_MAIN_XTAL)
|
|
|
+ ESP_LOGI(BT_LOG_TAG, "Bluetooth will use main XTAL as Bluetooth sleep clock.");
|
|
|
+#if !CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
|
|
|
+ s_lp_cntl.no_light_sleep = 1;
|
|
|
+#endif
|
|
|
+#elif (CONFIG_BT_CTRL_LPCLK_SEL_RTC_SLOW)
|
|
|
+ // check whether or not internal 150 kHz RC oscillator is working
|
|
|
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) {
|
|
|
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_RTC_SLOW; // Internal 150 kHz RC oscillator
|
|
|
- ESP_LOGW(BTDM_LOG_TAG, "Internal 150kHz RC osciallator. The accuracy of this clock is a lot larger than 500ppm which is "
|
|
|
+ ESP_LOGW(BT_LOG_TAG, "Internal 150kHz RC osciallator. The accuracy of this clock is a lot larger than 500ppm which is "
|
|
|
"required in Bluetooth communication, so don't select this option in scenarios such as BLE connection state.");
|
|
|
} else {
|
|
|
ESP_LOGW(BT_LOG_TAG, "Internal 150kHz RC oscillator not detected.");
|
|
|
assert(0);
|
|
|
}
|
|
|
-#else
|
|
|
- s_lp_cntl.no_light_sleep = 1;
|
|
|
#endif
|
|
|
|
|
|
bool select_src_ret __attribute__((unused));
|
|
|
bool set_div_ret __attribute__((unused));
|
|
|
if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL) {
|
|
|
+#ifdef CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
|
|
|
+ ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON));
|
|
|
+ s_lp_cntl.main_xtal_pu = 1;
|
|
|
+#endif
|
|
|
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL);
|
|
|
- set_div_ret = btdm_lpclk_set_div(esp_clk_xtal_freq() * 2 / MHZ);
|
|
|
+ set_div_ret = btdm_lpclk_set_div(esp_clk_xtal_freq() / MHZ);
|
|
|
assert(select_src_ret && set_div_ret);
|
|
|
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
|
|
- btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
|
|
|
+ btdm_lpcycle_us = 1 << (btdm_lpcycle_us_frac);
|
|
|
} else if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL32K) {
|
|
|
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL32K);
|
|
|
set_div_ret = btdm_lpclk_set_div(0);
|
|
|
@@ -1128,6 +1138,9 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
|
|
err = ESP_ERR_INVALID_ARG;
|
|
|
goto error;
|
|
|
}
|
|
|
+#if CONFIG_SW_COEXIST_ENABLE
|
|
|
+ coex_update_lpclk_interval();
|
|
|
+#endif
|
|
|
|
|
|
#ifdef CONFIG_PM_ENABLE
|
|
|
if (s_lp_cntl.no_light_sleep) {
|
|
|
@@ -1135,6 +1148,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
|
|
err = ESP_ERR_NO_MEM;
|
|
|
goto error;
|
|
|
}
|
|
|
+ ESP_LOGW(BT_LOG_TAG, "light sleep mode will not be able to apply when bluetooth is enabled.");
|
|
|
}
|
|
|
if ((err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock)) != ESP_OK) {
|
|
|
err = ESP_ERR_NO_MEM;
|
|
|
@@ -1205,6 +1219,22 @@ error:
|
|
|
s_wakeup_req_sem = NULL;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL) {
|
|
|
+#ifdef CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
|
|
|
+ if (s_lp_cntl.main_xtal_pu) {
|
|
|
+ ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF));
|
|
|
+ s_lp_cntl.main_xtal_pu = 0;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ btdm_lpclk_select_src(BTDM_LPCLK_SEL_RTC_SLOW);
|
|
|
+ btdm_lpclk_set_div(0);
|
|
|
+#if CONFIG_SW_COEXIST_ENABLE
|
|
|
+ coex_update_lpclk_interval();
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ btdm_lpcycle_us = 0;
|
|
|
} while (0);
|
|
|
|
|
|
#if CONFIG_MAC_BB_PD
|
|
|
@@ -1267,6 +1297,22 @@ esp_err_t esp_bt_controller_deinit(void)
|
|
|
semphr_delete_wrapper(s_wakeup_req_sem);
|
|
|
s_wakeup_req_sem = NULL;
|
|
|
}
|
|
|
+
|
|
|
+ if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL) {
|
|
|
+#ifdef CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
|
|
|
+ if (s_lp_cntl.main_xtal_pu) {
|
|
|
+ ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF));
|
|
|
+ s_lp_cntl.main_xtal_pu = 0;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ btdm_lpclk_select_src(BTDM_LPCLK_SEL_RTC_SLOW);
|
|
|
+ btdm_lpclk_set_div(0);
|
|
|
+#if CONFIG_SW_COEXIST_ENABLE
|
|
|
+ coex_update_lpclk_interval();
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ btdm_lpcycle_us = 0;
|
|
|
} while (0);
|
|
|
|
|
|
#if CONFIG_MAC_BB_PD
|
|
|
@@ -1284,7 +1330,6 @@ esp_err_t esp_bt_controller_deinit(void)
|
|
|
osi_funcs_p = NULL;
|
|
|
|
|
|
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
|
|
|
- btdm_lpcycle_us = 0;
|
|
|
return ESP_OK;
|
|
|
}
|
|
|
|