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

DFU with sd_power_system_off

Is it possible for an app after having gone to sd_power_system_off to reset by button without triggering DFU?

The app seems to need CONFIG_GPIO_AS_PINRESET to be set so that button p0.21 can get the app to advertise again, but when DFU is loaded, the advertise becomes DfuTarg. I was looking at invoking DfuTarg only when button p0.21 is pressed as power is being applied.

For DFU I tried enter_method_button 1 with enter_method_button_pin 21 (the app after system_off, button pressed goes to DfuTarg) , and separately enter_method_pinreset 0 (the app after system_off, no response with button pressed, but advertises app after power toggle but then no DFU).

-thank-you.

  • Hi,

    You can check the RESETREAS register in the dfu_enter_check() function in the bootloader to see if the reset was caused by pin reset or power on reset. Note that you have to use sd_power_reset_reason_get() and sd_power_reset_reason_clr() instead of accessing the registers directly if you are using the SoftDevice (as is the case for the BLE bootloader). The RESETREAS value will be all 0 (0x00000000) if a power on reset occurred.

  • An available example would better help to understand if there is one.

    -thank-you

  • Hi,

    The following diff is for SDK 15 and demonstrates how it can be done. Please note that I have not tested it.

    diff --git a/components/libraries/bootloader/nrf_bootloader.c b/components/libraries/bootloader/nrf_bootloader.c
    index 3e62e47..d209ebf 100644
    --- a/components/libraries/bootloader/nrf_bootloader.c
    +++ b/components/libraries/bootloader/nrf_bootloader.c
    @@ -58,6 +58,7 @@
     #include "nrf_bootloader_dfu_timers.h"
     #include "app_scheduler.h"
     #include "app_timer.h"
    +#include "nrf_soc.h"
     
     static nrf_dfu_observer_t m_user_observer; //<! Observer callback set by the user.
     
    @@ -272,8 +273,18 @@ static bool dfu_enter_check(void)
         if (NRF_BL_DFU_ENTER_METHOD_BUTTON &&
            (nrf_gpio_pin_read(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN) == 0))
         {
    -        NRF_LOG_DEBUG("DFU mode requested via button.");
    -        return true;
    +        uint32_t reset_reason;
    +        sd_power_reset_reason_get(&reset_reason);
    +        sd_power_reset_reason_clr(~0);
    +        if (reset_reason > 0)
    +        {
    +            NRF_LOG_DEBUG("Ignoring DFU button as device is not power cycled.");
    +        }
    +        else
    +        {
    +            NRF_LOG_DEBUG("DFU mode requested via button after power on reset.");
    +            return true;
    +        }
         }
     
         if (NRF_BL_DFU_ENTER_METHOD_PINRESET &&
    

     

  • By all accounts this should be working. The button on the custom is a tactile between p0.21 and GND. After flashing the bootloader and selecting FW, I toggle the power which makes reset_reason = 0. The FW is now advertising and by pressing the button, DfuTarg should now be advertising. But FW is still advertising. Maybe not understanding the sequence correctly.

  • There was a bug in the snippet, as I forgot to clear the RESETREAS register. I have updated the previous post so that it is cleared. Does it work with that update?

Related