mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-02 20:24:32 +02:00
Merge branch 'feature/btdm_modem_sleep_with_32K_XTAL_under_light_sleep' into 'master'
Feature/btdm modem sleep with 32 k xtal under light sleep See merge request idf/esp-idf!4744
This commit is contained in:
@@ -161,23 +161,65 @@ menu Bluetooth
|
|||||||
prompt "Bluetooth low power clock"
|
prompt "Bluetooth low power clock"
|
||||||
depends on BTDM_MODEM_SLEEP_MODE_ORIG
|
depends on BTDM_MODEM_SLEEP_MODE_ORIG
|
||||||
help
|
help
|
||||||
Select the low power clock source for bluetooth controller
|
Select the low power clock source for bluetooth controller. Bluetooth low power clock is
|
||||||
|
the clock source to maintain time in sleep mode.
|
||||||
|
|
||||||
|
- "Main crystal" option provides good accuracy and can support Dynamic Frequency Scaling
|
||||||
|
to be used with Bluetooth modem sleep. Light sleep is not supported.
|
||||||
|
- "External 32kHz crystal" option allows user to use a 32.768kHz crystal as Bluetooth low
|
||||||
|
power clock. This option is allowed as long as External 32kHz crystal is configured as
|
||||||
|
the system RTC clock source. This option provides good accuracy and supports Bluetooth
|
||||||
|
modem sleep to be used alongside Dynamic Frequency Scaling or light sleep.
|
||||||
|
|
||||||
config BTDM_LPCLK_SEL_MAIN_XTAL
|
config BTDM_LPCLK_SEL_MAIN_XTAL
|
||||||
bool "Main crystal"
|
bool "Main crystal"
|
||||||
help
|
help
|
||||||
Main crystal can be used as low power clock for bluetooth modem sleep. If this option is
|
Main crystal can be used as low power clock for bluetooth modem sleep. If this option is
|
||||||
selected, bluetooth modem sleep can work under Dynamic Frequency Scaling(DFS) enabled, but
|
selected, bluetooth modem sleep can work under Dynamic Frequency Scaling(DFS) enabled, but
|
||||||
cannot work when light sleep is enabled. Main crystal has a relatively better performance than
|
cannot work when light sleep is enabled. Main crystal has a good performance in accuracy as
|
||||||
other bluetooth low power clock sources.
|
the bluetooth low power clock source.
|
||||||
|
|
||||||
config BTDM_LPCLK_SEL_EXT_32K_XTAL
|
config BTDM_LPCLK_SEL_EXT_32K_XTAL
|
||||||
bool "External 32kHz crystal"
|
bool "External 32kHz crystal"
|
||||||
depends on ESP32_RTC_CLK_SRC_EXT_CRYS
|
depends on ESP32_RTC_CLK_SRC_EXT_CRYS
|
||||||
|
help
|
||||||
|
External 32kHz crystal has a nominal frequency of 32.768kHz and provides good frequency
|
||||||
|
stability. If used as Bluetooth low power clock, External 32kHz can support Bluetooth
|
||||||
|
modem sleep to be used with both DFS and light sleep.
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
choice BTDM_BLE_SLEEP_CLOCK_ACCURACY
|
||||||
|
prompt "BLE Sleep Clock Accuracy"
|
||||||
|
depends on BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM
|
||||||
|
default BTDM_BLE_DEFAULT_SCA_250PPM
|
||||||
|
help
|
||||||
|
BLE Sleep Clock Accuracy(SCA) for the local device is used to estimate window widening in BLE
|
||||||
|
connection events. With a lower level of clock accuracy(e.g. 500ppm over 250ppm), the slave
|
||||||
|
needs a larger RX window to synchronize with master in each anchor point, thus resulting in an
|
||||||
|
increase of power consumption but a higher level of robustness in keeping connected. According
|
||||||
|
to the requirements of Bluetooth Core specification 4.2, the worst-case accuracy of Classic
|
||||||
|
Bluetooth low power oscialltor(LPO) is +/-250ppm in STANDBY and in low power modes such as
|
||||||
|
sniff. For BLE the worst-case SCA is +/-500ppm.
|
||||||
|
|
||||||
|
- "151ppm to 250ppm" option is the default value for Bluetooth Dual mode
|
||||||
|
- "251ppm to 500ppm" option can be used in BLE only mode when using external 32kHz crystal as
|
||||||
|
low power clock. This option is provided in case that BLE sleep clock has a lower level of
|
||||||
|
accuracy, or other error sources contribute to the inaccurate timing during sleep.
|
||||||
|
|
||||||
|
config BTDM_BLE_DEFAULT_SCA_500PPM
|
||||||
|
bool "251ppm to 500ppm"
|
||||||
|
depends on BTDM_LPCLK_SEL_EXT_32K_XTAL && BTDM_CTRL_MODE_BLE_ONLY
|
||||||
|
config BTDM_BLE_DEFAULT_SCA_250PPM
|
||||||
|
bool "151ppm to 250ppm"
|
||||||
|
endchoice
|
||||||
|
config BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF
|
||||||
|
int
|
||||||
|
default 0 if BTDM_BLE_DEFAULT_SCA_500PPM
|
||||||
|
default 1 if BTDM_BLE_DEFAULT_SCA_250PPM
|
||||||
|
default 1
|
||||||
|
|
||||||
config BTDM_BLE_SCAN_DUPL
|
config BTDM_BLE_SCAN_DUPL
|
||||||
bool "BLE Scan Duplicate Options"
|
bool "BLE Scan Duplicate Options"
|
||||||
depends on (BTDM_CTRL_MODE_BTDM || BTDM_CTRL_MODE_BLE_ONLY)
|
depends on (BTDM_CTRL_MODE_BTDM || BTDM_CTRL_MODE_BLE_ONLY)
|
||||||
|
@@ -79,6 +79,14 @@
|
|||||||
#define BTDM_MIN_SLEEP_DURATION (12) // threshold of interval in slots to allow to fall into modem sleep
|
#define BTDM_MIN_SLEEP_DURATION (12) // threshold of interval in slots to allow to fall into modem sleep
|
||||||
#define BTDM_MODEM_WAKE_UP_DELAY (4) // delay in slots of modem wake up procedure, including re-enable PHY/RF
|
#define BTDM_MODEM_WAKE_UP_DELAY (4) // delay in slots of modem wake up procedure, including re-enable PHY/RF
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_ENABLE
|
||||||
|
#ifndef CONFIG_BTDM_LPCLK_SEL_MAIN_XTAL
|
||||||
|
#define BTDM_ALLOW_LIGHT_SLEEP 1
|
||||||
|
#else
|
||||||
|
#define BTDM_ALLOW_LIGHT_SLEEP 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BT_DEBUG(...)
|
#define BT_DEBUG(...)
|
||||||
#define BT_API_CALL_CHECK(info, api_call, ret) \
|
#define BT_API_CALL_CHECK(info, api_call, ret) \
|
||||||
do{\
|
do{\
|
||||||
@@ -373,8 +381,11 @@ static DRAM_ATTR uint8_t btdm_lpcycle_us_frac = 0; // number of fractional bit f
|
|||||||
#ifdef CONFIG_PM_ENABLE
|
#ifdef CONFIG_PM_ENABLE
|
||||||
static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr;
|
static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr;
|
||||||
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock;
|
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock;
|
||||||
static DRAM_ATTR esp_pm_lock_handle_t s_light_sleep_pm_lock; // pm_lock to prevent light sleep due to incompatibility currently
|
|
||||||
static DRAM_ATTR QueueHandle_t s_pm_lock_sem = NULL;
|
static DRAM_ATTR QueueHandle_t s_pm_lock_sem = NULL;
|
||||||
|
#if !BTDM_ALLOW_LIGHT_SLEEP
|
||||||
|
// pm_lock to prevent light sleep when using main crystal as Bluetooth low power clock
|
||||||
|
static DRAM_ATTR esp_pm_lock_handle_t s_light_sleep_pm_lock;
|
||||||
|
#endif /* #if !BTDM_ALLOW_LIGHT_SLEEP */
|
||||||
static void btdm_slp_tmr_callback(void *arg);
|
static void btdm_slp_tmr_callback(void *arg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -807,7 +818,7 @@ static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
|
|||||||
// start a timer to wake up and acquire the pm_lock before modem_sleep awakes
|
// start a timer to wake up and acquire the pm_lock before modem_sleep awakes
|
||||||
uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles);
|
uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles);
|
||||||
|
|
||||||
#define BTDM_MIN_TIMER_UNCERTAINTY_US (1800)
|
#define BTDM_MIN_TIMER_UNCERTAINTY_US (500)
|
||||||
assert(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
|
assert(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
|
||||||
// allow a maximum time uncertainty to be about 488ppm(1/2048) at least as clock drift
|
// allow a maximum time uncertainty to be about 488ppm(1/2048) at least as clock drift
|
||||||
// and set the timer in advance
|
// and set the timer in advance
|
||||||
@@ -1093,9 +1104,11 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PM_ENABLE
|
#ifdef CONFIG_PM_ENABLE
|
||||||
|
#if !BTDM_ALLOW_LIGHT_SLEEP
|
||||||
if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) {
|
if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
#endif /* #if !BTDM_ALLOW_LIGHT_SLEEP */
|
||||||
if ((err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock)) != ESP_OK) {
|
if ((err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock)) != ESP_OK) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@@ -1135,7 +1148,8 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
|||||||
set_div_ret = btdm_lpclk_set_div(0);
|
set_div_ret = btdm_lpclk_set_div(0);
|
||||||
assert(select_src_ret && set_div_ret);
|
assert(select_src_ret && set_div_ret);
|
||||||
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
|
||||||
btdm_lpcycle_us = esp_clk_slowclk_cal_get();
|
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);
|
assert(btdm_lpcycle_us != 0);
|
||||||
#endif // CONFIG_BTDM_LPCLK_SEL_XX
|
#endif // CONFIG_BTDM_LPCLK_SEL_XX
|
||||||
btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_ORIG);
|
btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_ORIG);
|
||||||
@@ -1158,10 +1172,12 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
#ifdef CONFIG_PM_ENABLE
|
#ifdef CONFIG_PM_ENABLE
|
||||||
|
#if !BTDM_ALLOW_LIGHT_SLEEP
|
||||||
if (s_light_sleep_pm_lock != NULL) {
|
if (s_light_sleep_pm_lock != NULL) {
|
||||||
esp_pm_lock_delete(s_light_sleep_pm_lock);
|
esp_pm_lock_delete(s_light_sleep_pm_lock);
|
||||||
s_light_sleep_pm_lock = NULL;
|
s_light_sleep_pm_lock = NULL;
|
||||||
}
|
}
|
||||||
|
#endif /* #if !BTDM_ALLOW_LIGHT_SLEEP */
|
||||||
if (s_pm_lock != NULL) {
|
if (s_pm_lock != NULL) {
|
||||||
esp_pm_lock_delete(s_pm_lock);
|
esp_pm_lock_delete(s_pm_lock);
|
||||||
s_pm_lock = NULL;
|
s_pm_lock = NULL;
|
||||||
@@ -1189,8 +1205,10 @@ esp_err_t esp_bt_controller_deinit(void)
|
|||||||
periph_module_disable(PERIPH_BT_MODULE);
|
periph_module_disable(PERIPH_BT_MODULE);
|
||||||
|
|
||||||
#ifdef CONFIG_PM_ENABLE
|
#ifdef CONFIG_PM_ENABLE
|
||||||
|
#if !BTDM_ALLOW_LIGHT_SLEEP
|
||||||
esp_pm_lock_delete(s_light_sleep_pm_lock);
|
esp_pm_lock_delete(s_light_sleep_pm_lock);
|
||||||
s_light_sleep_pm_lock = NULL;
|
s_light_sleep_pm_lock = NULL;
|
||||||
|
#endif /* #if !BTDM_ALLOW_LIGHT_SLEEP */
|
||||||
esp_pm_lock_delete(s_pm_lock);
|
esp_pm_lock_delete(s_pm_lock);
|
||||||
s_pm_lock = NULL;
|
s_pm_lock = NULL;
|
||||||
esp_timer_stop(s_btdm_slp_tmr);
|
esp_timer_stop(s_btdm_slp_tmr);
|
||||||
@@ -1231,7 +1249,9 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM_ENABLE
|
#ifdef CONFIG_PM_ENABLE
|
||||||
|
#if !BTDM_ALLOW_LIGHT_SLEEP
|
||||||
esp_pm_lock_acquire(s_light_sleep_pm_lock);
|
esp_pm_lock_acquire(s_light_sleep_pm_lock);
|
||||||
|
#endif /* #if !BTDM_ALLOW_LIGHT_SLEEP */
|
||||||
esp_pm_lock_acquire(s_pm_lock);
|
esp_pm_lock_acquire(s_pm_lock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1269,7 +1289,9 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
|
|||||||
}
|
}
|
||||||
esp_phy_rf_deinit(PHY_BT_MODULE);
|
esp_phy_rf_deinit(PHY_BT_MODULE);
|
||||||
#ifdef CONFIG_PM_ENABLE
|
#ifdef CONFIG_PM_ENABLE
|
||||||
|
#if !BTDM_ALLOW_LIGHT_SLEEP
|
||||||
esp_pm_lock_release(s_light_sleep_pm_lock);
|
esp_pm_lock_release(s_light_sleep_pm_lock);
|
||||||
|
#endif /* #if !BTDM_ALLOW_LIGHT_SLEEP */
|
||||||
esp_pm_lock_release(s_pm_lock);
|
esp_pm_lock_release(s_pm_lock);
|
||||||
#endif
|
#endif
|
||||||
return ESP_ERR_INVALID_STATE;
|
return ESP_ERR_INVALID_STATE;
|
||||||
@@ -1310,7 +1332,9 @@ esp_err_t esp_bt_controller_disable(void)
|
|||||||
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
|
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
|
||||||
|
|
||||||
#ifdef CONFIG_PM_ENABLE
|
#ifdef CONFIG_PM_ENABLE
|
||||||
|
#if !BTDM_ALLOW_LIGHT_SLEEP
|
||||||
esp_pm_lock_release(s_light_sleep_pm_lock);
|
esp_pm_lock_release(s_light_sleep_pm_lock);
|
||||||
|
#endif /* #if !BTDM_ALLOW_LIGHT_SLEEP */
|
||||||
esp_pm_lock_release(s_pm_lock);
|
esp_pm_lock_release(s_pm_lock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -37,6 +37,21 @@ typedef enum {
|
|||||||
ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */
|
ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */
|
||||||
} esp_bt_mode_t;
|
} esp_bt_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief BLE sleep clock accuracy(SCA), values for ble_sca field in esp_bt_controller_config_t,
|
||||||
|
* currently only ESP_BLE_SCA_500PPM and ESP_BLE_SCA_250PPM are supported
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
ESP_BLE_SCA_500PPM = 0, /*!< BLE SCA at 500ppm */
|
||||||
|
ESP_BLE_SCA_250PPM, /*!< BLE SCA at 250ppm */
|
||||||
|
ESP_BLE_SCA_150PPM, /*!< BLE SCA at 150ppm */
|
||||||
|
ESP_BLE_SCA_100PPM, /*!< BLE SCA at 100ppm */
|
||||||
|
ESP_BLE_SCA_75PPM, /*!< BLE SCA at 75ppm */
|
||||||
|
ESP_BLE_SCA_50PPM, /*!< BLE SCA at 50ppm */
|
||||||
|
ESP_BLE_SCA_30PPM, /*!< BLE SCA at 30ppm */
|
||||||
|
ESP_BLE_SCA_20PPM, /*!< BLE SCA at 20ppm */
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_BT_ENABLED
|
#ifdef CONFIG_BT_ENABLED
|
||||||
/* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE,
|
/* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE,
|
||||||
the adv packet will be discarded until the memory is restored. */
|
the adv packet will be discarded until the memory is restored. */
|
||||||
@@ -106,15 +121,16 @@ the adv packet will be discarded until the memory is restored. */
|
|||||||
.hci_uart_no = BT_HCI_UART_NO_DEFAULT, \
|
.hci_uart_no = BT_HCI_UART_NO_DEFAULT, \
|
||||||
.hci_uart_baudrate = BT_HCI_UART_BAUDRATE_DEFAULT, \
|
.hci_uart_baudrate = BT_HCI_UART_BAUDRATE_DEFAULT, \
|
||||||
.scan_duplicate_mode = SCAN_DUPLICATE_MODE, \
|
.scan_duplicate_mode = SCAN_DUPLICATE_MODE, \
|
||||||
.scan_duplicate_type = SCAN_DUPLICATE_TYPE_VALUE, \
|
.scan_duplicate_type = SCAN_DUPLICATE_TYPE_VALUE, \
|
||||||
.normal_adv_size = NORMAL_SCAN_DUPLICATE_CACHE_SIZE, \
|
.normal_adv_size = NORMAL_SCAN_DUPLICATE_CACHE_SIZE, \
|
||||||
.mesh_adv_size = MESH_DUPLICATE_SCAN_CACHE_SIZE, \
|
.mesh_adv_size = MESH_DUPLICATE_SCAN_CACHE_SIZE, \
|
||||||
.send_adv_reserved_size = SCAN_SEND_ADV_RESERVED_SIZE, \
|
.send_adv_reserved_size = SCAN_SEND_ADV_RESERVED_SIZE, \
|
||||||
.controller_debug_flag = CONTROLLER_ADV_LOST_DEBUG_BIT, \
|
.controller_debug_flag = CONTROLLER_ADV_LOST_DEBUG_BIT, \
|
||||||
.mode = BTDM_CONTROLLER_MODE_EFF, \
|
.mode = BTDM_CONTROLLER_MODE_EFF, \
|
||||||
.ble_max_conn = CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF, \
|
.ble_max_conn = CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF, \
|
||||||
.bt_max_acl_conn = CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF, \
|
.bt_max_acl_conn = CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF, \
|
||||||
.bt_max_sync_conn = CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF, \
|
.bt_max_sync_conn = CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF, \
|
||||||
|
.ble_sca = CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF, \
|
||||||
.magic = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL, \
|
.magic = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL, \
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -150,6 +166,7 @@ typedef struct {
|
|||||||
* So, do not modify the value when esp_bt_controller_init()
|
* So, do not modify the value when esp_bt_controller_init()
|
||||||
*/
|
*/
|
||||||
uint8_t bt_max_sync_conn; /*!< BR/EDR maximum ACL connection numbers. Effective in menuconfig */
|
uint8_t bt_max_sync_conn; /*!< BR/EDR maximum ACL connection numbers. Effective in menuconfig */
|
||||||
|
uint8_t ble_sca; /*!< BLE low power crystal accuracy index */
|
||||||
uint32_t magic; /*!< Magic number */
|
uint32_t magic; /*!< Magic number */
|
||||||
} esp_bt_controller_config_t;
|
} esp_bt_controller_config_t;
|
||||||
|
|
||||||
|
Submodule components/bt/lib updated: 70d6a277d7...be2b20bbfc
Reference in New Issue
Block a user