I'm trying to set up interrupts for pins 0,5, and 2 of Port D of my FRDM-KL25z. I want the interrupts to trigger on a falling edge. For testing purposes, I have written the ISR to turn on the Red LED, using code that wrote for a previous project (LED.c). Below is my main code file.
I've tried to execute the following steps to set up interrupts:
Use the NVIC_EnableIRQ function to enable interrupts from Port D
Configure pins 0,2,5 as GPIO inputs and to request interrupts on the falling edge
Write the PORTD_IRQHandler function to do something (in this case, turn on the red LED).
Unfortunately, the red LED is not turning on when I transition any of the pins from logical 1 to 0. I've confirmed that the pins are functioning as inputs through some code that I haven't included in this post, so I must conclude that I have done something incorrectly or that I have missed a step.
#include <MKL25Z4.h>
#include <LED.h>
/*----------------------------------------------------------------------------
Function that initializes LEDs
Note: You need to perform the following steps
1. Turn on the clock gating to the appropriate ports
2. Set the pin MUX to GPIO
3. Set the pin to output
----------------------------------------------------------------------------*/
void LED_Initialize(void){
//ENABLE RED LED
SIM->SCGC5 |= (1 << 10); //Enable the clock to port B
PORTB->PCR[18] = PORT_PCR_MUX(001); //Set up PTB18 as GPIO
PTB->PDDR |= (1 << 18); //Set bit 18 of PDDR for Port B to 1 (Port data direction register)
//ENABLE GREEN LED
//clock is already enabled to port B, don't need to do it again
PORTB->PCR[19] = PORT_PCR_MUX(001); //Set up PTB19 as GPIO
PTB->PDDR |= (1 << 19); //Set bit 19 of PDDR for Port B to 1 (Port data direction register)
//Enable Blue LED
SIM->SCGC5 |= (1 << 12); //Enable the clock to port D
PORTD->PCR[1] = PORT_PCR_MUX(001); //Set up PTD1 as GPIO
PTD->PDDR |= (1 << 1); //Set bit 1 of PDDR for Port D to 1 (Port data direction register)
}
/*---------------------------------------------------------------------------
Three functions for toggling the current state of each LED individually
----------------------------------------------------------------------------*/
void LEDRed_Toggle(void){
if(((PTB->PDOR >> 18) & 0b1) == 1){ //If pin 18 of port B is 1, the LED is off
LEDRed_On(); //so turn it on
}else{
LEDRed_Off(); //else turn it off
}
}
void LEDGreen_Toggle(void){
if(((PTB->PDOR >> 19) & 0b1) == 1){ //If pin 19 of port B is 1, the LED is off
LEDGreen_On(); //so turn it on
}else{
LEDGreen_Off(); //else turn it off
}
}
void LEDBlue_Toggle(void){
if(((PTD->PDOR >> 1) & 0b1) == 1){ //If pin 1 of port D is 1, the LED is off
LEDBlue_On(); //so turn it on
}else{
LEDBlue_Off(); //else turn it off
}
}
/*---------------------------------------------------------------------------
Three functions for toggling the turning ON LEDs individually
----------------------------------------------------------------------------*/
void LEDRed_On(void){
PTB->PCOR |= (1 << 18); //Turn on the red LED (Using PCOR because LED is active-low)
}
void LEDGreen_On(void){
PTB->PCOR |= (1 << 19); //Turn on the green LED (Using PCOR because LED is active-low)
}
void LEDBlue_On(void){
PTD->PCOR |= (1 << 1); //Turn on the blue LED (Using PCOR because LED is active-low)
}
/*---------------------------------------------------------------------------
Three functions for toggling the turning OFF LEDs individually
----------------------------------------------------------------------------*/
void LEDRed_Off(void){
PTB->PSOR |= (1 << 18); //Turn off the red LED (Using PSOR because LED is active-low)
}
void LEDGreen_Off(void){
PTB->PSOR |= (1 << 19); //Turn off the green LED (Using PSOR because LED is active-low)
}
void LEDBlue_Off(void){
PTD->PSOR |= (1 << 1); //Turn on the blue LED (Using PSOR because LED is active-low)
}
/*---------------------------------------------------------------------------
One function turning OFF all 3 LEDs
----------------------------------------------------------------------------*/
void LED_Off(void){
LEDRed_Off();
LEDGreen_Off();
LEDBlue_Off();
}
UPDATE: I have confirmed that bits in Port D's ISFR are being set when pins 0,5, and 2 experience a falling edge. This makes me think that the problem lies how I have enabled Port D interrupts rather than how I have configured the pins. The program continues running as normal despite the interrupt flags not being cleared. It seems that PORTD_IRQHandler is never being called.
UPDATE 2: The interrupts do not seem to be reaching NVIC->ISPR register. Attached is a console screenshot showing this behavior.