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

DFU on one button device

Hi there,

I'm trying to get a one button nrf52832 device to behave like the following:

1. Button press short: RESET or WAKE (depending on POWER state)

2. Button press long: POWEROFF

3. Button pressed while being connected to power source: DFU

Features 2 and 3 work fine, but every time I wake the device with a button press it goes to DFU instead of running the app.

I played around with GPREGRET a bit, but it seems those registers get overwritten by the bootloader. 

This post (https://devzone.nordicsemi.com/f/nordic-q-a/33507/bootloader-deep-sleep/128954#128954) talks very briefly about "disabling the BOOTLOADER_BUTTON", but it's unclear to me how to do that, and still retain the wake functionality. 

So if somebody could shed some light on wether it's possible to get features 1-3 implemented and if yes, I'd be very thankful.

Best

  • Hi,

    This post (https://devzone.nordicsemi.com/f/nordic-q-a/33507/bootloader-deep-sleep/128954#128954) talks very briefly about "disabling the BOOTLOADER_BUTTON", but it's unclear to me how to do that, and still retain the wake functionality. 

    Do you enter system OFF from the bootloader code? The BOOTLOADER_BUTTON is not directly tied to the wake-up functionality, but it will initialize the pin to input with sense enabled, see nrf_bootloader::dfu_enter_button_init().

    sdk_config.h settings if you use SDK 15.3.0:

    // </h> 
    //==========================================================
    
    // <h> DFU mode enter method 
    
    //==========================================================
    // <e> NRF_BL_DFU_ENTER_METHOD_BUTTON - Enter DFU mode on button press.
    //==========================================================
    #ifndef NRF_BL_DFU_ENTER_METHOD_BUTTON
    #define NRF_BL_DFU_ENTER_METHOD_BUTTON 1
    #endif
    // <o> NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN  - Button for entering DFU mode.
     
    // <0=> 0 (P0.0) 
    // <1=> 1 (P0.1) 
    // <2=> 2 (P0.2) 
    // <3=> 3 (P0.3) 
    // <4=> 4 (P0.4) 
    // <5=> 5 (P0.5) 
    // <6=> 6 (P0.6) 
    // <7=> 7 (P0.7) 
    // <8=> 8 (P0.8) 
    // <9=> 9 (P0.9) 
    // <10=> 10 (P0.10) 
    // <11=> 11 (P0.11) 
    // <12=> 12 (P0.12) 
    // <13=> 13 (P0.13) 
    // <14=> 14 (P0.14) 
    // <15=> 15 (P0.15) 
    // <16=> 16 (P0.16) 
    // <17=> 17 (P0.17) 
    // <18=> 18 (P0.18) 
    // <19=> 19 (P0.19) 
    // <20=> 20 (P0.20) 
    // <21=> 21 (P0.21) 
    // <22=> 22 (P0.22) 
    // <23=> 23 (P0.23) 
    // <24=> 24 (P0.24) 
    // <25=> 25 (P0.25) 
    // <26=> 26 (P0.26) 
    // <27=> 27 (P0.27) 
    // <28=> 28 (P0.28) 
    // <29=> 29 (P0.29) 
    // <30=> 30 (P0.30) 
    // <31=> 31 (P0.31) 
    
    #ifndef NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN
    #define NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN 16
    #endif
    
    // </e>
    
    // <q> NRF_BL_DFU_ENTER_METHOD_PINRESET  - Enter DFU mode on pin reset.
     
    
    #ifndef NRF_BL_DFU_ENTER_METHOD_PINRESET
    #define NRF_BL_DFU_ENTER_METHOD_PINRESET 0
    #endif
    
    // <q> NRF_BL_DFU_ENTER_METHOD_GPREGRET  - Enter DFU mode when bit 1 (0-indexed) is set in the NRF_POWER_GPREGRET register.
     
    
    #ifndef NRF_BL_DFU_ENTER_METHOD_GPREGRET
    #define NRF_BL_DFU_ENTER_METHOD_GPREGRET 1
    #endif
    
    // <q> NRF_BL_DFU_ENTER_METHOD_BUTTONLESS  - Enter DFU mode when the Boolean enter_buttonless_dfu in DFU settings is true.
     
    
    #ifndef NRF_BL_DFU_ENTER_METHOD_BUTTONLESS
    #define NRF_BL_DFU_ENTER_METHOD_BUTTONLESS 0
    #endif
    

  • No. I power down from the app. I managed to get something working by reading RESETREAS like this:

    uint32_t reset_reason;
    reset_reason = NRF_POWER->RESETREAS;
    NRF_POWER->RESETREAS = 0x00000000;
    
    // if not power cycle
    if (reset_reason > 0) {
        nrf_bootloader_app_start();
    } else {
        err_code = nrf_bootloader_init(dfu_observer);
        APP_ERROR_CHECK(err_code);
    }

  • Hi,

    Not sure I understand why it helps to check the RESTETREAS register helps. Do you have PINRESET enabled on this pin? 

  • Well, I use the same button for entering the DFU and for waking up the device. The device should only go into DFU mode if the restart was caused by a power cycle. In order to distinguish the restart after deep sleep from a power cycle I check RESETREAS in the bootloader. 

  • I see, thanks. I suggest that you step through the dfu_enter_check() function to see where 'true' is being returned if you want to debug this further. Maybe the gpregret flag wasn't cleared? 

Related