diff --git a/components/esp_hw_support/test_apps/.build-test-rules.yml b/components/esp_hw_support/test_apps/.build-test-rules.yml index 0585429eba..95cd9fa76e 100644 --- a/components/esp_hw_support/test_apps/.build-test-rules.yml +++ b/components/esp_hw_support/test_apps/.build-test-rules.yml @@ -52,5 +52,7 @@ components/esp_hw_support/test_apps/vad_wakeup: - if: SOC_LP_VAD_SUPPORTED != 1 components/esp_hw_support/test_apps/wakeup_tests: + enable: + - if: SOC_DEEP_SLEEP_SUPPORTED == 1 and SOC_LIGHT_SLEEP_SUPPORTED == 1 disable: - - if: IDF_TARGET in ["esp32c5", "esp32p4", "linux", "esp32c61"] + - if: IDF_TARGET in ["esp32c5", "linux", "esp32c61"] diff --git a/components/esp_hw_support/test_apps/wakeup_tests/README.md b/components/esp_hw_support/test_apps/wakeup_tests/README.md index a8b7833fa3..bf47d80ec6 100644 --- a/components/esp_hw_support/test_apps/wakeup_tests/README.md +++ b/components/esp_hw_support/test_apps/wakeup_tests/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_hw_support/test_apps/wakeup_tests/main/src/io_wakeup_cmd.c b/components/esp_hw_support/test_apps/wakeup_tests/main/src/io_wakeup_cmd.c index 3c8c9fc870..39b5591cd6 100644 --- a/components/esp_hw_support/test_apps/wakeup_tests/main/src/io_wakeup_cmd.c +++ b/components/esp_hw_support/test_apps/wakeup_tests/main/src/io_wakeup_cmd.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -10,6 +10,7 @@ #include "esp_sleep.h" #include "driver/rtc_io.h" #include "driver/gpio.h" +#include "hal/gpio_ll.h" #include "esp_console.h" #include "linenoise/linenoise.h" #include "argtable3/argtable3.h" @@ -128,7 +129,7 @@ static void register_ext1_wakeup(void) const esp_console_cmd_t cmd = { .command = "ext1", - .help = "configue ext1 wakeup", + .help = "configure ext1 wakeup", .hint = NULL, .func = &process_ext1_wakeup, .argtable = &ext1_wakeup_args @@ -202,7 +203,7 @@ static void register_rtcio_wakeup(void) const esp_console_cmd_t cmd = { .command = "rtcio", - .help = "configue rtcio wakeup", + .help = "configure rtcio wakeup", .hint = NULL, .func = &process_rtcio_wakeup, .argtable = &rtcio_wakeup_args @@ -247,13 +248,14 @@ static int process_gpio_wakeup(int argc, char **argv) if (gpio_wakeup_args.disable->count) { ESP_ERROR_CHECK(gpio_wakeup_disable(io_wakeup_num)); + ESP_ERROR_CHECK(gpio_intr_disable(io_wakeup_num)); } else { gpio_config_t config = { .pin_bit_mask = BIT64(io_wakeup_num), .mode = GPIO_MODE_INPUT, .pull_down_en = false, .pull_up_en = false, - .intr_type = GPIO_INTR_DISABLE + .intr_type = (io_wakeup_level == 0) ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL }; ESP_ERROR_CHECK(gpio_config(&config)); @@ -277,7 +279,7 @@ static void register_gpio_wakeup(void) const esp_console_cmd_t cmd = { .command = "gpio", - .help = "configue gpio wakeup", + .help = "configure gpio wakeup", .hint = NULL, .func = &process_gpio_wakeup, .argtable = &gpio_wakeup_args @@ -336,7 +338,7 @@ static void register_gpio_control(void) const esp_console_cmd_t cmd = { .command = "gpio_control", - .help = "configue gpio control", + .help = "configure gpio control", .hint = NULL, .func = &process_gpio_control, .argtable = &gpio_control_args @@ -358,11 +360,51 @@ static int process_get_wakeup_cause(int argc, char **argv) switch (esp_sleep_get_wakeup_cause()) { case ESP_SLEEP_WAKEUP_EXT1: { - printf("Wake up from EXT1\n"); +#if SOC_PM_SUPPORT_EXT1_WAKEUP && SOC_RTCIO_PIN_COUNT > 0 + uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status(); + if (wakeup_pin_mask != 0) { + int pin = __builtin_ffsll(wakeup_pin_mask) - 1; + printf("Wake up from EXT1 at IO%d\n", pin); + } else +#endif + { + printf("Wake up from EXT1 triggered, but unknown wake-up IO\n"); + } break; } case ESP_SLEEP_WAKEUP_GPIO: { - printf("Wake up from GPIO\n"); + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + uint64_t wakeup_pin_mask = esp_sleep_get_gpio_wakeup_status(); + if (wakeup_pin_mask != 0) { + int pin = __builtin_ffsll(wakeup_pin_mask) - 1; + printf("Wake up from GPIO at IO%d\n", pin); + } else { + printf("Wake up from GPIO triggered, but unknown wake-up IO\n"); + } +#endif + } else { + struct { + union { + struct + { + uint32_t status_l; + uint32_t status_h; + }; + uint64_t val; + }; + } gpio_intr_status; + gpio_ll_get_intr_status(&GPIO, 0, &gpio_intr_status.status_l); + gpio_ll_get_intr_status_high(&GPIO, 0, &gpio_intr_status.status_h); + + if (gpio_intr_status.val) { + printf("Wake up from GPIO at IO%d\n", __builtin_ffsll(gpio_intr_status.val) - 1); + } else { + printf("Wake up from GPIO triggered, but unknown wake-up IO\n"); + } + gpio_ll_clear_intr_status(&GPIO, 0xFFFFFFFF); + gpio_ll_clear_intr_status_high(&GPIO, 0xFFFFFFFF); + } break; } default: { diff --git a/components/esp_hw_support/test_apps/wakeup_tests/pytest_wakeup_tests.py b/components/esp_hw_support/test_apps/wakeup_tests/pytest_wakeup_tests.py index b99d1345a4..b4511844d1 100644 --- a/components/esp_hw_support/test_apps/wakeup_tests/pytest_wakeup_tests.py +++ b/components/esp_hw_support/test_apps/wakeup_tests/pytest_wakeup_tests.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - from time import sleep from typing import Tuple @@ -23,6 +22,40 @@ available_gpio_nums = { 'esp32c3': [0, 1, 2, 3, 4, 5, 6, 7, 10, 18, 19], 'esp32c6': [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 15, 18, 19, 20, 21, 22, 23], 'esp32h2': [0, 1, 2, 3, 4, 5, 10, 11, 12, 22, 25, 26, 27], + 'esp32p4': [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 28, + 29, + 30, + 31, + 32, + 33, + 36, + 49, + 50, + 51, + 52, + 53, + 54, + ], + 'esp32c5': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13, 14, 23, 24, 25, 26], } available_rtcio_nums = { @@ -33,6 +66,8 @@ available_rtcio_nums = { 'esp32c3': [0, 1, 2, 3, 4, 5], 'esp32c6': [0, 1, 2, 3, 4, 5, 6, 7], 'esp32h2': [7, 8, 9, 10, 11, 12, 13, 14], + 'esp32p4': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + 'esp32c5': [0, 1, 2, 3, 4, 5, 6], } @@ -41,6 +76,7 @@ available_rtcio_nums = { @pytest.mark.esp32s3 @pytest.mark.esp32c6 @pytest.mark.esp32h2 +@pytest.mark.esp32p4 @pytest.mark.generic_multi_device @pytest.mark.parametrize('count', [2], indirect=True) @pytest.mark.parametrize('config', TEST_CONFIGS, indirect=True) @@ -81,7 +117,12 @@ def test_ext1_deepsleep(dut: Tuple[IdfDut, IdfDut]) -> None: sleep(2) wakee.write('cause') - wakee.expect('Wake up from EXT1', timeout=10) + # esp32 ext1 all low wakeup mode can not detect wakeup pin. + if (dut[0].target == 'esp32') and (wakeup_level == 0): + wakee.expect('Wake up from EXT1', timeout=10) + else: + wakee.expect(f'Wake up from EXT1 at IO{gpio_num}', timeout=10) + wakee.write(f'ext1 -p {gpio_num} -d') wakee.expect(f'io_wakeup_num = {gpio_num}', timeout=10) @@ -89,6 +130,7 @@ def test_ext1_deepsleep(dut: Tuple[IdfDut, IdfDut]) -> None: @pytest.mark.esp32c2 @pytest.mark.esp32c3 @pytest.mark.esp32c6 +@pytest.mark.esp32p4 @pytest.mark.generic_multi_device @pytest.mark.parametrize('count', [2], indirect=True) @pytest.mark.parametrize('config', TEST_CONFIGS, indirect=True) @@ -129,7 +171,7 @@ def test_rtcio_deepsleep(dut: Tuple[IdfDut, IdfDut]) -> None: sleep(2) wakee.write('cause') - wakee.expect('Wake up from GPIO', timeout=10) + wakee.expect(f'Wake up from GPIO at IO{gpio_num}', timeout=10) wakee.write(f'rtcio -p {gpio_num} -d') wakee.expect(f'io_wakeup_num = {gpio_num}', timeout=10) @@ -141,6 +183,7 @@ def test_rtcio_deepsleep(dut: Tuple[IdfDut, IdfDut]) -> None: @pytest.mark.esp32s3 @pytest.mark.esp32c6 @pytest.mark.esp32h2 +@pytest.mark.esp32p4 @pytest.mark.generic_multi_device @pytest.mark.parametrize('count', [2], indirect=True) @pytest.mark.parametrize('config', TEST_CONFIGS, indirect=True) @@ -175,7 +218,7 @@ def test_gpio_wakeup_enable_lightsleep(dut: Tuple[IdfDut, IdfDut]) -> None: wakee.expect('esp_light_sleep_start', timeout=10) wakee.write('cause') - wakee.expect('Wake up from GPIO', timeout=10) + wakee.expect(f'Wake up from GPIO at IO{gpio_num}', timeout=10) wakee.write(f'gpio -p {gpio_num} -d') wakee.expect(f'io_wakeup_num = {gpio_num}', timeout=10) diff --git a/components/hal/esp32p4/include/hal/pmu_ll.h b/components/hal/esp32p4/include/hal/pmu_ll.h index 46f3f5902e..599dcbb79a 100644 --- a/components/hal/esp32p4/include/hal/pmu_ll.h +++ b/components/hal/esp32p4/include/hal/pmu_ll.h @@ -702,6 +702,7 @@ static inline uint32_t pmu_ll_ext1_get_wakeup_status(void) static inline void pmu_ll_ext1_clear_wakeup_status(void) { REG_SET_BIT(PMU_EXT_WAKEUP_CNTL_REG, PMU_EXT_WAKEUP_STATUS_CLR); + REG_CLR_BIT(PMU_EXT_WAKEUP_CNTL_REG, PMU_EXT_WAKEUP_STATUS_CLR); } /**