FRDM-K64 and GPIO configuration as interrupt input

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

FRDM-K64 and GPIO configuration as interrupt input

2,207 Views
nadine
Contributor III

Hi,

I'm using a FRDM-K64 board with SDK_2.0 and KDS 3.1.0.

I try to configure the pin PTC3  as an input interrupt. Here after, you'll find the initialization code that I use:

/* PTC3 - Pin 16 SLP_TR Pin */
#define BOARD_SLP_TR_PORT          PORTC
#define BOARD_SLP_TR_IRQ              PORTC_IRQn
#define BOARD_SLP_IRQ_HANDLER PORTC_IRQHandler
#define BOARD_SLP_TR_GPIO           GPIOC
#define BOARD_SLP_TR_GPIO_PIN   3

PORT_SetPinMux(PORTC, BOARD_SLP_TR_GPIO_PIN, kPORT_MuxAsGpio);       /* PTC3 */

GPIO_PinInit(BOARD_SLP_TR_GPIO, BOARD_SLP_TR_GPIO_PIN, &in_config);
NVIC_SetPriority(BOARD_SLP_TR_IRQ, 15);
EnableIRQ(BOARD_SLP_TR_IRQ);
PORT_SetPinInterruptConfig(BOARD_SLP_TR_PORT, BOARD_SLP_TR_GPIO_PIN, kPORT_InterruptEitherEdge);

The program fails as soon as the GPIO pin state is modified. It' looks like I never enter in the interrupt handler.

Any help is welcome. 

Thanks in advance

Nadine,

Labels (1)
0 Kudos
3 Replies

1,167 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi

Please enable the clock gate of PORTC first, and then configure the registers of PTC3.

CLOCK_EnableClock(kCLOCK_PortC);

Can't see the BOARD_SLP_IRQ_HANDLER function, you can refer below:

void BOARD_SLP_IRQ_HANDLER(void)
{
    /* Clear external interrupt flag. */
    GPIO_ClearPinsInterruptFlags(BOARD_SLP_TR_GPIO, 1U << BOARD_SLP_TR_GPIO_PIN);

    /* Change state of button. */
    g_ButtonPress = true;
}

Can't see the in_config, you can refer below:

    gpio_pin_config_t in_config = {
        kGPIO_DigitalInput, 0,
    };

I'm using a FRDM-K64F board with SDK_2.1_FRDM-K64F and KDS 3.2.0.

Best Regards,

Robin

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
---------------------------------------------------------------------------------------------------------------------

0 Kudos

787 Views
abdurrehman98
Contributor I

Your answer helped me. I am using SDK example GPIO_Input_Interrupt. SW3 used to generate Interrupt

I want to know about the working or these three lines. PortClear and GpioClear (Difference between them)

 

#if (defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT)

/* Clear external interrupt flag. */
GPIO_GpioClearInterruptFlags(BOARD_SW_GPIO, 1U << BOARD_SW_GPIO_PIN);

#else
/* Clear external interrupt flag. */
GPIO_PortClearInterruptFlags(BOARD_SW_GPIO, 1U << BOARD_SW_GPIO_PIN);

 

0 Kudos

1,167 Views
mjbcswitzerland
Specialist V

Hi Nadine

I don't know the SDK code but it may be that it expects you to clear the interrupt source in the user callback. If you don't it may be stuck in the interrupt (?). If it hangs "during" initialisation it may expect you to previously enable clocks to the port in question (?).

You could also look at uTasker code to do this -

extern void fnConfigInterrupts(void)
{
    INTERRUPT_SETUP interrupt_setup;                                     // interrupt configuration parameters
    interrupt_setup.int_type       = PORT_INTERRUPT;                     // identifier to configure port interrupt
    interrupt_setup.int_priority   = PRIORITY_PORT_C_INT;                // interrupt priority level
    interrupt_setup.int_port       = PORTC;                              // the port that the interrupt input is on

    interrupt_setup.int_port_bits  = PORTC_BIT1;
    interrupt_setup.int_port_sense = (IRQ_BOTH_EDGES | PULLUP_ON);
    interrupt_setup.int_handler    = myInterrupt1;                       // handling function - called on any edge on PTC1
    fnConfigureInterrupt((void *)&interrupt_setup);                      // configure interrupt

    interrupt_setup.int_port_bits  = PORTC_BIT2;
    interrupt_setup.int_port_sense = (IRQ_FALLING_EDGE | PULLUP_ON);
    interrupt_setup.int_handler    = myInterrupt2;                       // handling function - called on a falling edge on PTC2
    fnConfigureInterrupt((void *)&interrupt_setup);                      // configure interrupt

    interrupt_setup.int_port_bits  = PORTC_BIT3;
    interrupt_setup.int_port_sense = (IRQ_HIGH_LEVEL | PULLDOWN_ON);
    interrupt_setup.int_handler    = myInterrupt3;                       // handling function - called on high level sensitive state on PTC3
    fnConfigureInterrupt((void *)&interrupt_setup);                      // configure interrupt
}

// PTC1 interrupt call-back
//
static void myInterrupt1(void)
{
    // my code
}

// PTC2 interrupt call-back
//
static void myInterrupt2(void)
{
    // my code
}

// PTC3 interrupt call-back
//
static void myInterrupt3(void)
{
    // my code
}


This sets three different interrupts on Port C with their own characteristics and individual call-back handler (and can be used to enter DMA triggers or LLWUs). It also allows you to simulate the complete operation in the K64 simulator so that you can test complete code, interrupts, DMA etc. in order to avoid difficulties, to easily understand errors or learn the internal workings.

Unlike SDK any code that you write can be run on any Kinetis part (K, KL, KV, KM, KW) without needing porting and also builds with KDS3.x, CW10.x, IAR, Keil, Rowley, Atollic, Green Hills, CooCox, GCC, VisualStudio so is not restricted to particular environments.

Regards

Mark

K64 support:

µTasker Kinetis FRDM-K64F support 
µTasker Kinetis TWR-K64F120M support 

µTasker Teensy3.5 support 

0 Kudos