Skip to content

Instantly share code, notes, and snippets.

@igrr
Last active July 21, 2025 21:13
Show Gist options
  • Select an option

  • Save igrr/4b002047fc034180b8f7ca01858e1de5 to your computer and use it in GitHub Desktop.

Select an option

Save igrr/4b002047fc034180b8f7ca01858e1de5 to your computer and use it in GitHub Desktop.
ESP32 ULP ISR example
#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");
}
}
#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
@JellevanKraaij
Copy link

@mickeyl Did you find another solution?

@mickeyl
Copy link

mickeyl commented Jan 26, 2024

Seems to work fine these days. Espressif even added API for it in espressif/esp-idf@a67d15f#diff-62c3d8a0af115257113c79a645b4aa54908b590d97dd7473f705478b8bbd07c6

@BillBernacchi
Copy link

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