From defa3ccaa95f7268d1d4594d9aca9013129d96d8 Mon Sep 17 00:00:00 2001 From: hebinglin Date: Wed, 20 May 2026 22:05:36 +0800 Subject: [PATCH] change(examples): add esp32h4 lslp ci test --- examples/system/.build-test-rules.yml | 4 --- examples/system/light_sleep/README.md | 6 ++++- .../system/light_sleep/main/Kconfig.projbuild | 13 +++++++++ .../system/light_sleep/main/gpio_wakeup.c | 17 +++++++++--- .../system/light_sleep/pytest_light_sleep.py | 27 ++++++++++--------- 5 files changed, 47 insertions(+), 20 deletions(-) diff --git a/examples/system/.build-test-rules.yml b/examples/system/.build-test-rules.yml index 2879eafb491..9796f7d9796 100644 --- a/examples/system/.build-test-rules.yml +++ b/examples/system/.build-test-rules.yml @@ -121,10 +121,6 @@ examples/system/ipc/ipc_isr/xtensa: examples/system/light_sleep: disable: - if: SOC_LIGHT_SLEEP_SUPPORTED != 1 - disable_test: - - if: IDF_TARGET == "esp32h4" - temporary: true - reason: cannot pass # TODO: IDF-15611 examples/system/nmi_isr: enable: diff --git a/examples/system/light_sleep/README.md b/examples/system/light_sleep/README.md index 89f3d632cba..68c0b045c17 100644 --- a/examples/system/light_sleep/README.md +++ b/examples/system/light_sleep/README.md @@ -10,7 +10,7 @@ This example illustrates usage of light sleep mode. Unlike deep sleep mode, ligh The example enables the following wakeup sources: - Timer: wake up the chip in 2 seconds -- EXT0: wake up the chip if a button attached to GPIO0 is pressed (i.e. if GPIO0 goes low) +- GPIO: wake up the chip if a button attached to a GPIO is pressed (i.e. if GPIO goes low) - UART0: wake up the chip when the uart rx pin receive more than or equal to 3 rising edges. The example also prints time spent in light sleep mode to illustrate that timekeeping continues while the chip is in light sleep. @@ -65,6 +65,10 @@ If do nothing to the example, the chip will wake-up every 2000 ms by timer, and For this example, the wake-up GPIO is bound to the 'BOOT' button on the board, we can wake-up the chip from light sleep by pressing the 'BOOT' button, the chip will wake-up immediately after we pressed the button. We can see the wake-up reason is `pin` in this case and the chip will fall into light sleep again if we release the button. +> [!NOTE] +> On ESP32-H21 and ESP32-H4 boards, the on-board **BOOT** button is not routed to a GPIO pin. This example uses +> **GPIO0** for GPIO wake-up; connect external hardware to drive GPIO0 and wake the chip from light sleep. + ### Wake-up by UART For this example, the wake-up UART is bound to the default console port (UART_NUM_0), we can wake-up the chip from light sleep by inputting some keys on the key board. We can see the wake-up reason is `uart` in this case. diff --git a/examples/system/light_sleep/main/Kconfig.projbuild b/examples/system/light_sleep/main/Kconfig.projbuild index 698e25a5d8b..de16d54e0d9 100644 --- a/examples/system/light_sleep/main/Kconfig.projbuild +++ b/examples/system/light_sleep/main/Kconfig.projbuild @@ -1,5 +1,7 @@ menu "Example Configuration" + orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps" + choice EXAMPLE_UART_WAKEUP_MODE prompt "uart wakeup mode" default UART_WK_MODE_ACTIVE_THRESH @@ -30,4 +32,15 @@ menu "Example Configuration" default 2 if UART_WK_MODE_START_BIT default 3 if UART_WK_MODE_CHAR_SEQ + config EXAMPLE_GPIO_WAKEUP_NUM + int "gpio wakeup num" + depends on IDF_TARGET_ESP32H4 || IDF_TARGET_ESP32H21 + default 0 + range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX + help + GPIO pin number used as the light sleep wakeup source. + Avoid console UART, MSPI, USB, and other pins already used by peripherals, as they may interfere + with normal system operation. + + endmenu diff --git a/examples/system/light_sleep/main/gpio_wakeup.c b/examples/system/light_sleep/main/gpio_wakeup.c index aac5be4fd62..7a1a52ae94c 100644 --- a/examples/system/light_sleep/main/gpio_wakeup.c +++ b/examples/system/light_sleep/main/gpio_wakeup.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -19,16 +19,24 @@ #define BOOT_BUTTON_NUM 28 #elif CONFIG_IDF_TARGET_ESP32P4 #define BOOT_BUTTON_NUM 35 -#elif CONFIG_IDF_TARGET_ESP32H21 -#define BOOT_BUTTON_NUM 14 #elif CONFIG_IDF_TARGET_ESP32S31 #define BOOT_BUTTON_NUM 61 #else #define BOOT_BUTTON_NUM 0 #endif +/* In esp32h21 and esp32h4, the boot button is disconnected from GPIO */ +#if CONFIG_IDF_TARGET_ESP32H21 || CONFIG_IDF_TARGET_ESP32H4 +#undef BOOT_BUTTON_NUM +#endif + +#ifdef BOOT_BUTTON_NUM /* Use boot button as gpio input */ #define GPIO_WAKEUP_NUM BOOT_BUTTON_NUM +#else +#define GPIO_WAKEUP_NUM CONFIG_EXAMPLE_GPIO_WAKEUP_NUM +#endif + /* "Boot" button is active low */ #define GPIO_WAKEUP_LEVEL 0 @@ -52,6 +60,9 @@ esp_err_t example_register_gpio_wakeup(void) .pull_up_en = GPIO_PULLUP_DISABLE, .intr_type = GPIO_INTR_DISABLE }; +#ifndef BOOT_BUTTON_NUM + config.pull_up_en = GPIO_PULLUP_ENABLE; +#endif ESP_RETURN_ON_ERROR(gpio_config(&config), TAG, "Initialize GPIO%d failed", GPIO_WAKEUP_NUM); /* Enable wake up from GPIO */ diff --git a/examples/system/light_sleep/pytest_light_sleep.py b/examples/system/light_sleep/pytest_light_sleep.py index 0801c5f5c90..da90c39bee1 100644 --- a/examples/system/light_sleep/pytest_light_sleep.py +++ b/examples/system/light_sleep/pytest_light_sleep.py @@ -10,7 +10,6 @@ from pytest_embedded_idf.utils import idf_parametrize @pytest.mark.generic @idf_parametrize('target', ['supported_targets'], indirect=['target']) -@pytest.mark.temp_skip_ci(targets=['esp32h4'], reason='cannot pass') # TODO: IDF-15611 def test_light_sleep(dut: Dut) -> None: ENTERING_SLEEP_STR = 'Entering light sleep' EXIT_SLEEP_REGEX = r'Returned from light sleep, reason: (\w+), t=(\d+) ms, slept for (\d+) ms' @@ -19,6 +18,8 @@ def test_light_sleep(dut: Dut) -> None: WAITING_FOR_GPIO_STR = r'Waiting for GPIO\d+ to go high...' WAKEUP_INTERVAL_MS = 2000 + # esp32h4/esp32h21 boot button is not connected to GPIO0; DTR cannot trigger pin wakeup in CI + GPIO_WAKEUP_SKIP_TARGETS = ['esp32h4', 'esp32h21'] # Ensure DTR and RTS are de-asserted for proper control of GPIO0 dut.serial.proc.setDTR(False) @@ -42,19 +43,21 @@ def test_light_sleep(dut: Dut) -> None: and int(match.group(3)) <= WAKEUP_INTERVAL_MS + 1 ) - # this time we'll test gpio wakeup - dut.expect_exact(ENTERING_SLEEP_STR) - logging.info('Pulling GPIO0 low using DTR') - dut.serial.proc.setDTR(True) - time.sleep(1) - match = dut.expect(EXIT_SLEEP_PIN_REGEX) - logging.info(f'Got third sleep period, wakeup from {match.group(1)}, slept for {match.group(3)}') - assert int(match.group(3)) < WAKEUP_INTERVAL_MS + if dut.target not in GPIO_WAKEUP_SKIP_TARGETS: + # this time we'll test gpio wakeup + dut.expect_exact(ENTERING_SLEEP_STR) + logging.info('Pulling GPIO0 low using DTR') + dut.serial.proc.setDTR(True) + time.sleep(1) + match = dut.expect(EXIT_SLEEP_PIN_REGEX) + logging.info(f'Got third sleep period, wakeup from {match.group(1)}, slept for {match.group(3)}') + assert int(match.group(3)) < WAKEUP_INTERVAL_MS - dut.expect(WAITING_FOR_GPIO_STR) - logging.info('Is waiting for GPIO...') + dut.expect(WAITING_FOR_GPIO_STR) + logging.info('Is waiting for GPIO...') + + dut.serial.proc.setDTR(False) - dut.serial.proc.setDTR(False) dut.expect_exact(ENTERING_SLEEP_STR) logging.info('Went to sleep again')