nrf52810 Not jumping Bootloader from BLE Application

Hi,

Chip : NRF52810

Soft Device : s132_nrf52_5.1.0

SDK : nrf5_sdk_for_thread_and_zigbee_v4.2.0_af27f76 (BLE BootLoader) 

IDE : Segger Embedded Studio

SDK : nRF5_SDK_14.2.0_17b948a (BLE Application) 

IDE : IAR Embedded Workbench

in BLE Application i am trying to reboot and enter to bootloader for serial DFU. 

i have checked in nrf devzone and did some changed as suggested but still it reboot and enter to BLE Application.  

BLE application main.c has been added following codes to set start bootloader 

 sd_power_gpregret_set(1,BOOTLOADER_DFU_START);     // to enable dfu_check true

nrf_nvmc_write_word(0x00022000, (uint32_t) dfu_flag);   // to enable dfu_check true

nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);     //

NVIC_SystemReset();.   //reboot to jump to bootloader

in Application sdkconfig did following changes.

#define BLE_DFU_ENABLED 1

#define NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS 1

#define NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY 1

#define NRF_SDH_BLE_VS_UUID_COUNT 2

#define NRF_SDH_BLE_SERVICE_CHANGED 1

#define NRF_SDH_BLE_SERVICE_CHANGED 1

From bootloader dfu_enter_check() nrf_power_gpregret_get() but it never returns true.

also tries to read nvic memory to read flag to make dfu_enter_check true.

uint32_t DFU_Flag_data  = 0;

uint32_t* dfu_flag_mem2 = (uint32_t*) 0x00022000;
DFU_Flag_data = (uint32_t)*dfu_flag_mem2 ;

if(DFU_Flag_data  != 0xFFFFFFFF) dfu_enter = true;

but after NVIC_SystemReset(); the application restart without entering to dfu_check.

how can i verify and enter to bootloader after systemreset().

