GPIO ISR and Clearing ISR

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

GPIO ISR and Clearing ISR

2,176 Views
Keith4DSmith
Contributor V

I am working with the iMX RT1064 eval kit.

I have coded the interrupt handler for GPIO1_Combined_16_31_IRQHandler(). I have several external inputs on this group of GPIO bits. The inputs are on external pull ups. All inputs are set for interrupt on falling edge.

After the interrupt fires, in the handler, I call GPIO_PortGetInterruptFlags(). I see many bits asserted, not just the individual bit that caused the interrupt. Some bits are set that I don't have a circuit for. (possible the eval kit has pull ups for these bits).

I have also read the GPIO1 ISR after calling the appropriate Board_xxxx() at main(). I see the same set of ISR bits asserted.

I have also called GPIO_PortClearInterruptFlags(0xffffffff) to attempt to clear the ISR bits. None of the bits are cleared.

I have run the GPIO interrupt SDK example. It assigns 1 interrupt to GPIO5 bit 0, a push button. When the interrupt fires, I read the GPIO5 ISR. All the ISR bits are set. Calling GPIO_PortClearInterruptFlags() does clear bit 0 of the ISR.

My questions are: Any reason why the ISR bits are not cleared by calling GPIO_PortClearInterruptFlags()?

How do I determine which interrupt has occurred if multiple ISR bits are always set?

Labels (1)
Tags (2)
5 Replies

1,997 Views
mjbcswitzerland
Specialist V

Hi Keith

See the following for a GPIO port interrupt reference: https://www.utasker.com/iMX/RT1064.html

In your case you need to beware that the interrupt status of bits that are not configured for interrupt operation will read as being pending. Therefore you can not use just a check of the interrupt status like
if ((GPIO1_ISR & 0xffff0000) != 0) { // is an interrupt source pending?
    if ((GPIO1_ISR & 0x00010000) != 0) { // is GPIO1_IO16 pending?
    }
    if ((GPIO1_ISR & 0x00020000) != 0) { // is GPIO1_IO17 pending?
    }
    // etc.
}

But instead you need to also mask it with the enabled bits, such as
if (((GPIO1_ISR & 0xffff0000) & GPIO1_IMR)  != 0) { // is an interrupt source pending?
    if (((GPIO1_ISR & 0x00010000) & GPIO1_IMR) != 0) { // is GPIO1_IO16 enabled and pending?
    }
    if (((GPIO1_ISR & 0x00020000) & GPIO1_IMR) != 0) { // is GPIO1_IO17 enabled and pending?
    }
    // etc.
}

In the uTasker port interrupt driver all such details are hidden and the user just assigns the required interrupt call back to each individual pin (whether it has a dedicated vector or not) and the job is done. Details in the original link and videos.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

0 Kudos

1,997 Views
EdSutter
Senior Contributor II

Mark,

Thanks for posting this, but I don't quite get it...

The IMXRT1060 Reference Manual's GPIO chapter 12 section 2,  says this:

In addition, GPIO1 provides visibility to each of its 8 low order interrupt sources (i.e.
GPIO1 interrupt n, for n = 0 – 7). However, individual interrupt indications from other
GPIOx are not available.

That seems to imply that [strangely] only the low 8 bits of GPIO1's ISR can be queried for interrupt status.  Later in the text (in the register description section, it doesn't say anything like that regarding the ISR register (implying to me that all GPIO->ISR registers (when masked with IMR) do in fact show the interrupt status.

That doesn't make sense to me.  Your logic works, but as far as I can tell, it disagrees with [parts of] the reference manual.  Is this just a documentation error in the reference manual or am I totally confused?

Ed

0 Kudos

1,997 Views
mjbcswitzerland
Specialist V

Ed

Some ports have a single interrupt for all 32 bits. Then, when there is a port interrupt one needs to check which (up to 32) flag(s) is/are set.

Some ports have two interrupts - one for the high 16 bits and one for the low 16 bits, so when one of these fires one need to check which of the 16 possible inputs it was.

In the case of the i.MX RT 1060's port 1 there are 10 interrupt vectors for it. One for the highest 16 bits, one for bits 8..15 and 8 individual ones for bits 0..7.

I think that the manual is trying to state that the first 8 bits have their own interrupt vectors (which means that when the interrupt fires one knows exactly which pin it came from, without needing to look up which is pending) but the others don't (and so their status bits need checking).

If you read
"However, individual interrupt indications from other GPIOx are not available."
as
"However, individual interrupt VECTORS from other GPIOx are not available."
it probably makes more sense.

Attached is the port interrupt configuration and interrupt dispatches from the uTasker project which generically supports all i.MX RT parts and adapts itself to their port capabilities - as reference (it also allows port interrupt simulation) when used together with its i.MX RT simulator.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

1,997 Views
EdSutter
Senior Contributor II

Ok, if your translation of the manual text (indications --> VECTORS) is correct, then that makes sense...

Thanks,

0 Kudos

1,997 Views
mjbcswitzerland
Specialist V

Ed

One sometimes has to do some reading-between-the-line of the manuals and then get your hands dirty testing how it really works under the bonnet. Unclear things sometimes start to make sense, or one realises that someone may have written some nonsense (or cut and pasted from an incompatible source) and one's own translation takes priority.

Regards

Mark

[uTasker project developer for Kinetis and i.MX RT]

0 Kudos