diff --git a/components/ulp/lp_core/lp_core/include/ulp_lp_core_gpio.h b/components/ulp/lp_core/lp_core/include/ulp_lp_core_gpio.h index 3e722aea5a9..f388b29bc91 100644 --- a/components/ulp/lp_core/lp_core/include/ulp_lp_core_gpio.h +++ b/components/ulp/lp_core/lp_core/include/ulp_lp_core_gpio.h @@ -231,6 +231,11 @@ static inline void ulp_lp_core_gpio_intr_enable(lp_io_num_t lp_io_num, gpio_int_ static inline void ulp_lp_core_gpio_clear_intr_status(void) { rtcio_ll_clear_interrupt_status(); +#if SOC_RTC_GPIO_EDGE_WAKEUP_SUPPORTED + for (int rtcio_num = 0; rtcio_num < SOC_RTCIO_PIN_COUNT; rtcio_num++) { + rtcio_ll_clear_edge_wakeup_latch(rtcio_num); + } +#endif } /** diff --git a/components/ulp/test_apps/.build-test-rules.yml b/components/ulp/test_apps/.build-test-rules.yml index f83aeacf71d..8d8d7163435 100644 --- a/components/ulp/test_apps/.build-test-rules.yml +++ b/components/ulp/test_apps/.build-test-rules.yml @@ -19,6 +19,17 @@ components/ulp/test_apps/lp_core/lp_core_basic_tests: - esp_hw_support +components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests: + enable: + - if: (SOC_LP_CORE_SUPPORTED == 1) and (SOC_RTCIO_PIN_COUNT > 0) and (SOC_DEEP_SLEEP_SUPPORTED == 1) and (SOC_RTC_GPIO_EDGE_WAKEUP_SUPPORTED == 1) + depends_components: + - ulp + - esp_driver_gpio + - esp_hal_gpio + - esp_hal_pmu + - esp_hw_support + + components/ulp/test_apps/lp_core/lp_core_hp_mem: disable: - if: SOC_LP_CORE_SUPPORTED != 1 diff --git a/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/CMakeLists.txt b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/CMakeLists.txt new file mode 100644 index 00000000000..2f343bd260b --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/CMakeLists.txt @@ -0,0 +1,14 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.22) + +list(PREPEND SDKCONFIG_DEFAULTS "$ENV{IDF_PATH}/tools/test_apps/configs/sdkconfig.debug_helpers" "sdkconfig.defaults") + +set(EXTRA_COMPONENT_DIRS + "$ENV{IDF_PATH}/tools/test_apps/components" +) + +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +set(COMPONENTS main) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(lp_core_gpio_wakeup_tests) diff --git a/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/README.md b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/README.md new file mode 100644 index 00000000000..9f7cd737485 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/README.md @@ -0,0 +1,31 @@ +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | + +# LP Core GPIO Wakeup Tests + +This test app verifies LP core GPIO wakeup from deep sleep using an **external GPIO toggle** provided by a second board. + +It exercises the same flow as the `gpio_wakeup` example: + +1. HP configures the wakeup GPIO, loads and starts the LP program, and enters deep sleep +2. The waker holds the GPIO at the idle high level long enough to catch spurious wakeups +3. An external falling edge wakes LP, which records the LP wakeup cause, wakes HP, and clears GPIO interrupt status +4. HP verifies the ULP wakeup cause and the LP GPIO wakeup cause + +## Hardware setup + +This is a `generic_multi_device` test. Two boards of the same target must have the configured wakeup GPIO pin wired together (default: GPIO2). + +- **Wakee (DUT 0):** multi-stage test that enters deep sleep and verifies ULP wakeup after an external falling edge +- **Waker (DUT 1):** provides separate Unity test cases to drive the shared GPIO high or low + +The wakee side uses `TEST_CASE_MULTIPLE_STAGES` because deep sleep reboots the chip back to the Unity menu; pytest reruns the after-wake stage once the board wakes up. Pytest drives the waker GPIO high before the wakee enters deep sleep, verifies that the wakee does not reboot early, and then drives the falling edge. + +## Running locally + +```bash +cd components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests +idf.py set-target esp32p4 +idf.py build +pytest --target esp32p4 -m generic_multi_device +``` diff --git a/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/CMakeLists.txt b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/CMakeLists.txt new file mode 100644 index 00000000000..16e271f3eac --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/CMakeLists.txt @@ -0,0 +1,10 @@ +set(app_sources "test_app_main.c" "test_lp_gpio_wakeup.c") +set(lp_core_sources "lp_core/test_main_gpio_wakeup.c") + +idf_component_register(SRCS ${app_sources} + REQUIRES ulp unity test_utils esp_driver_gpio + WHOLE_ARCHIVE) + +set(lp_core_exp_dep_srcs ${app_sources}) + +ulp_embed_binary(lp_core_test_app_gpio_wakeup "${lp_core_sources}" "${lp_core_exp_dep_srcs}") diff --git a/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/Kconfig.projbuild b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/Kconfig.projbuild new file mode 100644 index 00000000000..5eb9154d762 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/Kconfig.projbuild @@ -0,0 +1,10 @@ +menu "LP GPIO Wakeup Test Configuration" + + config TEST_LP_GPIO_WAKEUP_PIN + int "GPIO pin wired between wakee and waker boards" + default 2 + help + RTC GPIO pin used for LP core GPIO wakeup on the sleeping board. + The same pin number must be wired to the GPIO output on the waker board. + +endmenu diff --git a/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/lp_core/test_main_gpio_wakeup.c b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/lp_core/test_main_gpio_wakeup.c new file mode 100644 index 00000000000..3e9d84169fd --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/lp_core/test_main_gpio_wakeup.c @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "ulp_lp_core_utils.h" +#include "ulp_lp_core_gpio.h" +#include "hal/lp_core_ll.h" + +uint32_t lp_wakeup_cause; + +int main(void) +{ + lp_wakeup_cause = ulp_lp_core_get_wakeup_cause(); + + ulp_lp_core_wakeup_main_processor(); + + ulp_lp_core_gpio_clear_intr_status(); + + return 0; +} diff --git a/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/test_app_main.c b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/test_app_main.c new file mode 100644 index 00000000000..043cc46e4b9 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/test_app_main.c @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" + +// Some resources are lazy allocated in the sleep code, the threshold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (-500) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +static void check_leak(size_t before_free, size_t after_free, const char *type) +{ + ssize_t delta = after_free - before_free; + printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); + TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); +} + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + check_leak(before_free_8bit, after_free_8bit, "8BIT"); + check_leak(before_free_32bit, after_free_32bit, "32BIT"); +} + +void app_main(void) +{ + unity_run_menu(); +} diff --git a/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/test_lp_gpio_wakeup.c b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/test_lp_gpio_wakeup.c new file mode 100644 index 00000000000..88c7ce14d78 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/main/test_lp_gpio_wakeup.c @@ -0,0 +1,107 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "unity.h" +#include "test_utils.h" +#include "esp_sleep.h" +#include "driver/rtc_io.h" +#include "driver/gpio.h" +#include "ulp_lp_core.h" +#include "hal/lp_core_ll.h" +#include "lp_core_test_app_gpio_wakeup.h" + +#define TEST_WAKEUP_PIN CONFIG_TEST_LP_GPIO_WAKEUP_PIN +#define GPIO_IDLE_HIGH_SIGNAL "gpio idle high" + +extern const uint8_t lp_core_gpio_wakeup_bin_start[] asm("_binary_lp_core_test_app_gpio_wakeup_bin_start"); +extern const uint8_t lp_core_gpio_wakeup_bin_end[] asm("_binary_lp_core_test_app_gpio_wakeup_bin_end"); + +static void configure_wakee_gpio(void) +{ + rtc_gpio_init(TEST_WAKEUP_PIN); + rtc_gpio_set_direction(TEST_WAKEUP_PIN, RTC_GPIO_MODE_INPUT_ONLY); + rtc_gpio_pulldown_dis(TEST_WAKEUP_PIN); + rtc_gpio_pullup_en(TEST_WAKEUP_PIN); + rtc_gpio_wakeup_enable(TEST_WAKEUP_PIN, GPIO_INTR_NEGEDGE); +} + +static void load_and_start_lp_core_program(void) +{ + TEST_ESP_OK(ulp_lp_core_load_binary(lp_core_gpio_wakeup_bin_start, + lp_core_gpio_wakeup_bin_end - lp_core_gpio_wakeup_bin_start)); + + ulp_lp_core_cfg_t cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_IO, + }; + + TEST_ESP_OK(ulp_lp_core_run(&cfg)); +} + +static void configure_waker_gpio_output(void) +{ + gpio_config_t io_conf = { + .pin_bit_mask = (1ULL << TEST_WAKEUP_PIN), + .mode = GPIO_MODE_OUTPUT, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .pull_up_en = GPIO_PULLUP_DISABLE, + .intr_type = GPIO_INTR_DISABLE, + }; + TEST_ESP_OK(gpio_config(&io_conf)); +} + +static void lp_gpio_wakeup_wakee_init(void) +{ + configure_wakee_gpio(); + load_and_start_lp_core_program(); + + unity_wait_for_signal(GPIO_IDLE_HIGH_SIGNAL); + + TEST_ESP_OK(esp_sleep_enable_ulp_wakeup()); + esp_deep_sleep_start(); + TEST_FAIL_MESSAGE("Should have entered deep sleep"); +} + +static void lp_gpio_wakeup_wakee_after_wake(void) +{ + TEST_ASSERT(esp_sleep_get_wakeup_causes() & BIT(ESP_SLEEP_WAKEUP_ULP)); + printf("LP wakeup cause: 0x%" PRIx32 "\n", ulp_lp_wakeup_cause); + TEST_ASSERT_EQUAL_HEX32(LP_CORE_LL_WAKEUP_SOURCE_LP_IO, ulp_lp_wakeup_cause); +} + +static void lp_gpio_wakeup_waker_idle_high(void) +{ + configure_waker_gpio_output(); + TEST_ESP_OK(gpio_set_level(TEST_WAKEUP_PIN, 1)); +} + +static void lp_gpio_wakeup_waker_wake_low(void) +{ + configure_waker_gpio_output(); + TEST_ESP_OK(gpio_set_level(TEST_WAKEUP_PIN, 0)); +} + +TEST_CASE_MULTIPLE_STAGES( + "LP GPIO wakeup wakee from deep sleep", + "[lp_core][lp_gpio_wakeup][test_env=generic_multi_device][timeout=120][deepsleep]", + lp_gpio_wakeup_wakee_init, + lp_gpio_wakeup_wakee_after_wake); + +TEST_CASE( + "LP GPIO wakeup waker set idle high", + "[lp_core][lp_gpio_wakeup][test_env=generic_multi_device][timeout=120]") +{ + lp_gpio_wakeup_waker_idle_high(); +} + +TEST_CASE( + "LP GPIO wakeup waker set wake low", + "[lp_core][lp_gpio_wakeup][test_env=generic_multi_device][timeout=120]") +{ + lp_gpio_wakeup_waker_wake_low(); +} diff --git a/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/pytest_lp_core_gpio_wakeup.py b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/pytest_lp_core_gpio_wakeup.py new file mode 100644 index 00000000000..ae6b226d0a3 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/pytest_lp_core_gpio_wakeup.py @@ -0,0 +1,116 @@ +# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +from typing import TYPE_CHECKING + +import pytest +from pexpect.exceptions import TIMEOUT +from pytest_embedded_idf import CaseTester +from pytest_embedded_idf import UnittestMenuCase +from pytest_embedded_idf.utils import idf_parametrize +from pytest_embedded_idf.utils import soc_filtered_targets + +if TYPE_CHECKING: + from pytest_embedded_idf.dut import IdfDut + +WAKEE_DUT_INDEX = 0 +WAKER_DUT_INDEX = 1 +TEST_TIMEOUT = 120.0 +NO_EARLY_WAKE_TIMEOUT = 2.0 +LP_GPIO_WAKEUP_GROUP = 'lp_gpio_wakeup' +GPIO_IDLE_HIGH_SIGNAL = 'gpio idle high' + + +def _wait_signal_line(signal: str) -> str: + return f'Waiting for signal: [{signal}]!' + + +def _start_unity_case(dut: 'IdfDut', case: UnittestMenuCase, timeout: float, *, wait_ready: bool = True) -> None: + if wait_ready: + dut._get_ready(timeout) + + dut.confirm_write(case.index, expect_str=f'Running {case.name}...') + + +def _run_unity_case(dut: 'IdfDut', case: UnittestMenuCase, timeout: float) -> None: + _start_unity_case(dut, case, timeout) + dut.expect_unity_test_output(timeout=timeout) + + +def _run_unity_stage( + dut: 'IdfDut', + case: UnittestMenuCase, + stage_index: int, + timeout: float, + *, + wait_ready: bool = True, +) -> None: + _start_unity_case(dut, case, timeout, wait_ready=wait_ready) + dut.write(str(stage_index)) + + +def _find_single_test_case( + case_tester: CaseTester, + case_type: str, + name_fragment: str | None = None, +) -> UnittestMenuCase: + cases = [ + case + for case in case_tester.test_menu + if case.type == case_type + and LP_GPIO_WAKEUP_GROUP in case.groups + and (name_fragment is None or name_fragment in case.name) + ] + assert len(cases) == 1, f"Expected 1 {case_type} case with group '{LP_GPIO_WAKEUP_GROUP}', found {len(cases)}." + return cases[0] + + +@pytest.mark.generic_multi_device +@pytest.mark.parametrize('count', [2], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'defaults', + ], + indirect=True, +) +@idf_parametrize( + 'target', + soc_filtered_targets( + '(SOC_LP_CORE_SUPPORTED == 1) and ' + '(SOC_RTCIO_PIN_COUNT > 0) and ' + '(SOC_DEEP_SLEEP_SUPPORTED == 1) and ' + '(SOC_RTC_GPIO_EDGE_WAKEUP_SUPPORTED == 1)' + ), + indirect=['target'], +) +def test_lp_gpio_wakeup_from_deep_sleep(case_tester: CaseTester) -> None: + wakee_case = _find_single_test_case(case_tester, 'multi_stage') + waker_idle_case = _find_single_test_case(case_tester, 'normal', name_fragment='idle high') + waker_wake_case = _find_single_test_case(case_tester, 'normal', name_fragment='wake low') + assert len(wakee_case.subcases) == 2, f'Expected 2 wakee stages, found {len(wakee_case.subcases)}.' + + wakee = case_tester.dut[WAKEE_DUT_INDEX] + waker = case_tester.dut[WAKER_DUT_INDEX] + wakee_init_stage, wakee_after_wake_stage = wakee_case.subcases + + wakee.serial.hard_reset() + waker.serial.hard_reset() + + _run_unity_case(waker, waker_idle_case, TEST_TIMEOUT) + + _run_unity_stage(wakee, wakee_case, int(wakee_init_stage['index']), TEST_TIMEOUT) + wakee.expect_exact(_wait_signal_line(GPIO_IDLE_HIGH_SIGNAL), timeout=TEST_TIMEOUT) + wakee.write('') + + try: + wakee._get_ready(NO_EARLY_WAKE_TIMEOUT) + except TIMEOUT: + pass + else: + pytest.fail('Wakee rebooted before the waker drove the GPIO falling edge') + + _run_unity_case(waker, waker_wake_case, TEST_TIMEOUT) + + wakee._get_ready(TEST_TIMEOUT) + _run_unity_stage(wakee, wakee_case, int(wakee_after_wake_stage['index']), TEST_TIMEOUT, wait_ready=False) + wakee.expect_unity_test_output(timeout=TEST_TIMEOUT) diff --git a/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/sdkconfig.ci.defaults b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/sdkconfig.ci.defaults new file mode 100644 index 00000000000..3b5dd38fb20 --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/sdkconfig.ci.defaults @@ -0,0 +1 @@ +# CI defaults for lp_core_gpio_wakeup_tests (see sdkconfig.defaults) diff --git a/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/sdkconfig.defaults b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/sdkconfig.defaults new file mode 100644 index 00000000000..79776d7ef1f --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests/sdkconfig.defaults @@ -0,0 +1,5 @@ +CONFIG_ESP_TASK_WDT_INIT=n + +CONFIG_ULP_COPROC_ENABLED=y +CONFIG_ULP_COPROC_TYPE_LP_CORE=y +CONFIG_ULP_COPROC_RESERVE_MEM=12000 diff --git a/examples/system/ulp/.build-test-rules.yml b/examples/system/ulp/.build-test-rules.yml index 3ef1abb041d..c74d218d22c 100644 --- a/examples/system/ulp/.build-test-rules.yml +++ b/examples/system/ulp/.build-test-rules.yml @@ -38,7 +38,7 @@ examples/system/ulp/lp_core/gpio_intr_pulse_counter: examples/system/ulp/lp_core/gpio_wakeup: enable: - - if: (SOC_LP_CORE_SUPPORTED == 1) and (SOC_RTCIO_PIN_COUNT > 0) and (SOC_DEEP_SLEEP_SUPPORTED == 1) + - if: (SOC_LP_CORE_SUPPORTED == 1) and (SOC_RTCIO_PIN_COUNT > 0) and (SOC_DEEP_SLEEP_SUPPORTED == 1) and (SOC_RTC_GPIO_EDGE_WAKEUP_SUPPORTED == 1) # TODO: [ESP32S31] IDF-15884 SOC_RTC_GPIO_EDGE_WAKEUP_SUPPORTED not declared yet <<: *ulp_default_depends depends_components+: - esp_driver_gpio diff --git a/examples/system/ulp/lp_core/gpio_wakeup/README.md b/examples/system/ulp/lp_core/gpio_wakeup/README.md index 0f8a94bf4c0..66925750726 100644 --- a/examples/system/ulp/lp_core/gpio_wakeup/README.md +++ b/examples/system/ulp/lp_core/gpio_wakeup/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-P4 | ESP32-S31 | -| ----------------- | -------- | -------- | -------- | --------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | # ULP-LP-Core simple example with GPIO Interrupt: This example demonstrates how to program the LP-Core coprocessor to wake up from a RTC IO interrupt, instead of waking periodically from the ULP timer. diff --git a/examples/system/ulp/lp_core/gpio_wakeup/main/lp_core_gpio_wake_up_example_main.c b/examples/system/ulp/lp_core/gpio_wakeup/main/lp_core_gpio_wake_up_example_main.c index ce1bcdfe576..724ba7f19d4 100644 --- a/examples/system/ulp/lp_core/gpio_wakeup/main/lp_core_gpio_wake_up_example_main.c +++ b/examples/system/ulp/lp_core/gpio_wakeup/main/lp_core_gpio_wake_up_example_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -13,10 +13,13 @@ */ #include +#include +#include #include "esp_sleep.h" #include "driver/rtc_io.h" #include "ulp_lp_core.h" #include "ulp_main.h" +#include "hal/lp_core_ll.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -50,6 +53,8 @@ void app_main(void) if (esp_sleep_get_wakeup_causes() & BIT(ESP_SLEEP_WAKEUP_ULP)) { /* ULP read and detected a change in WAKEUP_PIN, prints */ + printf("LP wakeup cause: 0x%" PRIx32 "\n", ulp_lp_wakeup_cause); + assert(ulp_lp_wakeup_cause == LP_CORE_LL_WAKEUP_SOURCE_LP_IO); printf("ULP woke up the main CPU! \n"); } else { /* not a wakeup from ULP, load the firmware */ diff --git a/examples/system/ulp/lp_core/gpio_wakeup/main/ulp/main.c b/examples/system/ulp/lp_core/gpio_wakeup/main/ulp/main.c index 642e425de2c..28092170245 100644 --- a/examples/system/ulp/lp_core/gpio_wakeup/main/ulp/main.c +++ b/examples/system/ulp/lp_core/gpio_wakeup/main/ulp/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -9,9 +9,11 @@ #include "ulp_lp_core_utils.h" #include "ulp_lp_core_gpio.h" +uint32_t lp_wakeup_cause; int main (void) { + lp_wakeup_cause = ulp_lp_core_get_wakeup_cause(); ulp_lp_core_wakeup_main_processor(); ulp_lp_core_gpio_clear_intr_status();