Last active
January 26, 2024 09:47
-
-
Save igrr/4b002047fc034180b8f7ca01858e1de5 to your computer and use it in GitHub Desktop.
ESP32 ULP ISR example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <unistd.h> | |
#include "soc/rtc_cntl_reg.h" | |
#include "esp32/ulp.h" | |
#include "driver/rtc_cntl.h" | |
#include "esp_log.h" | |
#include "ulp_main.h" | |
#include "freertos/FreeRTOS.h" | |
#include "freertos/semphr.h" | |
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start"); | |
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end"); | |
static void ulp_isr(void* arg) | |
{ | |
SemaphoreHandle_t done = (SemaphoreHandle_t) arg; | |
xSemaphoreGiveFromISR(done); | |
} | |
void app_main() | |
{ | |
esp_err_t err = ulp_load_binary(0, ulp_main_bin_start, | |
(ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t)); | |
ESP_ERROR_CHECK(err); | |
ulp_set_wakeup_period(0, 100); | |
SemaphoreHandle_t ulp_isr_sem = xSemaphoreCreateBinary(); | |
assert(ulp_isr_sem); | |
err = rtc_isr_register(&ulp_isr, (void*) ulp_isr_sem, RTC_CNTL_SAR_INT_ST_M); | |
ESP_ERROR_CHECK(err); | |
REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA_M); | |
err = ulp_run((&ulp_entry - RTC_SLOW_MEM) / sizeof(uint32_t)); | |
ESP_ERROR_CHECK(err); | |
int result = xSemaphoreTake(ulp_isr_sem, 1000 / portTICK_PERIOD_MS); | |
if (result == pdPASS) { | |
printf("ULP ISR triggered\n"); | |
} else { | |
printf("ULP ISR timeout\n"); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "soc/rtc_cntl_reg.h" | |
#include "soc/rtc_io_reg.h" | |
#include "soc/soc_ulp.h" | |
.text | |
.global entry | |
entry: | |
/* Do some stuff here */ | |
/* Then wake up */ | |
jump wake_up | |
wake_up: | |
/* Wake up the SoC, end program */ | |
wake | |
WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0) | |
halt |
@MacWyznawca for ULP RISC-V on ESP32-S3
you replace:
err = rtc_isr_register(&ulp_isr, (void*) ulp_isr_sem, RTC_CNTL_SAR_INT_ST_M);
ESP_ERROR_CHECK(err);
REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA_M);
with
err = rtc_isr_register(&ulp_isr, (void*) ulp_isr_sem, RTC_CNTL_COCPU_INT_ST_M);
ESP_ERROR_CHECK(err);
REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_COCPU_INT_ST_M);
and use ulp_riscv_wakeup_main_processor(); function in the riscv application to trigger the interrupt.
Thanks @darthcloud!
Thanks. The rtc_isr_register
seems to take one additional flags
argument and is a private function these days. #include "driver/rtc_cntl.h"
issues a deprecation warning. Is this still ok to use?
@mickeyl Did you find another solution?
Seems to work fine these days. Espressif even added API for it in espressif/esp-idf@a67d15f#diff-62c3d8a0af115257113c79a645b4aa54908b590d97dd7473f705478b8bbd07c6
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello!
Can you point out a similar example, but for ULP RISC-V with ESP-S3?
I am looking for a way to notify the active task on the main processor from ULP code (not in deep sleep).