Clear ULP Coprocessor interrupt?
Posted: Sat Jul 08, 2017 3:13 am
I'm working on a project that needs to monitor a GPIO to see if it goes high then back to low and deep-sleep when no activity. So I have started experimenting with the ULP coprocessor using the pulse counter examples/system/ulp/ example and am getting the RTC interrupt when ulp executes`wake` instruction as documented. However there's no documentation nor code available that properly clears the ulp generated RTC interrupt.
Here's the code I'm using:
Basically my program calls ulp_InitInterrupt() and then calls init_ulp_program() function (copied from ulp_example_main.c) to get the ulp coprocessor going. I use make flash monitor in msys2 to build, upload, and monitor the program.
Once its running I cause the monitored GPIO to go high then low via a PIR motion sensor trigger pin attached to it with its pulse signal (held high before going low) is roughly 1600ms. The moment the GPIO level goes low rtc_isr() is called and the event is successfully passed to the app_main task via event group set bits procedure. However it occurs multiple times and rtcISRCounter gets a value of 7 when app_main task gets to ESP_LOGI() the event.
So it seems to be that the ulp coprocessor RTC interrupt isn't being cleared correctly as I have no other code to go on. Doesn't help that esp32_technical_reference_manual_en.pdf improperly documents registers as it says register at address 0x3ff48048 is RTCIO_RTC_GPIO_PIN8_REG however soc.h + rtc_cntl_reg.h defines RTC_CNTL_INT_CLR_REG at that address:
So I can't lookup the register documentation to figure out whats going on.
Anyway, how do I properly clear the ULP coprocessor interrupt?
Here's the code I'm using:
Code: Select all
static void IRAM_ATTR rtc_isr(void *arg)
{
uint32_t rtc_intr = READ_PERI_REG(RTC_CNTL_INT_ST_REG);
// clear interrupt
WRITE_PERI_REG(RTC_CNTL_INT_CLR_REG, rtc_intr);
// abort when not ULP interrupt
if(!(rtc_intr & RTC_CNTL_SAR_INT_ST))
return;
++rtcISRCounter;
const EventBits_t bits = TaskFlag_Trigger_Active;
BaseType_t hptaskWoken, result;
result = xEventGroupSetBitsFromISR(sm_TaskEvent, bits, &hptaskWoken);
if((result == pdPASS) && (hptaskWoken == pdTRUE))
portYIELD_FROM_ISR();
(void)arg;
}
static void ulp_InitInterrupt(void)
{
// install RTC interrupt handler
esp_intr_alloc(ETS_RTC_CORE_INTR_SOURCE, 0, rtc_isr, NULL, NULL);
// enable ULP to trigger RTC interrupt when SoC cores are already running
SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA);
}
Once its running I cause the monitored GPIO to go high then low via a PIR motion sensor trigger pin attached to it with its pulse signal (held high before going low) is roughly 1600ms. The moment the GPIO level goes low rtc_isr() is called and the event is successfully passed to the app_main task via event group set bits procedure. However it occurs multiple times and rtcISRCounter gets a value of 7 when app_main task gets to ESP_LOGI() the event.
So it seems to be that the ulp coprocessor RTC interrupt isn't being cleared correctly as I have no other code to go on. Doesn't help that esp32_technical_reference_manual_en.pdf improperly documents registers as it says register at address 0x3ff48048 is RTCIO_RTC_GPIO_PIN8_REG however soc.h + rtc_cntl_reg.h defines RTC_CNTL_INT_CLR_REG at that address:
Code: Select all
// soc.h:
#define DR_REG_RTCCNTL_BASE 0x3ff48000
// rtc_cntl_reg.h:
#define RTC_CNTL_INT_CLR_REG (DR_REG_RTCCNTL_BASE + 0x48)
Anyway, how do I properly clear the ULP coprocessor interrupt?