diff --git a/components/bt/controller/esp32c2/Kconfig.in b/components/bt/controller/esp32c2/Kconfig.in index f4417f16a0..69623987e0 100644 --- a/components/bt/controller/esp32c2/Kconfig.in +++ b/components/bt/controller/esp32c2/Kconfig.in @@ -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 diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index bd2cc4425e..9d6c77d462 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -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()); diff --git a/components/bt/controller/esp32c5/Kconfig.in b/components/bt/controller/esp32c5/Kconfig.in index fbd1269355..6df6c58ee2 100644 --- a/components/bt/controller/esp32c5/Kconfig.in +++ b/components/bt/controller/esp32c5/Kconfig.in @@ -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 diff --git a/components/bt/controller/esp32c5/bt.c b/components/bt/controller/esp32c5/bt.c index c9fdc89100..da65ecd10e 100644 --- a/components/bt/controller/esp32c5/bt.c +++ b/components/bt/controller/esp32c5/bt.c @@ -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); diff --git a/components/bt/controller/esp32c6/Kconfig.in b/components/bt/controller/esp32c6/Kconfig.in index d0120d6f82..c48db83e79 100644 --- a/components/bt/controller/esp32c6/Kconfig.in +++ b/components/bt/controller/esp32c6/Kconfig.in @@ -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 diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index 9e3253d4c6..3c56967553 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -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); diff --git a/components/bt/controller/esp32h2/Kconfig.in b/components/bt/controller/esp32h2/Kconfig.in index 524785e45f..d549d0bdb5 100644 --- a/components/bt/controller/esp32h2/Kconfig.in +++ b/components/bt/controller/esp32h2/Kconfig.in @@ -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 diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index e5894ecd22..792cf64ded 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -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; diff --git a/components/bt/include/esp32c2/include/esp_bt.h b/components/bt/include/esp32c2/include/esp_bt.h index 262c411470..de161b08f6 100644 --- a/components/bt/include/esp32c2/include/esp_bt.h +++ b/components/bt/include/esp32c2/include/esp_bt.h @@ -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 } diff --git a/components/bt/include/esp32c5/include/esp_bt.h b/components/bt/include/esp32c5/include/esp_bt.h index ec292a573d..3333adee4b 100644 --- a/components/bt/include/esp32c5/include/esp_bt.h +++ b/components/bt/include/esp32c5/include/esp_bt.h @@ -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 diff --git a/components/bt/include/esp32c6/include/esp_bt.h b/components/bt/include/esp32c6/include/esp_bt.h index 9da4cbe8f4..dc44f58e3d 100644 --- a/components/bt/include/esp32c6/include/esp_bt.h +++ b/components/bt/include/esp32c6/include/esp_bt.h @@ -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 diff --git a/components/bt/include/esp32h2/include/esp_bt.h b/components/bt/include/esp32h2/include/esp_bt.h index 6b412834c0..6c0634033d 100644 --- a/components/bt/include/esp32h2/include/esp_bt.h +++ b/components/bt/include/esp32h2/include/esp_bt.h @@ -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 diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld index 16200a4de2..af1666fa9b 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld @@ -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; diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ble.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ble.ld index 1ff67da39f..22c81d7309 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ble.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ble.ld @@ -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;