Interrupt routine not working as intended. Did I do setup wrong?

Hello. I have a custom board with a digital sensor that gives a data-packet once every 8 seconds approximately. I have set up my code to enter an interrupt when a positive flank is received from the sensor. After the datapacket has been read, the receiving GPIO is first set to low output for 0.5 seconds and then set to high impedance input. After that I want the NRF to wait for the next positive flank on this GPIO from the sensor.

This seems to work for the most part. But sometimes, seemingly random, the NRF doesn't react on the received positive flank, and the NRF stays in the background-while loop. In the picture below I have measured on the GPIO which receives the data packet. On the left there is a data-packet which the ISR reacted on correctly. But for the next positive flank, the NRF did nothing. I suspect there is something wrong with my interrupt setup.

Below you can check my setup code for the interrupt. Is there anything you can see that is wrong or missing?

void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{

    
    nrf_drv_gpiote_in_event_disable(PIN_IN);

    nrf_drv_gpiote_in_uninit(PIN_IN);

    readlowpowerpyro(); // Read data packet from sensor
 
    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
    in_config.pull = NRF_GPIO_PIN_NOPULL;

    ret_code_t err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(PIN_IN, true);
    

  //  __WFE();
  //  __SEV();
  // __WFE();

}

static void gpio_init(void)
{
    ret_code_t err_code;

    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
    in_config.pull = NRF_GPIO_PIN_NOPULL;

    err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(PIN_IN, true);
}

Here is the code for setting the GPIO to low output for 0.5 seconds and then to high impedance, making it ready to receive the next datapacket.

  nrf_gpio_pin_clear(PIN_IN);
  nrf_gpio_cfg_output(PIN_IN);
  nrf_delay_us(500);
  nrf_gpio_cfg_input(PIN_IN,NRF_GPIO_PIN_NOPULL);

Parents
  • Hi,

    I'm not sure I follow correctly the flow of your application. Could you include the full main.c file for better understanding?

    Do you use the same pin for interrupt and for reading the datapacket, and for outputting a signal?

    Are you testing this with a minimal application, without any other peripherals running, or could there be some other interrupt handling preventing/delaying the handling of the pin interrupt?

    if(PIN_IN) will always be true, since this is the pin number (which is higher than zero). If your intention was to read the pin state, you need to use the nrf_drv_gpiote_in_is_set() API or similar GPIO HAL function.

    Best regards,
    Jørgen

  • Can you read out the values of the GPIO and GPIOTE peripheral registers when this issue occurs?

    When this happens, are you stuck in the state where the interrupt does not happen if a new pulse is generated on the input, or will the issue resort itself after some time?

    I could not see any obvious issues in the code (apart from the unnecessary call to nrf_drv_gpiote_init() inside if(nrf_gpio_pin_read(PIN_IN)) where the return code is not checked, but since this is not part of your original code, I do not expect this to be an issue).

  • When it happens I am stuck in this state until i have performed "nrf_drv_gpiote_in_uninit(PIN_IN);" inside of the while-loop. If I dont do "nrf_drv_gpiote_in_uninit(PIN_IN);" then the GPIO stays high forever since the positive flank (from the sensor) has set the GPIO high, and the GPIO is stuck in its "high Z state". 

    I cant see the GPIO registers during debug for some reason. Here are the GPIOTE registers:

Reply Children
Related