Last active
July 21, 2025 21:13
-
-
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 |
@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
I used the suggested changes from above to make this code work on a ESP32S3 processor and did not get it to work. Does anyone have working example code they could post. I'm using C code on the ULP. I'm not sure what I'm doing wrong but any help would be appreciated.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks. The
rtc_isr_registerseems to take one additionalflagsargument and is a private function these days.#include "driver/rtc_cntl.h"issues a deprecation warning. Is this still ok to use?