Page 1 of 2

Get interrupt reason in callback

Posted: Wed May 02, 2018 5:54 pm
by urbanze
I have one global callback to 7 GPIO's with ANY_EDGE interrupt. Inside of callback, I read pin state from REG, however, it's causing errors with fast edge's because slow input frequency of GPIO's (~5us per edge).

How can I get callback reason (POS_EDGE or NEG_EDGE) from my global ISR callback? I looked to some registers like:

-GPIO_STATUS_REG = GPIO 0-31 interrupt status register.
-GPIO_ACPU_INT_REG = GPIO 0-31 APP_CPU interrupt status.

But no sense to me.

Code: Select all

void IRAM_ATTR GISR(void*par)
{
	uint8_t gpio = (uint32_t) par;
	uint8_t read = 0;

	//Change to interrupt reason
	if 		(gpio < 32)	{read = (REG_READ(GPIO_IN_REG) >> gpio) & 0x1;}
	else				{read = (REG_READ(GPIO_IN1_REG) >> (gpio-32)) & 0x1;}



	switch (gpio)
	{
		case usr_inp0:	vTimerSetTimerID(pinTMR[0], (void*) 0+read);	xTimerReset(pinTMR[0], 0);	break;
		case usr_inp1:	vTimerSetTimerID(pinTMR[1], (void*) 2+read);	xTimerReset(pinTMR[1], 0);	break;
		case usr_inp2:	vTimerSetTimerID(pinTMR[2], (void*) 4+read);	xTimerReset(pinTMR[2], 0);	break;
		case usr_inp3:	vTimerSetTimerID(pinTMR[3], (void*) 6+read);	xTimerReset(pinTMR[3], 0);	break;
		case usr_inp4:	vTimerSetTimerID(pinTMR[4], (void*) 8+read);	xTimerReset(pinTMR[4], 0);	break;
		case usr_inp5:	vTimerSetTimerID(pinTMR[5], (void*)10+read);	xTimerReset(pinTMR[5], 0);	break;
		case usr_inp6:	vTimerSetTimerID(pinTMR[6], (void*)12+read);	xTimerReset(pinTMR[6], 0);	break;

		case sys_inp0:	webAP = 1;	break;
	}
}
void initPins()
{
	gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1);
	gpio_set_intr_type(gpio_num_t(usr_inp0), GPIO_INTR_ANYEDGE); gpio_isr_handler_add(gpio_num_t(usr_inp0), GISR, (void*)usr_inp0);
	//.......To all others 6 pins
}

Re: Get interrupt reason in callback

Posted: Thu May 03, 2018 11:52 am
by urbanze
any one can help me? :cry:

Re: Get interrupt reason in callback

Posted: Thu May 03, 2018 1:33 pm
by Pibbotley
Not sure if its helping but why not have an ISR per edge type, or read the pin state outside the ISR.

Re: Get interrupt reason in callback

Posted: Thu May 03, 2018 2:11 pm
by urbanze
Pibbotley wrote:Not sure if its helping but why not have an ISR per edge type, or read the pin state outside the ISR.
Yes, I thought I would leave two types of ISR (rising and falling), but when I make the 2 assignments, the last one will not overwrite the previous one?

Code: Select all

//Set rising ISR
gpio_set_intr_type(gpio_num_t(usr_inp0), GPIO_INTR_POSEDGE);
gpio_isr_handler_add(gpio_num_t(usr_inp0), RISING_ISR, (void*)usr_inp0);

//Set falling ISR will overwrite last call?
gpio_set_intr_type(gpio_num_t(usr_inp0), GPIO_INTR_NEGEDGE);
gpio_isr_handler_add(gpio_num_t(usr_inp0), FALLING_ISR, (void*)usr_inp0);

Re: Get interrupt reason in callback

Posted: Thu May 03, 2018 4:48 pm
by urbanze
I tried some registers but I can't find ISR reason (if callback is because rising/falling). :x :(

-GPIO_STATUS_REG
-GPIO_PCPU_INT_REG
-GPIO_PCPU_NMI_INT_REG
-GPIO_PIN0_REG

Please help :oops:

Re: Get interrupt reason in callback

Posted: Fri May 04, 2018 1:08 am
by WiFive
I don't think there is anything that would store the interrupt type, the logic just sets the interrupt flag or not.

Re: Get interrupt reason in callback

Posted: Fri May 04, 2018 1:56 am
by urbanze
WiFive wrote:I don't think there is anything that would store the interrupt type, the logic just sets the interrupt flag or not.
I test this problem by assigning for example, instead of any, posedge. Even so in some interrupts, the isr returns me LOW (reading the input pin), because low level after edge and etc.......... Except this in some interrupts, works perfecly.

Is there any way to assign an different ISR function per edge? as was quoted by the friend above ... Or new ideia?

Re: Get interrupt reason in callback

Posted: Fri May 04, 2018 2:07 am
by WiFive
You can read the pin state in the isr but this is limited by how fast isr can execute and pulse width and noise. What kind of signal are you trying to measure? Maybe you can use the rmt peripheral and then you have samples of the whole signal.

Re: Get interrupt reason in callback

Posted: Fri May 04, 2018 2:26 am
by urbanze
WiFive wrote:You can read the pin state in the isr but this is limited by how fast isr can execute and pulse width and noise. What kind of signal are you trying to measure? Maybe you can use the rmt peripheral and then you have samples of the whole signal.
There is no specific signal, it is the generic inputs of the company's supervisory system that I work with. So this can be connected to any type of relay, contactor, or even a push button.

Basically, the ISR detects the pin and edge (current state) that the interruption occurred, and this changes the ID of a Software timer and starts counting, so that when this timer's callback occurs, I know if the reason of counting was the pin go to HIGH or LOW.

This ID assignment is basically the OFFSET of the timer + the pin reading (0 or 1), so even when I release the push button (that has pull-up) for example, the isr returns 0, clearly the last edge was HIGH, but read returns LOW. I dont know if I miss edgs or reading problems inside isr. I think it's in the readings inside the ISR, because even assigning to a specific ramp, it returns me different values ​​from the assigned edge (as quoted above) ...

Do you/anyone have any idea what to do? If it is possible to assign edgs separately, it may work. If you need the code to better analyze what is being done, I will send it tomorrow (I notice that it is almost the same as the first post)

Re: Get interrupt reason in callback

Posted: Fri May 04, 2018 3:01 am
by WiFive
Personally I would suggest you use level interrupts and sw debouncing and when you receive a high interrupt, change the next interrupt to low and so on.