feat(ble): support ble light sleep on esp32c5

This commit is contained in:
cjin 2024-09-04 11:34:06 +08:00
parent 98cf50d140
commit 50d410e1c8
11 changed files with 104 additions and 63 deletions

View File

@ -40,12 +40,12 @@
#include "esp_phy_init.h" #include "esp_phy_init.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#include "soc/retention_periph_defs.h" #include "soc/retention_periph_defs.h"
#include "esp_private/sleep_retention.h"
#include "soc/regdma.h" #include "soc/regdma.h"
#include "bt_osi_mem.h" #include "bt_osi_mem.h"
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE #if CONFIG_FREERTOS_USE_TICKLESS_IDLE
#include "esp_private/sleep_modem.h" #include "esp_private/sleep_modem.h"
#include "esp_private/sleep_retention.h"
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
@ -128,8 +128,8 @@ extern void r_ble_rtc_wake_up_state_clr(void);
extern int os_msys_init(void); extern int os_msys_init(void);
extern void os_msys_deinit(void); extern void os_msys_deinit(void);
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE #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); extern sleep_retention_entries_config_t *r_esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra);
extern void esp_ble_set_wakeup_overhead(uint32_t overhead); extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead);
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
extern void r_esp_ble_change_rtc_freq(uint32_t freq); extern void r_esp_ble_change_rtc_freq(uint32_t freq);
extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x,
@ -303,12 +303,7 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src)
switch (slow_clk_src) { switch (slow_clk_src) {
case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL: case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL:
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source"); ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source");
uint32_t chip_version = efuse_hal_chip_revision(); modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (480 - 1));
if (chip_version == 0) {
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (400 - 1));
} else{
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1));
}
break; break;
case MODEM_CLOCK_LPCLK_SRC_RC_SLOW: 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_LOGI(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!");
@ -373,57 +368,48 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
} }
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE #if CONFIG_FREERTOS_USE_TICKLESS_IDLE
// TODO: IDF-10765 static esp_err_t sleep_modem_ble_mac_retention_init(void *arg)
// static esp_err_t sleep_modem_ble_mac_retention_init(void *arg) {
// { uint8_t size;
// uint8_t size; int extra = *(int *)arg;
// int extra = *(int *)arg; sleep_retention_entries_config_t *ble_mac_modem_config = r_esp_ble_mac_retention_link_get(&size, extra);
// 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_BT_MAC_BB, SLEEP_RETENTION_MODULE_BLE_MAC);
// esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_BT_MAC_BB, SLEEP_RETENTION_MODULE_BLE_MAC); if (err == ESP_OK) {
// if (err == ESP_OK) { ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization");
// ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization"); }
// } return err;
// return err; return ESP_OK;
// return ESP_OK; }
// }
static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra)
{ {
// TODO: IDF-10765 int retention_args = extra;
// int retention_args = extra; sleep_retention_module_init_param_t init_param = {
// sleep_retention_module_init_param_t init_param = { .cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } },
// .cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } }, .depends = BIT(SLEEP_RETENTION_MODULE_BT_BB)
// .depends = BIT(SLEEP_RETENTION_MODULE_BT_BB) };
// }; esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param);
// esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param); if (err == ESP_OK) {
// if (err == ESP_OK) { err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC);
// err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC); }
// } return err;
// return err;
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!");
return ESP_OK;
} }
static void sleep_modem_ble_mac_modem_state_deinit(void) static void sleep_modem_ble_mac_modem_state_deinit(void)
{ {
// TODO: IDF-10765 esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC);
// esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC); if (err == ESP_OK) {
// if (err == ESP_OK) { err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC);
// err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC); assert(err == ESP_OK);
// assert(err == ESP_OK); }
// }
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!");
} }
void sleep_modem_light_sleep_overhead_set(uint32_t overhead) void sleep_modem_light_sleep_overhead_set(uint32_t overhead)
{ {
// TODO: IDF-10765 r_esp_ble_set_wakeup_overhead(overhead);
// esp_ble_set_wakeup_overhead(overhead);
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!");
} }
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
esp_err_t controller_sleep_init(void) esp_err_t controller_sleep_init(void)
{ {
esp_err_t rc = 0; esp_err_t rc = 0;
@ -446,7 +432,7 @@ esp_err_t controller_sleep_init(void)
} }
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE #if CONFIG_FREERTOS_USE_TICKLESS_IDLE
/* Create a new regdma link for BLE related register restoration */ /* Create a new regdma link for BLE related register restoration */
rc = sleep_modem_ble_mac_modem_state_init(1); rc = sleep_modem_ble_mac_modem_state_init(0);
assert(rc == 0); assert(rc == 0);
esp_sleep_enable_bt_wakeup(); esp_sleep_enable_bt_wakeup();
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is BLE timer"); ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is BLE timer");

@ -1 +1 @@
Subproject commit 53056440bc6e76f5bf00fd920769a4979dcc7d66 Subproject commit b4f67e85c54cc8f55b5130e47805dc8c906a736c

View File

