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

DFU: nRF51822 OTA bootloader jams after reset_prepare()

I managed to upload my application OTA DFU when there was only the bootloader running. After my application is there, I can start DFU and my application runs thru reset_prepare() function as expected. However, it seems that it never enters the bootloader although DfuTarg seems to appear as an available BLE device. So I cannot upload my application another time :(

Any ideas what could be wrong? Why my application does not start bootloader (correctly) after reset_prepare()?

EDIT: The bootloader enters event loop and jams there, see the code below (from bootloader.c/nRF51_SDK_8.0.0_5fc2c3a). The DFU loader at phone side says "disconnected" (mostly, sometimes it jams). I cannot reconnect although DfuTarg is visible.

for (;;)
{
    // Wait in low power state for any events.
    uint32_t err_code = sd_app_evt_wait();
    APP_ERROR_CHECK(err_code);

	myLedIndication(); // This shows me bootloader is running here very busy

    // Event received. Process it from the scheduler.
    app_sched_execute();

    if ((m_update_status == BOOTLOADER_COMPLETE) ||
        (m_update_status == BOOTLOADER_TIMEOUT)  ||
        (m_update_status == BOOTLOADER_RESET))
    {
        // When update has completed or a timeout/reset occured we will return.
        return;
    }
}

And the reset_prepare() looks like:

static void reset_prepare(void)
{
	uint32_t err_code;
	if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
	{
		// Disconnect from peer.
		err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
		APP_ERROR_CHECK(err_code);
		//err_code = bsp_indication_set(BSP_INDICATE_IDLE);
		//APP_ERROR_CHECK(err_code);
	}
	else
	{
		// If not connected, the device will be advertising. Hence stop the advertising.
		advertising_stop();
	}
	err_code = ble_conn_params_stop();
	APP_ERROR_CHECK(err_code);
}
Parents
  • I think there is issue with the method of sending nrf into bootloader. I have successfully done ota for application, bootloader and also softdevice. So let me tell you what have i done. In your application code, go where bluetooth messages are recieved. there u can make a function which parses the message. in that function check if (say) 0th byte is 0x1 then just set NRF_POWER->GPREGRET to BOOTLOADER_DFU_START, that's a macro, you can assign whatever value you want, just make sure define it in both application and bootloader. in bootloader in main function just check NRF_POWER->GPREGRET, if it is equal to BOOTLOADER_DFU_START be in bootloader mode.

    How to go in bootloader mode from application? go to nrf master control panel app(android), connect to it, dicover services, bond it, enable services.

    1. Let's say my device's name is 1234, as shown in image. select it and connect it.

    image description 2.You get 2nd screen, there on topright corner tap to settings near Disconnect, a popup will open shown in second image. select Refresh services. image description 3.and then again go to settings and select bond. Your screen would be like: image description 4. now your device is bonded, now goto settings "status:connected, bonded" tab, from popup select "enable services". 5. Goto Unknown Service. image description in that goto Unkwnown Characteristics with UUID 0000900a... ahead of it you will see a 2 icon of upload, tap on it. 6.this will look like: image description change "byte array" to "byte" write 01 to new value then send. again tap on it and again select byte and write "1". as decided above. written above in bold.

    Now nrf will advertise as "DfuTarg".

    Now use nrf toolbox for ota

Reply
  • I think there is issue with the method of sending nrf into bootloader. I have successfully done ota for application, bootloader and also softdevice. So let me tell you what have i done. In your application code, go where bluetooth messages are recieved. there u can make a function which parses the message. in that function check if (say) 0th byte is 0x1 then just set NRF_POWER->GPREGRET to BOOTLOADER_DFU_START, that's a macro, you can assign whatever value you want, just make sure define it in both application and bootloader. in bootloader in main function just check NRF_POWER->GPREGRET, if it is equal to BOOTLOADER_DFU_START be in bootloader mode.

    How to go in bootloader mode from application? go to nrf master control panel app(android), connect to it, dicover services, bond it, enable services.

    1. Let's say my device's name is 1234, as shown in image. select it and connect it.

    image description 2.You get 2nd screen, there on topright corner tap to settings near Disconnect, a popup will open shown in second image. select Refresh services. image description 3.and then again go to settings and select bond. Your screen would be like: image description 4. now your device is bonded, now goto settings "status:connected, bonded" tab, from popup select "enable services". 5. Goto Unknown Service. image description in that goto Unkwnown Characteristics with UUID 0000900a... ahead of it you will see a 2 icon of upload, tap on it. 6.this will look like: image description change "byte array" to "byte" write 01 to new value then send. again tap on it and again select byte and write "1". as decided above. written above in bold.

    Now nrf will advertise as "DfuTarg".

    Now use nrf toolbox for ota

Children
  • Thanks for very comprehensive answer! I think my application enters bootloader correctly, but the bootloader might get mad because of our hardware peripherals and their interrupts. Would like to test that, but my project (Keil) corrupted somehow. I get errors:

    No Algorithm found for: 10001014H - 10001017H Partial Erase Done (areas with no algorithms skipped!) No Algorithm found for: 10001014H - 10001017H Partial Programming Done (areas with no algorithms skipped!) Partial Verify OK (areas with no algorithms skipped!)

    And the application fails to run. I have compared all the settings with an older copy of the project, and everything seems to be similar. But it just continues to give that error! So irritating and frustrating... :(

  • in bootloader_settings_arm.c file add "uint32_t m_uicr_bootloader_start_address attribute((at(NRF_UICR_BOOT_START_ADDRESS))) = BOOTLOADER_REGION_START;", #define NRF_UICR_BOOT_START_ADDRESS (NRF_UICR_BASE + 0x14) and #define DFU_BL_IMAGE_MAX_SIZE (BOOTLOADER_SETTINGS_ADDRESS - BOOTLOADER_REGION_START)

    it will be there just uncomment it, the error is because of the absence of this line, this line is used to write uicr registers. or use nrfjrog.exe to write image on nrf. else follow given links: developer.nordicsemi.com/.../a00098.html and infocenter.nordicsemi.com/index.jsp

  • Well, they were already there. When I try to flash the bootloader, the error message is as follows:

    nrfjprog.exe --reset --program "C:\Nordic Semiconductor\nRF51_SDK_8.0.0_5fc2c3a_backup\nRF51_SDK_8.0.0_5fc2c3a\examples\dfu\bootloader\pca10028\dual_bank_ble_s110\arm4_build\nrf51422_xxac.HEX"

    Parsing hex file(s).

    Checking that there is no data to be written in region 0.

    Checking that there are no UICR conflicts.

    ERROR: The device has data in the UICR area, and there is a conflict with the hex to download. No program command will automatically erase UICR area. Erase the UICR area and download the hex(s) files again.

    And on the other hand, I have two versions of the application project (not the bootloader). Another one does flash OK, while the other fails with the "No Algorithm ..." -error. This just does not make any sense... :( I cannot find the difference even with using WinMerge. AAARRRGGH :(

  • Actually, I had to comment the line "uint32_t m_uicr_bootloader_start_address..." away to get rid of the error message. And the older project was working because it did not have that file at all, yet. However, now I am back at the starting point: I cannot DFU if my own application is there. I will look your instructions carefully, let's see if I can manage to get it working. Thanks again!

  • Uncomment that line which you have commented out, otherwise bootloader will nerver get flashed. You just have to erase whole nrf chip, or just write, nrfjprog --eraseall --program filename.hex --reset --verify. It will definitely work. and always use given above command for flashing. It is because you can't overwrite UICR registers without erasing them, and those can only be erased by eerasing whole chip.

Related