Merge branch 'feat/support_136k_rc_clk_on_ble_sleep_v5.4' into 'release/v5.4'

Feat/support 136k rc clk on ble sleep (v5.4)

See merge request espressif/esp-idf!38621
This commit is contained in:
Island
2025-04-24 10:37:55 +08:00
14 changed files with 311 additions and 41 deletions

View File

@ -445,6 +445,23 @@ config BT_LE_LL_SCA
help
Sleep clock accuracy of our device (in ppm)
config BT_LE_LL_PEER_SCA_SET_ENABLE
bool "Enable to set constant peer SCA"
default n
help
Enable setting of constant peer SCA, use this if peer device has SCA larger than 500 PPM.
Enable this option, the controller will always use BT_LE_LL_PEER_SCA as the peer SCA value
to calculate the window widening instead of the value received from peer device.
config BT_LE_LL_PEER_SCA
int "Constant peer sleep clock accuracy value"
range 0 10000
depends on BT_LE_LL_PEER_SCA_SET_ENABLE
default 0
help
Set the sleep clock accuracy of peer device
config BT_LE_MAX_CONNECTIONS
int "Maximum number of concurrent connections"
depends on !BT_NIMBLE_ENABLED

View File

@ -45,6 +45,7 @@
#include "soc/syscon_reg.h"
#include "soc/modem_clkrst_reg.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_clk_tree_common.h"
#include "bt_osi_mem.h"
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
@ -151,6 +152,9 @@ extern void r_ble_rtc_wake_up_state_clr(void);
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
extern void esp_ble_set_wakeup_overhead(uint32_t overhead);
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
extern void r_ble_ll_customize_peer_sca_set(uint16_t peer_sca);
#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
extern int os_msys_init(void);
extern void os_msys_buf_free(void);
extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x,
@ -468,7 +472,13 @@ static bool s_ble_active = false;
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL;
#define BTDM_MIN_TIMER_UNCERTAINTY_US (200)
#endif // CONFIG_PM_ENABLE
#ifdef CONFIG_XTAL_FREQ_26
#define MAIN_XTAL_FREQ_HZ (26000000)
#else
#define MAIN_XTAL_FREQ_HZ (40000000)
#endif
static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID;
static DRAM_ATTR uint32_t s_bt_lpclk_freq = 100000;
#define BLE_RTC_DELAY_US (1800)
@ -599,6 +609,10 @@ modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void)
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src)
{
if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return;
}
if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) {
return;
}
@ -606,6 +620,27 @@ void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src)
s_bt_lpclk_src = clk_src;
}
uint32_t esp_bt_get_lpclk_freq(void)
{
return s_bt_lpclk_freq;
}
void esp_bt_set_lpclk_freq(uint32_t clk_freq)
{
if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return;
}
if (!clk_freq) {
return;
}
if (MAIN_XTAL_FREQ_HZ % clk_freq) {
return;
}
s_bt_lpclk_freq = clk_freq;
}
void controller_sleep_cb(uint32_t enable_tick, void *arg)
{
if (!s_ble_active) {
@ -624,11 +659,18 @@ void controller_wakeup_cb(void *arg)
if (s_ble_active) {
return;
}
esp_phy_enable(PHY_MODEM_BT);
// need to check if need to call pm lock here
#ifdef CONFIG_PM_ENABLE
esp_pm_config_t pm_config;
esp_pm_lock_acquire(s_pm_lock);
esp_pm_get_configuration(&pm_config);
assert(esp_rom_get_cpu_ticks_per_us() == pm_config.max_freq_mhz);
#endif //CONFIG_PM_ENABLE
esp_phy_enable(PHY_MODEM_BT);
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) {
uint32_t *clk_freq = (uint32_t *)arg;
*clk_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5;
}
// need to check if need to call pm lock here
s_ble_active = true;
}
@ -705,11 +747,7 @@ static void esp_bt_rtc_slow_clk_select(modem_clock_lpclk_src_t slow_clk_src)
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 1, MODEM_CLKRST_LP_TIMER_SEL_XTAL_S);
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_8M_S);
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_RTC_SLOW_S);
#ifdef CONFIG_XTAL_FREQ_26
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 129, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S);
#else
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 249, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S);
#endif // CONFIG_XTAL_FREQ_26
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, (MAIN_XTAL_FREQ_HZ/(5 * s_bt_lpclk_freq) - 1), MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S);
break;
case MODEM_CLOCK_LPCLK_SRC_EXT32K:
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using external 32.768 kHz XTAL as clock source");
@ -719,6 +757,14 @@ static void esp_bt_rtc_slow_clk_select(modem_clock_lpclk_src_t slow_clk_src)
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_RTC_SLOW_S);
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 0, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S);
break;
case MODEM_CLOCK_LPCLK_SRC_RC_SLOW:
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, use with caution as it may not maintain ACL or Sync process due to low clock accuracy!");
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL32K_S);
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL_S);
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_8M_S);
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 1, MODEM_CLKRST_LP_TIMER_SEL_RTC_SLOW_S);
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 0, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S);
break;
default:
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported slow clock");
assert(0);
@ -734,23 +780,26 @@ static modem_clock_lpclk_src_t ble_rtc_clk_init(esp_bt_controller_config_t *cfg)
#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
#else
#if CONFIG_RTC_CLK_SRC_INT_RC
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC_SLOW;
#elif CONFIG_RTC_CLK_SRC_EXT_OSC
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K;
} else {
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
}
#endif // CONFIG_RTC_CLK_SRC_INT_RC
#endif // CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL
}
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) {
cfg->rtc_freq = 32768;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
#ifdef CONFIG_XTAL_FREQ_26
cfg->rtc_freq = 40000;
#else
cfg->rtc_freq = 32000;
#endif // CONFIG_XTAL_FREQ_26
cfg->rtc_freq = s_bt_lpclk_freq;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) {
cfg->rtc_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5;
cfg->ble_ll_sca = 3000;
}
esp_bt_rtc_slow_clk_select(s_bt_lpclk_src);
return s_bt_lpclk_src;
@ -853,6 +902,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
goto modem_deint;
}
#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
r_ble_ll_customize_peer_sca_set(CONFIG_BT_LE_LL_PEER_SCA);
#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version());
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble rom commit:[%s]", r_ble_controller_get_rom_compile_version());

