Merge branch 'feature/lp_core_lp_timer_p4' into 'master'

feat(lp_core): add support for lp timer and lp gpio on P4

Closes IDF-7536, IDF-7532, and IDF-8986

See merge request espressif/esp-idf!28871
This commit is contained in:
Marius Vikhammer 2024-02-06 11:14:24 +08:00
commit db65efe0bd
8 changed files with 50 additions and 15 deletions

View File

@ -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

View File

@ -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

View File

@ -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 <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdbool.h>
#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;
/**

View File

@ -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();
}

View File

@ -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)

View File

@ -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

View File

@ -7,6 +7,7 @@
#include <stdio.h>
#include <inttypes.h>
#include <sys/time.h>
#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);

View File

@ -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()