This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Configure GPIO Interrupt on nRF9160

Hi all,

I am interfacing with a CAN Controller (MCP25625) that sets an Interrupt pin when data is ready (active low). That pin is then connected to a GPIO on the nRF9160. I want to configure an interrupt on the nRF9160 that calls a SPI read function when the corresponding pin on the nRF9160 goes low. It looks like there's a few ways I can do this, but I want to make sure I am on the right track.

1. I am seeing examples that use a gpio_callback struct and function to act as the interrupt handler, is that correct?

2. I see another function called gpio_pin_interrupt_configure that looks to configure a GPIO for an interrupt.

My questions are:

Are ways 1 and 2 the same way to do this, or does 2 also require a callback?

I am still getting used to Zephyr, which handles the interrupts, but on other ARM devices I would normally create an interrupt service routine where the NVIC is configured. Is this how it is done with Zephyr as well? If so, where can I find these startup files that have all the IRQs for Zephyr?

All I really want to do is configure the GPIO pin for falling edge, and make an ISR that performs a SPI read when this interrupt is triggered. Since I'm not using a button or anything, what would be the first argument to gpio_pin_interrupt_configure()? The docs say it's a struct device *port, but what device am I binding when I create this struct if it's just Pin 5 on the nRF?

Thanks for the assistance.

Sincerely,

Kyle Garland

Parents
  • Since I've just had to go through the same discovery process, here is what works for me:

      static struct gpio_callback button_callback;
    
      gpio_pin_configure(gpio0, BUTTON, GPIO_INPUT | GPIO_ACTIVE_LOW);
      gpio_init_callback(&button_callback, button_callback_handler, BIT(BUTTON));
      gpio_add_callback(gpio0, &button_callback);
      gpio_pin_interrupt_configure(gpio0, BUTTON, GPIO_INT_EDGE_BOTH);
      
      

    And to get your gpio0:

    #define GPIO_PORT DT_LABEL(DT_NODELABEL(gpio0))
    const struct device *gpio0;
    gpio0 = device_get_binding(GPIO_PORT);
    

    Be careful with the last parameter to gpio_init_callback(), it does not take the pin number, but a bit mask. That's one hour of my life I'm not getting back.

    I am still unclear what context the callback executes in, but I suspect it's the interrupt context, because trying to sleep there promptly hangs my system. I wish this was documented.

Reply
  • Since I've just had to go through the same discovery process, here is what works for me:

      static struct gpio_callback button_callback;
    
      gpio_pin_configure(gpio0, BUTTON, GPIO_INPUT | GPIO_ACTIVE_LOW);
      gpio_init_callback(&button_callback, button_callback_handler, BIT(BUTTON));
      gpio_add_callback(gpio0, &button_callback);
      gpio_pin_interrupt_configure(gpio0, BUTTON, GPIO_INT_EDGE_BOTH);
      
      

    And to get your gpio0:

    #define GPIO_PORT DT_LABEL(DT_NODELABEL(gpio0))
    const struct device *gpio0;
    gpio0 = device_get_binding(GPIO_PORT);
    

    Be careful with the last parameter to gpio_init_callback(), it does not take the pin number, but a bit mask. That's one hour of my life I'm not getting back.

    I am still unclear what context the callback executes in, but I suspect it's the interrupt context, because trying to sleep there promptly hangs my system. I wish this was documented.

Children
Related