View File

@ -484,6 +484,23 @@ config BT_LE_LL_SCA
help
Sleep clock accuracy of our device (in ppm)
config BT_LE_LL_PEER_SCA_SET_ENABLE
bool "Enable to set constant peer SCA"
default n
help
Enable setting of constant peer SCA, use this if peer device has SCA larger than 500 PPM.
Enable this option, the controller will always use BT_LE_LL_PEER_SCA as the peer SCA value
to calculate the window widening instead of the value received from peer device.
config BT_LE_LL_PEER_SCA
int "Constant peer sleep clock accuracy value"
range 0 10000
depends on BT_LE_LL_PEER_SCA_SET_ENABLE
default 0
help
Set the sleep clock accuracy of peer device
config BT_LE_MAX_CONNECTIONS
int "Maximum number of concurrent connections"
depends on !BT_NIMBLE_ENABLED

View File

@ -52,6 +52,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_private/esp_clk_tree_common.h"
#include "hal/efuse_hal.h"
#include "soc/rtc.h"
@ -146,7 +147,9 @@ extern void r_priv_sdk_config_insert_proc_time_set(uint16_t insert_proc_time);
extern sleep_retention_entries_config_t *r_esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra);
extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead);
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
extern void r_esp_ble_change_rtc_freq(uint32_t freq);
#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
extern void r_ble_ll_customize_peer_sca_set(uint16_t peer_sca);
#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x,
const uint8_t *peer_pub_key_y,
const uint8_t *our_priv_key, uint8_t *out_dhkey);
@ -417,7 +420,10 @@ static bool s_ble_active = false;
#ifdef CONFIG_PM_ENABLE
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL;
#endif // CONFIG_PM_ENABLE
#define MAIN_XTAL_FREQ_HZ (48000000)
static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID;
static DRAM_ATTR uint32_t s_bt_lpclk_freq = 100000;
#define BLE_RTC_DELAY_US_LIGHT_SLEEP (2500)
#define BLE_RTC_DELAY_US_MODEM_SLEEP (500)
@ -547,10 +553,10 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src)
switch (slow_clk_src) {
case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL:
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source");
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (480 - 1));
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (MAIN_XTAL_FREQ_HZ/s_bt_lpclk_freq - 1));
break;
case MODEM_CLOCK_LPCLK_SRC_RC_SLOW:
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!");
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, use with caution as it may not maintain ACL or Sync process due to low clock accuracy!");
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1));
break;
case MODEM_CLOCK_LPCLK_SRC_XTAL32K:
@ -576,6 +582,10 @@ modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void)
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src)
{
if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return;
}
if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) {
return;
}
@ -583,6 +593,28 @@ void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src)
s_bt_lpclk_src = clk_src;
}
uint32_t esp_bt_get_lpclk_freq(void)
{
return s_bt_lpclk_freq;
}
void esp_bt_set_lpclk_freq(uint32_t clk_freq)
{
if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return;
}
if (!clk_freq) {
return;
}
if (MAIN_XTAL_FREQ_HZ % clk_freq) {
return;
}
s_bt_lpclk_freq = clk_freq;
}
IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg)
{
if (!s_ble_active) {
@ -604,10 +636,17 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
return;
}
#ifdef CONFIG_PM_ENABLE
esp_pm_config_t pm_config;
esp_pm_lock_acquire(s_pm_lock);
esp_pm_get_configuration(&pm_config);
assert(esp_rom_get_cpu_ticks_per_us() == pm_config.max_freq_mhz);
r_ble_rtc_wake_up_state_clr();
#endif //CONFIG_PM_ENABLE
esp_phy_enable(PHY_MODEM_BT);
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) {
uint32_t *clk_freq = (uint32_t *)arg;
*clk_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5;
}
s_ble_active = true;
}
@ -835,11 +874,12 @@ static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg)
}
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
cfg->rtc_freq = 100000;
cfg->rtc_freq = s_bt_lpclk_freq;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) {
cfg->rtc_freq = 32768;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) {
cfg->rtc_freq = 30000;
cfg->rtc_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5;
cfg->ble_ll_sca = 3000;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC32K) {
cfg->rtc_freq = 32000;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) {
@ -938,6 +978,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
goto modem_deint;
}
#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
r_ble_ll_customize_peer_sca_set(CONFIG_BT_LE_LL_PEER_SCA);
#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
ret = ble_stack_initEnv();
if (ret != ESP_OK) {
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_stack_initEnv failed %d", ret);

View File

@ -525,6 +525,23 @@ config BT_LE_LL_SCA
help
Sleep clock accuracy of our device (in ppm)
config BT_LE_LL_PEER_SCA_SET_ENABLE
bool "Enable to set constant peer SCA"
default n
help
Enable setting of constant peer SCA, use this if peer device has SCA larger than 500 PPM.
Enable this option, the controller will always use BT_LE_LL_PEER_SCA as the peer SCA value
to calculate the window widening instead of the value received from peer device.
config BT_LE_LL_PEER_SCA
int "Constant peer sleep clock accuracy value"
range 0 10000
depends on BT_LE_LL_PEER_SCA_SET_ENABLE
default 0
help
Set the sleep clock accuracy of peer device
config BT_LE_MAX_CONNECTIONS
int "Maximum number of concurrent connections"
depends on !BT_NIMBLE_ENABLED

View File

@ -42,6 +42,7 @@
#include "esp_phy_init.h"
#endif
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_clk_tree_common.h"
#include "bt_osi_mem.h"
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
@ -149,7 +150,9 @@ extern void r_priv_sdk_config_insert_proc_time_set(uint16_t insert_proc_time);
extern sleep_retention_entries_config_t *r_esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra);
extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead);
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
extern void r_esp_ble_change_rtc_freq(uint32_t freq);
#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
extern void r_ble_ll_customize_peer_sca_set(uint16_t peer_sca);
#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x,
const uint8_t *peer_pub_key_y,
const uint8_t *our_priv_key, uint8_t *out_dhkey);
@ -420,8 +423,12 @@ static bool s_ble_active = false;
#ifdef CONFIG_PM_ENABLE
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL;
#endif // CONFIG_PM_ENABLE
#define MAIN_XTAL_FREQ_HZ (40000000)
#define MAIN_XTAL_FREQ_HZ_WORKROUND (500000)
static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID;
#define BLE_RTC_DELAY_US_LIGHT_SLEEP (2500)
static DRAM_ATTR uint32_t s_bt_lpclk_freq = 100000;
#define BLE_RTC_DELAY_US_LIGHT_SLEEP (3200)
#define BLE_RTC_DELAY_US_MODEM_SLEEP (500)
#define BLE_CONTROLLER_MALLOC_CAPS (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT|MALLOC_CAP_DMA)
@ -548,20 +555,21 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src)
/* Select slow clock source for BT momdule */
switch (slow_clk_src) {
case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL:
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source");
#if SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND
uint32_t chip_version = efuse_hal_chip_revision();
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source, chip ver: %d", chip_version);
if (chip_version == 0) {
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (400 - 1));
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (MAIN_XTAL_FREQ_HZ/s_bt_lpclk_freq - 1));
} else{
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1));
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (MAIN_XTAL_FREQ_HZ_WORKROUND/s_bt_lpclk_freq - 1));
}
#else
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (400 - 1));
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source");
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (MAIN_XTAL_FREQ_HZ/s_bt_lpclk_freq - 1));
#endif // SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND
break;
case MODEM_CLOCK_LPCLK_SRC_RC_SLOW:
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!");
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, use with caution as it may not maintain ACL or Sync process due to low clock accuracy!");
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1));
break;
case MODEM_CLOCK_LPCLK_SRC_XTAL32K:
@ -587,6 +595,10 @@ modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void)
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src)
{
if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return;
}
if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) {
return;
}
@ -594,6 +606,38 @@ void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src)
s_bt_lpclk_src = clk_src;
}
uint32_t esp_bt_get_lpclk_freq(void)
{
return s_bt_lpclk_freq;
}
void esp_bt_set_lpclk_freq(uint32_t clk_freq)
{
uint32_t xtal_freq;
if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return;
}
if (!clk_freq) {
return;
}
xtal_freq = MAIN_XTAL_FREQ_HZ;
#if SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND
uint32_t chip_version = efuse_hal_chip_revision();
if (chip_version == 1) {
xtal_freq = MAIN_XTAL_FREQ_HZ_WORKROUND;
}
#endif // SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND
if (xtal_freq % clk_freq) {
return;
}
s_bt_lpclk_freq = clk_freq;
}
IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg)
{
if (!s_ble_active) {
@ -615,10 +659,17 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
return;
}
#ifdef CONFIG_PM_ENABLE
esp_pm_config_t pm_config;
esp_pm_lock_acquire(s_pm_lock);
esp_pm_get_configuration(&pm_config);
assert(esp_rom_get_cpu_ticks_per_us() == pm_config.max_freq_mhz);
r_ble_rtc_wake_up_state_clr();
#endif //CONFIG_PM_ENABLE
esp_phy_enable(PHY_MODEM_BT);
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) {
uint32_t *clk_freq = (uint32_t *)arg;
*clk_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5;
}
s_ble_active = true;
}
@ -853,11 +904,12 @@ static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg)
}
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
cfg->rtc_freq = 100000;
cfg->rtc_freq = s_bt_lpclk_freq;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) {
cfg->rtc_freq = 32768;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) {
cfg->rtc_freq = 30000;
cfg->rtc_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5;
cfg->ble_ll_sca = 3000;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC32K) {
cfg->rtc_freq = 32000;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) {
@ -956,6 +1008,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
goto modem_deint;
}
#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
r_ble_ll_customize_peer_sca_set(CONFIG_BT_LE_LL_PEER_SCA);
#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
ret = ble_stack_initEnv();
if (ret != ESP_OK) {
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_stack_initEnv failed %d", ret);

View File

@ -519,6 +519,23 @@ config BT_LE_LL_SCA
help
Sleep clock accuracy of our device (in ppm)
config BT_LE_LL_PEER_SCA_SET_ENABLE
bool "Enable to set constant peer SCA"
default n
help
Enable setting of constant peer SCA, use this if peer device has SCA larger than 500 PPM.
Enable this option, the controller will always use BT_LE_LL_PEER_SCA as the peer SCA value
to calculate the window widening instead of the value received from peer device.
config BT_LE_LL_PEER_SCA
int "Constant peer sleep clock accuracy value"
range 0 10000
depends on BT_LE_LL_PEER_SCA_SET_ENABLE
default 0
help
Set the sleep clock accuracy of peer device
config BT_LE_MAX_CONNECTIONS
int "Maximum number of concurrent connections"
depends on !BT_NIMBLE_ENABLED

View File

@ -51,6 +51,7 @@
#include "freertos/task.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_sleep.h"
#include "soc/rtc.h"
@ -147,7 +148,9 @@ extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead);
#if CONFIG_PM_ENABLE
extern void r_esp_ble_stop_wakeup_timing(void);
#endif // CONFIG_PM_ENABLE
extern void r_esp_ble_change_rtc_freq(uint32_t freq);
#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
extern void r_ble_ll_customize_peer_sca_set(uint16_t peer_sca);
#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x,
const uint8_t *peer_pub_key_y,
const uint8_t *our_priv_key, uint8_t *out_dhkey);
@ -418,7 +421,9 @@ static bool s_ble_active = false;
#ifdef CONFIG_PM_ENABLE
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL;
#endif // CONFIG_PM_ENABLE
#define MAIN_XTAL_FREQ_HZ (32000000)
static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID;
static DRAM_ATTR uint32_t s_bt_lpclk_freq = 100000;
#define BLE_CONTROLLER_MALLOC_CAPS (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT|MALLOC_CAP_DMA)
void *malloc_ble_controller_mem(size_t size)
@ -549,10 +554,10 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src)
switch (slow_clk_src) {
case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL:
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source");
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (320 - 1));
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (MAIN_XTAL_FREQ_HZ/s_bt_lpclk_freq - 1));
break;
case MODEM_CLOCK_LPCLK_SRC_RC_SLOW:
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!");
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, use with caution as it may not maintain ACL or Sync process due to low clock accuracy!");
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1));
break;
case MODEM_CLOCK_LPCLK_SRC_XTAL32K:
@ -578,6 +583,10 @@ modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void)
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src)
{
if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return;
}
if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) {
return;
}
@ -585,6 +594,28 @@ void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src)
s_bt_lpclk_src = clk_src;
}
uint32_t esp_bt_get_lpclk_freq(void)
{
return s_bt_lpclk_freq;
}
void esp_bt_set_lpclk_freq(uint32_t clk_freq)
{
if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return;
}
if (!clk_freq) {
return;
}
if (MAIN_XTAL_FREQ_HZ % clk_freq) {
return;
}
s_bt_lpclk_freq = clk_freq;
}
IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg)
{
if (!s_ble_active) {
@ -606,10 +637,17 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
return;
}
#ifdef CONFIG_PM_ENABLE
esp_pm_config_t pm_config;
esp_pm_lock_acquire(s_pm_lock);
esp_pm_get_configuration(&pm_config);
assert(esp_rom_get_cpu_ticks_per_us() == pm_config.max_freq_mhz);
r_ble_rtc_wake_up_state_clr();
#endif //CONFIG_PM_ENABLE
esp_phy_enable(PHY_MODEM_BT);
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) {
uint32_t *clk_freq = (uint32_t *)arg;
*clk_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5;
}
s_ble_active = true;
}
@ -830,11 +868,12 @@ static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg)
}
if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
cfg->rtc_freq = 100000;
cfg->rtc_freq = s_bt_lpclk_freq;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) {
cfg->rtc_freq = 32768;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) {
cfg->rtc_freq = 30000;
cfg->rtc_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5;
cfg->ble_ll_sca = 3000;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC32K) {
cfg->rtc_freq = 32000;
} else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) {
@ -932,6 +971,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
goto modem_deint;
}
#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
r_ble_ll_customize_peer_sca_set(CONFIG_BT_LE_LL_PEER_SCA);
#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE
ret = ble_stack_initEnv();
if (ret != ESP_OK) {
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_stack_initEnv failed %d", ret);
@ -1225,7 +1268,6 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
return ret;
}
esp_bt_controller_status_t esp_bt_controller_get_status(void)
{
return ble_controller_status;

View File

@ -438,11 +438,13 @@ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr);
void esp_ble_controller_log_dump_all(bool output);
#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
#if CONFIG_PM_ENABLE
modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void);
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src);
#endif // CONFIG_PM_ENABLE
uint32_t esp_bt_get_lpclk_freq(void);
void esp_bt_set_lpclk_freq(uint32_t clk_freq);
#ifdef __cplusplus
}

