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

GPREGRET clears on sd_nvic_SystemReset()

I'm developing on the nRF52840, SDK15, and s140 v6.0. I'm trying to use the sd_power_gpregret_set() function to write a value that would then be read after reset to start the BLE dfu bootloader. The example bootloader is already set up to run this way but my issue is that the GPREGRET clears after a sd_nvic_SystemReset(). If I call the sd_power_system_off() and wake from that (which I believe also performs a reset) the GPREGRET value persists.

Should the GPREGRET persist after a NVIC_SystemReset()?

Parents
  • Hi Ryan, 

    The GPREGRET registers should persist through both Soft resets(NVIC_SystemReset) and Wakeup from System OFF mode resets, see Retained registers in the nRF52840 Product Specification. 

    We use the method in our bootloader example, i.e. this code is run in the app

    uint32_t ble_dfu_buttonless_bootloader_start_finalize(void)
    {
        uint32_t err_code;
    
        NRF_LOG_DEBUG("In ble_dfu_buttonless_bootloader_start_finalize\r\n");
    
        err_code = sd_power_gpregret_clr(0, 0xffffffff);
        VERIFY_SUCCESS(err_code);
    
        err_code = sd_power_gpregret_set(0, BOOTLOADER_DFU_START);
        VERIFY_SUCCESS(err_code);
    
        // Indicate that the Secure DFU bootloader will be entered
        m_dfu.evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER);
    
        // Signal that DFU mode is to be enter to the power management module
        nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);
    
        return NRF_SUCCESS;
    }

    and this code is run in the bootloader 

     if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
           (nrf_power_gpregret_get() & BOOTLOADER_DFU_START))
        {
            NRF_LOG_DEBUG("DFU mode requested via GPREGRET.");
            return true;
        }

    Note, our bootloader implementation will clear the GPREGRET register

    static void dfu_enter_flags_clear(void)
    {
        if (NRF_BL_DFU_ENTER_METHOD_PINRESET &&
           (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk))
        {
            // Clear RESETPIN flag.
            NRF_POWER->RESETREAS |= POWER_RESETREAS_RESETPIN_Msk;
        }
    
        if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
           (nrf_power_gpregret_get() & BOOTLOADER_DFU_START))
        {
            // Clear DFU mark in GPREGRET register.
            nrf_power_gpregret_set(nrf_power_gpregret_get() & ~BOOTLOADER_DFU_START);
        }
    
        if (NRF_BL_DFU_ENTER_METHOD_BUTTONLESS &&
           (s_dfu_settings.enter_buttonless_dfu == 1))
        {
            // Clear DFU flag in flash settings.
            s_dfu_settings.enter_buttonless_dfu = 0;
            APP_ERROR_CHECK(nrf_dfu_settings_write(NULL));
        }
    }

  • I performed a flash erase and only have the soft device and application on the device. If I perform the sd_power_gpregret_set() I can read the register with nrfjprog and get the correct value. However, if I do the same sd_power_gpregret_set() then sd_nvic_SystemReset, when the application restarts I read the register and it's always 0.

Reply Children
Related