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

Interrupt from two input pins for the same handler

Hi everyone,

I am trying to use the Port interrupts on the nRF52840. I started from the example "pin-change-int" and it works fine when I use one input pin.

But when I try to get my callback from 2 input pins, with 2 interrupts, only one of the 2 handled. In my application I want to use the PORT interrupt, not the IN_EVENT, so using “low accuracy” mode.

I also tried with the high accuracy mode, just to see if it worked, and the management of the 2 inputs worked fine.

Also, I did set the #define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS in sdk_config.h from to 2 (or even higher).

You will find my code below, if any of you has an idea, that would be wonderful.

 

void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    nrf_drv_gpiote_out_set(GPIO_OUT_PIN);
}

static void gpio_init(void)
{
    ret_code_t  err_code;

    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(false);
    err_code = nrf_drv_gpiote_out_init(GPIO_OUT_PIN, &out_config);
    APP_ERROR_CHECK(err_code);
        
    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);

    err_code = nrf_drv_gpiote_in_init(GPIO_IN_PIN, &in_config, in_pin_handler);
    APP_ERROR_CHECK(err_code);
        
    err_code = nrf_drv_gpiote_in_init(GPIO_IN_PIN2, &in_config, in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(GPIO_IN_PIN, true);
    nrf_drv_gpiote_in_event_enable(GPIO_IN_PIN2, true);
}

Thank you

Parents
  • You need to read the IN registers to check for what pin or pins have changed state in the event handler. If both port events happen at the same time or close together they will register as one event. Only when the EVENTS_PORT has been cleared by the GPIOTE driver can it fire another interrupt. 

    If you used both Port0 and Port1 you will have to read both port's IN registers.

  • hello and thank you already for your help.


    In my application, no matter which pin is changing state, the task executed is the same.
    On the other hand, I added the EVENTS_PORT registry reset but it does not work.
    Would there be errors in the configuration of my entries?

  • haakonsh said:
    You need to read the IN registers to check for what pin or pins have changed state in the event handler. If both port events happen at the same time or close together they will register as one event. Only when the EVENTS_PORT has been cleared by the GPIOTE driver can it fire another interrupt. 

     After you've discerned what pins have changed state you need to act accordingly. 

  • I modified my "in_pin_handler" with your comments. You can find the code below

    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
        if (nrf_gpio_pin_read(GPIO_IN_PIN) == 1)
        {
          nrf_drv_gpiote_out_set(GPIO_OUT_PIN);
        }
        if (nrf_gpio_pin_read(GPIO_IN_PIN2) == 1)
        {
          nrf_drv_gpiote_out_set(GPIO_OUT_PIN);
        }
              NRF_GPIOTE->EVENTS_PORT = 0;
    }

    This doesn't work : I have just one pin interrupt - PIN2

    What is wrong in my code?

Reply
  • I modified my "in_pin_handler" with your comments. You can find the code below

    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
        if (nrf_gpio_pin_read(GPIO_IN_PIN) == 1)
        {
          nrf_drv_gpiote_out_set(GPIO_OUT_PIN);
        }
        if (nrf_gpio_pin_read(GPIO_IN_PIN2) == 1)
        {
          nrf_drv_gpiote_out_set(GPIO_OUT_PIN);
        }
              NRF_GPIOTE->EVENTS_PORT = 0;
    }

    This doesn't work : I have just one pin interrupt - PIN2

    What is wrong in my code?

Children
Related