Actions

EmSys

Tm4clib GPIO Interrupt control

From EdWiki

GPIO Interrupt control

Functions

Configuring interrupts from GPIO pins

GPIO pins can trigger interrupts on either edges or levels. The type of trigger can be configured with gpio_configure_int_trigger(). To have an event on the given pin generate an interrupt, its interrupt source must be unmasked. This can be achieved with gpio_enable_interrupts(). Interrupts which are no longer needed can be disabled through gpio_disable_interrupts().

In order for the interrupt to generate an IRQ and a call to the interrupt service routine, the interrupt for the GPIO port must be routed through the NVIC with nvic_enable_irq(). For this last step, the nvic.h header is needed:

Enabling an interrupt is as simple as configuring the desired trigger, unmasking the desired interrupt, and routing the desired GPIO port's interrupt through the NVIC.

/* Trigger interrupt on each rising edge */
gpio_configure_trigger(GPIOF, GPIO_TRIG_EDGE_RISE, GPIO0 | GPIO4);
/* Unmask the interrupt on those pins */
gpio_enable_interrupts(GPIOF, GPIO0 | GPIO4);
/* Enable the interrupt in the NVIC as well */
nvic_enable_irq(NVIC_GPIOF_IRQ);

After interrupts are properly enabled and routed through the NVIC, when an event occurs, the appropriate IRQ flag is set by hardware, and execution jumps to the GPIO ISR. The ISR should query the IRQ flags to determine which event caused the interrupt. For this, use gpio_is_interrupt_source(), with the desired GPIO flag. After one or more interrupt sources are serviced, the IRQ flags must be cleared by the ISR. This can be done with gpio_clear_interrupt_flag().

A typical GPIO ISR may look like the following:

void gpiof_isr(void)
{
     uint8_t serviced_irqs = 0;
     /* Process individual IRQs */
     if( gpio_is_interrupt_source(GPIOF, GPIO0) ) {
        process_gpio0_event();
        serviced_irq |= GPIO0;
     }
     if( gpio_is_interrupt_source(GPIOF, GPIO4) ) {
        process_gpio4_event();
        serviced_irq |= GPIO4;
     }
     /* Clear the interrupt flag for the processed IRQs */
     gpio_clear_interrupt_flag(GPIOF, serviced_irqs);
}