View File

@ -441,6 +441,10 @@ modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void);
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src);
uint32_t esp_bt_get_lpclk_freq(void);
void esp_bt_set_lpclk_freq(uint32_t clk_freq);
#ifdef __cplusplus
}
#endif

View File

@ -500,6 +500,10 @@ modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void);
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src);
uint32_t esp_bt_get_lpclk_freq(void);
void esp_bt_set_lpclk_freq(uint32_t clk_freq);
#ifdef __cplusplus
}
#endif

View File

@ -444,6 +444,10 @@ modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void);
void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src);
uint32_t esp_bt_get_lpclk_freq(void);
void esp_bt_set_lpclk_freq(uint32_t clk_freq);
#ifdef __cplusplus
}
#endif

View File

@ -236,7 +236,6 @@ r_ble_ll_conn_master_init = 0x40000df8;
r_ble_ll_conn_module_deinit = 0x40000dfc;
r_ble_ll_conn_module_init = 0x40000e00;
r_ble_ll_conn_module_reset = 0x40000e04;
r_ble_ll_conn_next_event = 0x40000e08;
r_ble_ll_conn_num_comp_pkts_event_send = 0x40000e0c;
r_ble_ll_conn_prepare_tx_pdu = 0x40000e10;
r_ble_ll_conn_process_conn_params = 0x40000e14;
@ -438,7 +437,6 @@ r_ble_ll_read_rf_path_compensation = 0x40001120;
r_ble_ll_read_supp_features = 0x40001124;
r_ble_ll_read_supp_states = 0x40001128;
r_ble_ll_read_tx_power = 0x4000112c;
r_ble_ll_reset = 0x40001130;
r_ble_ll_resolv_clear_all_pl_bit = 0x40001134;
r_ble_ll_resolv_clear_all_wl_bit = 0x40001138;
r_ble_ll_resolv_deinit = 0x4000113c;
@ -598,7 +596,6 @@ r_ble_ll_usecs_to_ticks_round_up = 0x400013a0;
r_ble_ll_utils_calc_access_addr = 0x400013a4;
r_ble_ll_utils_calc_dci_csa2 = 0x400013a8;
r_ble_ll_utils_calc_num_used_chans = 0x400013ac;
r_ble_ll_utils_calc_window_widening = 0x400013b0;
r_ble_ll_utils_csa2_perm = 0x400013b4;
r_ble_ll_utils_csa2_prng = 0x400013b8;
r_ble_ll_utils_remapped_channel = 0x400013bc;
@ -911,11 +908,9 @@ r_ble_phy_sequence_update_conn_ind_params = 0x40001884;
r_ble_phy_set_adv_mode = 0x40001888;
r_ble_phy_set_coex_pti = 0x4000188c;
r_ble_phy_set_conn_ind_pdu = 0x40001890;
r_ble_phy_set_conn_mode = 0x40001894;
r_ble_phy_set_dev_address = 0x40001898;
r_ble_phy_set_rx_pwr_compensation = 0x4000189c;
r_ble_phy_set_rxhdr = 0x400018a0;
r_ble_phy_set_scan_mode = 0x400018a4;
r_ble_phy_set_sequence_mode = 0x400018a8;
r_ble_phy_set_single_packet_rx_sequence = 0x400018ac;
r_ble_phy_set_single_packet_tx_sequence = 0x400018b0;

View File

@ -480,7 +480,6 @@ r_ble_ll_usecs_to_ticks_round_up = 0x400013a0;
r_ble_ll_utils_calc_access_addr = 0x400013a4;
r_ble_ll_utils_calc_dci_csa2 = 0x400013a8;
r_ble_ll_utils_calc_num_used_chans = 0x400013ac;
r_ble_ll_utils_calc_window_widening = 0x400013b0;
r_ble_ll_utils_csa2_perm = 0x400013b4;
r_ble_ll_utils_csa2_prng = 0x400013b8;
r_ble_ll_utils_remapped_channel = 0x400013bc;
@ -719,7 +718,6 @@ r_ble_phy_sequence_tx_end_invoke = 0x40001880;
r_ble_phy_sequence_update_conn_ind_params = 0x40001884;
r_ble_phy_set_coex_pti = 0x4000188c;
r_ble_phy_set_conn_ind_pdu = 0x40001890;
r_ble_phy_set_conn_mode = 0x40001894;
r_ble_phy_set_dev_address = 0x40001898;
r_ble_phy_set_rx_pwr_compensation = 0x4000189c;
r_ble_phy_set_single_packet_rx_sequence = 0x400018ac;