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

System hangs switching from Application to Bootloader

I've implemented a Application and Bootloader.  I have the Bootloader set to Buttonless.  However when I try to transition from the Application to Bootloader via:

/* Sets Flags for DFU Triggering */
uint8_t reg_val = nrf_power_gpregret_get();
reg_val = reg_val | 0xB1; /* Set bit 1 to triger DFU */
nrf_power_gpregret_set(reg_val);

/* Reset Device */
sd_nvic_SystemReset();

The system simply seems to hang.  On Power reset, it reverts back to the Application.  If I program the SD and bootloader I can successfully upload an Application image.  However when I tried to trigger a DFU again from the App, it again hangs after the reset.  I can't see what I've done wrong.  Here are my linker file settings:

Application:

MEMORY
{
FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x2ED08
RAM (rwx) : ORIGIN = 0x200059b8, LENGTH = 0xa648
CUSTOM_MEM (rx) : ORIGIN = 0x55000, LENGTH = 0x0C300
}

Bootloader

MEMORY
{
FLASH (rx) : ORIGIN = 0x78000, LENGTH = 0x6000
RAM (rwx) : ORIGIN = 0x200057b8, LENGTH = 0xa848
mbr_params_page (r) : ORIGIN = 0x0007E000, LENGTH = 0x1000
bootloader_settings_page (r) : ORIGIN = 0x0007F000, LENGTH = 0x1000
dfu(r) : ORIGIN = 0x10001018, LENGTH = 0x4
uicr_bootloader_start_address (r) : ORIGIN = 0x10001014, LENGTH = 0x4
}

As you may note I can set aside a section of Flash in the Application for some custom code I use to program external IC's.  I'm using SD 132 v 6.1.1

  • Glad to hear that you found the issue! 

    Just one comment regarding the delay after you set the gpregret register. Perhaps it is even safer to use a while() to check the register:

    uint8_t reg_val = nrf_power_gpregret_get();
    reg_val = reg_val | 0xB1; /* Set bit 1 to trigger DFU */
    nrf_power_gpregret_set(reg_val);
    
    reg_val = 0x00; /* reset test value */
    while ((reg_val & 0xB1) != 0xB1)
    {
        reg_val = nrf_power_gpregret_get();
    }
    NVIC_Systemreset();

    The point of the delay is to not reset until the register is properly written, so reading the register until it is correct would give the accurate delay.

Related