interrupt still triggered after interrupt service has been disabled
interrupt still triggered after interrupt service has been disabled
Hi all,
I use GPIO pin to receive interrupts. Rising and falling edge are both enabled. As soon as one interrupt has been triggered, I first send the pin number to a task.
Inside the task I disabled the interrupt for that pin using gpio_intr_disable, then do some gpio level manipulation which could trigger new interrupt. And at the end of the task I enable the interrupt for that pin again.
But now I can see a bunch of interrupts are generated, gpio_isr_handler is called several times even when the interrupt is disabled for that pin!
I am totally running out of idea. Please help! Thanks!
I use GPIO pin to receive interrupts. Rising and falling edge are both enabled. As soon as one interrupt has been triggered, I first send the pin number to a task.
Inside the task I disabled the interrupt for that pin using gpio_intr_disable, then do some gpio level manipulation which could trigger new interrupt. And at the end of the task I enable the interrupt for that pin again.
But now I can see a bunch of interrupts are generated, gpio_isr_handler is called several times even when the interrupt is disabled for that pin!
I am totally running out of idea. Please help! Thanks!
-
- Posts: 9708
- Joined: Thu Nov 26, 2015 4:08 am
Re: interrupt still triggered after interrupt service has been disabled
Can you post a representative sample for the code that does that?
Re: interrupt still triggered after interrupt service has been disabled
Thanks for the quick reply.
Sure I can put some codes here. For the sake of readability the pasted code is simplified.
First a brief description of the configuration.
GPIO26 used as INPUT, rising edge and falling edge are enabled for receiving interrupt. Internal pull-up enabled, I add one external 10k pull-up resistor as well.
GPIO18 used as OUTPUT, initial output = 0.
GPIO26 is connected to GPIO18 using a button. When the button is pressed, GPIO26 changes to low(falling edge), button released, GPIO changes to high(rising edge).
Macro definition:
appMain:
ISR code:
task code:
I made some simple modification to the GPIO example. So hopefully it is still readable.
The weird behavior is that when I pressed the button, and kept it pressed. I saw ISR counter kept incrementing, although interrupt of GPIO26 has been disabled.
Sure I can put some codes here. For the sake of readability the pasted code is simplified.
First a brief description of the configuration.
GPIO26 used as INPUT, rising edge and falling edge are enabled for receiving interrupt. Internal pull-up enabled, I add one external 10k pull-up resistor as well.
GPIO18 used as OUTPUT, initial output = 0.
GPIO26 is connected to GPIO18 using a button. When the button is pressed, GPIO26 changes to low(falling edge), button released, GPIO changes to high(rising edge).
Macro definition:
Code: Select all
#define GPIO_IN_KEY_ROW_0 GPIO_NUM_26
#define GPIO_IN_KEY_ROW_1 GPIO_NUM_34
#define GPIO_IN_KEY_ROW_2 GPIO_NUM_35
#define GPIO_IN_KEY_ROW_3 GPIO_NUM_36
#define GPIO_IN_KEY_ROW_4 GPIO_NUM_39
#define GPIO_IN_PIN_SEL (((uint64_t)1<<GPIO_IN_KEY_ROW_0) | ((uint64_t)1<<GPIO_IN_KEY_ROW_1) | \
((uint64_t)1<<GPIO_IN_KEY_ROW_2) | ((uint64_t)1<<GPIO_IN_KEY_ROW_3) | \
((uint64_t)1<<GPIO_IN_KEY_ROW_4))
#define GPIO_OUT_KEY_COL_0 GPIO_NUM_18
#define GPIO_OUT_KEY_COL_1 GPIO_NUM_19
#define GPIO_OUT_KEY_COL_2 GPIO_NUM_21
#define GPIO_OUT_KEY_COL_3 GPIO_NUM_22
#define GPIO_OUT_PIN_SEL (((uint64_t)1<<GPIO_OUT_KEY_COL_0) | ((uint64_t)1<<GPIO_OUT_KEY_COL_1) | \
((uint64_t)1<<GPIO_OUT_KEY_COL_2) | ((uint64_t)1<<GPIO_OUT_KEY_COL_3))
appMain:
Code: Select all
void app_main()
{
gpio_config_t io_conf_out, io_conf_in;
//disable interrupt
io_conf_out.intr_type = GPIO_PIN_INTR_DISABLE;
//set as output mode
io_conf_out.mode = GPIO_MODE_OUTPUT;
//bit mask of the pins that you want to set,e.g.GPIO18/19
io_conf_out.pin_bit_mask = GPIO_OUT_PIN_SEL;
//disable pull-down mode
io_conf_out.pull_down_en = 0;
//disable pull-up mode
io_conf_out.pull_up_en = 0;
//configure GPIO with the given settings
gpio_config(&io_conf_out);
//interrupt of rising and falling edge
io_conf_in.intr_type = GPIO_INTR_ANYEDGE;
//bit mask of the pins
io_conf_in.pin_bit_mask = GPIO_IN_PIN_SEL;
//set as input mode
io_conf_in.mode = GPIO_MODE_INPUT;
//disable pull-down mode
io_conf_in.pull_down_en = 0;
//enable pull-up mode
io_conf_in.pull_up_en = 1;
gpio_config(&io_conf_in);
//create a queue to handle gpio event from isr
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
//start gpio task
xTaskCreate(gpio_task, "gpio_task", 2048, NULL, 10, NULL);
//install gpio isr service
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(GPIO_IN_KEY_ROW_0, gpio_isr_handler, (void*) GPIO_IN_KEY_ROW_0);
gpio_isr_handler_add(GPIO_IN_KEY_ROW_1, gpio_isr_handler, (void*) GPIO_IN_KEY_ROW_1);
gpio_isr_handler_add(GPIO_IN_KEY_ROW_2, gpio_isr_handler, (void*) GPIO_IN_KEY_ROW_2);
gpio_isr_handler_add(GPIO_IN_KEY_ROW_3, gpio_isr_handler, (void*) GPIO_IN_KEY_ROW_3);
gpio_isr_handler_add(GPIO_IN_KEY_ROW_4, gpio_isr_handler, (void*) GPIO_IN_KEY_ROW_4);
//init button COL GPIO pins to low
gpio_set_level(GPIO_OUT_KEY_COL_0, 0);
gpio_set_level(GPIO_OUT_KEY_COL_1, 0);
gpio_set_level(GPIO_OUT_KEY_COL_2, 0);
gpio_set_level(GPIO_OUT_KEY_COL_3, 0);
int cnt = 0;
while(1) {
printf("cnt: %d\n", cnt++);
vTaskDelay(1000 / portTICK_RATE_MS);
printf("row 0 level = %d\n", gpio_get_level(GPIO_IN_KEY_ROW_0));
printf("row 1 level = %d\n", gpio_get_level(GPIO_IN_KEY_ROW_1));
printf("row 2 level = %d\n", gpio_get_level(GPIO_IN_KEY_ROW_2));
printf("row 3 level = %d\n", gpio_get_level(GPIO_IN_KEY_ROW_3));
printf("row 4 level = %d\n", gpio_get_level(GPIO_IN_KEY_ROW_4));
}
}
ISR code:
Code: Select all
static void gpio_isr_handler(void* arg)
{
static uint32_t isr_counter = 0;
uint32_t gpio_num = (uint32_t) arg;
gpio_intr_disable(26);
gpio_num += ((isr_counter++)<<24);
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
Code: Select all
static void gpio_task(void* arg)
{
uint32_t row = 0;
uint32_t col = 0;
uint32_t gpio_num = 0;
uint32_t isr_counter = 0;
char *button_pressed = "pressed";
char *button_released = "released";
for(;;)
{
if(xQueueReceive(gpio_evt_queue, &gpio_num, portMAX_DELAY))
{
//in case of falling edge
if(gpio_get_level(row) == 0)
{
// col = find_pressed_buttons_col(row);
gpio_set_level(18, 1);
vTaskDelay(200 / portTICK_RATE_MS);
gpio_set_level(18, 0);
}
//in case of rising edge
else
{
col = find_released_buttons_col(row);
}
isr_counter = gpio_num >> 24;
printf(" ISR counter %d \n", isr_counter);
gpio_intr_enable(26);
}
}
}
The weird behavior is that when I pressed the button, and kept it pressed. I saw ISR counter kept incrementing, although interrupt of GPIO26 has been disabled.
-
- Posts: 9708
- Joined: Thu Nov 26, 2015 4:08 am
Re: interrupt still triggered after interrupt service has been disabled
Just wondering: Are you sure those interrupts stem from GPIO26? If for whatever reason, any of the other GPIO pins are pulled low, you'd also see this behaviour.
Asking because I just took a look at the GPIO int code, and it seems simple enough that I couldn't spot any obvious bugs that could generate this.
Asking because I just took a look at the GPIO int code, and it seems simple enough that I couldn't spot any obvious bugs that could generate this.
Re: interrupt still triggered after interrupt service has been disabled
Hi adherent,The weird behavior is that when I pressed the button, and kept it pressed. I saw ISR counter kept incrementing, although interrupt of GPIO26 has been disabled.
I don't have the time to mock up a test. But what I woundered is: Keeping on pressed down that button won't trigger any kind of "falling" / "rising" event on theory, which will trigger the ISR routine. So would it be helpful to probe GPIO 26 with a Scope or just a digital analyser to see what actually it does?
(Just got my ESD protection workshop yesterday & get shocked by how easy to produced a hardware damage. And those half-killed chips are the worst dream ever for Software developer... )
Cheers
Gfast2
Re: interrupt still triggered after interrupt service has been disabled
Even if other GPIO pins are pulled low, it cannot explain the behavior here, as the interrupts keep coming endless. Seems like someone keeps pushing another button and released it, pushed again then release again ....ESP_Sprite wrote:Just wondering: Are you sure those interrupts stem from GPIO26? If for whatever reason, any of the other GPIO pins are pulled low, you'd also see this behaviour.
Asking because I just took a look at the GPIO int code, and it seems simple enough that I couldn't spot any obvious bugs that could generate this.
Re: interrupt still triggered after interrupt service has been disabled
yea, I could check what happens exactly to GPIO26 using a probe. However whatever I will see, it does not matter actually, because I disabled the interrupt of that pin. No matter how it changes, ISR should not be called.Gfast2 wrote:Hi adherent,The weird behavior is that when I pressed the button, and kept it pressed. I saw ISR counter kept incrementing, although interrupt of GPIO26 has been disabled.
I don't have the time to mock up a test. But what I woundered is: Keeping on pressed down that button won't trigger any kind of "falling" / "rising" event on theory, which will trigger the ISR routine. So would it be helpful to probe GPIO 26 with a Scope or just a digital analyser to see what actually it does?
(Just got my ESD protection workshop yesterday & get shocked by how easy to produced a hardware damage. And those half-killed chips are the worst dream ever for Software developer... )
Cheers
Gfast2
Re: interrupt still triggered after interrupt service has been disabled
Remember you have queue size 10, so you can have up to 10 readings after you turn off interrupts.
Re: interrupt still triggered after interrupt service has been disabled
Solved, after reading this post: https://esp32.com/viewtopic.php?f=2&t=1836
The problem here is during the time while one GPIO's interrupt is disabled, the newly generated interrupts are somehow "registered" internally, and as soon as the interrupt is enabled again ISR will be called.
The problem here is during the time while one GPIO's interrupt is disabled, the newly generated interrupts are somehow "registered" internally, and as soon as the interrupt is enabled again ISR will be called.
Who is online
Users browsing this forum: Dennie and 111 guests