iMX8M Plus M7 GPIO Interrupt example code

Hi,
I was wondering if anyone had some example code for a GPIO interrupt on the M7 of the verdin imx8.
The SDK for the evkmimx8mp doesn’t have a driver example.
Thanks !

Hi, I’m the Toradex AI Assistant. I’m in early beta, and I would appreciate your feedback.
The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


Hello,

For implementing a GPIO interrupt on the M7 core of a Verdin iMX8M Plus module, you can adapt the example provided for the iMX7 Colibri M4, as the principles behind setting up GPIO interrupts are similar across different NXP SoCs. While the specific SDK for the EVK iMX8M Plus might not include a direct example, the process involves configuring the GPIO pin as an interrupt source, setting up the interrupt handler, and enabling the interrupt in the M7’s NVIC (Nested Vectored Interrupt Controller).

Here’s a simplified approach to achieve this on the Verdin iMX8M Plus:

  1. GPIO Configuration: First, configure the GPIO pin you intend to use for the interrupt. This involves setting the pin’s direction as input and enabling the interrupt capability for that pin.

  2. Interrupt Handler Setup: Implement an interrupt handler function that will be called when the GPIO interrupt is triggered. This function will typically clear the interrupt flag and perform any required processing.

  3. NVIC Configuration: Configure the NVIC to enable the interrupt for the specific GPIO. This involves setting the interrupt priority and enabling it.

  4. Enable GPIO Interrupt: Finally, enable the interrupt on the GPIO by configuring the appropriate registers to detect either a rising edge, falling edge, or both, depending on your application requirements.

Since the exact register addresses, interrupt numbers, and configuration details can vary significantly between the iMX7 and iMX8M Plus, it’s crucial to refer to the iMX8M Plus reference manual for the specific details relevant to configuring GPIOs and interrupts on this platform. Additionally, the FreeRTOS BSP for the Verdin iMX8M Plus might provide some abstractions that simplify interacting with the GPIO and NVIC.

Remember, when working with FreeRTOS alongside Linux (in a heterogenous multicore environment), you must ensure that the Linux device tree does not claim the GPIO bank used by FreeRTOS, to avoid conflicts.

This approach should give you a starting point for implementing GPIO interrupts on the M7 core of the Verdin iMX8M Plus. Adjustments will be necessary to accommodate the differences in hardware registers and interrupt handling mechanisms between the iMX7 and iMX8M Plus.

Best regards,
Toradex AI Assistant

Please, also check if these links can help you solve your problem:

Application Development - .NET Example | Toradex Developer Center.

Unfortunately, we do not have example code for a GPIO interrupt on the M7 of the verdin imx8, but maybe the links below will be helpful:

Hello

i have a similar issue and have been honestly banging my head against this for days already.
along with more internet searches and greping the sdk for anything that could fell relevant.
Is there a way to get more informations?
(i’ll gladly open a new thread if required)

Have a good day

Yes, we strongly oppose thread hijacking.

However, I highly doubt we can provide any additional information beyond what has already been listed in this thread.

Hi @fennecdjay,

I used the M7 interrupts on one of our demos, but the source is still not published and the interrupt is just a small part of it, so I’ll share the relevant parts/details here:

The biggest issue with the GPIO interrupts on the Cortex-M is the shared interrupt controller for the GPIOs in a given bank, which means that, if a GPIO is assigned to a given subsystem (Cortex-A, Cortex-M), its entire bank may only be used on that subsystem.

When selecting the GPIOs to run on the Cortex-M, select a GPIO from a bank that will not affect other functionality you need (some GPIOs are used, for example, to enable voltage regulators).

Now to the interrupt code:

Interrupt handler

The interrupt handler is a weakly defined symbol in the mcuxpresso sdk, to see other interrupt handlers you may Ctrl-F this function name and find the file where it is defined.

This function is called by NVIC when an interrupt is raised. I’ll explain the SDK_ISR_EXIT... later.

void GPIO4_Combined_0_15_IRQHandler() {
    tdx_encoder_irq_handler();
    SDK_ISR_EXIT_BARRIER;
}

This function handles the combined interrupts for the gpios 0 to 15 on the bank 4. We check which pins actually changed through software.

The function we call in the irq handler, tdx_encoder_irq_handler(...), calls the correct GPIO_PortClearInterruptFlags(...) for the pin that triggered the interrupt, but more on that later. Just don’t forget to add the “clear interrupt” function to your code.

One of the SoC GPIO banks supports per-gpio interrupt instead of combined gpios, but this bank is used by Linux for a lot of other stuff.

Pin mode configuration

You’ll have to do two things in order to use the GPIO on the Cortex-M:

  1. Disable every reference to the GPIO you want to use and every GPIO from that bank from the Linux Device Tree
  2. Configure the pin using the IOMUXC functions in the SDK (configurations are usually set in the pin_mux.c file)

For the device tree configuration, see our guides on developer.toradex.com.

For the SDK pin configuration, here are the relevant functions to configure it:

// Encoder #1 A on SODIMM_133
IOMUXC_SetPinMux(IOMUXC_SAI2_RXD0_GPIO4_IO23, 0U);
IOMUXC_SetPinConfig(IOMUXC_SAI2_RXD0_GPIO4_IO23,
                    IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
                    IOMUXC_SW_PAD_CTL_PAD_HYS_MASK |
                    IOMUXC_SW_PAD_CTL_PAD_PE_MASK);

This first function, IOMUXC_SetPinMux, defines the mux mode (we are using the SAI2_DXD0 pin with the GPIO4_IO23 alternate function).

The second function, IOMUXC_SetPinConfig, sets the parameters such as pull up/down (PUE = pull-up), hysteresis (HYS), enabling pull (PE), but there are many others to choose (such as drive strength, …).

In our case we needed pull-up and hysteresis, but you may choose what fits best for your project.

Interrupt manipulation

You’ll need to enable (and possibly disable) the interrupt in your code. The functions to do that come from the fsl_gpio library. You’ll probably want to include the register defs from the SDK too.

// Device defs
#include "MIMX8ML8_cm7.h"

// Mcuxpresso includes
#include "fsl_gpio.h"

The library provides functions such as DisableIRQ(irq_n), EnableIRQ(irq_n), GPIO_PortEnableInterrupts(gpio_base, 1 << gpio_pin), and GPIO_PortClearInterruptFlags(gpio_base, 1 << gpio_pin).

I’ll put here some examples:

EnableIRQ(GPIO4_Combined_0_15_IRQn);
GPIO_PortClearInterruptFlags(GPIO4, 1 << 2);

You’ll need to call EnableIRQ(...) somewhere in your firmware, as GPIO IRQs come disabled by default.

Kernel panics and troubleshooting

If a pin is already assigned to the Cortex-M when Linux boots, you may see a kernel panic, or Linux may just steal the pin (or GPIO controller).

When developing the Cortex M firmware, first we booted only the Cortex-M (through u-boot), keeping things simple. Only later we enabled Linux to boot, and a lot of things broke, but we knew that the firmware was good, so we knew the issues were mostly device tree configuration.

SDK_ISR_EXIT_BARRIER

This macro is used at the end of interrupt handlers due to ARM’s errata 838869.
NXP documentation explains it:

ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt.
For Cortex-M7, if core speed much faster than peripheral register write speed,
the peripheral interrupt flags may be still set after exiting ISR, this results to
the same error similar with errata 83869.
2 Likes

Thank you so much!
This is very helpful and also extremely appreciated

Hi @fennecdjay!

Were you able to test it?

Best regards.
Lucas Azeituno