Multiple GPIO interrupts from SYSTEM_SOFT_OFF

OK, so it seems if you accidently hit "VERIFY ANSWER" your discussion gets locked and you can no longer comment, nor reverse that process.  So, I've had to start a new discussion in order to keep on with the old one:

https://devzone.nordicsemi.com/f/nordic-q-a/88286/multiple-gpio-interrupts-from-system_soft_off

What I wanted to say, rather than verify the answer, was:

Hi Simon,

Firstly, I seem to have accidently set your reply to "verified answer" and I can't seem to work out how to reverse that.

Anyway, I'm actually using the nRF Connect SDK (V1.9.1) and Zephyr, and may be 'cross-pollinating" by using those API's.  But I did ask on here if they were the only ones to use and didn't ever get an answer, so have just made them work for the moment.

What I'm seeing I don't think will benefit from button debounce, but I may be wrong.  What seems to be happening is that the first button press will trigger the device out of SYSTEM_OFF mode, and then my code starts running.  But any subsequent button press seems to interrupt the code that is being run and boot the device out of SYSTEM_OFF mode, even though I don't think it is actually in that mode.  This then seems to scramble all the registers I am using to determine how/why it came out of SYSTEM_OFF, and then I can't get it to do what it is supposed to do.

What I want to be able to do is the moment any GPIO triggers an exit from SYSTEM_OFF, that I disable this function so that any subsequent button presses will have no impact.  Essentially a bit like disabling interrupts whilst you service an exisiting interrupt.

But I can't find anywhere online where the functionality to achieve this is described.

I'd be happy to go with a low power mode rather than SYSTEM_OFF if it makes achieving what I want easier.  I can probably deal with quiescent currents of < 5uA.  Its just I couldn't actually find any helpful Zephyr/nRF Connect SDK low power examples, and everyone I have asked seems to look at me blankly.

I had a quick look at the example you listed in the original post.  Can't immediately understand much of it, but I'll go and have a more detailed look.  Also, not sure how relevant it is given I'm not using the nRF5 SDK

Cheers,

Mike

Parents
  • Hi MIke

    We already have a good discussion on how to implement debouncing to GPIOs in your application in this thread that should be helpful. There is a "verified answer" with a code snippet shoing how/where you can add the debounce. As for the multiple button issue. Does just any button in your design wake the device from System OFF mode, and is that why you need the debounce on multiple buttons?

    As for your confusion between the GPIO functions in your previous answer I'm not sure how to explain it better than the descriptions of the functions themselves.

    nrf_gpio_cfg_input: "Function for configuring the given GPIO pin number as input, hiding inner details. This function can be used to configure a pin as simple input."

    gpio_pin_configure_dt: "Configure a single pin from a @p gpio_dt_spec and some extra flags. This is equivalent to: gpio_pin_configure(spec->port, spec->pin, spec->dt_flags | extra_flags);
    Best regards,
    Simon
  • Hi Simon,

    Thanks for the link.  Seems pretty straight forward.

    I still think there is something else going on.  To test this, I put a simple 1 sec delay (using kmsleep() ) at the very start of my code, and then a similar 1 second delay just prior to my code going back into System OFF.

    This is the behaviour I see:

    Press one of the buttons to bring it out of System OFF mode - it will succesfully detect that a GPIO caused the exit (as indicated by RESETREAS), and will successfully detect which button was pressed (via LATCH).  It will then go back into System OFF mode

    Press one of the buttons to bring it out of System OFF mode, then within 0.5 sec (effectively whilst its still in its waiting mode), press the same button a second time - it will successfully detect that a GPIO caused the exit (as indicated by RESETEREAS) but it no longer is able to detect what button was pressed (via LATCH).  The result for LATCH = 0 in this case, which means I've got a scenario where my code has detected a GPIO has caused the exit from System OFF, but it can't tell which button has caused it.  In this scenario, my code then just goes back into System OFF, and doesn't update any of my counters.

    I'm using buttons in my testing, but ultimately the GPIO's will be triggered via an external signal.  I will have three GPIO's, corresponding to a "Small", "Medium" or "Large" level on the external signal.  These signals are very transient (will only be present for a few tens of milliseconds) and with the behaviour I am seeing at the moment, if I get two external signals within a short period of time, rather than detecting the first and ignoring any subsequent ones (what I would prefer) its essentially not correctly detecting any of them.  And that's what I'm trying to sort out.

    In my limited understanding, I think its something to do with the way the DETECT signal works.  And I've been trying to disable the GPIO from impacting the DETECT signal at the start of my code, via a call to:

    nrf_gpio_cfg_sense_input(pin, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE);

    But this isn't achieving what I want, so perhaps there is another way?

    So, what I want to be able to do the moment my code exits System OFF is:

    1. Check the value of RESETREAS

    2. Check the value of LATCH

    3. Disable any GPIO from triggering anything

    4. Process my counters based on the values of RESETREAS and LATCH

    5. Re-enable GPIO's to allow exit from System OFF

    6. Enter System OFF

    Its step 3 that I seem to be unable to achieve

    Cheers,

    Mike

Reply
  • Hi Simon,

    Thanks for the link.  Seems pretty straight forward.

    I still think there is something else going on.  To test this, I put a simple 1 sec delay (using kmsleep() ) at the very start of my code, and then a similar 1 second delay just prior to my code going back into System OFF.

    This is the behaviour I see:

    Press one of the buttons to bring it out of System OFF mode - it will succesfully detect that a GPIO caused the exit (as indicated by RESETREAS), and will successfully detect which button was pressed (via LATCH).  It will then go back into System OFF mode

    Press one of the buttons to bring it out of System OFF mode, then within 0.5 sec (effectively whilst its still in its waiting mode), press the same button a second time - it will successfully detect that a GPIO caused the exit (as indicated by RESETEREAS) but it no longer is able to detect what button was pressed (via LATCH).  The result for LATCH = 0 in this case, which means I've got a scenario where my code has detected a GPIO has caused the exit from System OFF, but it can't tell which button has caused it.  In this scenario, my code then just goes back into System OFF, and doesn't update any of my counters.

    I'm using buttons in my testing, but ultimately the GPIO's will be triggered via an external signal.  I will have three GPIO's, corresponding to a "Small", "Medium" or "Large" level on the external signal.  These signals are very transient (will only be present for a few tens of milliseconds) and with the behaviour I am seeing at the moment, if I get two external signals within a short period of time, rather than detecting the first and ignoring any subsequent ones (what I would prefer) its essentially not correctly detecting any of them.  And that's what I'm trying to sort out.

    In my limited understanding, I think its something to do with the way the DETECT signal works.  And I've been trying to disable the GPIO from impacting the DETECT signal at the start of my code, via a call to:

    nrf_gpio_cfg_sense_input(pin, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE);

    But this isn't achieving what I want, so perhaps there is another way?

    So, what I want to be able to do the moment my code exits System OFF is:

    1. Check the value of RESETREAS

    2. Check the value of LATCH

    3. Disable any GPIO from triggering anything

    4. Process my counters based on the values of RESETREAS and LATCH

    5. Re-enable GPIO's to allow exit from System OFF

    6. Enter System OFF

    Its step 3 that I seem to be unable to achieve

    Cheers,

    Mike

Children
Related