mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feat/set_get_lpclk_src_v5.0' into 'release/v5.0'
feat(ble): Added API to get low power clock source(v5.0) See merge request espressif/esp-idf!30109
This commit is contained in:
commit
3b6ee156c9
@ -74,12 +74,12 @@ enum {
|
|||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t enable : 1; // whether low power mode is required
|
uint32_t enable : 1; // whether low power mode is required
|
||||||
uint32_t lpclk_sel : 2; // low power clock source
|
uint32_t lpclk_sel : 3; // low power clock source
|
||||||
uint32_t mac_bb_pd : 1; // whether hardware(MAC, BB) force-power-down is required during sleep
|
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 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 no_light_sleep : 1; // do not allow system to enter light sleep after bluetooth is enabled
|
||||||
uint32_t main_xtal_pu : 1; // power up main XTAL
|
uint32_t main_xtal_pu : 1; // power up main XTAL
|
||||||
uint32_t reserved : 25; // reserved
|
uint32_t reserved : 24; // reserved
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} btdm_lpcntl_t;
|
} btdm_lpcntl_t;
|
||||||
@ -402,7 +402,7 @@ static DRAM_ATTR uint8_t btdm_lpcycle_us_frac = 0;
|
|||||||
// semaphore used for blocking VHCI API to wait for controller to wake up
|
// semaphore used for blocking VHCI API to wait for controller to wake up
|
||||||
static DRAM_ATTR QueueHandle_t s_wakeup_req_sem = NULL;
|
static DRAM_ATTR QueueHandle_t s_wakeup_req_sem = NULL;
|
||||||
// wakeup timer
|
// wakeup timer
|
||||||
static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr;
|
static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr = NULL;
|
||||||
|
|
||||||
#ifdef CONFIG_PM_ENABLE
|
#ifdef CONFIG_PM_ENABLE
|
||||||
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock;
|
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock;
|
||||||
@ -1141,6 +1141,147 @@ static void IRAM_ATTR btdm_mac_bb_power_up_cb(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// init low-power control resources
|
||||||
|
static esp_err_t btdm_low_power_mode_init(esp_bt_controller_config_t *cfg)
|
||||||
|
{
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
|
||||||
|
do {
|
||||||
|
// 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.lpclk_sel = (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) ? cfg->sleep_clock : ESP_BT_SLEEP_CLOCK_MAIN_XTAL;
|
||||||
|
s_lp_cntl.no_light_sleep = 0;
|
||||||
|
|
||||||
|
if (s_lp_cntl.enable) {
|
||||||
|
#if CONFIG_MAC_BB_PD
|
||||||
|
if (!btdm_deep_sleep_mem_init()) {
|
||||||
|
err = ESP_ERR_NO_MEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s_lp_cntl.mac_bb_pd = 1;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_PM_ENABLE
|
||||||
|
s_lp_cntl.wakeup_timer_required = 1;
|
||||||
|
#endif
|
||||||
|
// async wakeup semaphore for VHCI
|
||||||
|
s_wakeup_req_sem = semphr_create_wrapper(1, 0);
|
||||||
|
if (s_wakeup_req_sem == NULL) {
|
||||||
|
err = ESP_ERR_NO_MEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
btdm_vnd_offload_task_register(BTDM_VND_OL_SIG_WAKEUP_TMR, btdm_sleep_exit_phase0);
|
||||||
|
|
||||||
|
if (s_lp_cntl.wakeup_timer_required) {
|
||||||
|
esp_timer_create_args_t create_args = {
|
||||||
|
.callback = btdm_slp_tmr_callback,
|
||||||
|
.arg = NULL,
|
||||||
|
.name = "btSlp",
|
||||||
|
};
|
||||||
|
if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set default bluetooth sleep clock cycle and its fractional bits
|
||||||
|
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
||||||
|
btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
|
||||||
|
|
||||||
|
if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_EXT_32K_XTAL) { // External 32 kHz XTAL
|
||||||
|
// check whether or not EXT_CRYS is working
|
||||||
|
if (rtc_clk_slow_src_get() != SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
|
||||||
|
ESP_LOGW(BT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
|
||||||
|
s_lp_cntl.lpclk_sel = ESP_BT_SLEEP_CLOCK_MAIN_XTAL;
|
||||||
|
#if !CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
|
||||||
|
s_lp_cntl.no_light_sleep = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_RTC_SLOW) { // Internal 136kHz RC oscillator
|
||||||
|
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) {
|
||||||
|
ESP_LOGW(BT_LOG_TAG, "Internal 136kHz RC oscillator. 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 136kHz RC oscillator not detected.");
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
} else if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_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
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s_lp_cntl.no_light_sleep = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool select_src_ret __attribute__((unused));
|
||||||
|
bool set_div_ret __attribute__((unused));
|
||||||
|
if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_MAIN_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() / MHZ);
|
||||||
|
assert(select_src_ret && set_div_ret);
|
||||||
|
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
||||||
|
btdm_lpcycle_us = 1 << (btdm_lpcycle_us_frac);
|
||||||
|
} else if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_EXT_32K_XTAL) {
|
||||||
|
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL32K);
|
||||||
|
set_div_ret = btdm_lpclk_set_div(0);
|
||||||
|
assert(select_src_ret && set_div_ret);
|
||||||
|
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
||||||
|
btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15) ? (1000000 << (RTC_CLK_CAL_FRACT - 15)) :
|
||||||
|
(1000000 >> (15 - RTC_CLK_CAL_FRACT));
|
||||||
|
assert(btdm_lpcycle_us != 0);
|
||||||
|
} else if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_RTC_SLOW) {
|
||||||
|
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_RTC_SLOW);
|
||||||
|
set_div_ret = btdm_lpclk_set_div(0);
|
||||||
|
assert(select_src_ret && set_div_ret);
|
||||||
|
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
||||||
|
btdm_lpcycle_us = esp_clk_slowclk_cal_get();
|
||||||
|
} else {
|
||||||
|
err = ESP_ERR_INVALID_ARG;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if CONFIG_SW_COEXIST_ENABLE
|
||||||
|
coex_update_lpclk_interval();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_ENABLE
|
||||||
|
if (s_lp_cntl.no_light_sleep) {
|
||||||
|
if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
s_lp_stat.pm_lock_released = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_bt_sleep_clock_t esp_bt_get_lpclk_src(void)
|
||||||
|
{
|
||||||
|
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED &&
|
||||||
|
btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||||
|
return ESP_BT_SLEEP_CLOCK_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_lp_cntl.lpclk_sel;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||||
{
|
{
|
||||||
esp_err_t err = ESP_FAIL;
|
esp_err_t err = ESP_FAIL;
|
||||||
@ -1176,6 +1317,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
|||||||
ESP_LOGE(BT_LOG_TAG, "SLEEP_MODE_1 enabled but sleep clock not configured");
|
ESP_LOGE(BT_LOG_TAG, "SLEEP_MODE_1 enabled but sleep clock not configured");
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
if (cfg->sleep_clock > ESP_BT_SLEEP_CLOCK_RTC_SLOW) {
|
||||||
|
ESP_LOGE(BT_LOG_TAG, "SLEEP_MODE_1 is enabled but this sleep clock is not supported");
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// overwrite some parameters
|
// overwrite some parameters
|
||||||
@ -1201,133 +1346,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
|||||||
|
|
||||||
ESP_LOGI(BT_LOG_TAG, "BT controller compile version [%s]", btdm_controller_get_compile_version());
|
ESP_LOGI(BT_LOG_TAG, "BT controller compile version [%s]", btdm_controller_get_compile_version());
|
||||||
|
|
||||||
// init low-power control resources
|
if ((err = btdm_low_power_mode_init(cfg)) != ESP_OK) {
|
||||||
do {
|
ESP_LOGE(BT_LOG_TAG, "Low power module initialization failed");
|
||||||
// set default values for global states or resources
|
goto error;
|
||||||
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 = 0;
|
|
||||||
|
|
||||||
if (s_lp_cntl.enable) {
|
|
||||||
#if CONFIG_MAC_BB_PD
|
|
||||||
if (!btdm_deep_sleep_mem_init()) {
|
|
||||||
err = ESP_ERR_NO_MEM;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
s_lp_cntl.mac_bb_pd = 1;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_PM_ENABLE
|
|
||||||
s_lp_cntl.wakeup_timer_required = 1;
|
|
||||||
#endif
|
|
||||||
// async wakeup semaphore for VHCI
|
|
||||||
s_wakeup_req_sem = semphr_create_wrapper(1, 0);
|
|
||||||
if (s_wakeup_req_sem == NULL) {
|
|
||||||
err = ESP_ERR_NO_MEM;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
btdm_vnd_offload_task_register(BTDM_VND_OL_SIG_WAKEUP_TMR, btdm_sleep_exit_phase0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_lp_cntl.wakeup_timer_required) {
|
|
||||||
esp_timer_create_args_t create_args = {
|
|
||||||
.callback = btdm_slp_tmr_callback,
|
|
||||||
.arg = NULL,
|
|
||||||
.name = "btSlp",
|
|
||||||
};
|
|
||||||
if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set default bluetooth sleep clock cycle and its fractional bits
|
|
||||||
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
|
||||||
btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
|
|
||||||
|
|
||||||
// set default bluetooth sleep clock source
|
|
||||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
|
|
||||||
#if CONFIG_BT_CTRL_LPCLK_SEL_EXT_32K_XTAL
|
|
||||||
// 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
|
|
||||||
} else {
|
|
||||||
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_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(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);
|
|
||||||
}
|
|
||||||
#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() / MHZ);
|
|
||||||
assert(select_src_ret && set_div_ret);
|
|
||||||
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
|
||||||
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);
|
|
||||||
assert(select_src_ret && set_div_ret);
|
|
||||||
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
|
||||||
btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15) ? (1000000 << (RTC_CLK_CAL_FRACT - 15)) :
|
|
||||||
(1000000 >> (15 - RTC_CLK_CAL_FRACT));
|
|
||||||
assert(btdm_lpcycle_us != 0);
|
|
||||||
} else if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_RTC_SLOW) {
|
|
||||||
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_RTC_SLOW);
|
|
||||||
set_div_ret = btdm_lpclk_set_div(0);
|
|
||||||
assert(select_src_ret && set_div_ret);
|
|
||||||
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
|
||||||
btdm_lpcycle_us = esp_clk_slowclk_cal_get();
|
|
||||||
} else {
|
|
||||||
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) {
|
|
||||||
if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) {
|
|
||||||
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;
|
|
||||||
goto error;
|
|
||||||
} else {
|
|
||||||
s_lp_stat.pm_lock_released = 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
#if CONFIG_SW_COEXIST_ENABLE
|
#if CONFIG_SW_COEXIST_ENABLE
|
||||||
coex_init();
|
coex_init();
|
||||||
@ -1365,69 +1387,70 @@ esp_err_t esp_bt_controller_deinit(void)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deinit low power control resources
|
||||||
|
static void btdm_low_power_mode_deinit(void)
|
||||||
|
{
|
||||||
|
#if CONFIG_MAC_BB_PD
|
||||||
|
if (s_lp_cntl.mac_bb_pd) {
|
||||||
|
btdm_deep_sleep_mem_deinit();
|
||||||
|
s_lp_cntl.mac_bb_pd = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_ENABLE
|
||||||
|
if (s_lp_cntl.no_light_sleep) {
|
||||||
|
if (s_light_sleep_pm_lock != NULL) {
|
||||||
|
esp_pm_lock_delete(s_light_sleep_pm_lock);
|
||||||
|
s_light_sleep_pm_lock = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_pm_lock != NULL) {
|
||||||
|
esp_pm_lock_delete(s_pm_lock);
|
||||||
|
s_pm_lock = NULL;
|
||||||
|
s_lp_stat.pm_lock_released = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (s_lp_cntl.wakeup_timer_required && s_btdm_slp_tmr != NULL) {
|
||||||
|
if (s_lp_stat.wakeup_timer_started) {
|
||||||
|
esp_timer_stop(s_btdm_slp_tmr);
|
||||||
|
}
|
||||||
|
s_lp_stat.wakeup_timer_started = 0;
|
||||||
|
esp_timer_delete(s_btdm_slp_tmr);
|
||||||
|
s_btdm_slp_tmr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_lp_cntl.enable) {
|
||||||
|
btdm_vnd_offload_task_deregister(BTDM_VND_OL_SIG_WAKEUP_TMR);
|
||||||
|
if (s_wakeup_req_sem != NULL) {
|
||||||
|
semphr_delete_wrapper(s_wakeup_req_sem);
|
||||||
|
s_wakeup_req_sem = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_MAIN_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;
|
||||||
|
}
|
||||||
|
|
||||||
static void bt_controller_deinit_internal(void)
|
static void bt_controller_deinit_internal(void)
|
||||||
{
|
{
|
||||||
periph_module_disable(PERIPH_BT_MODULE);
|
periph_module_disable(PERIPH_BT_MODULE);
|
||||||
|
|
||||||
// deinit low power control resources
|
btdm_low_power_mode_deinit();
|
||||||
do {
|
|
||||||
|
|
||||||
#if CONFIG_MAC_BB_PD
|
|
||||||
if (s_lp_cntl.mac_bb_pd) {
|
|
||||||
btdm_deep_sleep_mem_deinit();
|
|
||||||
s_lp_cntl.mac_bb_pd = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM_ENABLE
|
|
||||||
if (s_lp_cntl.no_light_sleep) {
|
|
||||||
if (s_light_sleep_pm_lock != NULL) {
|
|
||||||
esp_pm_lock_delete(s_light_sleep_pm_lock);
|
|
||||||
s_light_sleep_pm_lock = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_pm_lock != NULL) {
|
|
||||||
esp_pm_lock_delete(s_pm_lock);
|
|
||||||
s_pm_lock = NULL;
|
|
||||||
s_lp_stat.pm_lock_released = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (s_lp_cntl.wakeup_timer_required) {
|
|
||||||
if (s_lp_stat.wakeup_timer_started) {
|
|
||||||
esp_timer_stop(s_btdm_slp_tmr);
|
|
||||||
}
|
|
||||||
s_lp_stat.wakeup_timer_started = 0;
|
|
||||||
esp_timer_delete(s_btdm_slp_tmr);
|
|
||||||
s_btdm_slp_tmr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_lp_cntl.enable) {
|
|
||||||
btdm_vnd_offload_task_deregister(BTDM_VND_OL_SIG_WAKEUP_TMR);
|
|
||||||
if (s_wakeup_req_sem != NULL) {
|
|
||||||
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);
|
|
||||||
|
|
||||||
esp_bt_power_domain_off();
|
esp_bt_power_domain_off();
|
||||||
#if CONFIG_MAC_BB_PD
|
#if CONFIG_MAC_BB_PD
|
||||||
|
@ -289,7 +289,7 @@ typedef struct {
|
|||||||
uint8_t sleep_clock; /*!< controller sleep clock */
|
uint8_t sleep_clock; /*!< controller sleep clock */
|
||||||
uint8_t ble_st_acl_tx_buf_nb; /*!< controller static ACL TX BUFFER number */
|
uint8_t ble_st_acl_tx_buf_nb; /*!< controller static ACL TX BUFFER number */
|
||||||
uint8_t ble_hw_cca_check; /*!< controller hardware triggered CCA check */
|
uint8_t ble_hw_cca_check; /*!< controller hardware triggered CCA check */
|
||||||
uint16_t ble_adv_dup_filt_max; /*!< maxinum number of duplicate scan filter */
|
uint16_t ble_adv_dup_filt_max; /*!< maximum number of duplicate scan filter */
|
||||||
bool coex_param_en; /*!< deprecated */
|
bool coex_param_en; /*!< deprecated */
|
||||||
uint8_t ce_len_type; /*!< connection event length computation method */
|
uint8_t ce_len_type; /*!< connection event length computation method */
|
||||||
bool coex_use_hooks; /*!< deprecated */
|
bool coex_use_hooks; /*!< deprecated */
|
||||||
@ -600,6 +600,15 @@ void esp_wifi_bt_power_domain_on(void);
|
|||||||
*/
|
*/
|
||||||
void esp_wifi_bt_power_domain_off(void);
|
void esp_wifi_bt_power_domain_off(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the Bluetooth module sleep clock source.
|
||||||
|
*
|
||||||
|
* Note that this function shall not be invoked before esp_bt_controller_init()
|
||||||
|
*
|
||||||
|
* @return clock source used in Bluetooth low power mode
|
||||||
|
*/
|
||||||
|
esp_bt_sleep_clock_t esp_bt_get_lpclk_src(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user