Hi all,
I found the following strange behaviour when I was testing Teensy 4.0's GPIO interrupt, handling it directly.
When a GPIO interrupt is activated, a bit in GPIOx_ISR corresponding to the pin is set to 1, and the interrupt service routine (ISR) given at _VectorsRam[IRQ_GPIO6789 + 16] is called, if I understood the IMXRT1062 manual and Paul's Teensy4 core code correctly. But it is observed that sometimes (not always) the ISR is called with the bit in GPIOx_ISR zero, not 1.
In the following example, the GPIO interrupt is enabled only for one pin, so all GPIO interrupts must be invoked by that pin, but its GPIOx_ISR bit is not always 1 when the ISR is called.
A test run gave the following output:
In the test, the signal sent to the GPIO pin is from a 74LVC buffer powered by 3.3V from Teensy. So I assume the signal is not dirty (unfortunately I don't have an oscilloscope...) Even if the signal was not clean, it might have had effects on invoking interrupts but should have not cause this behaviour, I guess.
I am really curious and want to understand why this happens. Perhaps I am not understanding the interrupt operation correctly, or it could be a very nasty bug. Any comments will be greatly appreciated!
I found the following strange behaviour when I was testing Teensy 4.0's GPIO interrupt, handling it directly.
When a GPIO interrupt is activated, a bit in GPIOx_ISR corresponding to the pin is set to 1, and the interrupt service routine (ISR) given at _VectorsRam[IRQ_GPIO6789 + 16] is called, if I understood the IMXRT1062 manual and Paul's Teensy4 core code correctly. But it is observed that sometimes (not always) the ISR is called with the bit in GPIOx_ISR zero, not 1.
In the following example, the GPIO interrupt is enabled only for one pin, so all GPIO interrupts must be invoked by that pin, but its GPIOx_ISR bit is not always 1 when the ISR is called.
Code:
#define MASK (1<<31)
#define PIN 29
void setup() {
GPIO9_EDGE_SEL = 0;
GPIO9_ICR2 = 3 << 30; // falling
GPIO9_ISR = MASK; // clear interrupt
GPIO9_IMR = MASK; // enable interrupt
_VectorsRam[IRQ_GPIO6789 + 16] = isr;
NVIC_SET_PRIORITY(IRQ_GPIO6789, 0);
NVIC_ENABLE_IRQ(IRQ_GPIO6789);
}
bool found = false;
uint32_t tm;
void isr() {
if (!(GPIO9_ISR & MASK)) {
found = true;
tm = ARM_DWT_CYCCNT;
}
GPIO9_ISR = MASK; // clear interrupt
}
void loop() {
while (true) {
delay(500);
if (found) {
Serial.printf("%10u: mysterious interrupt found\n", tm);
found = false;
}
}
}
A test run gave the following output:
Code:
26740749: mysterious interrupt found
420006679: mysterious interrupt found
705485238: mysterious interrupt found
2040385731: mysterious interrupt found
2420998282: mysterious interrupt found
In the test, the signal sent to the GPIO pin is from a 74LVC buffer powered by 3.3V from Teensy. So I assume the signal is not dirty (unfortunately I don't have an oscilloscope...) Even if the signal was not clean, it might have had effects on invoking interrupts but should have not cause this behaviour, I guess.
I am really curious and want to understand why this happens. Perhaps I am not understanding the interrupt operation correctly, or it could be a very nasty bug. Any comments will be greatly appreciated!