I wrote a simple program to test GPIOD6 interupt. I hooked up a function generator to trigger the interrupt. For every pulse from the function generator, the interrupt handler was executed twice. I finally found the work around by moving the interrupt flag clear statement up to the beginning of the interrupt handler and that fixed the problem. Attached is the original program and the modified interrupt handler that works at the end.
I am assuming that there is a latency in clearing the interrupt flag or maybe you can help me spot the bugs in my code.
I am using Keil uVision 4.72.10.0.
Original program that produced two interrupt handler with one pulse:
#include "TM4C123GH6PM.h"
int main(void)
{
SYSCTL->RCGCGPIO |= 0x20; // enable clock to PORTF
SYSCTL->RCGCGPIO |= 0x08; // enable clock to PORTD
// configure PORTF for LED output
GPIOF->DIR |= 0x0E; // make PORTF3, 2, 1 output for LEDs
GPIOF->DEN |= 0x0E; // make PORTF4-0 digital pins
// configure PORTD6 for falling edge trigger interrupt
GPIOD->DIR &= ~0x40; // make PORTD6 input pin
GPIOD->DEN |= 0x40; // make PORTD6 digital pin
GPIOD->IS &= ~0x40; // make bit 4, 0 edge sensitive
GPIOD->IBE &= ~0x40; // trigger is controlled by IEV
GPIOD->IEV &= ~0x40; // falling edge trigger
GPIOD->ICR |= 0x40; // clear any prior interrupt
GPIOD->IM |= 0x40; // unmask interrupt
// enable interrupt in NVIC and set priority to 6
NVIC->IP[3] = 6 << 5; // set interrupt priority to 6
NVIC->ISER[0] |= 0x00000008; // enable IRQ3
__enable_irq(); // global enable IRQs
while(1)
{ // wait for interrupts
}
}
void GPIOD_Handler(void)
{
GPIOF->DATA ^= 8; // toggle green LED
GPIOD->ICR |= 0x40; // clear the interrupt flag
}
By swapping the two statements, the interrupt handler is executed only once for each pulse.
void GPIOD_Handler(void)
{
GPIOD->ICR |= 0x40; // clear the interrupt flag
GPIOF->DATA ^= 8; // toggle green LED
}