From 66d1d594e450fae00291ebd27a3073087be75aa1 Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Wed, 29 Apr 2026 10:26:40 +0800 Subject: [PATCH] feat(ulp): add lp uart support for ULP on S31 --- components/esp_driver_uart/CMakeLists.txt | 7 ++++++- .../soc/esp32s31/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32s31/include/soc/soc_caps.h | 2 +- components/ulp/lp_core/include/lp_core_uart.h | 5 +++++ .../shared/include/ulp_lp_core_lp_uart_shared.h | 2 ++ .../ulp/lp_core/shared/ulp_lp_core_lp_uart_shared.c | 3 +++ .../lp_core/lp_core_basic_tests/main/CMakeLists.txt | 12 +++++++++--- .../lp_core_basic_tests/pytest_lp_core_basic.py | 1 + .../lp_core_hp_uart/pytest_lp_core_hp_uart.py | 3 --- docs/doxygen/Doxyfile_esp32s31 | 2 ++ examples/system/ulp/.build-test-rules.yml | 2 +- .../lp_uart/lp_uart_char_seq_wakeup/README.md | 3 ++- .../ulp/lp_core/lp_uart/lp_uart_echo/README.md | 1 + .../ulp/lp_core/lp_uart/lp_uart_print/README.md | 1 + 14 files changed, 38 insertions(+), 10 deletions(-) diff --git a/components/esp_driver_uart/CMakeLists.txt b/components/esp_driver_uart/CMakeLists.txt index 7af0ff0c712..7bb23130f53 100644 --- a/components/esp_driver_uart/CMakeLists.txt +++ b/components/esp_driver_uart/CMakeLists.txt @@ -3,7 +3,12 @@ idf_build_get_property(target IDF_TARGET) set(srcs) set(public_include "include") if(CONFIG_SOC_UART_SUPPORTED) - list(APPEND srcs "src/uart.c" "src/uart_wakeup.c") + list(APPEND srcs "src/uart.c") + + if(CONFIG_SOC_DEEP_SLEEP_SUPPORTED OR CONFIG_SOC_LIGHT_SLEEP_SUPPORTED) + list(APPEND srcs "src/uart_wakeup.c") + endif() + if(CONFIG_SOC_UHCI_SUPPORTED) list(APPEND srcs "src/uhci.c") endif() diff --git a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in index af6140a8873..879fd55ffce 100644 --- a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in @@ -171,6 +171,10 @@ config SOC_RTC_TIMER_SUPPORTED bool default y +config SOC_ULP_LP_UART_SUPPORTED + bool + default y + config SOC_LP_GPIO_MATRIX_SUPPORTED bool default y diff --git a/components/soc/esp32s31/include/soc/soc_caps.h b/components/soc/esp32s31/include/soc/soc_caps.h index 24d9a36ef47..b2a8cf7da12 100644 --- a/components/soc/esp32s31/include/soc/soc_caps.h +++ b/components/soc/esp32s31/include/soc/soc_caps.h @@ -79,7 +79,7 @@ #define SOC_PAU_SUPPORTED 1 #define SOC_PMU_SUPPORTED 1 #define SOC_RTC_TIMER_SUPPORTED 1 -// #define SOC_ULP_LP_UART_SUPPORTED 1 // TODO: [ESP32S31] IDF-14634 +#define SOC_ULP_LP_UART_SUPPORTED 1 #define SOC_LP_GPIO_MATRIX_SUPPORTED 1 #define SOC_LP_PERIPHERALS_SUPPORTED 1 #define SOC_LP_I2C_SUPPORTED 1 diff --git a/components/ulp/lp_core/include/lp_core_uart.h b/components/ulp/lp_core/include/lp_core_uart.h index d24a451061b..2cd166c23a4 100644 --- a/components/ulp/lp_core/include/lp_core_uart.h +++ b/components/ulp/lp_core/include/lp_core_uart.h @@ -31,6 +31,11 @@ extern "C" { #define LP_UART_DEFAULT_RX_GPIO_NUM GPIO_NUM_4 #define LP_UART_DEFAULT_RTS_GPIO_NUM GPIO_NUM_2 #define LP_UART_DEFAULT_CTS_GPIO_NUM GPIO_NUM_3 +#elif CONFIG_IDF_TARGET_ESP32S31 +#define LP_UART_DEFAULT_TX_GPIO_NUM GPIO_NUM_6 +#define LP_UART_DEFAULT_RX_GPIO_NUM GPIO_NUM_7 +#define LP_UART_DEFAULT_RTS_GPIO_NUM GPIO_NUM_4 +#define LP_UART_DEFAULT_CTS_GPIO_NUM GPIO_NUM_5 #else #error "LP IO Mux pins undefined for LP UART" #endif /* CONFIG_IDF_TARGET_ESP32P4 */ diff --git a/components/ulp/lp_core/shared/include/ulp_lp_core_lp_uart_shared.h b/components/ulp/lp_core/shared/include/ulp_lp_core_lp_uart_shared.h index 2c8e59bd255..63ff39d0f7d 100644 --- a/components/ulp/lp_core/shared/include/ulp_lp_core_lp_uart_shared.h +++ b/components/ulp/lp_core/shared/include/ulp_lp_core_lp_uart_shared.h @@ -13,6 +13,7 @@ extern "C" { #endif +#if SOC_DEEP_SLEEP_SUPPORTED /** * @brief Initialize and configure the LP UART wakeup mode. * @@ -28,6 +29,7 @@ extern "C" { * @return esp_err_t ESP_OK when successful */ esp_err_t lp_core_uart_wakeup_setup(const uart_wakeup_cfg_t *cfg); +#endif /* SOC_DEEP_SLEEP_SUPPORTED */ /** * @brief Clear LP UART rx tx buffer. diff --git a/components/ulp/lp_core/shared/ulp_lp_core_lp_uart_shared.c b/components/ulp/lp_core/shared/ulp_lp_core_lp_uart_shared.c index 57faac9a7dd..7efdb4b6dac 100644 --- a/components/ulp/lp_core/shared/ulp_lp_core_lp_uart_shared.c +++ b/components/ulp/lp_core/shared/ulp_lp_core_lp_uart_shared.c @@ -5,16 +5,19 @@ */ #include "ulp_lp_core_lp_uart_shared.h" #include "hal/uart_hal.h" +#include "soc/soc_caps.h" /* LP UART HAL Context */ static uart_hal_context_t hal = { .dev = (uart_dev_t *)UART_LL_GET_HW(LP_UART_NUM_0), }; +#if SOC_DEEP_SLEEP_SUPPORTED esp_err_t lp_core_uart_wakeup_setup(const uart_wakeup_cfg_t *cfg) { return uart_wakeup_setup(LP_UART_NUM_0, cfg); } +#endif /* SOC_DEEP_SLEEP_SUPPORTED */ void lp_core_uart_clear_buf(void) { diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt index 40a1cb0bec8..471a9448404 100644 --- a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt @@ -6,7 +6,9 @@ endif() if(CONFIG_SOC_ULP_LP_UART_SUPPORTED) list(APPEND app_sources "test_lp_core_uart.c") - list(APPEND app_sources "test_lp_core_uart_wakeup.c") + if(CONFIG_SOC_DEEP_SLEEP_SUPPORTED) + list(APPEND app_sources "test_lp_core_uart_wakeup.c") + endif() endif() if(CONFIG_SOC_LP_SPI_SUPPORTED) @@ -43,7 +45,9 @@ endif() if(CONFIG_SOC_ULP_LP_UART_SUPPORTED) set(lp_core_sources_uart "lp_core/test_main_uart.c") - set(lp_core_sources_uart_wakeup "lp_core/test_main_uart_wakeup.c") + if(CONFIG_SOC_DEEP_SLEEP_SUPPORTED) + set(lp_core_sources_uart_wakeup "lp_core/test_main_uart_wakeup.c") + endif() endif() if(CONFIG_SOC_LP_SPI_SUPPORTED) @@ -89,7 +93,9 @@ endif() if(CONFIG_SOC_ULP_LP_UART_SUPPORTED) ulp_embed_binary(lp_core_test_app_uart "${lp_core_sources_uart}" "${lp_core_exp_dep_srcs}") - ulp_embed_binary(lp_core_test_app_uart_wakeup "${lp_core_sources_uart_wakeup}" "${lp_core_exp_dep_srcs}") + if(CONFIG_SOC_DEEP_SLEEP_SUPPORTED) + ulp_embed_binary(lp_core_test_app_uart_wakeup "${lp_core_sources_uart_wakeup}" "${lp_core_exp_dep_srcs}") + endif() endif() if(CONFIG_SOC_LP_SPI_SUPPORTED) diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py b/components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py index 888d153239e..0bb7325637e 100644 --- a/components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py @@ -79,6 +79,7 @@ def test_lp_core_multi_device(case_tester: CaseTester) -> None: indirect=True, ) @idf_parametrize('target', soc_filtered_targets('SOC_ULP_LP_UART_SUPPORTED == 1'), indirect=['target']) +@pytest.mark.temp_skip_ci(targets=['esp32s31'], reason='TODO IDF-15572 Enable ULP multi device tests for ESP32-S31') def test_lp_uart_multi_device(case_tester: CaseTester) -> None: uart_cases = [case for case in case_tester.test_menu if 'uart' in case.groups and 'wakeup' not in case.groups] for case in uart_cases: diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py b/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py index 3dd0213ec49..92d70c7aff0 100644 --- a/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py @@ -17,9 +17,6 @@ def test_lp_core_hp_uart_print(dut: Dut) -> None: @pytest.mark.generic -@pytest.mark.temp_skip_ci( - targets=['esp32s31'], reason='TODO IDF-15567 investigate esp32s31.default.test_lp_core_panic failure' -) @idf_parametrize('target', soc_filtered_targets('SOC_LP_CORE_SUPPORTED == 1'), indirect=['target']) def test_lp_core_panic(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') diff --git a/docs/doxygen/Doxyfile_esp32s31 b/docs/doxygen/Doxyfile_esp32s31 index a94076ee2ee..f035112c1ed 100644 --- a/docs/doxygen/Doxyfile_esp32s31 +++ b/docs/doxygen/Doxyfile_esp32s31 @@ -14,11 +14,13 @@ INPUT += \ $(PROJECT_PATH)/components/bt/include/esp32s31/include/esp_bt.h \ $(PROJECT_PATH)/components/bt/include/esp32s31/include/esp_bt_vs.h \ $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_etm.h \ + $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_uart.h \ $(PROJECT_PATH)/components/ulp/lp_core/include/lp_core_spi.h \ $(PROJECT_PATH)/components/ulp/lp_core/include/ulp_lp_core.h \ $(PROJECT_PATH)/components/ulp/lp_core/shared/include/ulp_lp_core_lp_uart_shared.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_gpio.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h \ + $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_uart.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_utils.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h \ $(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_spi.h \ diff --git a/examples/system/ulp/.build-test-rules.yml b/examples/system/ulp/.build-test-rules.yml index 31eb109e40d..e5f68895551 100644 --- a/examples/system/ulp/.build-test-rules.yml +++ b/examples/system/ulp/.build-test-rules.yml @@ -95,7 +95,7 @@ examples/system/ulp/lp_core/lp_touch: examples/system/ulp/lp_core/lp_uart/lp_uart_char_seq_wakeup: disable: - - if: (SOC_ULP_LP_UART_SUPPORTED != 1) + - if: (SOC_ULP_LP_UART_SUPPORTED != 1) or (SOC_DEEP_SLEEP_SUPPORTED != 1) <<: *ulp_default_depends depends_components+: - esp_hal_uart diff --git a/examples/system/ulp/lp_core/lp_uart/lp_uart_char_seq_wakeup/README.md b/examples/system/ulp/lp_core/lp_uart/lp_uart_char_seq_wakeup/README.md index b54710235e3..3dc2d4833a8 100644 --- a/examples/system/ulp/lp_core/lp_uart/lp_uart_char_seq_wakeup/README.md +++ b/examples/system/ulp/lp_core/lp_uart/lp_uart_char_seq_wakeup/README.md @@ -13,7 +13,7 @@ This example demonstrates how to use LP UART in specific character sequence wake ### Hardware Required -To run this example, you should have an ESP based development board which supports LP UART wakeup such as the ESP32-C6 and a host machine with a serial input connection. +To run this example, you should have an ESP based development board which supports LP UART wakeup such as the ESP32-C6 or ESP32-S31 and a host machine with a serial input connection. #### Pin Assignment: @@ -24,6 +24,7 @@ To run this example, you should have an ESP based development board which suppor | ESP32-C6 | GPIO4 | GPIO5 | | ESP32-C5 | GPIO4 | GPIO5 | | ESP32-P4 | GPIO15 | GPIO14 | +| ESP32-S31 | GPIO7 | GPIO6 | | Host machine | Tx | Rx | ### Build and Flash diff --git a/examples/system/ulp/lp_core/lp_uart/lp_uart_echo/README.md b/examples/system/ulp/lp_core/lp_uart/lp_uart_echo/README.md index 3d0c1d1fe87..daf06d51b0c 100644 --- a/examples/system/ulp/lp_core/lp_uart/lp_uart_echo/README.md +++ b/examples/system/ulp/lp_core/lp_uart/lp_uart_echo/README.md @@ -24,6 +24,7 @@ To run this example, you should have an ESP based development board that support | ESP32-C6 | GPIO4 | GPIO5 | | ESP32-C5 | GPIO4 | GPIO5 | | ESP32-P4 | GPIO15 | GPIO14 | +| ESP32-S31 | GPIO7 | GPIO6 | | Host machine | Tx | Rx | ### Build and Flash diff --git a/examples/system/ulp/lp_core/lp_uart/lp_uart_print/README.md b/examples/system/ulp/lp_core/lp_uart/lp_uart_print/README.md index ba5291b852a..ca96fdc0a36 100644 --- a/examples/system/ulp/lp_core/lp_uart/lp_uart_print/README.md +++ b/examples/system/ulp/lp_core/lp_uart/lp_uart_print/README.md @@ -25,6 +25,7 @@ To run this example, you should have an ESP based development board that support | ESP32-C6 | GPIO5 | | ESP32-C5 | GPIO5 | | ESP32-P4 | GPIO14 | +| ESP32-S31 | GPIO6 | | Host machine | Rx | ### Build and Flash