Can't enable more than 1 interrupt m4

When I initialize more than 1 interrupt in the same gpio bank it does deinitialize the ones configured before.

As a temporary fix I added this quick fix. Could someone check if they have this problem too and if there is maybe another way to fix it?

hello @andriscewo

Could you provide the version of the hardware and software of your module?

Regarding your issue, could you explain better what you are trying to do? Are you configuring the one interrupt on rising and the other one on falling edge?

Best regards, Jaski

hello @jaski.tx

I added the hardware version. As for the software I use the newest version you provided.

Sorry, it was a bit unclear what I do from the description. It’s not the initialization that causes problems but the enabling of the interrupt. I try to enable more than 1 pin as interrupt with GPIO_SetPinIntMode in the same bank and the same interrupt handler (for example pin 4 and pin 16 from GPIO bank 2).

hello @andriscewo

Looking at the original code from NXP this should work. Your quick fix is overwriting the old values, thus you cannot activate two pins from same bank.

Could you tell what happens exactly when you enable interrupt on pin 4 and pin 16 from GPIO bank 2? Maybe you could also share a sample code, so we could reproduce this issue on our side easily?

hello @jaski.tx

Yes, it should work, but it does not.

Yes, my quick fix overwrites the old values but consistently synchronized with all calls to GPIO_SetPinIntMode (it’s a function static variable). As long as one only writes to the register over this function it’s fine.

When I enable the interrupt on pin 4 and afterwards the interrupt on pin 16 I won’t get an interrupt anymore from pin 4.

This is strange. Could you check if you change the order of interrupt enabling, you get the similar behaviour? Can you assure that those pins are only accessed by M4 and not also by A7.

Additionally can you read back the register GPIO_IMR_REG over UART to be sure that the values are set correctly?
Are you debugging over JTAG?

Yes, it is very strange. That is why I asked if you can reproduce the error.

I changed the order multiple times. I get the same behavior. The pins are not used by the m4. I disabled the gpio2 bank and all belonging pins. Also it works with the quick fix.

I did read back the value of the GPIO_IMR_REG. After setting it I see the value, but before writing to it it is always 0. That is why I did this quick fix to remember the state in the function itself.

Hi @andriscewo

Can you check if the problem also happens if you don’t start Linux? It cloud be that Linux overwrites the values.

Wat do you mean with the pins are not used by the M4? Do you mean they are not used by the A7, because if they are not used by the M4 why do you try to configure an interrupt?

I’ve patched the hello_world as shown in this patch, the second set does not overwrite the first one. Can you provide us some code, so that we can test your specific problem?

Regards,
Stefan

Hi @stefan_e.tx

Problem is independent of linux and yes, that should have been A7 not M4, but I localized the issue now. Your example worked fine so I tried to add stuff to your example like GPIO_Init and reduced my example as much as possible. Thought I would go nuts, but finally found the problem. GPIO_Init resets the whole GPIO_IMR_REG. As I implemented a function that does all the initialization for interrupts with GPIO_Init and GPIO_SetPinIntMode the described problem will happen. Anyway, I Should probably use a debugger for such problems.

The GPIO_Init function will always reset the whole Interrupt enable register and gpio edge select. If one were to program an init_interrupt function that will call GPIO_Init and GPIO_SetPinIntMode then it will always overwrite previously enabled interrupts. The behavior can be a matter of taste, but I don’t like it this way because of the described complication.

Recommended patch

-    /* Register reset to default value */
-    GPIO_IMR_REG(base) = 0;
-	GPIO_EDGE_SEL_REG(base) = 0;
-
     /* Get pin number */
     pin = initConfig->pin;
 
+    /* Reset pin to default value */
+    GPIO_IMR_REG(base) &= ~(1U << pin);
+    GPIO_EDGE_SEL_REG(base) &= ~(1U << pin);

Perfect, thanks a lot for your answer!

Regards,
Stefan