Both BLE Application and BLE Bootloader is tested individually and works fine.

 

  • Hi,

    did you clear the register before trying to enter the bootloader?
    That's the function I normally use to enter the bootloader:

    void app_enter_dfu_bootloader(void)
    {
      uint32_t err_code;
    
      err_code = sd_power_gpregret_clr(0, 0xffffffff);
      VERIFY_SUCCESS(err_code);
    
      err_code = sd_power_gpregret_set(0, 0xB1);
      VERIFY_SUCCESS(err_code);
    
      // Signal that DFU mode is to be enter to the power management module
      nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);
     
      /* this should not be reached! */
      NVIC_SystemReset();
    }

    Kind regards,
    Johannes

  • Hi,

    yes i did.

    Here follow the  BLE application Jump Code..

    #define BOOTLOADER_DFU_START  0xB1
    
    void Uart_check_rx(void) {
     ...
     
      if(memcmp(command,(uint8_t *)"AT+SERIALDFU",length)==0)
      {
         NRF_LOG_INFO("Command Recived: AT+SERIALDFU?");
         ble_dfu_buttonless_bootloader_start_finalize_local();
         NVIC_SystemReset();
      }
      ..
     }
    
    
    uint32_t ble_dfu_buttonless_bootloader_start_finalize_local(void)
    {
        uint32_t err_code;
        NRF_LOG_INFO("Going to Bootloader Start");
    
        err_code = sd_power_gpregret_clr(1,0xffffffff);   //
        err_code = sd_power_gpregret_clr(0,0xffffffff);
        
        NRF_LOG_INFO("err code %d",err_code);
        VERIFY_SUCCESS(err_code);
        NRF_LOG_INFO("Register clear Success");
    
    	err_code = sd_power_gpregret_set(1,BOOTLOADER_DFU_START);
        err_code = sd_power_gpregret_set(0,BOOTLOADER_DFU_START);
    	
    	NRF_LOG_INFO("err code %d",err_code);
    	VERIFY_SUCCESS(err_code);
        NRF_LOG_INFO("Register Set Success");
        
    	user_write_flash(0x00022000,(uint32_t)0x12341234);
    
       // m_dfu.evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER);
    
        nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);
    
        return NRF_SUCCESS;
    }  

    i have checked gpregister using "nrfjprog --memrd 0x4000051c"  and it returns 0x4000051c : 0xB1

    and "nrfjprog --memrd 0x00022000"  returns 0x00022000: 0x12341234.

    Even i do  nrfjprog --reset from cmd prompt after setting gpregister and memory location , the BLE application restarts.

    In Bootloader i did like this.

    uint32_t DFU_Flag_data  = 0;
    
    main() {
    	...
    	....
    uint32_t* dfu_flag_mem2 = (uint32_t*) 0x00022000;
    DFU_Flag_data = (uint32_t)*dfu_flag_mem2 ;
    	...
    	....
    }
    
    extern uint32_t DFU_Flag_data;
    
    ret_code_t nrf_bootloader_init(nrf_dfu_observer_t observer) {
    	...
    	....
    	..
    
        switch (activation_result)
        {
            case ACTIVATION_NONE:
                initial_timeout = NRF_BOOTLOADER_MS_TO_TICKS(NRF_BL_DFU_INACTIVITY_TIMEOUT_MS);
                dfu_enter       = dfu_enter_check();
    
               if(DFU_Flag_data != 0xFFFFFFFF) {
                  dfu_enter = true;
                }
    
    	...
    	}
    	...
    	if(dfu_enter) {
    		// enter to dfu
    	} else {
    		//start application
    	}
    }
    
    
    static bool dfu_enter_check(void) {
        if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
           (nrf_power_gpregret_get() & BOOTLOADER_DFU_START))
        {
            NRF_LOG_DEBUG("DFU mode requested via GPREGRET.");
            return true;
        }
    }
    
    sdk_config.h
    #define NRF_BL_DFU_ENTER_METHOD_GPREGRET 1
    
    #define NRF_BL_DFU_ENTER_METHOD_BUTTONLESS 1
    
    

    Anything else is missing in application or Bootloader settings ?

  • Hello,

    Please verify that the bootloader start address is correctly stored at address 0x10001014 when both bootloader and app is loaded to your device. If not, the bootloader will not be included in the boot sequence: https://docs.nordicsemi.com/bundle/sds_s132/page/SDS/s1xx/mbr_bootloader/mbr_sd_reset_behavior.html 

    Also, nrf5_sdk_for_thread_and_zigbee_v4.2.0_af27f76 and nRF5_SDK_14.2.0_17b948a are not compatible with the same Softdevices. Is there a particular reason for using this combination? Normally you would want to base the application and bootloader on the same SDK version. There should also not be any reason to use the Thread & Zigbee SDK when targeting the nRF52810 which does not have a 15.4 RADIO needed for thread and zigbee.

    Best regards,

    Vidar

  • Hi,

    >nrfjprog --memrd 0x10001014
    0x10001014: 00029000 |....|

    >nrfjprog --memrd 0x10001018
    0x10001018: 0002E000 |....|

    i have checked by writing memory using nrf_nvmc_write_word() from bootloader it is writting the memory location while booting before jump to BLE Application.

    #include "nrf_nvmc.h"
    
    ret_code_t nrf_bootloader_init(nrf_dfu_observer_t observer)
    {
        NRF_LOG_DEBUG("In nrf_bootloader_init");
    
       ....
    
        switch (activation_result)
        {
            case ACTIVATION_NONE:
    
                nrf_nvmc_write_word(0x00022100,0x12341234);
                initial_timeout = NRF_BOOTLOADER_MS_TO_TICKS(NRF_BL_DFU_INACTIVITY_TIMEOUT_MS);
                dfu_enter       = dfu_enter_check();
                
                ...
                break;

    Also i read the memory while running application and received following result.

    >nrfjprog --memrd 0x00022100
    0x00022100: 12341234 |4.4.|

    and here is the result which i written from BLE Application

    >nrfjprog --memrd 0x00022000
    0x00022000: 12341234  

    from bootloader am reading the same memory and used to enter DFU mode which is getting fail or not reading proper value similarly  with gpregister also.

    how to read nvmc proper ? 

    BLE Application is developed in nRF5_SDK_14.2.0_17b948a which is developed long back ago and we do not want to disturb right now.

    where Bootloader developing in nrf5_sdk_for_thread_and_zigbee_v4.2.0_af27f76 currently where we want to add OTA in our coming BLE products.

    lately we will move both Application and Bootloader into one SDK.

  • Hi,

    Thanks for confirming that the UICR registers were set. 

    The application and bootloader running on your device must always be compatible with the same softdevice. You can't have the bootloader built for one major version and the application for another. So first the first step is to make sure both are compatible with the same softdevice version.

    NikhilVV said:
    i have checked by writing memory using nrf_nvmc_write_word() from bootloader it is writting the memory location while booting before jump to BLE Application.

    I'm not sure I understand what you are trying to test with this or why you are writing to this address. If the bootloader changes any of the data in the application region (or the app writes to itself), then the boot validation  of the app will fail.

Related