GPIO Interrupt not triggering for FRDM-KL25z

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

GPIO Interrupt not triggering for FRDM-KL25z

Jump to solution
459 Views
MelonM
Contributor II

IMPORTANT: Updates at bottom of post

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:

  1. Use the NVIC_EnableIRQ function to enable interrupts from Port D
  2. Configure pins 0,2,5 as GPIO inputs and to request interrupts on the falling edge
  3. 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.

 

Main code file:

 

Spoiler
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "MKL25Z4.h"
#include "fsl_debug_console.h"
/* TODO: insert other include files here. */
#include "LED.h"
/* TODO: insert other definitions and declarations here. */

/*
 * @brief   Application entry point.
 */

const uint32_t INPUT_CONFIG =   PORT_PCR_IRQC(1010) | // IRQ Falling Edge
                                PORT_PCR_MUX(001)   | // Pin set to GPIO
                                PORT_PCR_DSE(0)     | // Low drive strength
                                PORT_PCR_PFE(0)     | // TODO: Passive filter disabled, try enabling if noisy
                                PORT_PCR_SRE(0)     | // TODO: Fast slew rate, look up what slow would mean
                                PORT_PCR_PE(0)      | // Pull resistor is disabled
                                PORT_PCR_PS(0);       // Pull resistor is set to pulldown (but is still disabled)

int main(void) {

  	/* Init board hardware. */
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitBootPeripherals();
#ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL
    /* Init FSL debug console. */
    BOARD_InitDebugConsole();
#endif

    NVIC_EnableIRQ(PORTD_IRQn);

    // LED Initialization
    LED_Initialize();
    LED_Off();

    // Enable and setup 3 pins in PORTA
    SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK;    //Enable the clock to port D

    PORTD->PCR[5] = INPUT_CONFIG;     //Setup PTD5
    PORTD->PCR[0] = INPUT_CONFIG;     //Setup PTD0
    PORTD->PCR[2] = INPUT_CONFIG;     //Setup PTD2

    /* Force the counter to be placed into memory. */
    volatile static int i = 0 ;
    /* Enter an infinite loop, just incrementing a counter. */
    while(1) {
        i++ ;
        /* 'Dummy' NOP to allow source level single stepping of
            tight while() loop */
        __asm volatile ("nop");
    }
    return 0 ;
}

void PORTD_IRQHandler(void){
    //TODO: USE ISFR to see which pin triggered the interrupt

    LEDRed_On();

    //CLEAR INTERRUPT FLAG
    PORTD->ISFR = 0xFFFFFFFF;
}

LED Utility Functions

 

 

Spoiler
#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.

Interrupts Registers.png

 

0 Kudos
Reply
1 Solution
403 Views
MelonM
Contributor II

I discovered the problem. In my declaration of the INPUT_CONFIG const, I wrote.

PORT_PCR_IRQC(1010)

 

I intended to have this value be binary, but I forgot to write indicate it as such. Replacing it with the below line fixed the issue.

PORT_PCR_IRQC(0b1010)

 

View solution in original post

0 Kudos
Reply
1 Reply
404 Views
MelonM
Contributor II

I discovered the problem. In my declaration of the INPUT_CONFIG const, I wrote.

PORT_PCR_IRQC(1010)

 

I intended to have this value be binary, but I forgot to write indicate it as such. Replacing it with the below line fixed the issue.

PORT_PCR_IRQC(0b1010)

 

0 Kudos
Reply