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
  • Thanks Simon.

    I think I may have solved my problem.  Lets just say I had a convoluted mess of various gpio configs and interrupt configs, and when I stripped everything back to the basics to test what was causing my issue, it looks like the multiple reset issue has gone away.  But I'll need to do a bit more investigations to be sure of that, using something that can operate my GPIO a bit quicker than I can!

    I think my confusion (and it still exists to an extent) is trying to understand the difference between using:

    nrf_gpio_cfg_input(pin, flags) & 
    nrf_gpio_cfg_sense_input(pin, flags)
    compared to using:
    gpio_pin_configure_dt(spec, flags)
    I think its something to do with the difference between GPIO and GPIOTE, in that I need to use the nrf_gpio API's to set up my GPIO to trigger out of System-Off mode, but then need to use the gpio_pin_configure API's to set up those GPIO if I want to read in their status whilst my code is running.  But don't quote me on that!
    Any clarification would be greatly appreciate :-)
    Cheers,
    Mike
  • Hi (again) Simon,

    OK, a little bit more paring down my code, and some late afternoon testing, and I think my issue is somehow related to this:

    Trying to put the system to System OFF while DETECT is high will cause a wakeup from System OFF reset.

    What I do in my code when it first comes out of System OFF is the following:

    reset_reason = NRF_POWER->RESETREAS;
    gpio_trigger = NRF_GPIO->LATCH;
    printk("reset_reason = %d\n", reset_reason);
    printk("gpio_trigger = %d\n", gpio_trigger);

    I then check reset_reason and gpio_trigger to determine what, principally, caused the exit from System_OFF and, in the case of it being a GPIO state change, which of my GPIO was the cause of this.  The printk statements just let me check that what my code thinks has caused the exit, is actually the case.

    What I notice is that if I only push the button the once, I will get the correct values for reset_reason and gpio_trigger.  For example, if I push the button associated with P0.13, I will get:

    reset_reason = 0x1000

    gpio_trigger = 0x2000

    However, if I push the button several times in quick succession, I will not get the correct value for gpio_trigger; this will almost always come back as zero, even though the reset_reason value is correct.

    I put a k_sleep(K_SECONDS(1)); statement just prior to going back into System_OFF, to delay things for a second and thus try and prevent the multiple button press issue.  This doesn't work reliably - if I press one button and then quickly a second one, I can get the issue described above where the gpio_trigger value comes out as zero.

    Does it look like I'm on the right track in terms of thinking the DETECT signal is what is causing the second reset (even though my code is in the middle of operating at the time of the second button press)?  And if so, is a software GPIO debounce at the very start of my code, where I just loop around until all the GPIOs have returned to their non-trigger state, the best approach to resolving it?

    Cheers,

    Mike

Reply
  • Hi (again) Simon,

    OK, a little bit more paring down my code, and some late afternoon testing, and I think my issue is somehow related to this:

    Trying to put the system to System OFF while DETECT is high will cause a wakeup from System OFF reset.

    What I do in my code when it first comes out of System OFF is the following:

    reset_reason = NRF_POWER->RESETREAS;
    gpio_trigger = NRF_GPIO->LATCH;
    printk("reset_reason = %d\n", reset_reason);
    printk("gpio_trigger = %d\n", gpio_trigger);

    I then check reset_reason and gpio_trigger to determine what, principally, caused the exit from System_OFF and, in the case of it being a GPIO state change, which of my GPIO was the cause of this.  The printk statements just let me check that what my code thinks has caused the exit, is actually the case.

    What I notice is that if I only push the button the once, I will get the correct values for reset_reason and gpio_trigger.  For example, if I push the button associated with P0.13, I will get:

    reset_reason = 0x1000

    gpio_trigger = 0x2000

    However, if I push the button several times in quick succession, I will not get the correct value for gpio_trigger; this will almost always come back as zero, even though the reset_reason value is correct.

    I put a k_sleep(K_SECONDS(1)); statement just prior to going back into System_OFF, to delay things for a second and thus try and prevent the multiple button press issue.  This doesn't work reliably - if I press one button and then quickly a second one, I can get the issue described above where the gpio_trigger value comes out as zero.

    Does it look like I'm on the right track in terms of thinking the DETECT signal is what is causing the second reset (even though my code is in the middle of operating at the time of the second button press)?  And if so, is a software GPIO debounce at the very start of my code, where I just loop around until all the GPIOs have returned to their non-trigger state, the best approach to resolving it?

    Cheers,

    Mike

Children
No Data
Related