I am using the iMX6 BSP and have a question about interrupt handling.
As I understand the flow in the BSP, the following happens on GPIO interrupt (assuming a handler is installed with register_interrupt_routine(IRQ, ISR):
1. ARM Core takes IRQ Exception and globally masks the IRQ bit in the CPSR (Disables IRQ interrupts)
2. The Freescale IRQ_HDLR() is called because it is in the ARM vector for IRQ exception
3. The GIC is checked for the highest priority interrupt pending and the GIC is ACKed
4. That interrupt is called by looking up the address (in this case, handle_GPIO())
5. The GIC is signafied that the interrupt is handled
6. ARM core is restored to resume "mainline" execution
My question is: What should happen in handle_GPIO() to ensure safe interrupt handling? Specifically, when should I ACK the status in the GPIO_ISR register to make sure interrupts are not missed, and should I mask the GPIO_IMR register while handling the interrupt?
Currently i am doing this:
uint32_t mask = HW_GPIO_IMR_RD(port);
HW_GPIO_IMR_WR(port, mask & ~(1UL << pin)); // Mask the interrupt
uint32_t status = HW_GPIO_ISR_RD(port) ; // Read the status
HW_GPIO_ISR_WR(port, (1UL << pin)); // ACK the status
if (status & mask & (1UL << pin) ) {
// Call the ISR function that is assigned to this pin
gpio_irqs_in_use[i].isr_func();
}
HW_GPIO_IMR_WR(port, mask); // Un-mask the interrupt
But I don't know if it is correct. Also, I would like to be able to mask the interrupt FROM the isr_func() which is impossible with this approach.