mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
Merge branch 'ble_dev/support_esp32h2_modem_clock_selection' into 'master'
ble: support esp32h2 modem clock selection Closes EBLE50Y23-129 See merge request espressif/esp-idf!24387
This commit is contained in:
commit
d918b5226c
@ -395,6 +395,26 @@ choice BT_LE_WAKEUP_SOURCE
|
||||
Use BLE rtc timer to wakeup CPU
|
||||
endchoice
|
||||
|
||||
choice BT_LE_LP_CLK_SRC
|
||||
prompt "BLE low power clock source"
|
||||
default BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
config BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
bool "Use main XTAL as RTC clock source"
|
||||
help
|
||||
User main XTAL as RTC clock source.
|
||||
This option is recommended if external 32.768k XTAL is not available.
|
||||
Using the external 32.768 kHz XTAL will have lower current consumption
|
||||
in light sleep compared to using the main XTAL.
|
||||
|
||||
config BT_LE_LP_CLK_SRC_DEFAULT
|
||||
bool "Use system RTC slow clock source"
|
||||
help
|
||||
Use the same slow clock source as system RTC
|
||||
Using any clock source other than external 32.768 kHz XTAL supports only
|
||||
legacy ADV and SCAN due to low clock accuracy.
|
||||
|
||||
endchoice
|
||||
|
||||
config BT_LE_USE_ESP_TIMER
|
||||
bool "Enable Esp Timer for Callout"
|
||||
depends on !BT_NIMBLE_ENABLED
|
||||
|
@ -40,6 +40,10 @@
|
||||
#include "hci_uart.h"
|
||||
#include "bt_osi_mem.h"
|
||||
|
||||
#if SOC_PM_RETENTION_HAS_CLOCK_BUG
|
||||
#include "esp_private/sleep_retention.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||
#include "hci/hci_hal.h"
|
||||
#endif // CONFIG_BT_BLUEDROID_ENABLED
|
||||
@ -49,7 +53,6 @@
|
||||
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_sleep.h"
|
||||
|
||||
/* Macro definition
|
||||
************************************************************************
|
||||
*/
|
||||
@ -122,9 +125,12 @@ extern void npl_freertos_mempool_deinit(void);
|
||||
extern int os_msys_buf_alloc(void);
|
||||
extern uint32_t r_os_cputime_get32(void);
|
||||
extern uint32_t r_os_cputime_ticks_to_usecs(uint32_t ticks);
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
extern const sleep_retention_entries_config_t *esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra);
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
extern void ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg,
|
||||
void *w_arg, uint32_t us_to_enabled);
|
||||
extern void ble_rtc_wake_up_state_clr(void);
|
||||
extern void r_ble_rtc_wake_up_state_clr(void);
|
||||
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,
|
||||
@ -184,11 +190,13 @@ static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL;
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
|
||||
#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
#define BLE_RTC_DELAY_US (1100)
|
||||
#define BLE_RTC_DELAY_US_LIGHT_SLEEP (5100)
|
||||
#define BLE_RTC_DELAY_US_MODEM_SLEEP (1500)
|
||||
#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
|
||||
#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER
|
||||
#define BLE_RTC_DELAY_US (0)
|
||||
#define BLE_RTC_DELAY_US_LIGHT_SLEEP (2000)
|
||||
#define BLE_RTC_DELAY_US_MODEM_SLEEP (0)
|
||||
static void ble_sleep_timer_callback(void *arg);
|
||||
static DRAM_ATTR esp_timer_handle_t s_ble_sleep_timer = NULL;
|
||||
#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER
|
||||
@ -427,8 +435,7 @@ IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg)
|
||||
if (!s_ble_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER
|
||||
uint32_t delta_tick;
|
||||
uint32_t us_to_sleep;
|
||||
@ -458,11 +465,14 @@ IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg)
|
||||
#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
r_ble_rtc_wake_up_state_clr();
|
||||
#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
|
||||
#if SOC_PM_RETENTION_HAS_CLOCK_BUG
|
||||
sleep_retention_do_extra_retention(true);
|
||||
#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
esp_phy_disable();
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_release(s_pm_lock);
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
|
||||
esp_phy_disable();
|
||||
s_ble_active = false;
|
||||
}
|
||||
|
||||
@ -471,24 +481,44 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
|
||||
if (s_ble_active) {
|
||||
return;
|
||||
}
|
||||
esp_phy_enable();
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
esp_pm_lock_acquire(s_pm_lock);
|
||||
r_ble_rtc_wake_up_state_clr();
|
||||
#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_RETENTION_HAS_CLOCK_BUG
|
||||
sleep_retention_do_extra_retention(false);
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_RETENTION_HAS_CLOCK_BUG */
|
||||
#endif //CONFIG_PM_ENABLE
|
||||
|
||||
esp_phy_enable();
|
||||
s_ble_active = true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
#ifdef CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER
|
||||
static void ble_sleep_timer_callback(void * arg)
|
||||
{
|
||||
esp_pm_lock_acquire(s_pm_lock);
|
||||
}
|
||||
#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER
|
||||
|
||||
static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra)
|
||||
{
|
||||
uint8_t size;
|
||||
const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra);
|
||||
esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
if (err == ESP_OK) {
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization");
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
static void sleep_modem_ble_mac_modem_state_deinit(void)
|
||||
{
|
||||
sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BLE_MAC);
|
||||
}
|
||||
|
||||
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
|
||||
esp_err_t controller_sleep_init(void)
|
||||
{
|
||||
@ -496,12 +526,13 @@ esp_err_t controller_sleep_init(void)
|
||||
|
||||
#ifdef CONFIG_BT_LE_SLEEP_ENABLE
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "BLE modem sleep is enabled");
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
|
||||
500 + BLE_RTC_DELAY_US);
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
BLE_RTC_DELAY_US_LIGHT_SLEEP);
|
||||
#else
|
||||
ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
|
||||
BLE_RTC_DELAY_US_MODEM_SLEEP);
|
||||
#endif /* FREERTOS_USE_TICKLESS_IDLE */
|
||||
#endif // CONFIG_BT_LE_SLEEP_ENABLE
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
@ -510,7 +541,7 @@ esp_err_t controller_sleep_init(void)
|
||||
goto error;
|
||||
}
|
||||
esp_pm_lock_acquire(s_pm_lock);
|
||||
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER
|
||||
esp_timer_create_args_t create_args = {
|
||||
.callback = ble_sleep_timer_callback,
|
||||
@ -524,20 +555,23 @@ esp_err_t controller_sleep_init(void)
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is ESP timer");
|
||||
#endif //CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER
|
||||
|
||||
/* Create a new regdma link for BLE related register restoration */
|
||||
rc = sleep_modem_ble_mac_modem_state_init(1);
|
||||
assert(rc == 0);
|
||||
#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
esp_sleep_enable_bt_wakeup();
|
||||
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is BLE timer");
|
||||
#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
return rc;
|
||||
|
||||
error:
|
||||
/*lock should release first and then delete*/
|
||||
if (s_pm_lock != NULL) {
|
||||
esp_pm_lock_release(s_pm_lock);
|
||||
esp_pm_lock_delete(s_pm_lock);
|
||||
s_pm_lock = NULL;
|
||||
}
|
||||
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
esp_sleep_disable_bt_wakeup();
|
||||
#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
|
||||
#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER
|
||||
if (s_ble_sleep_timer != NULL) {
|
||||
esp_timer_stop(s_ble_sleep_timer);
|
||||
@ -545,34 +579,26 @@ error:
|
||||
s_ble_sleep_timer = NULL;
|
||||
}
|
||||
#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER
|
||||
|
||||
#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
esp_sleep_disable_bt_wakeup();
|
||||
#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
|
||||
#endif //CONFIG_PM_ENABLE
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
/*lock should release first and then delete*/
|
||||
if (s_pm_lock != NULL) {
|
||||
esp_pm_lock_release(s_pm_lock);
|
||||
esp_pm_lock_delete(s_pm_lock);
|
||||
s_pm_lock = NULL;
|
||||
}
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void controller_sleep_deinit(void)
|
||||
{
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
r_ble_rtc_wake_up_state_clr();
|
||||
esp_sleep_disable_bt_wakeup();
|
||||
#endif //CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER
|
||||
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_AUTO);
|
||||
|
||||
/* lock should be released first */
|
||||
if (s_ble_active) {
|
||||
esp_pm_lock_release(s_pm_lock);
|
||||
}
|
||||
|
||||
esp_pm_lock_delete(s_pm_lock);
|
||||
s_pm_lock = NULL;
|
||||
|
||||
sleep_modem_ble_mac_modem_state_deinit();
|
||||
#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER
|
||||
if (s_ble_sleep_timer != NULL) {
|
||||
esp_timer_stop(s_ble_sleep_timer);
|
||||
@ -580,6 +606,12 @@ void controller_sleep_deinit(void)
|
||||
s_ble_sleep_timer = NULL;
|
||||
}
|
||||
#endif //CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER
|
||||
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
/* lock should be released first */
|
||||
esp_pm_lock_release(s_pm_lock);
|
||||
esp_pm_lock_delete(s_pm_lock);
|
||||
s_pm_lock = NULL;
|
||||
#endif //CONFIG_PM_ENABLE
|
||||
}
|
||||
|
||||
@ -715,7 +747,27 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
|
||||
/* Enable BT-related clocks */
|
||||
modem_clock_module_enable(PERIPH_BT_MODULE);
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL, 249);
|
||||
#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source");
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL, (320 - 1));
|
||||
#else
|
||||
#if CONFIG_RTC_CLK_SRC_INT_RC
|
||||
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!");
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_RC_SLOW, (5 - 1));
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_CRYS
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using external 32.768 kHz XTAL as clock source");
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_XTAL32K, (1 - 1));
|
||||
#elif CONFIG_RTC_CLK_SRC_INT_RC32K
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!");
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_RC32K, (1 - 1));
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_OSC
|
||||
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz oscillator as clock source, can only run legacy ADV or SCAN due to low clock accuracy!");
|
||||
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_EXT32K, (1 - 1));
|
||||
#else
|
||||
ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source");
|
||||
assert(0);
|
||||
#endif
|
||||
#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */
|
||||
esp_phy_enable();
|
||||
esp_btbb_enable();
|
||||
s_ble_active = true;
|
||||
|
@ -196,7 +196,17 @@ extern "C" {
|
||||
|
||||
#define BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N (3000)
|
||||
|
||||
#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL
|
||||
#define RTC_FREQ_N (100000) /* in Hz */
|
||||
#else
|
||||
#if CONFIG_RTC_CLK_SRC_INT_RC
|
||||
#define RTC_FREQ_N (30000) /* in Hz */
|
||||
#elif CONFIG_RTC_CLK_SRC_EXT_CRYS
|
||||
#define RTC_FREQ_N (32768) /* in Hz */
|
||||
#else
|
||||
#define RTC_FREQ_N (32000) /* in Hz */
|
||||
#endif
|
||||
#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */
|
||||
|
||||
#define BLE_LL_TX_PWR_DBM_N (9)
|
||||
|
||||
|
@ -29,6 +29,7 @@ extern "C" {
|
||||
#define REGDMA_PHY_LINK(_pri) ((0x00 << 8) | _pri)
|
||||
#define REGDMA_PCR_LINK(_pri) ((0x01 << 8) | _pri)
|
||||
#define REGDMA_MODEMSYSCON_LINK(_pri) ((0x02 << 8) | _pri)
|
||||
#define REGDMA_MODEMLPCON_LINK(_pri) ((0x03 << 8) | _pri)
|
||||
|
||||
#define REGDMA_INTMTX_LINK(_pri) ((0x0d << 8) | _pri)
|
||||
#define REGDMA_HPSYS_LINK(_pri) ((0x0e << 8) | _pri)
|
||||
|
@ -23,6 +23,10 @@
|
||||
#include "soc/pcr_reg.h"
|
||||
#include "modem/modem_syscon_reg.h"
|
||||
|
||||
#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG
|
||||
#include "modem/modem_lpcon_reg.h"
|
||||
#endif
|
||||
|
||||
static __attribute__((unused)) const char *TAG = "sleep_clock";
|
||||
|
||||
esp_err_t sleep_clock_system_retention_init(void)
|
||||
@ -50,9 +54,15 @@ void sleep_clock_system_retention_deinit(void)
|
||||
esp_err_t sleep_clock_modem_retention_init(void)
|
||||
{
|
||||
#define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1)
|
||||
#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG
|
||||
#define N_REGS_LPCON() (((MODEM_LPCON_MEM_CONF_REG - MODEM_LPCON_TEST_CONF_REG) / 4) + 1)
|
||||
#endif
|
||||
|
||||
const static sleep_retention_entries_config_t modem_regs_retention[] = {
|
||||
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */
|
||||
#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG
|
||||
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK(0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) } /* MODEM LPCON */
|
||||
#endif
|
||||
};
|
||||
|
||||
esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_2, SLEEP_RETENTION_MODULE_CLOCK_MODEM);
|
||||
|
24
components/esp_phy/esp32h2/include/btbb_retention_reg.h
Normal file
24
components/esp_phy/esp32h2/include/btbb_retention_reg.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// btbb sleep retention reg
|
||||
|
||||
#define BB_PART_0_SIZE 93
|
||||
#define BB_PART_1_SIZE 62
|
||||
#define BB_PART_2_SIZE 19
|
||||
#define BB_PART_0_ADDR 0x600A2000
|
||||
#define BB_PART_1_ADDR 0x600A2800
|
||||
#define BB_PART_2_ADDR 0x600A2C00
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -17,7 +17,7 @@ static _lock_t s_btbb_access_lock;
|
||||
static uint8_t s_btbb_access_ref = 0;
|
||||
|
||||
|
||||
#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE && !CONFIG_IDF_TARGET_ESP32H2
|
||||
#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#include "esp_private/sleep_retention.h"
|
||||
#include "btbb_retention_reg.h"
|
||||
static const char* TAG = "btbb_init";
|
||||
@ -33,7 +33,7 @@ static esp_err_t btbb_sleep_retention_init(void)
|
||||
const static sleep_retention_entries_config_t btbb_regs_retention[] = {
|
||||
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_BT_BB_LINK(0x00), BB_PART_0_ADDR, BB_PART_0_ADDR, BB_PART_0_SIZE, 0, 0), .owner = BTBB_LINK_OWNER },
|
||||
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_BT_BB_LINK(0x01), BB_PART_1_ADDR, BB_PART_1_ADDR, BB_PART_1_SIZE, 0, 0), .owner = BTBB_LINK_OWNER },
|
||||
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_BT_BB_LINK(0x02), BB_PART_2_ADDR, BB_PART_2_ADDR, BB_PART_2_SIZE, 0, 0), .owner = BTBB_LINK_OWNER }
|
||||
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_BT_BB_LINK(0x02), BB_PART_2_ADDR, BB_PART_2_ADDR, BB_PART_2_SIZE, 0, 0), .owner = BTBB_LINK_OWNER },
|
||||
};
|
||||
esp_err_t err = sleep_retention_entries_create(btbb_regs_retention, ARRAY_SIZE(btbb_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BT_BB);
|
||||
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for btbb retention");
|
||||
@ -45,7 +45,7 @@ static void btbb_sleep_retention_deinit(void)
|
||||
{
|
||||
sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BT_BB);
|
||||
}
|
||||
#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE && !CONFIG_IDF_TARGET_ESP32H2
|
||||
#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
|
||||
|
||||
void esp_btbb_enable(void)
|
||||
@ -53,9 +53,9 @@ void esp_btbb_enable(void)
|
||||
_lock_acquire(&s_btbb_access_lock);
|
||||
if (s_btbb_access_ref == 0) {
|
||||
bt_bb_v2_init_cmplx(BTBB_ENABLE_VERSION_PRINT);
|
||||
#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE && !CONFIG_IDF_TARGET_ESP32H2
|
||||
#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
btbb_sleep_retention_init();
|
||||
#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE && !CONFIG_IDF_TARGET_ESP32H2
|
||||
#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
}
|
||||
s_btbb_access_ref++;
|
||||
_lock_release(&s_btbb_access_lock);
|
||||
@ -65,9 +65,9 @@ void esp_btbb_disable(void)
|
||||
{
|
||||
_lock_acquire(&s_btbb_access_lock);
|
||||
if (s_btbb_access_ref && (--s_btbb_access_ref == 0)) {
|
||||
#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE && !CONFIG_IDF_TARGET_ESP32H2
|
||||
#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
btbb_sleep_retention_deinit();
|
||||
#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE && !CONFIG_IDF_TARGET_ESP32H2
|
||||
#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
}
|
||||
_lock_release(&s_btbb_access_lock);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -12,14 +12,13 @@
|
||||
#define PHY_ENABLE_VERSION_PRINT 1
|
||||
|
||||
static DRAM_ATTR portMUX_TYPE s_phy_int_mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
extern void phy_version_print(void);
|
||||
|
||||
extern void phy_version_print(void);
|
||||
static _lock_t s_phy_access_lock;
|
||||
|
||||
/* Reference count of enabling PHY */
|
||||
static uint8_t s_phy_access_ref = 0;
|
||||
|
||||
extern void bt_bb_v2_init_cmplx(int print_version);
|
||||
static bool s_phy_is_enabled = false;
|
||||
|
||||
uint32_t IRAM_ATTR phy_enter_critical(void)
|
||||
{
|
||||
@ -47,17 +46,32 @@ void esp_phy_enable(void)
|
||||
{
|
||||
_lock_acquire(&s_phy_access_lock);
|
||||
if (s_phy_access_ref == 0) {
|
||||
register_chipv7_phy(NULL, NULL, PHY_RF_CAL_FULL);
|
||||
phy_version_print();
|
||||
if (!s_phy_is_enabled) {
|
||||
register_chipv7_phy(NULL, NULL, PHY_RF_CAL_FULL);
|
||||
phy_version_print();
|
||||
s_phy_is_enabled = true;
|
||||
} else {
|
||||
phy_wakeup_init();
|
||||
}
|
||||
}
|
||||
|
||||
s_phy_access_ref++;
|
||||
|
||||
_lock_release(&s_phy_access_lock);
|
||||
// ESP32H2-TODO: enable common clk.
|
||||
}
|
||||
|
||||
void esp_phy_disable(void)
|
||||
{
|
||||
// ESP32H2-TODO: close rf and disable clk for modem sleep and light sleep
|
||||
_lock_acquire(&s_phy_access_lock);
|
||||
|
||||
if (s_phy_access_ref) {
|
||||
s_phy_access_ref--;
|
||||
}
|
||||
|
||||
if (s_phy_access_ref == 0) {
|
||||
phy_close_rf();
|
||||
phy_xpd_tsens();
|
||||
}
|
||||
|
||||
_lock_release(&s_phy_access_lock);
|
||||
}
|
||||
|
@ -270,6 +270,6 @@ examples/bluetooth/nimble/hci:
|
||||
|
||||
examples/bluetooth/nimble/power_save:
|
||||
enable:
|
||||
- if: IDF_TARGET in ["esp32", "esp32c3", "esp32s3", "esp32c6"]
|
||||
- if: IDF_TARGET in ["esp32", "esp32c3", "esp32s3", "esp32c6", "esp32h2"]
|
||||
temporary: true
|
||||
reason: the other targets are not tested yet
|
||||
|
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- |
|
||||
|
||||
Bluetooth Power Save Example
|
||||
=================================
|
||||
@ -10,7 +10,6 @@ If the modem sleep mode is enabled, bluetooth will switch periodically between a
|
||||
In sleep state, RF, PHY and BB are turned off in order to reduce power consumption.
|
||||
|
||||
This example contains five build configurations. For each configuration, a few configuration options are set:
|
||||
|
||||
- `sdkconfig.defaults.esp32`: ESP32 uses 32kHz XTAL as low power clock in light sleep enabled.
|
||||
- `sdkconfig.defaults.esp32c3`: ESP32C3 uses 32kHz XTAL as low power clock in light sleep enabled.
|
||||
- `sdkconfig.40m.esp32c3`: ESP32C3 uses main XTAL as low power clock in light sleep enabled.
|
||||
@ -18,12 +17,13 @@ This example contains five build configurations. For each configuration, a few c
|
||||
- `sdkconfig.40m.esp32c6`: ESP32C6 uses main XTAL as low power clock in light sleep enabled.
|
||||
- `sdkconfig.defaults.esp32s3`: ESP32S3 uses 32kHz XTAL as low power clock in light sleep enabled.
|
||||
- `sdkconfig.40m.esp32s3`: ESP32S3 uses main XTAL as low power clock in light sleep enabled.
|
||||
|
||||
- `sdkconfig.defaults.esp32h2`: ESP32H2 uses 32kHz XTAL as low power clock in light sleep enabled.
|
||||
- `sdkconfig.40m.esp32h2`: ESP32H2 uses main XTAL as low power clock in light sleep enabled.
|
||||
## How to use example
|
||||
|
||||
### Hardware Required
|
||||
|
||||
This example should be able to run on any commonly available ESP32/ESP32-C3/ESP32-S3/ESP32-C6 development board.
|
||||
This example should be able to run on any commonly available ESP32/ESP32-C3/ESP32-S3/ESP32-H2/ESP32-C6 development board.
|
||||
|
||||
### Configure the project
|
||||
|
||||
@ -37,11 +37,10 @@ idf.py menuconfig
|
||||
- `Component config > Power Management > [*] Support for power management`
|
||||
3. Configure FreeRTOS:
|
||||
- `Component config > FreeRTOS > Kernel`
|
||||
- `(1000) configTICK_RATE_HZ`
|
||||
- `[*] configUSE_TICKLESS_IDLE`
|
||||
- `(3) configEXPECTED_IDLE_TIME_BEFORE_SLEEP`
|
||||
|
||||
#### For ESP32/ESP32-C3/ESP32-S3 Chip:
|
||||
- `(1000) configTICK_RATE_HZ`
|
||||
- `[*] configUSE_TICKLESS_IDLE`
|
||||
- `(3) configEXPECTED_IDLE_TIME_BEFORE_SLEEP`
|
||||
#### For Chip ESP32/ESP32-C3/ESP32-S3:
|
||||
|
||||
4. Enable power down MAC and baseband:
|
||||
- `Component config > PHY > [*] Power down MAC and baseband of Wi-Fi and Bluetooth when PHY is disabled`
|
||||
@ -54,7 +53,7 @@ idf.py menuconfig
|
||||
7. Enable power up main XTAL during light sleep:
|
||||
- `Component config > Bluetooth > Controller Options > MODEM SLEEP Options > [*] power up main XTAL during light sleep`
|
||||
|
||||
#### For ESP32-C6 Chip:
|
||||
#### For Chip ESP32-C6/ESP32-H2
|
||||
|
||||
4. Enable bluetooth modem sleep:
|
||||
- `Component config > Bluetooth > Controller Options`
|
||||
@ -129,6 +128,7 @@ I (463) NimBLE:
|
||||
| ESP32C3 | 262 mA | 12 mA | 2.3 mA | 140 uA |
|
||||
| ESP32S3 | 240 mA | 17.9 mA | 3.3 mA | 230 uA |
|
||||
| ESP32C6 | 240 mA | 22 mA | 3.3 mA | 34 uA |
|
||||
| ESP32H2 | 82 mA | 16.0 mA | 4.0 mA | 24 uA |
|
||||
X: This feature is currently not supported.
|
||||
|
||||
## Example Breakdown
|
||||
|
@ -2,13 +2,17 @@ menu "Example Configuration"
|
||||
|
||||
choice EXAMPLE_MAX_CPU_FREQ
|
||||
prompt "Maximum CPU frequency"
|
||||
default EXAMPLE_MAX_CPU_FREQ_160
|
||||
default EXAMPLE_MAX_CPU_FREQ_160 if !IDF_TARGET_ESP32H2
|
||||
default EXAMPLE_MAX_CPU_FREQ_96 if IDF_TARGET_ESP32H2
|
||||
depends on PM_ENABLE
|
||||
help
|
||||
Maximum CPU frequency to use for dynamic frequency scaling.
|
||||
|
||||
config EXAMPLE_MAX_CPU_FREQ_80
|
||||
bool "80 MHz"
|
||||
config EXAMPLE_MAX_CPU_FREQ_96
|
||||
bool "96 MHz"
|
||||
depends on IDF_TARGET_ESP32H2
|
||||
config EXAMPLE_MAX_CPU_FREQ_160
|
||||
bool "160 MHz"
|
||||
config EXAMPLE_MAX_CPU_FREQ_240
|
||||
@ -19,12 +23,14 @@ menu "Example Configuration"
|
||||
config EXAMPLE_MAX_CPU_FREQ_MHZ
|
||||
int
|
||||
default 80 if EXAMPLE_MAX_CPU_FREQ_80
|
||||
default 96 if EXAMPLE_MAX_CPU_FREQ_96
|
||||
default 160 if EXAMPLE_MAX_CPU_FREQ_160
|
||||
default 240 if EXAMPLE_MAX_CPU_FREQ_240
|
||||
|
||||
choice EXAMPLE_MIN_CPU_FREQ
|
||||
prompt "Minimum CPU frequency"
|
||||
default EXAMPLE_MIN_CPU_FREQ_40M
|
||||
default EXAMPLE_MIN_CPU_FREQ_40M if !IDF_TARGET_ESP32H2
|
||||
default EXAMPLE_MIN_CPU_FREQ_32M if IDF_TARGET_ESP32H2
|
||||
depends on PM_ENABLE
|
||||
help
|
||||
Minimum CPU frequency to use for dynamic frequency scaling.
|
||||
@ -42,6 +48,10 @@ menu "Example Configuration"
|
||||
config EXAMPLE_MIN_CPU_FREQ_40M
|
||||
bool "40 MHz (use with 40MHz XTAL)"
|
||||
depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO
|
||||
config EXAMPLE_MIN_CPU_FREQ_32M
|
||||
bool "32 MHz (use with 32MHz XTAL)"
|
||||
depends on IDF_TARGET_ESP32H2
|
||||
depends on XTAL_FREQ_32 || XTAL_FREQ_AUTO
|
||||
config EXAMPLE_MIN_CPU_FREQ_20M
|
||||
bool "20 MHz (use with 40MHz XTAL)"
|
||||
depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO
|
||||
@ -54,6 +64,7 @@ menu "Example Configuration"
|
||||
int
|
||||
default 80 if EXAMPLE_MIN_CPU_FREQ_80M
|
||||
default 40 if EXAMPLE_MIN_CPU_FREQ_40M
|
||||
default 32 if EXAMPLE_MIN_CPU_FREQ_32M
|
||||
default 20 if EXAMPLE_MIN_CPU_FREQ_20M
|
||||
default 10 if EXAMPLE_MIN_CPU_FREQ_10M
|
||||
|
||||
|
23
examples/bluetooth/nimble/power_save/sdkconfig.32m.esp32h2
Normal file
23
examples/bluetooth/nimble/power_save/sdkconfig.32m.esp32h2
Normal file
@ -0,0 +1,23 @@
|
||||
CONFIG_IDF_TARGET="esp32h2"
|
||||
|
||||
# Bluetooth Low Power Config
|
||||
CONFIG_BT_LE_SLEEP_ENABLE=y
|
||||
# CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER is not set
|
||||
CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER=y
|
||||
CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL=y
|
||||
# CONFIG_BT_LE_LP_CLK_SRC_DEFAULT is not set
|
||||
|
||||
#
|
||||
# Power Management
|
||||
#
|
||||
CONFIG_PM_ENABLE=y
|
||||
CONFIG_PM_DFS_INIT_AUTO=y
|
||||
CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y
|
||||
# CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP is not set
|
||||
# end of Power Management
|
||||
|
||||
#
|
||||
# Sleep Config
|
||||
#
|
||||
CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y
|
||||
# end of Sleep Config
|
@ -0,0 +1,32 @@
|
||||
CONFIG_IDF_TARGET="esp32h2"
|
||||
|
||||
# Bluetooth Low Power Config
|
||||
CONFIG_BT_LE_SLEEP_ENABLE=y
|
||||
# CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER is not set
|
||||
CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER=y
|
||||
# CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL is not set
|
||||
CONFIG_BT_LE_LP_CLK_SRC_DEFAULT=y
|
||||
|
||||
#
|
||||
# Power Management
|
||||
#
|
||||
CONFIG_PM_ENABLE=y
|
||||
CONFIG_PM_DFS_INIT_AUTO=y
|
||||
CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y
|
||||
CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y
|
||||
# end of Power Management
|
||||
|
||||
#
|
||||
# Sleep Config
|
||||
#
|
||||
CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y
|
||||
# end of Sleep Config
|
||||
|
||||
#
|
||||
# RTC Clock Config
|
||||
#
|
||||
# CONFIG_RTC_CLK_SRC_INT_RC is not set
|
||||
CONFIG_RTC_CLK_SRC_EXT_CRYS=y
|
||||
# CONFIG_RTC_CLK_SRC_EXT_OSC is not set
|
||||
# CONFIG_RTC_CLK_SRC_INT_RC32K is not set
|
||||
# end of RTC Clock Config
|
Loading…
x
Reference in New Issue
Block a user