diff --git a/components/hal/esp32c6/include/hal/lp_core_ll.h b/components/hal/esp32c6/include/hal/lp_core_ll.h index c79830f5f0..7c6c5667ef 100644 --- a/components/hal/esp32c6/include/hal/lp_core_ll.h +++ b/components/hal/esp32c6/include/hal/lp_core_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -117,6 +117,14 @@ static inline uint32_t lp_core_ll_get_wakeup_source(void) return PMU.lp_ext.pwr1.wakeup_en; } +/** + * @brief Request PMU to put LP core to sleep + */ +static inline void lp_core_ll_request_sleep(void) +{ + PMU.lp_ext.pwr1.sleep_req = 1; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/include/hal/lp_core_ll.h b/components/hal/esp32p4/include/hal/lp_core_ll.h index 67fd2bb215..d67c0c52bb 100644 --- a/components/hal/esp32p4/include/hal/lp_core_ll.h +++ b/components/hal/esp32p4/include/hal/lp_core_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -140,6 +140,14 @@ static inline void lp_core_ll_set_app_boot_address(intptr_t boot_address) LP_SYS.boot_addr_hp_lp_reg.boot_addr_hp_lp = boot_address; } +/** + * @brief Request PMU to put LP core to sleep + */ +static inline void lp_core_ll_request_sleep(void) +{ + PMU.lp_ext.pwr1.sleep_req = 1; +} + #ifdef __cplusplus } #endif diff --git a/components/ulp/lp_core/include/ulp_lp_core.h b/components/ulp/lp_core/include/ulp_lp_core.h index 8931f80890..9a17cd5c80 100644 --- a/components/ulp/lp_core/include/ulp_lp_core.h +++ b/components/ulp/lp_core/include/ulp_lp_core.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,8 +8,10 @@ #include #include #include +#include #include "esp_err.h" #include "ulp_common.h" +#include "esp_rom_caps.h" #ifdef __cplusplus extern "C" { @@ -28,6 +30,11 @@ extern "C" { typedef struct { uint32_t wakeup_source; /*!< Wakeup source flags */ uint32_t lp_timer_sleep_duration_us; /*!< Sleep duration when ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER is specified. Measurement unit: us */ +#if ESP_ROM_HAS_LP_ROM + bool skip_lp_rom_boot; /* !< Skips the LP rom code and boots directly into the app code placed in LP RAM, + this gives faster boot time for time sensitive use-cases at the cost of skipping + setup e.g. of UART */ +#endif //ESP_ROM_HAS_LP_ROM } ulp_lp_core_cfg_t; /** diff --git a/components/ulp/lp_core/lp_core.c b/components/ulp/lp_core/lp_core.c index 54d7c3a483..d52047a759 100644 --- a/components/ulp/lp_core/lp_core.c +++ b/components/ulp/lp_core/lp_core.c @@ -59,7 +59,14 @@ esp_err_t ulp_lp_core_run(ulp_lp_core_cfg_t* cfg) #if ESP_ROM_HAS_LP_ROM /* If we have a LP ROM we boot from it, before jumping to the app code */ - lp_core_ll_set_boot_address(SOC_LP_ROM_LOW); + intptr_t boot_addr; + if (cfg->skip_lp_rom_boot) { + boot_addr = RTC_SLOW_MEM; + } else { + boot_addr = SOC_LP_ROM_LOW; + } + + lp_core_ll_set_boot_address(boot_addr); lp_core_ll_set_app_boot_address(RTC_SLOW_MEM); #endif //ESP_ROM_HAS_LP_ROM @@ -131,6 +138,6 @@ esp_err_t ulp_lp_core_load_binary(const uint8_t* program_binary, size_t program_ void ulp_lp_core_stop(void) { /* Disable wake-up source and put lp core to sleep */ - REG_SET_FIELD(PMU_LP_CPU_PWR1_REG, PMU_LP_CPU_WAKEUP_EN, 0); - REG_SET_FIELD(PMU_LP_CPU_PWR1_REG, PMU_LP_CPU_SLEEP_REQ, 1); + lp_core_ll_set_wakeup_source(0); + lp_core_ll_request_sleep(); } diff --git a/components/ulp/lp_core/lp_core/lp_core_utils.c b/components/ulp/lp_core/lp_core/lp_core_utils.c index e08ffdcf87..96d5fe170d 100644 --- a/components/ulp/lp_core/lp_core/lp_core_utils.c +++ b/components/ulp/lp_core/lp_core/lp_core_utils.c @@ -20,7 +20,7 @@ #if CONFIG_IDF_TARGET_ESP32C6 #define LP_CORE_CPU_FREQUENCY_HZ 16000000 #elif CONFIG_IDF_TARGET_ESP32P4 -#define LP_CORE_CPU_FREQUENCY_HZ 20000000 +#define LP_CORE_CPU_FREQUENCY_HZ 16000000 // TRM says 20 MHz by default, but we tune it closer to 16 MHz #endif static uint32_t lp_wakeup_cause = 0; @@ -108,7 +108,7 @@ void ulp_lp_core_delay_cycles(uint32_t cycles) void ulp_lp_core_halt(void) { - REG_SET_FIELD(PMU_LP_CPU_PWR1_REG, PMU_LP_CPU_SLEEP_REQ, 1); + lp_core_ll_request_sleep(); while (1); } @@ -116,8 +116,8 @@ void ulp_lp_core_halt(void) void ulp_lp_core_stop_lp_core(void) { /* Disable wake-up source and put lp core to sleep */ - REG_SET_FIELD(PMU_LP_CPU_PWR1_REG, PMU_LP_CPU_WAKEUP_EN, 0); - REG_SET_FIELD(PMU_LP_CPU_PWR1_REG, PMU_LP_CPU_SLEEP_REQ, 1); + lp_core_ll_set_wakeup_source(0); + lp_core_ll_request_sleep(); } void __attribute__((noreturn)) abort(void) diff --git a/components/ulp/test_apps/.build-test-rules.yml b/components/ulp/test_apps/.build-test-rules.yml index c938f7ba11..b601d66f14 100644 --- a/components/ulp/test_apps/.build-test-rules.yml +++ b/components/ulp/test_apps/.build-test-rules.yml @@ -3,10 +3,6 @@ components/ulp/test_apps/lp_core: disable: - if: SOC_LP_CORE_SUPPORTED != 1 - disable_test: - - if: IDF_TARGET in ["esp32p4"] - temporary: true - reason: not tested yet # TODO: IDF-8986 depends_components: - ulp diff --git a/components/ulp/test_apps/lp_core/main/test_lp_core.c b/components/ulp/test_apps/lp_core/main/test_lp_core.c index 5c40910e28..c87c6752ad 100644 --- a/components/ulp/test_apps/lp_core/main/test_lp_core.c +++ b/components/ulp/test_apps/lp_core/main/test_lp_core.c @@ -7,6 +7,7 @@ #include #include #include +#include "esp_rom_caps.h" #include "lp_core_test_app.h" #include "lp_core_test_app_counter.h" #include "lp_core_test_app_set_timer_wakeup.h" @@ -215,6 +216,10 @@ TEST_CASE("LP Timer can wakeup lp core periodically", "[lp_core]") ulp_lp_core_cfg_t cfg = { .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER, .lp_timer_sleep_duration_us = LP_TIMER_TEST_SLEEP_DURATION_US, +#if ESP_ROM_HAS_LP_ROM + /* ROM Boot takes quite a bit longer, which skews the numbers of wake-ups. skip rom boot to keep the calculation simple */ + .skip_lp_rom_boot = true, +#endif }; load_and_start_lp_core_firmware(&cfg, lp_core_main_counter_bin_start, lp_core_main_counter_bin_end); @@ -273,6 +278,10 @@ TEST_CASE("LP core can schedule next wake-up time by itself", "[ulp]") /* Load ULP firmware and start the coprocessor */ ulp_lp_core_cfg_t cfg = { .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER, +#if ESP_ROM_HAS_LP_ROM + /* ROM Boot takes quite a bit longer, which skews the numbers of wake-ups. skip rom boot to keep the calculation simple */ + .skip_lp_rom_boot = true, +#endif }; load_and_start_lp_core_firmware(&cfg, lp_core_main_set_timer_wakeup_bin_start, lp_core_main_set_timer_wakeup_bin_end); diff --git a/components/ulp/test_apps/lp_core/pytest_lp_core.py b/components/ulp/test_apps/lp_core/pytest_lp_core.py index 2325394b4c..6c14deba2a 100644 --- a/components/ulp/test_apps/lp_core/pytest_lp_core.py +++ b/components/ulp/test_apps/lp_core/pytest_lp_core.py @@ -1,11 +1,11 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @pytest.mark.esp32c6 +@pytest.mark.esp32p4 @pytest.mark.generic def test_lp_core(dut: Dut) -> None: dut.run_all_single_board_cases()