Mysterious interrupts on Teensy 4.0

Status
Not open for further replies.

CTRL

Member
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.

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!
 
maybe just use the arduino-way instead.

pinmode(x,INPUT),
attachInterrupt...

(may it be, that the pin you use is disabled?(<- that's the default) and... your #define PIN is never used anywhere in the code above)

- is there a pullup- or pulldown on the 74lvc-input?
 
I'm aiming to a very time-critical application, so I need to handle the interrupt directly. Yes, the arduino-way would not show this strange behaviour, because Paul's internal ISR checks the bit in GPIOx_ISR and calls user's ISR only when the bit is 1. (This is how to find which pin invoked the interrupt, I believe.)

Yes, #define PIN may be viewed as just a comment :) The actual code uses only the fact that pin 29 is bit 31 on GPIO9.

All unused inputs of the 74lvc are grounded :)
 
I believe that the pin is enabled for input by default --- Just in case, I've just added
Code:
pinMode(PIN, INPUT);
at the beginning of setup(), and confirmed that the behaviour is the same.
 
No, it is disabled.
Your program outputs nothing on my T4.
Do you have a pullup or pulldown somewhere?
 
..i'd just use pinMode + attachInterrupt (this way everthing gets initialized correctly) and after that use _VectorsRam[IRQ_GPIO6789 + 16] = isr; to set my own interrupt.
You might need a "dsb".
 
The strange output is shown only when I connect PIN 29 to a signal which frequently activates (roughly 1Mhz~500Hz range). I don't have any pullup/down. Could this be related to signal quality..?
 
1MHz is slow, the arduino-way can do it, I think. Or just use the way in post #7

You need to prevent floating pins... I don't know your circuit :)
 
I indeed had used the pinMode+attachInterrupt+settting _VectorsRam[...] method earlier. To make it sure, I've just replaced the whole content of setup() by
Code:
    pinMode(PIN, INPUT);
    attachInterrupt(PIN, dummy, FALLING);
    _VectorsRam[IRQ_GPIO6789 + 16] = isr;
and confirmed that the same behaviour is observed.
 
Well, IF there was a problem - you could be sure it was noticed before by other users of the 1062 (don't know how many chips NXP produces.. millions?)
If I use your program, I have NO output. So it must be something with your setup. Agreed?
 
Then, perhaps the guess is that when the signal is not clean (eg floating), such a weird behaviour may happen (ISR called without the GPIOx_ISR bit set) ... ? The signal into 74LVC is from some other gadget I didn't make, so I am not sure whether it might be indeed floating sometimes, even though the spec said it is not. Unfortunately I don't have an oscilloscope... :(

Perhaps I have to test it with a pullup added to the signal, or some other signal of similar frequency which is confirmed to be clean...
 
Yes, I' disconnect the input on the 74 and - at least for a test - add a pulldown/up to the specific nput. This will tell you if it is an electrical problem.

Hope you can find it :) Good luck!
 
Cause I can't do soldering where I am at right now, I've tried to use INPUT_PULLUP (with the original signal still connected) on the pin, as follows:

Code:
void setup() {
    pinMode(PIN, INPUT_PULLUP);
    attachInterrupt(PIN, dummy, FALLING);
    _VectorsRam[IRQ_GPIO6789 + 16] = isr;
}

Even with this, the same behaviour is observed. Would an external pullup may give a different result...?
 
can you post the part of the schematic that shows the connection to the 74.. input? what is it? another gate? a transistor?
 
The input to my 74LVC buffer (whose output is directly connected to Teensy's pin 29) is from an old 8-bit computer, which uses TTL level gates. So I guess I can't post its schematics... but it should be from some ~40 year old TTL gates (5V)...
 
As Frank noted, try adding asm("dsb"); to the end of your isr.

i'm assuming you're not using 5v with your74LVC (T4 is NOT 5v tolerant)
 
Unfortunately my old computer is a rarer one... I tried to find the schematics from the web several times, but only found that others said it was not available anywhere... :(
 
Yes, my 74LVC is on 3.3V :)

I added
Code:
asm("dsb");
.. and it changed the behavior! Every time the ISR is called, the corresponding bit on GPIOx_ISR is set to 1!

Would you mind explaining a bit more about asm("dsb"), in this context of an interrupt handler?
 
Also, I've just checked Paul's source code of Teensy 4.0 core, and it seems like that the internal GPIO ISR does NOT use asm("dsb"). Perhaps the internal ISR would also need it, to prevent such calls?
 
I prefer to leave that to others with better English skills.

There is a document from ARM about this, several pages about "barriers", but I can't find it right now.

Also, I've just checked Paul's source code of Teensy 4.0 core, and it seems like that the internal GPIO ISR does NOT use asm("dsb"). Perhaps the internal ISR would also need it, to prevent such calls?
Maybe, maybe not :) The DSB just makes sure evrything in the pipelne is written.
It slows down everything a bit, as it mght have to wait some cycles.
As long nobody complains... it seems to work without (in this special case).
 
Status
Not open for further replies.
Back
Top