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

Atomically changing pin SENSE so PORT interrupt isn't missed

I have an nrf52833 wired up to 25 switches and detect changes via the pin SENSE configuration triggering the GPIOTE PORT interrupt.
My interrupt handler:

1. reads the pin values and,
2. writes their complements to the PIN_CFG registers SENSE field, which should prepare the system to detect the next transition of any of the keys.

This works fine for 10--100 keypresses, but eventually the interrupt stops firing entirely.
Other aspects of the system continue to work fine (logging, bluetooth, etc.).

I believe there may be a race condition where a pin changes value between the two steps of the interrupt handler, such that the DETECT signal never goes low and so the interrupt (triggered by rising edge of DETECT) never fires again.

The best potential solution I can think of is to use the fact that:

> If the CPU performs a clear operation on a bit in the LATCH register when the associated PINx.DETECT signal is high, the bit in the LATCH register will not be cleared.

and thus I can use the LATCH register as a way to read the DETECT signal, and loop reading pins and changing sense polarity until the DETECT signal goes low and I'm thus guaranteed a future interrupt on pin change.

A few questions:

1. Is this a reasonable hypothesis?
2. Is there nicer a way to atomically "flip" a pin's sense polarity or otherwise solve the problem of detecting level changes on 25 GPIOs?

Thanks!

Parents Reply Children
  • Thanks Jonathan.

    I did attempt the latch-based solution I described in my original post, but continued to run into the problem.

    Based on Jack Ganssle's advice (http://www.ganssle.com/debouncing-pt2.htm) I ended up removing the interrupts entirely and moving to a tick-based polling approach, which resolved the issue.

    I'm still curious about why the interrupt-based approach wasn't working, so I'll study that link and see if I can create a minimum reproducible example in C that I can share here. However, since I've developed an working alternative solution for now, it may be a while before I can spend time on this question.

Related