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

Any way to completely clear phantom GPIO DETECT signals & PORT interrupt?

Hi Nordic--

Our custom nRF51822 design has 13 signals routed into the app_buttons module through the GPIO -> GPIOTE->PORT -> nrf_drv_gpiote.c -> app_buttons.c path. For a yet-to-be-determined reason, one of the signals "flaps" briefly during initial power-on; that is, the state of the pin rapidly changes from high to low and back again. Because the transition happens so fast, this results in a GPIOTE PORT interrupt in which none of the 13 signals have their SENSE value changed (I have debugged this in nrf_drv_gpiote.c's GPIOTE_IrqHandler code). At the termination of the interrupt, I believe that the pin which triggered the interrupt is still asserting its DETECT signal, because if I enter system POWER OFF state, the chip immediately wakes up. Also, after the interrupt, none of the 13 signals generate any additional interrupts, which is a big problem. It seems the fact that the firmware is unable to absolutely determine which pin triggered the PORT interrupt seems to be an unfortunate limitation in the chip as discussed here and here.

My question is: given my ability to detect when the problem has occurred (GPIOTE_IrqHandler completes without changing any pin state information), and given that in our specific circumstance, the problem only happens during initial power on, is there any way to completely reset the GPIO & GPIOTE hardware blocks in such a way that any phantom DETECT signals are totally cleared out? Maybe an undocumented register that controls the power to the GPIO hardware block (analogous to NRF_GPIOTE->POWER)? This is with SDK 9/SD 110 v8, and I'm using the stock, un-modified implementation of nrf_drv_gpiote.c and app_buttons.c.

  • Actually, I think the act of writing the question helped me to come up with a solid workaround. The first few times inside GPIOTE_IrqHandler, I disable the SENSE mechanism for every pin configured to generate PORT events, then restore the configuration. This seems to clear the phantom PORT events and get everything back to working state. Here is the pseudocode corresponding to what I added at the bottom of GPIOTE_IrqHandler:

    if (++gpiote_interrupt_count > 10):
      foreach pin in the port configuration:
        orig_config[pin] = NRF_GPIO->PIN_CNF[pin] /* Save off how the pin was configured */
        NRF_GPIO->PIN_CNF[pin] = 0 /* Reset the pin configuration to initial poweron state */
    
      foreach pin in the port configuration:
        NRF_GPIO->PIN_CNF[pin] = orig_config[pin] /* Restore the pin config to the saved value */
    
Related