@@ -450,7 +450,11 @@ static DRAM_ATTR uint8_t btdm_lpcycle_us_frac = 0; // number of fractional bit f
450450
451451#if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG
452452// used low power clock
453- static DRAM_ATTR uint8_t btdm_lpclk_sel ;
453+ #if CONFIG_BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL
454+ static DRAM_ATTR uint8_t btdm_lpclk_sel = ESP_BT_SLEEP_CLOCK_EXT_32K_XTAL ;
455+ #else
456+ static DRAM_ATTR uint8_t btdm_lpclk_sel = ESP_BT_SLEEP_CLOCK_MAIN_XTAL ;
457+ #endif /* CONFIG_BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL */
454458#endif /* #ifdef CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG */
455459
456460static DRAM_ATTR QueueHandle_t s_wakeup_req_sem = NULL ;
@@ -1492,6 +1496,117 @@ static void hli_queue_setup_pinned_to_core(int core_id)
14921496}
14931497#endif /* CONFIG_BTDM_CTRL_HLI */
14941498
1499+ // init low-power control resources
1500+ static esp_err_t btdm_low_power_mode_init (void )
1501+ {
1502+ esp_err_t err = ESP_OK ;
1503+
1504+ #ifdef CONFIG_PM_ENABLE
1505+ s_btdm_allow_light_sleep = false;
1506+ #endif
1507+
1508+ // set default sleep clock cycle and its fractional bits
1509+ btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT ;
1510+ btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac );
1511+
1512+ #if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG
1513+ if (btdm_lpclk_sel == ESP_BT_SLEEP_CLOCK_EXT_32K_XTAL ) {
1514+ // check whether or not EXT_CRYS is working
1515+ if (rtc_clk_slow_src_get () == SOC_RTC_SLOW_CLK_SRC_XTAL32K ) {
1516+ #ifdef CONFIG_PM_ENABLE
1517+ s_btdm_allow_light_sleep = true;
1518+ #endif
1519+ } else {
1520+ ESP_LOGW (BTDM_LOG_TAG , "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n"
1521+ "light sleep mode will not be able to apply when bluetooth is enabled" );
1522+ btdm_lpclk_sel = ESP_BT_SLEEP_CLOCK_MAIN_XTAL ; // set default value
1523+ }
1524+ } else if (btdm_lpclk_sel != ESP_BT_SLEEP_CLOCK_MAIN_XTAL ) {
1525+ assert (0 );
1526+ }
1527+
1528+ bool select_src_ret __attribute__((unused ));
1529+ bool set_div_ret __attribute__((unused ));
1530+ if (btdm_lpclk_sel == ESP_BT_SLEEP_CLOCK_MAIN_XTAL ) {
1531+ select_src_ret = btdm_lpclk_select_src (BTDM_LPCLK_SEL_XTAL );
1532+ set_div_ret = btdm_lpclk_set_div (esp_clk_xtal_freq () * 2 / MHZ - 1 );
1533+ assert (select_src_ret && set_div_ret );
1534+ btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT ;
1535+ btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac );
1536+ } else { // btdm_lpclk_sel == BTDM_LPCLK_SEL_XTAL32K
1537+ select_src_ret = btdm_lpclk_select_src (BTDM_LPCLK_SEL_XTAL32K );
1538+ set_div_ret = btdm_lpclk_set_div (0 );
1539+ assert (select_src_ret && set_div_ret );
1540+ btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT ;
1541+ btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15 ) ? (1000000 << (RTC_CLK_CAL_FRACT - 15 )) :
1542+ (1000000 >> (15 - RTC_CLK_CAL_FRACT ));
1543+ assert (btdm_lpcycle_us != 0 );
1544+ }
1545+ btdm_controller_set_sleep_mode (BTDM_MODEM_SLEEP_MODE_ORIG );
1546+
1547+ #elif CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED
1548+ btdm_controller_set_sleep_mode (BTDM_MODEM_SLEEP_MODE_EVED );
1549+ #else
1550+ btdm_controller_set_sleep_mode (BTDM_MODEM_SLEEP_MODE_NONE );
1551+ #endif
1552+
1553+ #ifdef CONFIG_PM_ENABLE
1554+ if (!s_btdm_allow_light_sleep ) {
1555+ if ((err = esp_pm_lock_create (ESP_PM_NO_LIGHT_SLEEP , 0 , "btLS" , & s_light_sleep_pm_lock )) != ESP_OK ) {
1556+ return err ;
1557+ }
1558+ }
1559+ if ((err = esp_pm_lock_create (ESP_PM_APB_FREQ_MAX , 0 , "bt" , & s_pm_lock )) != ESP_OK ) {
1560+ return err ;
1561+ }
1562+ esp_timer_create_args_t create_args = {
1563+ .callback = btdm_slp_tmr_callback ,
1564+ .arg = NULL ,
1565+ .name = "btSlp"
1566+ };
1567+ if ((err = esp_timer_create (& create_args , & s_btdm_slp_tmr )) != ESP_OK ) {
1568+ return err ;
1569+ }
1570+
1571+ s_pm_lock_acquired = true;
1572+ #endif
1573+
1574+ return err ;
1575+ }
1576+
1577+ esp_bt_sleep_clock_t esp_bt_get_lpclk_src (void )
1578+ {
1579+ #if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG
1580+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED &&
1581+ btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED ) {
1582+ return ESP_BT_SLEEP_CLOCK_NONE ;
1583+ }
1584+ return btdm_lpclk_sel ;
1585+ #else
1586+ return ESP_BT_SLEEP_CLOCK_NONE ;
1587+ #endif
1588+ }
1589+
1590+ esp_err_t esp_bt_set_lpclk_src (esp_bt_sleep_clock_t lpclk )
1591+ {
1592+ #if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG
1593+ if (lpclk < ESP_BT_SLEEP_CLOCK_MAIN_XTAL || lpclk > ESP_BT_SLEEP_CLOCK_EXT_32K_XTAL ) {
1594+ return ESP_ERR_INVALID_ARG ;
1595+ }
1596+
1597+ if (btdm_controller_status == ESP_BT_CONTROLLER_STATUS_INITED ||
1598+ btdm_controller_status == ESP_BT_CONTROLLER_STATUS_ENABLED ) {
1599+ ESP_LOGW (BTDM_LOG_TAG , "Please set the Bluetooth sleep clock source before Bluetooth initialization" );
1600+ return ESP_ERR_INVALID_STATE ;
1601+ }
1602+
1603+ btdm_lpclk_sel = lpclk ;
1604+ return ESP_OK ;
1605+ #else
1606+ return ESP_ERR_NOT_SUPPORTED ;
1607+ #endif
1608+ }
1609+
14951610esp_err_t esp_bt_controller_init (esp_bt_controller_config_t * cfg )
14961611{
14971612 esp_err_t err ;
@@ -1556,85 +1671,17 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
15561671 periph_module_enable (PERIPH_BT_MODULE );
15571672 periph_module_reset (PERIPH_BT_MODULE );
15581673
1559- #ifdef CONFIG_PM_ENABLE
1560- s_btdm_allow_light_sleep = false;
1561- #endif
1562-
1563- // set default sleep clock cycle and its fractional bits
1564- btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT ;
1565- btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac );
1566-
1567- #if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG
1568-
1569- btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL ; // set default value
1570- #if CONFIG_BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL
1571- // check whether or not EXT_CRYS is working
1572- if (rtc_clk_slow_src_get () == SOC_RTC_SLOW_CLK_SRC_XTAL32K ) {
1573- btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL32K ; // External 32kHz XTAL
1574- #ifdef CONFIG_PM_ENABLE
1575- s_btdm_allow_light_sleep = true;
1576- #endif
1577- } else {
1578- ESP_LOGW (BTDM_LOG_TAG , "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n"
1579- "light sleep mode will not be able to apply when bluetooth is enabled" );
1580- btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL ; // set default value
1581- }
1582- #else
1583- btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL ; // set default value
1584- #endif
1585-
1586- bool select_src_ret __attribute__((unused ));
1587- bool set_div_ret __attribute__((unused ));
1588- if (btdm_lpclk_sel == BTDM_LPCLK_SEL_XTAL ) {
1589- select_src_ret = btdm_lpclk_select_src (BTDM_LPCLK_SEL_XTAL );
1590- set_div_ret = btdm_lpclk_set_div (esp_clk_xtal_freq () * 2 / MHZ - 1 );
1591- assert (select_src_ret && set_div_ret );
1592- btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT ;
1593- btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac );
1594- } else { // btdm_lpclk_sel == BTDM_LPCLK_SEL_XTAL32K
1595- select_src_ret = btdm_lpclk_select_src (BTDM_LPCLK_SEL_XTAL32K );
1596- set_div_ret = btdm_lpclk_set_div (0 );
1597- assert (select_src_ret && set_div_ret );
1598- btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT ;
1599- btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15 ) ? (1000000 << (RTC_CLK_CAL_FRACT - 15 )) :
1600- (1000000 >> (15 - RTC_CLK_CAL_FRACT ));
1601- assert (btdm_lpcycle_us != 0 );
1602- }
1603- btdm_controller_set_sleep_mode (BTDM_MODEM_SLEEP_MODE_ORIG );
1604-
1605- #elif CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED
1606- btdm_controller_set_sleep_mode (BTDM_MODEM_SLEEP_MODE_EVED );
1607- #else
1608- btdm_controller_set_sleep_mode (BTDM_MODEM_SLEEP_MODE_NONE );
1609- #endif
1610-
16111674#if CONFIG_BTDM_CTRL_HCI_UART_FLOW_CTRL_EN
16121675 sdk_config_set_uart_flow_ctrl_enable (true);
16131676#else
16141677 sdk_config_set_uart_flow_ctrl_enable (false);
16151678#endif
16161679
1617- #ifdef CONFIG_PM_ENABLE
1618- if (!s_btdm_allow_light_sleep ) {
1619- if ((err = esp_pm_lock_create (ESP_PM_NO_LIGHT_SLEEP , 0 , "btLS" , & s_light_sleep_pm_lock )) != ESP_OK ) {
1620- goto error ;
1621- }
1622- }
1623- if ((err = esp_pm_lock_create (ESP_PM_APB_FREQ_MAX , 0 , "bt" , & s_pm_lock )) != ESP_OK ) {
1624- goto error ;
1625- }
1626- esp_timer_create_args_t create_args = {
1627- .callback = btdm_slp_tmr_callback ,
1628- .arg = NULL ,
1629- .name = "btSlp"
1630- };
1631- if ((err = esp_timer_create (& create_args , & s_btdm_slp_tmr )) != ESP_OK ) {
1680+ if ((err = btdm_low_power_mode_init ()) != ESP_OK ) {
1681+ ESP_LOGE (BTDM_LOG_TAG , "Low power module initialization failed" );
16321682 goto error ;
16331683 }
16341684
1635- s_pm_lock_acquired = true;
1636- #endif
1637-
16381685#if CONFIG_SW_COEXIST_ENABLE
16391686 coex_init ();
16401687#endif
@@ -1673,10 +1720,9 @@ esp_err_t esp_bt_controller_deinit(void)
16731720 return ESP_OK ;
16741721}
16751722
1676- static void bt_controller_deinit_internal (void )
1723+ // deinit low power control resources
1724+ static void btdm_low_power_mode_deinit (void )
16771725{
1678- periph_module_disable (PERIPH_BT_MODULE );
1679-
16801726#ifdef CONFIG_PM_ENABLE
16811727 if (!s_btdm_allow_light_sleep ) {
16821728 esp_pm_lock_delete (s_light_sleep_pm_lock );
@@ -1697,6 +1743,16 @@ static void bt_controller_deinit_internal(void)
16971743 s_pm_lock_acquired = false;
16981744#endif
16991745
1746+ btdm_lpcycle_us = 0 ;
1747+ btdm_controller_set_sleep_mode (BTDM_MODEM_SLEEP_MODE_NONE );
1748+ }
1749+
1750+ static void bt_controller_deinit_internal (void )
1751+ {
1752+ periph_module_disable (PERIPH_BT_MODULE );
1753+
1754+ btdm_low_power_mode_deinit ();
1755+
17001756 if (s_wakeup_req_sem ) {
17011757 semphr_delete_wrapper (s_wakeup_req_sem );
17021758 s_wakeup_req_sem = NULL ;
@@ -1709,9 +1765,6 @@ static void bt_controller_deinit_internal(void)
17091765
17101766 btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE ;
17111767
1712- btdm_lpcycle_us = 0 ;
1713- btdm_controller_set_sleep_mode (BTDM_MODEM_SLEEP_MODE_NONE );
1714-
17151768 esp_bt_power_domain_off ();
17161769
17171770 esp_phy_modem_deinit ();
0 commit comments