AnsweredAssumed Answered

Proper GPIO interrupt handling in iMX6

Question asked by Nathan Palmer on Mar 25, 2015
Latest reply on Aug 24, 2015 by Andrea Tessadri

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.

Outcomes