feat(ble): supported ble light sleep feat on esp32s31

This commit is contained in:
cjin
2026-05-11 08:34:15 +08:00
committed by BOT
parent 9bbb6446b8
commit b6643c4786
15 changed files with 79 additions and 77 deletions
@@ -325,7 +325,7 @@ btdm_lp_init(void)
if (rc != ESP_OK) { if (rc != ESP_OK) {
return -2; return -2;
} }
// rc = esp_pm_register_skip_light_sleep_callback(r_btdm_sleep_should_skip_light_sleep_check); rc = esp_pm_register_skip_light_sleep_callback(r_btdm_sleep_should_skip_light_sleep_check);
if (rc != ESP_OK) { if (rc != ESP_OK) {
return -3; return -3;
} }
@@ -340,7 +340,7 @@ void
btdm_lp_deinit(void) btdm_lp_deinit(void)
{ {
#if UC_BT_CTRL_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE #if UC_BT_CTRL_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE
// esp_pm_unregister_skip_light_sleep_callback(r_btdm_sleep_should_skip_light_sleep_check); esp_pm_unregister_skip_light_sleep_callback(r_btdm_sleep_should_skip_light_sleep_check);
esp_pm_unregister_inform_out_light_sleep_overhead_callback(r_btdm_sleep_wake_up_overhead_set); esp_pm_unregister_inform_out_light_sleep_overhead_callback(r_btdm_sleep_wake_up_overhead_set);
esp_sleep_disable_bt_wakeup(); esp_sleep_disable_bt_wakeup();
btdm_lp_modem_state_deinit(); btdm_lp_modem_state_deinit();
@@ -51,7 +51,7 @@ bool clock_domain_pd_allowed(void);
*/ */
esp_err_t sleep_clock_system_retention_init(void *arg); esp_err_t sleep_clock_system_retention_init(void *arg);
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE #if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_BT_CTRL_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE || SOC_PM_MODEM_CLK_CONF_RETENTION
/** /**
* @brief Modem system clock retention initialize. * @brief Modem system clock retention initialize.
* *
@@ -43,7 +43,7 @@ esp_err_t sleep_clock_system_retention_init(void *arg)
#undef N_REGS_PCR #undef N_REGS_PCR
} }
#if CONFIG_MAC_BB_PD || CONFIG_BTDM_CTRL_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE #if CONFIG_MAC_BB_PD || CONFIG_BT_CTRL_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
#include "rom/ets_sys.h" #include "rom/ets_sys.h"
esp_err_t sleep_clock_modem_retention_init(void *arg) esp_err_t sleep_clock_modem_retention_init(void *arg)
{ {
@@ -96,7 +96,7 @@ bool clock_domain_pd_allowed(void)
mask.bitmap[SLEEP_RETENTION_MODULE_CLOCK_SYSTEM >> 5] |= BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM % 32); mask.bitmap[SLEEP_RETENTION_MODULE_CLOCK_SYSTEM >> 5] |= BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM % 32);
} }
#if SOC_WIFI_SUPPORTED || SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED #if SOC_WIFI_SUPPORTED || SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED
const sleep_retention_module_bitmap_t modem_modules = sleep_retention_module_bitmap_and(inited_modules, modem_clk_dep_modules); const sleep_retention_module_bitmap_t modem_modules = sleep_retention_module_bitmap_and(inited_modules, modem_clk_dep_modules);
if (!sleep_retention_module_bitmap_eq(modem_modules, null_module)) { if (!sleep_retention_module_bitmap_eq(modem_modules, null_module)) {
mask.bitmap[SLEEP_RETENTION_MODULE_CLOCK_MODEM >> 5] |= BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM % 32); mask.bitmap[SLEEP_RETENTION_MODULE_CLOCK_MODEM >> 5] |= BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM % 32);
@@ -116,7 +116,7 @@ ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, SECONDARY, BIT(0), 106)
}; };
sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM, &init_param); sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM, &init_param);
#if CONFIG_MAC_BB_PD || CONFIG_BTDM_CTRL_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE #if CONFIG_MAC_BB_PD || CONFIG_BT_CTRL_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
init_param = (sleep_retention_module_init_param_t) { init_param = (sleep_retention_module_init_param_t) {
.cbs = { .create = { .handle = sleep_clock_modem_retention_init, .arg = NULL } }, .cbs = { .create = { .handle = sleep_clock_modem_retention_init, .arg = NULL } },
.attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE .attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE
-1
View File
@@ -716,7 +716,6 @@ static SLEEP_FN_ATTR void misc_modules_wake_prepare(uint32_t sleep_flags)
#if CONFIG_ESP_ENABLE_PVT && SOC_PVT_EN_WITH_SLEEP #if CONFIG_ESP_ENABLE_PVT && SOC_PVT_EN_WITH_SLEEP
pvt_func_enable(true); pvt_func_enable(true);
#endif #endif
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_WDT_SUPPORTED #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_WDT_SUPPORTED
if (sleep_flags & PMU_SLEEP_PD_TOP) { if (sleep_flags & PMU_SLEEP_PD_TOP) {
// There is no driver to manage the flashboot watchdog, and it is definitely be in off state when // There is no driver to manage the flashboot watchdog, and it is definitely be in off state when
@@ -1071,6 +1071,10 @@ config SOC_TOUCH_SAMPLE_CFG_NUM
int int
default 3 default 3
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
@@ -434,6 +434,7 @@
#define SOC_TOUCH_SAMPLE_CFG_NUM (3) /*!< The sample configurations number in total, each sampler can be used to sample on one frequency */ #define SOC_TOUCH_SAMPLE_CFG_NUM (3) /*!< The sample configurations number in total, each sampler can be used to sample on one frequency */
/*-------------------------- Power Management CAPS ----------------------------*/ /*-------------------------- Power Management CAPS ----------------------------*/
#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_EXT1_WAKEUP_BY_PMU (1) #define SOC_PM_EXT1_WAKEUP_BY_PMU (1)
@@ -318,9 +318,6 @@ enc_adv_data_cent_ext_should_connect(const struct ble_gap_ext_disc_desc *disc)
{ {
int offset = 0; int offset = 0;
int ad_struct_len = 0; int ad_struct_len = 0;
#if CONFIG_EXAMPLE_USE_CI_ADDRESS
uint32_t *addr_offset;
#endif // CONFIG_EXAMPLE_USE_CI_ADDRESS
uint8_t test_addr[6]; uint8_t test_addr[6];
uint32_t peer_addr[6]; uint32_t peer_addr[6];
@@ -331,25 +328,17 @@ enc_adv_data_cent_ext_should_connect(const struct ble_gap_ext_disc_desc *disc)
return 0; return 0;
} }
if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen ("ADDR_ANY")) != 0)) { if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen ("ADDR_ANY")) != 0)) {
#if !CONFIG_EXAMPLE_USE_CI_ADDRESS
ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR); ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR);
/* Convert string to address */ /* Convert string to address */
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%lx:%lx:%lx:%lx:%lx:%lx", sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%lx:%lx:%lx:%lx:%lx:%lx",
&peer_addr[5], &peer_addr[4], &peer_addr[3], &peer_addr[5], &peer_addr[4], &peer_addr[3],
&peer_addr[2], &peer_addr[1], &peer_addr[0]); &peer_addr[2], &peer_addr[1], &peer_addr[0]);
#endif
/* Conversion */ /* Conversion */
for(int i=0; i<6; i++) { for(int i=0; i<6; i++) {
test_addr[i] = (uint8_t )peer_addr[i]; test_addr[i] = (uint8_t )peer_addr[i];
} }
#if CONFIG_EXAMPLE_USE_CI_ADDRESS
addr_offset = (uint32_t *)&test_addr[1];
*addr_offset = atoi(CONFIG_EXAMPLE_PEER_ADDR);
test_addr[5] = 0xC3;
test_addr[0] = TEST_CI_ADDRESS_CHIP_OFFSET;
#endif
if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) { if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
return 0; return 0;
} }
+2 -28
View File
@@ -31,32 +31,6 @@
#include "host/ble_esp_gattc_cache.h" #include "host/ble_esp_gattc_cache.h"
#endif #endif
#if CONFIG_EXAMPLE_USE_CI_ADDRESS
#ifdef CONFIG_IDF_TARGET_ESP32
#define TEST_CI_ADDRESS_CHIP_OFFSET (0)
#elif CONFIG_IDF_TARGET_ESP32C2
#define TEST_CI_ADDRESS_CHIP_OFFSET (1)
#elif CONFIG_IDF_TARGET_ESP32C3
#define TEST_CI_ADDRESS_CHIP_OFFSET (2)
#elif CONFIG_IDF_TARGET_ESP32C6
#define TEST_CI_ADDRESS_CHIP_OFFSET (3)
#elif CONFIG_IDF_TARGET_ESP32C5
#define TEST_CI_ADDRESS_CHIP_OFFSET (4)
#elif CONFIG_IDF_TARGET_ESP32H2
#define TEST_CI_ADDRESS_CHIP_OFFSET (5)
#elif CONFIG_IDF_TARGET_ESP32P4
#define TEST_CI_ADDRESS_CHIP_OFFSET (6)
#elif CONFIG_IDF_TARGET_ESP32S3
#define TEST_CI_ADDRESS_CHIP_OFFSET (7)
#elif CONFIG_IDF_TARGET_ESP32C61
#define TEST_CI_ADDRESS_CHIP_OFFSET (8)
#elif CONFIG_IDF_TARGET_ESP32H4
#define TEST_CI_ADDRESS_CHIP_OFFSET (9)
#elif CONFIG_IDF_TARGET_ESP32S31
#define TEST_CI_ADDRESS_CHIP_OFFSET (10)
#endif
#endif
#if MYNEWT_VAL(BLE_GATTC) #if MYNEWT_VAL(BLE_GATTC)
/*** The UUID of the service containing the subscribable characteristic ***/ /*** The UUID of the service containing the subscribable characteristic ***/
static const ble_uuid_t * remote_svc_uuid = static const ble_uuid_t * remote_svc_uuid =
@@ -533,7 +507,7 @@ ext_blecent_should_connect(const struct ble_gap_ext_disc_desc *disc)
addr_offset = (uint32_t *)&test_addr[1]; addr_offset = (uint32_t *)&test_addr[1];
*addr_offset = atoi(CONFIG_EXAMPLE_PEER_ADDR); *addr_offset = atoi(CONFIG_EXAMPLE_PEER_ADDR);
test_addr[5] = 0xC3; test_addr[5] = 0xC3;
test_addr[0] = TEST_CI_ADDRESS_CHIP_OFFSET; test_addr[0] = CONFIG_IDF_FIRMWARE_CHIP_ID;
#endif #endif
if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) { if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
return 0; return 0;
@@ -610,7 +584,7 @@ blecent_should_connect(const struct ble_gap_disc_desc *disc)
addr_offset = (uint32_t *)&test_addr[1]; addr_offset = (uint32_t *)&test_addr[1];
*addr_offset = atoi(CONFIG_EXAMPLE_PEER_ADDR); *addr_offset = atoi(CONFIG_EXAMPLE_PEER_ADDR);
test_addr[5] = 0xC3; test_addr[5] = 0xC3;
test_addr[0] = TEST_CI_ADDRESS_CHIP_OFFSET; test_addr[0] = CONFIG_IDF_FIRMWARE_CHIP_ID;
#endif #endif
if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) { if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
@@ -26,6 +26,8 @@ This example contains some build configurations. For each configuration, a few c
- `sdkconfig.48m.esp32c5`: ESP32C5 uses main XTAL as low power clock in light sleep enabled. - `sdkconfig.48m.esp32c5`: ESP32C5 uses main XTAL as low power clock in light sleep enabled.
- `sdkconfig.defaults.esp32c61`: ESP32C61 uses 32kHz XTAL as low power clock in light sleep enabled. - `sdkconfig.defaults.esp32c61`: ESP32C61 uses 32kHz XTAL as low power clock in light sleep enabled.
- `sdkconfig.40m.esp32c61`: ESP32C61 uses main XTAL as low power clock in light sleep enabled. - `sdkconfig.40m.esp32c61`: ESP32C61 uses main XTAL as low power clock in light sleep enabled.
- `sdkconfig.defaults.esp32s31`: ESP32S31 uses 32kHz XTAL as low power clock in light sleep enabled.
- `sdkconfig.40m.esp32s31`: ESP32S31 uses main XTAL as low power clock in light sleep enabled.
## How to use example ## How to use example
@@ -2,10 +2,12 @@ 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 && !IDF_TARGET_ESP32C5 default EXAMPLE_MAX_CPU_FREQ_160 if !IDF_TARGET_ESP32H2 && !IDF_TARGET_ESP32C2 && \
!IDF_TARGET_ESP32C5 && !IDF_TARGET_ESP32S31
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 default EXAMPLE_MAX_CPU_FREQ_240 if IDF_TARGET_ESP32C5
default EXAMPLE_MAX_CPU_FREQ_320 if IDF_TARGET_ESP32S31
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.
@@ -23,6 +25,9 @@ menu "Example Configuration"
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 || IDF_TARGET_ESP32C5 depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C5
config EXAMPLE_MAX_CPU_FREQ_320
bool "320 MHz"
depends on IDF_TARGET_ESP32S31
endchoice endchoice
config EXAMPLE_MAX_CPU_FREQ_MHZ config EXAMPLE_MAX_CPU_FREQ_MHZ
@@ -32,6 +37,7 @@ menu "Example Configuration"
default 120 if EXAMPLE_MAX_CPU_FREQ_120 default 120 if EXAMPLE_MAX_CPU_FREQ_120
default 160 if EXAMPLE_MAX_CPU_FREQ_160 default 160 if EXAMPLE_MAX_CPU_FREQ_160
default 240 if EXAMPLE_MAX_CPU_FREQ_240 default 240 if EXAMPLE_MAX_CPU_FREQ_240
default 320 if EXAMPLE_MAX_CPU_FREQ_320
choice EXAMPLE_MIN_CPU_FREQ choice EXAMPLE_MIN_CPU_FREQ
prompt "Minimum CPU frequency" prompt "Minimum CPU frequency"
@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -17,32 +17,6 @@
#include "services/gap/ble_svc_gap.h" #include "services/gap/ble_svc_gap.h"
#include "bleprph.h" #include "bleprph.h"
#if CONFIG_EXAMPLE_USE_CI_ADDRESS
#ifdef CONFIG_IDF_TARGET_ESP32
#define TEST_CI_ADDRESS_CHIP_OFFSET (0)
#elif CONFIG_IDF_TARGET_ESP32C2
#define TEST_CI_ADDRESS_CHIP_OFFSET (1)
#elif CONFIG_IDF_TARGET_ESP32C3
#define TEST_CI_ADDRESS_CHIP_OFFSET (2)
#elif CONFIG_IDF_TARGET_ESP32C6
#define TEST_CI_ADDRESS_CHIP_OFFSET (3)
#elif CONFIG_IDF_TARGET_ESP32C5
#define TEST_CI_ADDRESS_CHIP_OFFSET (4)
#elif CONFIG_IDF_TARGET_ESP32H2
#define TEST_CI_ADDRESS_CHIP_OFFSET (5)
#elif CONFIG_IDF_TARGET_ESP32P4
#define TEST_CI_ADDRESS_CHIP_OFFSET (6)
#elif CONFIG_IDF_TARGET_ESP32S3
#define TEST_CI_ADDRESS_CHIP_OFFSET (7)
#elif CONFIG_IDF_TARGET_ESP32C61
#define TEST_CI_ADDRESS_CHIP_OFFSET (8)
#elif CONFIG_IDF_TARGET_ESP32H4
#define TEST_CI_ADDRESS_CHIP_OFFSET (9)
#elif CONFIG_IDF_TARGET_ESP32S31
#define TEST_CI_ADDRESS_CHIP_OFFSET (10)
#endif
#endif
#if CONFIG_EXAMPLE_EXTENDED_ADV #if CONFIG_EXAMPLE_EXTENDED_ADV
static uint8_t ext_adv_pattern_1[] = { static uint8_t ext_adv_pattern_1[] = {
0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06,
@@ -535,7 +509,7 @@ bleprph_on_sync(void)
uint32_t *offset = (uint32_t *)&addr[1]; uint32_t *offset = (uint32_t *)&addr[1];
*offset = atoi(CONFIG_EXAMPLE_CI_ADDRESS_OFFSET); *offset = atoi(CONFIG_EXAMPLE_CI_ADDRESS_OFFSET);
addr[5] = 0xC3; addr[5] = 0xC3;
addr[0] = TEST_CI_ADDRESS_CHIP_OFFSET; addr[0] = CONFIG_IDF_FIRMWARE_CHIP_ID;
rc = ble_hs_id_set_rnd(addr); rc = ble_hs_id_set_rnd(addr);
assert(rc == 0); assert(rc == 0);
} }
@@ -0,0 +1,23 @@
CONFIG_IDF_TARGET="esp32s31"
# Bluetooth Low Power Config
CONFIG_BT_CTRL_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
CONFIG_ESP_MODEM_CLOCK_ENABLE_CHECKING=y
#
# Sleep Config
#
CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y
CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION=y
# end of Sleep Config
@@ -0,0 +1,30 @@
CONFIG_IDF_TARGET="esp32s31"
# Bluetooth Low Power Config
CONFIG_BT_CTRL_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
CONFIG_ESP_MODEM_CLOCK_ENABLE_CHECKING=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
@@ -27,7 +27,7 @@ CUR_DIR = Path(__file__).parent.resolve()
['esp32c6', 'esp32h2', 'esp32c3', 'esp32s3', 'esp32c5', 'esp32c61', 'esp32'], ['esp32c6', 'esp32h2', 'esp32c3', 'esp32s3', 'esp32c5', 'esp32c61', 'esp32'],
indirect=['target'], indirect=['target'],
) )
@pytest.mark.temp_skip_ci(targets=['esp32s31'], reason='s31 light sleep not supported yet') @pytest.mark.temp_skip_ci(targets=['esp32s31'], reason='lack of runners')
def test_power_save_conn(app_path: str, dut: tuple[IdfDut, IdfDut]) -> None: def test_power_save_conn(app_path: str, dut: tuple[IdfDut, IdfDut]) -> None:
peripheral = dut[0] peripheral = dut[0]
central = dut[1] central = dut[1]