MCX Microcontroller from NXP semiconductor are going to be widely used MCU’s as they have best of their LPC and Kenetis Series MCU. They might will even stop producing older generation LPC and Kenetic MCUs once MCX Microcontrollers start getting used in the products.

On the FRDM Development board we have a switch connected on Pin P3_29, we can configure this pin as input to receive Interrupt.

GPIO interrupt example is provided. You can import by going to New>Import SDK examples, Select the FRDM Board, and select the right example.

In order to configure any GPIO as input and receive interrupt, here are a few things we need to do:
- Enable System Clock
- Enable GPIO Port, PIn Port Clock
- Configure Pin and Port
- Configure Interrupt and Enable it
- Handle received interrupt using handler function
System clock is enable via BOARD_InitBootClocks() which calls BOARD_BootClockFRO96M() to set system frequency to 96Mhz
void BOARD_InitBootClocks(void)
{
BOARD_BootClockFRO96M();
}
Then, Clock is enabled and reset is released for PORT3 and GPIO3 and later the input pin is configured as shown below. BOARD_InitPins() function contains all this configuration instructions.
/* Write to GPIO3: Peripheral clock is enabled */
CLOCK_EnableClock(kCLOCK_GateGPIO3);
/* Write to PORT3: Peripheral clock is enabled */
CLOCK_EnableClock(kCLOCK_GatePORT3);
/* GPIO3 peripheral is released from reset */
RESET_ReleasePeripheralReset(kGPIO3_RST_SHIFT_RSTn);
/* PORT3 peripheral is released from reset */
RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn);
const port_pin_config_t port3_29_pin32_config = {/* Internal pull-up/down resistor is disabled */
kPORT_PullDisable,
/* Low internal pull resistor value is selected. */
kPORT_LowPullResistor,
/* Fast slew rate is configured */
kPORT_FastSlewRate,
/* Passive input filter is disabled */
kPORT_PassiveFilterDisable,
/* Open drain output is disabled */
kPORT_OpenDrainDisable,
/* Low drive strength is configured */
kPORT_LowDriveStrength,
/* Normal drive strength is configured */
kPORT_NormalDriveStrength,
/* Pin is configured as P3_29 */
kPORT_MuxAlt0,
/* Digital input enabled */
kPORT_InputBufferEnable,
/* Digital input is not inverted */
kPORT_InputNormal,
/* Pin Control Register fields [15:0] are not locked */
kPORT_UnlockRegister};
/* PORT3_29 (pin 32) is configured as P3_29 */
PORT_SetPinConfig(PORT3, 29U, &port3_29_pin32_config);
Interrupt for MCXA Microcontroller GPIO Input
Next is to configure the interrupt for the Inpit pin P3_29 and Enable the interrupt which is done as shown below:
Macros are defined in the board.h header file.
GPIO_SetPinInterruptConfig(BOARD_SW_GPIO, BOARD_SW_GPIO_PIN, kGPIO_InterruptFallingEdge);
EnableIRQ(BOARD_SW_IRQ);
various options are available for selecting the type of interrupt:
typedef enum _gpio_interrupt_config
{
kGPIO_InterruptStatusFlagDisabled = 0x0U, /*!< Interrupt status flag is disabled. */
kGPIO_DMARisingEdge = 0x1U, /*!< ISF flag and DMA request on rising edge. */
kGPIO_DMAFallingEdge = 0x2U, /*!< ISF flag and DMA request on falling edge. */
kGPIO_DMAEitherEdge = 0x3U, /*!< ISF flag and DMA request on either edge. */
kGPIO_FlagRisingEdge = 0x05U, /*!< Flag sets on rising edge. */
kGPIO_FlagFallingEdge = 0x06U, /*!< Flag sets on falling edge. */
kGPIO_FlagEitherEdge = 0x07U, /*!< Flag sets on either edge. */
kGPIO_InterruptLogicZero = 0x8U, /*!< Interrupt when logic zero. */
kGPIO_InterruptRisingEdge = 0x9U, /*!< Interrupt on rising edge. */
kGPIO_InterruptFallingEdge = 0xAU, /*!< Interrupt on falling edge. */
kGPIO_InterruptEitherEdge = 0xBU, /*!< Interrupt on either edge. */
kGPIO_InterruptLogicOne = 0xCU, /*!< Interrupt when logic one. */
kGPIO_ActiveHighTriggerOutputEnable = 0xDU, /*!< Enable active high-trigger output. */
kGPIO_ActiveLowTriggerOutputEnable = 0xEU, /*!< Enable active low-trigger output. */
} gpio_interrupt_config_t;
#endif
Now, we need a handler which will be called once the interrupt is received.
void BOARD_SW_IRQ_HANDLER(void) is the handler function which is called in the example but it ultimately calls GPIO3_IRQHandler(). So, this handle will be called if any interrupt comes in any pin of GPIO3 which is configured for interrupt.
Once interrupt comes, you will need to check if interrupt is received for that pin (you can use either GPIO_GpioGetInterruptFlags() or GPIO_PinGetInterruptFlag() )
and then clear the interrupt flag and enable one variable flag so that you can check that in supper loop and execute the task you want to do when interrupt occurs like toggle the LED.
void BOARD_SW_IRQ_HANDLER(void)
{
GPIO_GpioClearInterruptFlags(BOARD_SW_GPIO, 1U << BOARD_SW_GPIO_PIN);
/* Change state of button. */
g_ButtonPress = true;
SDK_ISR_EXIT_BARRIER;
}
Main loop will look like this:
You are basically checking the variable flag and executing the task(Toggle LED) and then resetting the variable flag.
while (1)
{
if (g_ButtonPress)
{
/* Toggle LED. */
GPIO_PortToggle(BOARD_LED_GPIO, 1U << BOARD_LED_GPIO_PIN);
/* Reset state of button. */
g_ButtonPress = false;
}
}
You can see how it work in the video shown below:
Polling mode for GPIO Input
In certain situations you don’t want to read input via interrupt but just want to read input state in polling mode. For that you can call the function GPIO_PinRead().
And, on the configuration part, you don’t need to configure the interrupt and don’t need to enable interrupt.
/*!
* @brief Reads the current input value of the GPIO port.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param pin GPIO pin number
* @retval GPIO port input value
* - 0: corresponding pin input low-logic level.
* - 1: corresponding pin input high-logic level.
*/
static inline uint32_t GPIO_PinRead(GPIO_Type *base, uint32_t pin)
{
return (((uint32_t)(base->PDIR) >> pin) & 0x01UL);
}
So, this is how you use the GPIO input.
That’s all in this tutorial blog for MXA Microcontroller, I hope it was easy to follow. My new blog will focus on UART interface on MCXA Microcontroller. Stay tuned!
I am running an Embedded Design House, CAPUF Embedded Pvt. Ltd, located in Bangalore, India. At CAPUF, we help companies build embedded products with our hardware and firmware design services.
We also help in design optimizations for power consumption, cost, mass manufacturing, and performance.
Additionally, we develop PCB testing jigs and provide cloud-based monitoring solutions.