GPIOs Interruption IMX8MM SDK Cortex M4

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

GPIOs Interruption IMX8MM SDK Cortex M4

GPIOs Interruption IMX8MM SDK Cortex M4

In the IMX8MM SDK unfortunately we cannot find any example about of use a GPIO as an input with interrupt. 

To use a GPIO as input with interrupt we need to keep in mind how the GPIO IRQs works in the ARM Cortex M4.  

We can find in Table 7-2 (CM4 Interrupt Summary) of IMX8MMRM (IMX8MM Reference Manual) the GPIOs IRQs are divided by two parts:  

 

  • Combined interrupt indication for GPIOn signal 0 throughout 15 
  • Combined interrupt indication for GPIOn signal 16 throughout 31 

 

This basically means, the pines of GPIOn from 0 to 15 are handled by Combined interrupt indication for GPIOn signal 0 throughout 15 and the pines from 16 to 31 are handled by Combined interrupt indication for GPIOn signal 16 throughout 31. 

Alejandro_Salas_0-1706127701440.png

 

In SDK we can find these definitions in: 

<SDK root>/devices/MIMX8MM6/MIMX8MM6_cm4.h (Remember this is for IM8MM SDK) 

Alejandro_Salas_1-1706127740049.png

 

In this example I will use GPIO5_IO12 (ECSPI2_MISO) as Input with IRQ and GPIO5_IO11 (ECSPI_MOSI) as Output of IMX8MM-EVK. I will connect the Output to the Input and will see the behavior of the IRQ in Rising and Falling edge. 

Alejandro_Salas_2-1706127787773.pngAlejandro_Salas_3-1706127804093.png

 

For this example I will connect ECSPI2_MOSI (GPIO5_IO11) to ECSPI_MISO (GPIO5_IO12):  

Alejandro_Salas_4-1706127830066.png

See the below definitions:

Alejandro_Salas_5-1706127847121.png

 

#define IN_GPIO  

GPIO5 

This define the GPIO base of the IN pin 

#define IN_GPIO_PIN 

12u 

This define the pin number (for in) 

#define IN_IRQ 

GPIO5_Combined_0_15_IRQn 

This define the IRQ number (72 in this case) 

#define GPIO_IRQ_HANDLER 

GPIO5_Combined_0_15_IRQHandler 

This is a "pointer" to function that will handle the interrupt 

#define IN_NAME 

"IN GPIO5_IO12" 

This is only a name or description for the pin 

 

See below definitions: 

Alejandro_Salas_6-1706128301737.png

 

#define OUT_GPIO 

GPIO5 

This is the GPIO base of OUT pin 

#define OUT_GPIO_PIN 

11u 

This define the pin number (for out) 

#define OUT_NAME 

"OUT GPIO5_IO11" 

This is only a name or description for the pin 

 

 

Now the below section is the IRQ handler (which was defined before)

Alejandro_Salas_8-1706128362819.png

 

The GPIO_ClearPinsInterruptFlags(IN_GPIO, 1u << IN_GPIO_PIN); refers to GPIOx_ISR register: 
 
Alejandro_Salas_9-1706128379494.pngAlejandro_Salas_10-1706128389932.png

 

For this example, the IRQ Handler will print "IRQ detected ............" in each interrupt. 

 

We will create two different GPIOs config, one for Output and other one for Input with IRQ Falling edge: 

Alejandro_Salas_11-1706128421672.png

 

Then configure the GPIOs and IRQ:  

Alejandro_Salas_12-1706128434880.png

 

EnableIRQ refers to enable the 72 IRQ.  

GPIO_PortEnableInterrupts refers to GPIOx_IMR:

Alejandro_Salas_13-1706128465396.png

Finally, the example put the out GPIO5_IO11 in High state and then in low state many. First the IRQ is configured as Falling edge, then as Rising edge. 

Alejandro_Salas_14-1706128482221.png

 

 I will attach the complete source file. 

 

To compile it you can use ARMGCC toolchain directly, but I like to use VSCode with MCUXpresso integration. 

Once, when you have your .bin file (in my case igpio_led_output.bin) you can load to board with UUU tool:

In your Linux machine:

sudo uuu -b fat_write igpio_led_output.bin mmc 2:1 gpio.bin

In U-boot board:

u-boot=> fastboot 0

 

Then, when the .bin file was loaded, you can load to the CORTEX M4 in U-boot whit:

u-boot=> fatload mmc 2:1 ${loadaddr} gpio.bin
7076 bytes read in 14 ms (493.2 KiB/s)
u-boot=> cp.b 0x80000000 0x7e0000 0x10000
u-boot=> bootaux 0x7e0000
## No elf image ar address 0x007e0000
## Starting auxiliary core stack = 0x20020000, pc = 0x1FFE02CD...
u-boot=>

 

NOTE: You can load the binary to cortex m4 with Custom bootscripts for practicity.

 

Once the binary loaded in M4 core you should see in seria terminal this logs (Remember GPIO5_IO11 and GPIO5_IO12 must be connected to get the same logs): 

Alejandro_Salas_15-1706128516905.png

 

And the logs when you disconnect the GPIO5_IO11 and GPIO5_IO12 in execution time: 

Alejandro_Salas_16-1706128531282.png

Disconnection (Red color)

Reconnection (Blue color)

 

I hope this can helps. 

  

Best regards! 

 

Salas. 

Attachments
Comments

Thank you for this article.  I am doing a similar task and I got the interrupt working at the u-boot stage.

However I observed that, when the linux kernel is started, the initial interrupt setting for the cortex M4 is overwritten and the interrupt functionality of the GPIO pin is no longer possible.

Have you also observed this?  I observed that in your example, you did not proceed to start the linux kernel.  Is there a reason for this?

I have checked the entire kernel to see why this behaviour but I could not find any.  

What is the solution to this.

Thanks.

Hello @ababatola 

This behavior is because Linux is handling the peripheral, in this case, with this application you need to disable the gpio5 in device tree, then you will be able to handle the entire gpio5 and interrupts from cortex M.

 

Best regards,

Salas. 

Thanks.

No ratings
Version history
Last update:
‎01-24-2024 02:02 PM
Updated by: