Knowledge Base
HOME » KNOWLEDGE BASE » FORUM

External interrupts

Avatar
Could you guys help me out getting an external interrupt working? I tried using the gpio_cfg_extirq(), IRQ_PIN() and NVIC functions but all to no avail.

I suspect I need to enable something else besides just the IO pin, but I've been digging around the stack too long now trying to get it to work.
Avatar
The next release of Basic MAC will contain a platform-independent unified external interrupt service (uexti) that simplifies the dispatching of such events to different consumers.

Until then, you can define your own custom EXTI handler that will be called by the stack after it handles its own events (mainly the DIO* lines to the radio chip) and use the STM32 HAL-specific functions to configure the interrupts.

To configure a GPIO line as input and receive interrupts, initialize it as follows:

#include "lmic.h"
#include "peripherals.h"

#define GPIO_EVENT        BRD_GPIO(PORT_B, 9) // event line on PB9

// configure GPIO as input/hi-z
pio_set(GPIO_EVENT, PIO_INP_HIZ);

// configure interrupt on both rising and falling edge
gpio_cfg_extirq_ex(BRD_PORT(GPIO_EVENT), BRD_PIN(GPIO_EVENT), true, true);

// enable interrupt
gpio_set_extirq(BRD_PIN(GPIO_EVENT), true);


Then, define a global function for the custom EXTI handler in your application, let's call it my_exti_handler:

void my_exti_handler (void) {
    // read EXTI->PR to get pending interrupts
    // handle pending interrupts, if any
    // don't forget to clear the handled ones in EXTI->PR
}


Last, you need to add your handler to the build environment by adding this line to your projects' Makefile:

LMICCFG += EXTI_IRQ_HANDLER=my_exti_handler


Hope that helps!
Avatar
Thanks for your help! The entry in the makefile did the trick (I think I called the interrupt handler the wrong way previously). But we can move on now;)
Avatar
Hi! It has been a while!

I recently picked up the LoRa basic again and upon activating external interrupts again I encountered a collision with the radio irq routines.

I try to use pin A0 for external interrupts but I think it is linked to the same EXTI line as the radio. I tried shutting it off but everytime I trigger my external interrupt the radio has an irq timeout (line 50 of radio.c).

Is there a way to completely disable the radio irq's while using the other interrupt? Or check if the interrupt is caused by the radio or gpio in my own handler?

-EDIT-
I see the radio uses pin C0 (RST) and pin B0 (DIO2) which could share an EXTI line with pin A0 (the one I'm using). And I suspect the RST pin is causing the issue for me.

I do find when entering my interrupt routine the irq pending bits are empty again, meaning the radio irq routine is handled first (before my custom routine). Probably triggering the irq timeout for the radio before I can process my own handler.

-EDIT2-
I found a way to fix it but it needs an adjustment in the BASIC stack:

In hal.c, function EXTI_IRQHandler() it checks for the DIO pins from the radio and runs the radio_irq_handler when the corresponding EXTI lines have been triggered.

I added a simple check around each DIO_UPDATE functions to see if the actual pins are high before handling the interrupts:

#ifdef GPIO_DIO0
// DIO 0
if(gpio_get_pin(BRD_PORT(GPIO_DIO0), BRD_PIN(GPIO_DIO0))){
DIO_UPDATE(0, &diomask;, &now;);
}
#endif

After the DIO checks the function enters the custom IRQ handler and will process my interrupt of pin A0 (which shares an EXTI line with DIO2 in my case).

From my end it would be a recommendation to add into the BASIC stack as I can't change my hardware. Do I need to file an issue in the repository or will this be picked up from here?

Thanks!