mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 02:37:19 +02:00
feat(ble): support ble sleep using 136 kHz RC on ESP32-C5
(cherry picked from commit cb8ea7951c
)
Co-authored-by: cjin <jinchen@espressif.com>
This commit is contained 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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user