Hi guys - I've spent significant time toying with the code below and cannot for the life of me figure out the odd behavior. Originally this code was part of a larger project I've been working on but have since, in attempts to determine what is happening, stripped the code down to it's essentials (what you see below) and the issue persists.
As you'll see below, I've configured pins B0-thru-B7 as general purpose digital output and I've configured pins D0-thru-D3 as general purpose digital input. The D0-thru-D3 pins are set to trigger an interrupt. I have these hooked into some typical buttons on a bread board, so that when a button is pressed the interrupt triggers.
Now, what's happening is that the interrupt is mysteriously being triggered every time the write to GPIO_PORTB_DATA_R occurs with differing data. If I comment out the writes to GPIO_PORTB_DATA_R the port D interrupt is only triggered when I press a button on my bread board (as it should).
Also, if I change the while loop in main to just write a single value to GPIO_PORTB_DATA_R it will trigger the interrupt once (when it writes this initial value) and then never agin for subsequent writes (always of the same value). So it appears it only triggers the port D interrupt when updating the value in port B's data.
I have no idea why this is happening. I've followed the GPIO configuration steps from the datasheet (section 10.3) as you'll see in the comments in my InitPortB and InitPortD functions.
Any thoughts anyone might have are very welcomed as I'm pretty much out of ideas as to why this is occurring.
#include <stdint.h>
#include "inc/tm4c123gh6pm.h"
void InitPortB()
{
// Step 1: Enable a clock to port D
SYSCTL_RCGCGPIO_R |= 0x02;
// Step 2: Set the direction (output)
GPIO_PORTB_DIR_R = 0xFF;
// Step 3: Configure the pins to GPIOAFSEL - Skipping as the pins are GPIO by default
// Step 4: Skipping, I don't care about drive strength
// Step 5: Skipping, not using pull-up, down or open drain functionality
// Step 6: Configure the as digital
GPIO_PORTB_DEN_R |= 0xFF;
// Step 7: Skipping, not using an interrupt with these pins
// Step 8: Unlock the port/pins to allow writing to them
GPIO_PORTB_LOCK_R = 0x4C4F434B;
GPIO_PORTB_CR_R = 0xFF;
}
void InitPortD()
{
// Step 1: Enable a clock to port D
SYSCTL_RCGCGPIO_R |= 0x08;
// Step 2: Set the direction (input)
GPIO_PORTD_DIR_R &= ~0x0F;
// Step 3: Configure the pins to GPIOAFSEL - Skipping as the pins are GPIO by default
// Step 4: Skipping, I don't care about drive strength
// Step 5: Skipping, not using pull-up, down or open drain functionality
// Step 6: Configure the as digital
GPIO_PORTD_DEN_R |= 0x0F;
// Step 7a: Disable the interrupt while it's being configured
GPIO_PORTD_IM_R &= ~0x0F;
// Step 7b: Configure the IS field in the GPIOIS register and the IBE field in the GPIOIBE register
GPIO_PORTD_IS_R &= ~0x0F; // Configure the interrupt for edge detection
GPIO_PORTD_IBE_R &= ~0x0F; // Interrupt generation is controlled by the GPIOIEV
GPIO_PORTD_IEV_R |= 0x0F; // Detect interrupt on a rising edge
// Step 7c: Clear the GPIORIS register
GPIO_PORTD_RIS_R &= ~0x0F;
// Step 7d: Unmask the port by setting the IME field in the GPIOIM register
GPIO_PORTD_IM_R |= 0x0F;
// Step 8: Skipping, not writing to the pins so don't care about locking
// Enable the Port D interrupt
NVIC_EN0_R |= (1<<3);
}
void PortDInterruptHandler()
{
GPIO_PORTD_ICR_R |= 0xFF; // Clear the interrupt
}
int main(void)
{
InitPortB();
InitPortD();
uint32_t counter = 0;
while(1)
{
if(counter % 2 == 0)
{
GPIO_PORTB_DATA_R = 99;
}
else
{
GPIO_PORTB_DATA_R = 0;
}
++counter;
}
}