Configuring Interrupt falling edge not triggering the handler

Product: custom board on nRF52840
    aliases {   // MUTHU: This also working
        ex10irq = &ex10_irq_n;
    };
    gpio_keys  {
            compatible = "gpio-keys";
            ex10_irq_n:ex10_irq_n {
                gpios = <&gpio1 15 (GPIO_ACTIVE_LOW)>;
                label = "ex10 irq";
                status = "okay";
            };
};
#define EX10_IRQ_NODE DT_ALIAS(ex10irq)
#if !DT_NODE_HAS_STATUS(EX10_IRQ_NODE, okay)
#error "Unsupported board: ex10_irq_n node in the devicetree is not defined"
#define EX10_IRQ_GPIO_LABEL ""
#define EX10_IRQ_GPIO_PIN   0
#define EX10_IRQ_GPIO_FLAGS 0
#else
#define EX10_IRQ_GPIO_LABEL DT_GPIO_LABEL(EX10_IRQ_NODE, gpios)
#define EX10_IRQ_GPIO_PIN   DT_GPIO_PIN(EX10_IRQ_NODE, gpios)
#define EX10_IRQ_GPIO_FLAGS (DT_GPIO_FLAGS(EX10_IRQ_NODE, gpios))
#endif
static const struct gpio_dt_spec ex10_irq_st = GPIO_DT_SPEC_GET_OR(EX10_IRQ_NODE, gpios,{0});
static struct gpio_callback ex10_irq_cb;


    ret = gpio_pin_configure_dt(&ex10_irq_st, GPIO_INPUT);
    if (ret != 0) {
        printk("Error %d: failed to configure %s pin %d\n",
               ret, ex10_irq_st.port->name, ex10_irq_st.pin);
        return;
    }
    ret = gpio_pin_interrupt_configure_dt(&ex10_irq_st, GPIO_INT_EDGE_FALLING);
     if (ret != 0) {
      printk("Error %d: failed to configure %s pin %d\n",
             ret, ex10_irq_st.port->name, ex10_irq_st.pin);
      return;
     }
    gpio_init_callback(&ex10_irq_cb, interrupt_handler, BIT(ex10_irq_st.pin));
    gpio_add_callback(ex10_irq_st.port, &ex10_irq_cb);
static void interrupt_handler(void)
{
}
Here the interrupt handler is not get called even after the lines (GPIO 1 15) goes from high to low. (Duration of high state is 50ms). It is not detecting falling edge.
I tried feeding lot of pulse from the other GPIO, after 3 to 4 toggles, the handler called finally.
Did i missed something, appreciate the response!
And Is it ok to use 
static void interrupt_handler(void) 
instead of 
void interrupt_handler(const struct device *dev, struct gpio_callback *cb,
            uint32_t pins)
Thanks,
MUTHUKUMAR V
  • Hi Muthukumar,

    Thank you for contacting DevZone at NordicSemi.

    Would you please send me the zip file of your minimal project (including overlays, configurations and main) so that I may flash on the DK and see the issue.

    Thanks.

    Naeem

  • Thanks for your reply!

    I can see it is getting called every time. I will keep you posted with details, if I observed this issue again.

    Added to that, How to enable and disable the interrupt from the code?

    After the initialization with the below steps.

        ret = gpio_pin_configure_dt(&ex10_irq_st, GPIO_INPUT);
        if (ret != 0) {
            printk("Error %d: failed to configure %s pin %d\n",
                   ret, ex10_irq_st.port->name, ex10_irq_st.pin);
            return;
        }
        ret = gpio_pin_interrupt_configure_dt(&ex10_irq_st, GPIO_INT_EDGE_FALLING);
         if (ret != 0) {
          printk("Error %d: failed to configure %s pin %d\n",
                 ret, ex10_irq_st.port->name, ex10_irq_st.pin);
          return;
         }
        gpio_init_callback(&ex10_irq_cb, interrupt_handler, BIT(ex10_irq_st.pin));
        gpio_add_callback(ex10_irq_st.port, &ex10_irq_cb);

    I middle of our implementation, i need to enable and disable lot many times.

    I can use the below API for enable and disable and it is safe to use in middle of the implementation?

    gpio_pin_interrupt_configure_dt(&ex10_irq_st, GPIO_INT_EDGE_FALLING); // enable
    gpio_pin_interrupt_configure_dt(&ex10_irq_st, GPIO_INT_DISABLE); // disable
    or do we have any other means to enable/disable the interrupt?
    I noticed irq_enable(irq number) as well in the documentation. if it ok to use, how can we get IRQ number from the above initialization? because we haven't provided the custom IRQ number during initialization.
    Thanks,
    MUTHUKUMAR V
  • Hi Muthukumar,

    Good to know that your project is working.

    As you have configured the pin, interrupt, and connected the callbacks. In the code, you can disable the interrupt by using instructions like:

    //Disabling the interrupt
    ret = gpio_pin_interrupt_configure_dt(&ex10_irq_st, GPIO_INT_DISABLE);
    //Checking if disabled or not
    if (ret != 0) {
        printk("Error %d: failed to DISABLE interrupt on %s pin %d\n",ret, button.port->name, button.pin);
        return;
    }
    printk("\r\nINT Disabled\n");


    Regarding usage of irq_enable(irqn) and irq_disable(irqn) macros as defined in the Zephyr ISR APIs: 
    they require irqn, that is irq line number. You can obtain this irqn using DT_IRQN(nid) macro which takes node id and returns the irq number of that node. Use can use DT_NODELABEL(nlabel) to get the node label of nlabel node.

    Regards,

    Naeem

Related