@ -12,8 +12,8 @@ extern "C" {
// btbb sleep retention reg // btbb sleep retention reg
#define BB_PART_0_SIZE 93 #define BB_PART_0_SIZE 128
#define BB_PART_1_SIZE 62 #define BB_PART_1_SIZE 68
#define BB_PART_2_SIZE 19 #define BB_PART_2_SIZE 19
#define BB_PART_0_ADDR 0x600A2000 #define BB_PART_0_ADDR 0x600A2000
#define BB_PART_1_ADDR 0x600A2800 #define BB_PART_1_ADDR 0x600A2800

View File

@ -1207,6 +1207,10 @@ config SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH
int int
default 12 default 12
config SOC_PM_SUPPORT_BT_WAKEUP
bool
default y
config SOC_PM_SUPPORT_EXT1_WAKEUP config SOC_PM_SUPPORT_EXT1_WAKEUP
bool bool
default y default y

View File

@ -538,7 +538,7 @@
/*-------------------------- Power Management CAPS ----------------------------*/ /*-------------------------- Power Management CAPS ----------------------------*/
// #define SOC_PM_SUPPORT_WIFI_WAKEUP (1) // #define SOC_PM_SUPPORT_WIFI_WAKEUP (1)
// #define SOC_PM_SUPPORT_BEACON_WAKEUP (1) // #define SOC_PM_SUPPORT_BEACON_WAKEUP (1)
// #define SOC_PM_SUPPORT_BT_WAKEUP (1) #define SOC_PM_SUPPORT_BT_WAKEUP (1)
#define SOC_PM_SUPPORT_EXT1_WAKEUP (1) #define SOC_PM_SUPPORT_EXT1_WAKEUP (1)
#define SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN (1) /*!<Supports one bit per pin to configure the EXT1 trigger level */ #define SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN (1) /*!<Supports one bit per pin to configure the EXT1 trigger level */
#define SOC_PM_SUPPORT_CPU_PD (1) #define SOC_PM_SUPPORT_CPU_PD (1)

View File

@ -200,10 +200,6 @@ examples/bluetooth/nimble/blecent:
<<: *bt_default_depends <<: *bt_default_depends
disable: disable:
- if: SOC_BLE_SUPPORTED != 1 - if: SOC_BLE_SUPPORTED != 1
disable_test:
- if: IDF_TARGET in ["esp32c5"]
temporary: true
reason: Not supported yet
depends_components: depends_components:
- bt - bt
- esp_phy - esp_phy
@ -252,10 +248,6 @@ examples/bluetooth/nimble/power_save:
<<: *bt_default_depends <<: *bt_default_depends
disable: disable:
- if: SOC_BLE_SUPPORTED != 1 - if: SOC_BLE_SUPPORTED != 1
disable_test:
- if: IDF_TARGET in ["esp32c5"]
temporary: true
reason: Not supported yet
depends_components: depends_components:
- bt - bt
- esp_phy - esp_phy

View File

@ -22,6 +22,8 @@ This example contains some build configurations. For each configuration, a few c
- `sdkconfig.32m.esp32h2`: ESP32H2 uses main XTAL as low power clock in light sleep enabled. - `sdkconfig.32m.esp32h2`: ESP32H2 uses main XTAL as low power clock in light sleep enabled.
- `sdkconfig.defaults.esp32c2`: ESP32C2 uses 32kHz XTAL as low power clock in light sleep enabled. - `sdkconfig.defaults.esp32c2`: ESP32C2 uses 32kHz XTAL as low power clock in light sleep enabled.
- `sdkconfig.26m.esp32c2`: ESP32C2 uses main XTAL as low power clock in light sleep enabled. - `sdkconfig.26m.esp32c2`: ESP32C2 uses main XTAL as low power clock in light sleep enabled.
- `sdkconfig.defaults.esp32c5`: ESP32C5 uses 32kHz XTAL as low power clock in light sleep enabled.
- `sdkconfig.48m.esp32c5`: ESP32C5 uses main XTAL as low power clock in light sleep enabled.
## How to use example ## How to use example

View File

@ -2,9 +2,10 @@ menu "Example Configuration"
choice EXAMPLE_MAX_CPU_FREQ choice EXAMPLE_MAX_CPU_FREQ
prompt "Maximum CPU frequency" prompt "Maximum CPU frequency"
default EXAMPLE_MAX_CPU_FREQ_160 if !IDF_TARGET_ESP32H2 && !IDF_TARGET_ESP32C2 default EXAMPLE_MAX_CPU_FREQ_160 if !IDF_TARGET_ESP32H2 && !IDF_TARGET_ESP32C2 && !IDF_TARGET_ESP32C5
default EXAMPLE_MAX_CPU_FREQ_96 if IDF_TARGET_ESP32H2 default EXAMPLE_MAX_CPU_FREQ_96 if IDF_TARGET_ESP32H2
default EXAMPLE_MAX_CPU_FREQ_120 if IDF_TARGET_ESP32C2 default EXAMPLE_MAX_CPU_FREQ_120 if IDF_TARGET_ESP32C2
default EXAMPLE_MAX_CPU_FREQ_240 if IDF_TARGET_ESP32C5
depends on PM_ENABLE depends on PM_ENABLE
help help
Maximum CPU frequency to use for dynamic frequency scaling. Maximum CPU frequency to use for dynamic frequency scaling.
@ -21,7 +22,7 @@ menu "Example Configuration"
depends on IDF_TARGET_ESP32C2 depends on IDF_TARGET_ESP32C2
config EXAMPLE_MAX_CPU_FREQ_240 config EXAMPLE_MAX_CPU_FREQ_240
bool "240 MHz" bool "240 MHz"
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3 depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C5
endchoice endchoice
config EXAMPLE_MAX_CPU_FREQ_MHZ config EXAMPLE_MAX_CPU_FREQ_MHZ
@ -34,7 +35,8 @@ menu "Example Configuration"
choice EXAMPLE_MIN_CPU_FREQ choice EXAMPLE_MIN_CPU_FREQ
prompt "Minimum CPU frequency" prompt "Minimum CPU frequency"
default EXAMPLE_MIN_CPU_FREQ_40M if !IDF_TARGET_ESP32H2 && !IDF_TARGET_ESP32C2 default EXAMPLE_MIN_CPU_FREQ_40M if !IDF_TARGET_ESP32H2 && !IDF_TARGET_ESP32C2 && !IDF_TARGET_ESP32C5
default EXAMPLE_MIN_CPU_FREQ_48M if IDF_TARGET_ESP32C5
default EXAMPLE_MIN_CPU_FREQ_32M if IDF_TARGET_ESP32H2 default EXAMPLE_MIN_CPU_FREQ_32M if IDF_TARGET_ESP32H2
default EXAMPLE_MIN_CPU_FREQ_26M if IDF_TARGET_ESP32C2 default EXAMPLE_MIN_CPU_FREQ_26M if IDF_TARGET_ESP32C2
depends on PM_ENABLE depends on PM_ENABLE
@ -51,6 +53,9 @@ menu "Example Configuration"
BBPLL and then re-enable it with a different frequency.Since the BBPLL and then re-enable it with a different frequency.Since the
Bluetooth baseband works from PLL frequency, it will temporarily Bluetooth baseband works from PLL frequency, it will temporarily
lose its 80 MHz clock, while the BBPLL is disabled. lose its 80 MHz clock, while the BBPLL is disabled.
config EXAMPLE_MIN_CPU_FREQ_48M
bool "48 MHz (use with 48MHz XTAL)"
depends on XTAL_FREQ_48 || XTAL_FREQ_AUTO
config EXAMPLE_MIN_CPU_FREQ_40M config EXAMPLE_MIN_CPU_FREQ_40M
bool "40 MHz (use with 40MHz XTAL)" bool "40 MHz (use with 40MHz XTAL)"
depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO
@ -73,6 +78,7 @@ menu "Example Configuration"
config EXAMPLE_MIN_CPU_FREQ_MHZ config EXAMPLE_MIN_CPU_FREQ_MHZ
int int
default 80 if EXAMPLE_MIN_CPU_FREQ_80M default 80 if EXAMPLE_MIN_CPU_FREQ_80M
default 48 if EXAMPLE_MIN_CPU_FREQ_48M
default 40 if EXAMPLE_MIN_CPU_FREQ_40M default 40 if EXAMPLE_MIN_CPU_FREQ_40M
default 32 if EXAMPLE_MIN_CPU_FREQ_32M default 32 if EXAMPLE_MIN_CPU_FREQ_32M
default 26 if EXAMPLE_MIN_CPU_FREQ_26M default 26 if EXAMPLE_MIN_CPU_FREQ_26M

View File

@ -0,0 +1,22 @@
CONFIG_IDF_TARGET="esp32c5"
# Bluetooth Low Power Config
CONFIG_BT_LE_SLEEP_ENABLE=y
CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL=y
#
# Power Management
#
CONFIG_PM_ENABLE=y
CONFIG_PM_DFS_INIT_AUTO=y
CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y
# end of Power Management
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
#
# Sleep Config
#
CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y
CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION=y
# end of Sleep Config

View File

@ -0,0 +1,29 @@
CONFIG_IDF_TARGET="esp32c5"
# Bluetooth Low Power Config
CONFIG_BT_LE_SLEEP_ENABLE=y
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
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
#
# Sleep Config
#
CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y
CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION=y
# end of Sleep Config
#
# RTC Clock Config
#
CONFIG_RTC_CLK_SRC_EXT_CRYS=y
# end of RTC Clock Config

View File

@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
import os.path import os.path
from typing import Tuple from typing import Tuple
@ -14,6 +13,7 @@ from pytest_embedded_idf.dut import IdfDut
@pytest.mark.esp32h2 @pytest.mark.esp32h2
@pytest.mark.esp32c3 @pytest.mark.esp32c3
@pytest.mark.esp32s3 @pytest.mark.esp32s3
@pytest.mark.esp32c5
@pytest.mark.esp32 @pytest.mark.esp32
@pytest.mark.wifi_two_dut @pytest.mark.wifi_two_dut
@pytest.mark.parametrize( @pytest.mark.parametrize(