feat(ulp): support interrupts for C6/P4 LP core

Closes https://github.com/espressif/esp-idf/issues/13059
This commit is contained in:
Marius Vikhammer
2024-04-19 14:03:29 +08:00
parent 73190dd04e
commit c5a513cf49
34 changed files with 796 additions and 32 deletions

View File

@@ -26,6 +26,7 @@ set(lp_core_exp_dep_srcs ${app_sources})
ulp_embed_binary(lp_core_test_app "${lp_core_sources}" "${lp_core_exp_dep_srcs}")
ulp_embed_binary(lp_core_test_app_counter "${lp_core_sources_counter}" "${lp_core_exp_dep_srcs}")
ulp_embed_binary(lp_core_test_app_isr "lp_core/test_main_isr.c" "${lp_core_exp_dep_srcs}")
if(CONFIG_SOC_LP_TIMER_SUPPORTED)
ulp_embed_binary(lp_core_test_app_set_timer_wakeup "${lp_core_sources_set_timer_wakeup}" "${lp_core_exp_dep_srcs}")

View File

@@ -0,0 +1,42 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "ulp_lp_core_utils.h"
#include "ulp_lp_core_interrupts.h"
#include "ulp_lp_core_gpio.h"
#include "hal/pmu_ll.h"
volatile uint32_t io_isr_counter = 0;
volatile uint32_t pmu_isr_counter = 0;
volatile bool isr_test_started;
void LP_CORE_ISR_ATTR ulp_lp_core_lp_io_intr_handler(void)
{
ulp_lp_core_gpio_clear_intr_status();
io_isr_counter++;
}
void LP_CORE_ISR_ATTR ulp_lp_core_lp_pmu_intr_handler(void)
{
ulp_lp_core_sw_intr_clear();
pmu_isr_counter++;
}
int main(void)
{
ulp_lp_core_sw_intr_enable(true);
ulp_lp_core_intr_enable();
isr_test_started = true;
while (1) {
// Busy wait for the interrupts to occur
}
return 0;
}

View File

@@ -11,6 +11,7 @@
#include "esp_rom_caps.h"
#include "lp_core_test_app.h"
#include "lp_core_test_app_counter.h"
#include "lp_core_test_app_isr.h"
#if SOC_LP_TIMER_SUPPORTED
#include "lp_core_test_app_set_timer_wakeup.h"
@@ -26,6 +27,10 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "hal/lp_core_ll.h"
#include "hal/rtc_io_ll.h"
#include "driver/rtc_io.h"
extern const uint8_t lp_core_main_bin_start[] asm("_binary_lp_core_test_app_bin_start");
extern const uint8_t lp_core_main_bin_end[] asm("_binary_lp_core_test_app_bin_end");
@@ -38,6 +43,9 @@ extern const uint8_t lp_core_main_set_timer_wakeup_bin_end[] asm("_binary_lp_c
extern const uint8_t lp_core_main_gpio_bin_start[] asm("_binary_lp_core_test_app_gpio_bin_start");
extern const uint8_t lp_core_main_gpio_bin_end[] asm("_binary_lp_core_test_app_gpio_bin_end");
extern const uint8_t lp_core_main_isr_bin_start[] asm("_binary_lp_core_test_app_isr_bin_start");
extern const uint8_t lp_core_main_isr_bin_end[] asm("_binary_lp_core_test_app_isr_bin_end");
static void load_and_start_lp_core_firmware(ulp_lp_core_cfg_t* cfg, const uint8_t* firmware_start, const uint8_t* firmware_end)
{
TEST_ASSERT(ulp_lp_core_load_binary(firmware_start,
@@ -325,3 +333,49 @@ TEST_CASE("LP core gpio tests", "[ulp]")
}
#endif //SOC_LP_TIMER_SUPPORTED
#define ISR_TEST_ITERATIONS 100
#define IO_TEST_PIN 0
#include "lp_core_uart.h"
TEST_CASE("LP core ISR tests", "[ulp]")
{
lp_core_uart_cfg_t ucfg = LP_CORE_UART_DEFAULT_CONFIG();
ESP_ERROR_CHECK(lp_core_uart_init(&ucfg));
/* Load ULP firmware and start the coprocessor */
ulp_lp_core_cfg_t cfg = {
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU,
};
load_and_start_lp_core_firmware(&cfg, lp_core_main_isr_bin_start, lp_core_main_isr_bin_end);
while (!ulp_isr_test_started) {
}
for (int i = 0; i < ISR_TEST_ITERATIONS; i++) {
lp_core_ll_hp_wake_lp();
vTaskDelay(pdMS_TO_TICKS(10));
}
printf("ULP PMU ISR triggered %"PRIu32" times\n", ulp_pmu_isr_counter);
TEST_ASSERT_EQUAL(ISR_TEST_ITERATIONS, ulp_pmu_isr_counter);
/* Test LP IO interrupt */
rtc_gpio_init(IO_TEST_PIN);
rtc_gpio_set_direction(IO_TEST_PIN, RTC_GPIO_MODE_INPUT_ONLY);
TEST_ASSERT_EQUAL(0, ulp_io_isr_counter);
for (int i = 0; i < ISR_TEST_ITERATIONS; i++) {
#if CONFIG_IDF_TARGET_ESP32C6
LP_IO.status_w1ts.val = 0x00000001; // Set GPIO 0 intr status to high
#else
LP_GPIO.status_w1ts.val = 0x00000001; // Set GPIO 0 intr status to high
#endif
vTaskDelay(pdMS_TO_TICKS(10));
}
printf("ULP LP IO ISR triggered %"PRIu32" times\n", ulp_io_isr_counter);
TEST_ASSERT_EQUAL(ISR_TEST_ITERATIONS, ulp_io_isr_counter);
}