Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use esp_intr_alloc_intrstatus to register an ISR on HP core woken up by LP core (IDFGH-14487) #15257

Closed
3 tasks done
pat-bert opened this issue Jan 22, 2025 · 2 comments
Assignees
Labels
Awaiting Response awaiting a response from the author Resolution: Done Issue is done internally Status: Done Issue is done internally

Comments

@pat-bert
Copy link

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

General issue report

Dear Espressif Team,

I'm working with the ESP32C6 and ESP-IDF5.4 to read some sensor measurements via the LP I2C.
The LP core is notifying the HP core via ulp_lp_core_wakeup_main_processor() when it is done and waits for 1 min.
Currently I'm only using light sleep mode.

According to the technical reference manual this should trigger a PMU interrupt that can be routed via the interrupt matrix to a CPU software interrupt.

I'm trying to register an interrupt callback for handling the notification with the following code:

static void isr(void *arg)
{
    gpio_set_direction(GPIO_NUM_15, GPIO_MODE_OUTPUT);
    gpio_set_level(GPIO_NUM_15, 1);
}

extern "C" void app_main(void)
{
        intr_handle_t interruptHandle{};
        ESP_ERROR_CHECK(esp_intr_alloc_intrstatus(ETS_PMU_INTR_SOURCE, 0, PMU_HP_LP_CPU_COMM_REG, PMU_LP_TRIGGER_HP, isr, nullptr, &interruptHandle));
        ESP_ERROR_CHECK(esp_intr_enable(interruptHandle));
        esp_intr_enable_source(ETS_PMU_INTR_SOURCE);
        ESP_ERROR_CHECK(esp_sleep_enable_ulp_wakeup());

        ESP_ERROR_CHECK(ulp_lp_core_load_binary(ulp_lp_sensor_bin_start, (ulp_lp_sensor_bin_end - ulp_lp_sensor_bin_start)));

        /* Start the program */
        ulp_lp_core_cfg_t cfg{};
        cfg.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU;

        ESP_ERROR_CHECK(ulp_lp_core_run(&cfg));

        ... // start other FreeRTOS tasks

        vTaskSuspend(nullptr);
}

I already verified that the LP-core is running correctly by

  • polling a shared variable on the HP-core and reading the measurements
  • registering a light sleep exit callback via esp_pm_light_sleep_register_cbs() to handle the measurements

My understanding is that registering an ISR would be more flexible since I can already read measurements before the HP-core actually goes to sleep. Currently with using the light sleep exit callback I see a delay until the first measurement arrives because the HP is still busy with other tasks and doesn't go to sleep immediately.

Is my understanding of esp_intr_alloc_intrstatus incorrect or do I need to do some additional steps to enable the interrupt?
The programming guide unfortunately does not provide an example for using a software interrupt.

@espressif-bot espressif-bot added the Status: Opened Issue is new label Jan 22, 2025
@github-actions github-actions bot changed the title How to use esp_intr_alloc_intrstatus to register an ISR on HP core woken up by LP core How to use esp_intr_alloc_intrstatus to register an ISR on HP core woken up by LP core (IDFGH-14487) Jan 22, 2025
@ESP-Marius
Copy link
Collaborator

Hi,

You are almost there, but missed a few points:

  • esp_intr_alloc_intrstatus takes the interrupt status register and mask, which is PMU_HP_INT_ST_REG, PMU_SW_INT_ST in this case.
  • esp_intr_enable_source(ETS_PMU_INTR_SOURCE); is not needed

Now the interrupt allocator is setup correctly, but this only takes care of the interrupt matrix and the CPU side of things, you also have to configure the peripheral that will trigger the interrupt (the PMU in our case).
To do this simply enable the interrupt with REG_SET_BIT(PMU_HP_INT_ENA_REG, PMU_SW_INT_ENA);

Remember to also clear it in your interrupt handler with REG_SET_BIT(PMU_HP_INT_CLR_REG, PMU_SW_INT_CLR);

The programming guide unfortunately does not provide an example for using a software interrupt.

From the CPU/interrupt matrix point of view there isnt really a difference between an interrupt that is triggered by HW vs writing to a register, it is all the same.

Hope this is enough to get it working for you.

@espressif-bot espressif-bot added the Awaiting Response awaiting a response from the author label Jan 23, 2025
@pat-bert
Copy link
Author

Hi,

Thanks a lot for the fast and detailed support!
That solved my issue immediately.

@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: Done Issue is done internally and removed Status: Opened Issue is new labels Jan 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting Response awaiting a response from the author Resolution: Done Issue is done internally Status: Done Issue is done internally
Projects
None yet
Development

No branches or pull requests

3 participants