Page 1 of 2
Interrupt WDT
Posted: Mon Sep 09, 2019 12:53 am
by gibson12345
Hey everyone,
I'm currently working with an accelerometer to use as a way to wakeup my esp32, but I'm running into an issue where upon wakeup and the interrupt task being called it gets stuck in an infinite loop and then eventually WDT is triggered. Are there any common causes for this that I might be missing (it happens even if the task does nothing but print, and the ISR does nothing but call then send something to the queue).
Cheers,
Gibson
Re: Interrupt WDT
Posted: Mon Sep 09, 2019 1:16 am
by gibson12345
I noticed that in the timer interrupt example that you "clear" the interrupts? Is there a way to do this for gpio interrupts that I am missing?
Re: Interrupt WDT
Posted: Mon Sep 09, 2019 3:34 am
by ESP_Sprite
How do you setup your GPIO and/or interrupts?
Re: Interrupt WDT
Posted: Mon Sep 09, 2019 4:04 am
by gibson12345
Hello Sprite,
ESP_Sprite wrote: ↑Mon Sep 09, 2019 3:34 am
How do you setup your GPIO and/or interrupts?
Here is how I'm setting up allowing wakeup from GPIO
Code: Select all
gpio_wakeup_enable(LIS3DH_INTR, GPIO_INTR_HIGH_LEVEL);
esp_sleep_enable_gpio_wakeup();
esp_light_sleep_start();
and here is the interrupt task
Code: Select all
void user_task_interrupt (void *pvParameters)
{
uint8_t gpio_num;
while (1)
{
if (xQueueReceive(gpio_evt_queue, &gpio_num, portMAX_DELAY))
{\
gpio_set_level(GPIO_NUM_2, 0);
// get the source of the interrupt and reset *INTx* signals
printf("Waking up from sleep\n");
/* Determine wake up reason */
const char* wakeup_reason;
int wakeup = esp_sleep_get_wakeup_cause();
switch (wakeup) {
case ESP_SLEEP_WAKEUP_TIMER:
wakeup_reason = "timer";
break;
case ESP_SLEEP_WAKEUP_GPIO:
wakeup_reason = "pin";
break;
default:
wakeup_reason = "other";
break;
}
printf("Returned from light sleep, reason: %s\n",wakeup_reason);
}
}
}
and heres how I setup the GPIO
Code: Select all
gpio_pad_select_gpio(GPIO_NUM_2);
/* Set the GPIO as a push/pull output */
gpio_set_direction(GPIO_NUM_2, GPIO_MODE_OUTPUT);
Let me know if you spot anything out of line, it's quite possible I missed something in setup.
Cheers,
Gibson
Re: Interrupt WDT
Posted: Mon Sep 09, 2019 7:43 am
by ESP_Sprite
Well, if any, you configure the GPIO as a level interrupt, meaning the interrupt keeps triggering as long as the line is high. Perhaps that is your issue?
Re: Interrupt WDT
Posted: Mon Sep 09, 2019 11:35 pm
by gibson12345
Hey Sprite,
I tried getting it to trigger on rising edge but I got an error saying the following.
Code: Select all
E (11047) gpio: GPIO wakeup only supports level mode, but edge mode set. gpio_num:17
Am I missing something with that as I would prefer it to occur on the edge?
Cheers,
Gibson
Re: Interrupt WDT
Posted: Tue Sep 10, 2019 3:06 am
by gibson12345
Hey Sprite,
When I remove everything from the interrupt task except a print statement it loops on that and then triggers a WDT.
Any thoughts?
Cheers,
Gibson
Re: Interrupt WDT
Posted: Tue Sep 10, 2019 6:35 am
by gibson12345
Hey everyone,
I believe the issue might be that the interrupt isn't being cleared for whatever reason when I am waking from sleep, but it's strange that this is done automatically when I have the interrupt happen when awake. Could anyone advise on what to do? I'm unable to find any documentation on how to reset a hardware interrupt that isn't a timer or something.
Cheers,
Gibson
Re: Interrupt WDT
Posted: Wed Sep 11, 2019 3:41 am
by ESP_Sprite
I think you're conflating two things here: one is wake-up, the other one is the interrupt. At the moment, it seems you have both set to level, that is, while the line is high, the CPU will keep waking up (which I think is what you want) and while the line is high, it will also keep triggering the interrupt. The second bit is what bites you: as the CPU keeps executing the interrupt handler over and over and over again, it does never have time to do other things and the watchdog will kill it.
Normally, the way you use a level interrupt is that in the interrupt routine, you clear the interrupt, in other words, you 'take away' the reason for the interrupt line to be high. In your case, it would mean e.g. resetting a chip that is connected to your GPIO line. In case you cannot do this, you're better served by an edge interrupt, which only triggers once when the signal goes high.
Note that this is different from using a GPIO as a wake-up source: the settings of that are, to my knowledge, not connected to the interrupt handling of a pin at all.
Re: Interrupt WDT
Posted: Wed Sep 11, 2019 4:31 am
by WiFive
Since the interrupt type is shared *if the gpio is NOT a valid rtc gpio*, if you configure the gpio interrupt as edge and then call
Code: Select all
gpio_wakeup_enable(LIS3DH_INTR, GPIO_INTR_HIGH_LEVEL);
the interrupt type is changed to level. When coming out of sleep, the gpio interrupt type is now level so it will repeat. You should probably disable the gpio interrupt before enabling the wakeup interrupt and then change it back to edge interrupt and reenable the gpio interrupt when coming out of light sleep. Or change it in the interrupt handler.
https://github.com/espressif/esp-idf/bl ... pio.c#L103
https://github.com/espressif/esp-idf/bl ... pio.c#L480