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_private/periph_ctrl.h"
#include "soc/retention_periph_defs.h"
#include "esp_private/sleep_retention.h"
#include "soc/regdma.h"
#include "bt_osi_mem.h"
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
#include "esp_private/sleep_modem.h"
#include "esp_private/sleep_retention.h"
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
#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 void os_msys_deinit(void);
#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 void esp_ble_set_wakeup_overhead(uint32_t overhead);
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);
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) {
case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL:
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source");
uint32_t chip_version = efuse_hal_chip_revision();
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));
}
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (480 - 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!");
@ -373,57 +368,48 @@ IRAM_ATTR void controller_wakeup_cb(void *arg)
}
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
// TODO: IDF-10765
// static esp_err_t sleep_modem_ble_mac_retention_init(void *arg)
// {
// uint8_t size;
// int extra = *(int *)arg;
// 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);
// if (err == ESP_OK) {
// ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization");
// }
// return err;
// return ESP_OK;
// }
static esp_err_t sleep_modem_ble_mac_retention_init(void *arg)
{
uint8_t size;
int extra = *(int *)arg;
sleep_retention_entries_config_t *ble_mac_modem_config = r_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);
if (err == ESP_OK) {
ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization");
}
return err;
return ESP_OK;
}
static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra)
{
// TODO: IDF-10765
// int retention_args = extra;
// sleep_retention_module_init_param_t init_param = {
// .cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } },
// .depends = BIT(SLEEP_RETENTION_MODULE_BT_BB)
// };
// esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param);
// if (err == ESP_OK) {
// err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC);
// }
// return err;
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!");
return ESP_OK;
int retention_args = extra;
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } },
.depends = BIT(SLEEP_RETENTION_MODULE_BT_BB)
};
esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param);
if (err == ESP_OK) {
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC);
}
return err;
}
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);
// if (err == ESP_OK) {
// err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC);
// assert(err == ESP_OK);
// }
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!");
esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC);
if (err == ESP_OK) {
err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC);
assert(err == ESP_OK);
}
}
void sleep_modem_light_sleep_overhead_set(uint32_t overhead)
{
// TODO: IDF-10765
// esp_ble_set_wakeup_overhead(overhead);
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "This func temporary not supported for current target!");
r_esp_ble_set_wakeup_overhead(overhead);
}
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
esp_err_t controller_sleep_init(void)
{
esp_err_t rc = 0;
@ -446,7 +432,7 @@ esp_err_t controller_sleep_init(void)
}
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
/* 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);
esp_sleep_enable_bt_wakeup();
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
#define BB_PART_0_SIZE 93
#define BB_PART_1_SIZE 62
#define BB_PART_0_SIZE 128
#define BB_PART_1_SIZE 68
#define BB_PART_2_SIZE 19
#define BB_PART_0_ADDR 0x600A2000
#define BB_PART_1_ADDR 0x600A2800

View File

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

View File

@ -538,7 +538,7 @@
/*-------------------------- Power Management CAPS ----------------------------*/
// #define SOC_PM_SUPPORT_WIFI_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_MODE_PER_PIN (1) /*!<Supports one bit per pin to configure the EXT1 trigger level */
#define SOC_PM_SUPPORT_CPU_PD (1)

View File

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

View File

@ -2,9 +2,10 @@ menu "Example Configuration"
choice EXAMPLE_MAX_CPU_FREQ
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_120 if IDF_TARGET_ESP32C2
default EXAMPLE_MAX_CPU_FREQ_240 if IDF_TARGET_ESP32C5
depends on PM_ENABLE
help
Maximum CPU frequency to use for dynamic frequency scaling.
@ -21,7 +22,7 @@ menu "Example Configuration"
depends on IDF_TARGET_ESP32C2
config EXAMPLE_MAX_CPU_FREQ_240
bool "240 MHz"
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C5
endchoice
config EXAMPLE_MAX_CPU_FREQ_MHZ
@ -34,7 +35,8 @@ menu "Example Configuration"
choice EXAMPLE_MIN_CPU_FREQ
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_26M if IDF_TARGET_ESP32C2
depends on PM_ENABLE
@ -51,6 +53,9 @@ menu "Example Configuration"
BBPLL and then re-enable it with a different frequency.Since the
Bluetooth baseband works from PLL frequency, it will temporarily
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
bool "40 MHz (use with 40MHz XTAL)"
depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO
@ -73,6 +78,7 @@ menu "Example Configuration"
config EXAMPLE_MIN_CPU_FREQ_MHZ
int
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 32 if EXAMPLE_MIN_CPU_FREQ_32M
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-License-Identifier: CC0-1.0
import os.path
from typing import Tuple
@ -14,6 +13,7 @@ from pytest_embedded_idf.dut import IdfDut
@pytest.mark.esp32h2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.esp32c5
@pytest.mark.esp32
@pytest.mark.wifi_two_dut
@pytest.mark.parametrize(