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

USB DFU combined with Buttonless BLE DFU

Hi

I am working with nRF52840 DK  v2.0.1, in SDK 17.0.2., trying to implement combined BLE+USB DFU in my application.

First I tried combining bootloaders from SDK (secure_bootloader/pca10056_s140_ble and secure_bootloader/pca10056_usb), and I used pca10056_s140_ble  as starting point.

I imported all files that are in the pca10056_usb bootloader, along with all skd_config.h definitions and include paths. Also, I changed flash start and flash size, to fit new bootloader into the flash memory.

In my main application, I tried using USB DFU trigger library, to trigger USB DFU (BLE DFU was already implemented before but now it doesn't work)

I connected P0.05 to P.018, as required by the library, and I've enabled PINRESET entry mode in the bootloader sdk_config.h.

Can anyone tell me what am I missing here? The application works fine, I'm using BLE, UART and USB CLI, It's just won't go into DFU mode.

I would appreciate if someone could tell me steps required to combine two bootloaders, and including these bootloaders into the main application?

Thanks!

  • Update:
    I was able to solve the problem regarding the USB DFU. Turns out, the project I was working on was modified in the past, and it was broken. I used clean SDK USB bootloader example, along with some logic in my main app to trigger USB DFU, write to GPREGRET and perform system restart, after which I'm able to perform USB DFU. 

    After I successfully implemented USB DFU I tried combining BLE and USB bootloaders.

    As I said, I'm using BLE bootloader as a starting point, and I'm including files from the USB bootloader example, along with sdk_config.h defines. (I couldn't include following files: nrf_soc.c and nrf_nvic.c along with include path /components/drivers/nrf/nrf_soc_nosd. Also I had to set the following config in sdk_config.h:

    NRF_DRV_PROTOCOL_REDUCED 0 )

    I modified Section placement macros to: FLASH_START = 0xf0000 and FLASH_SIZE = 0xf000 and I was able to build the solution..

    Everything else is the same as in the secure_bootloader/pca10056_s140_ble example.

    When I merge bootloader, settings file, softdevice and the app .hex files and when I flash the merged file onto the nRF52840 application starts as it should, everything works fine. However I can't enter DFU mode from the bootloader, I've tried entering through:

    • BLE DFU via nRF Connect mobile app
    • USB DFU via nrfutil in terminal
    • Also I've tried pressing BUTTON4 while performing reset (BUTTON entry method is enabled in the bootloader and the BUTTON4 is selected), but it won't enter DFU mode, it goes straight to the application. (If I'm holding the reset button with Button4 LED0 and LED1 are blinking as long as I keep holding the buttons)

    Also, I've tried with clean BLE bootloader from SDK, and BLE DFU works fine (even with NRF_DRV_PROTOCOL_REDUCED set to 0)

    Could you please guide me on how to combine these bootloaders?

  • Another update:

    I tried the same approach in secure_bootloader/pca10056_s140_ble_debug and secure_bootloader/pca10056_s140_usb_debug examples, to see what is really going on. Here is the log in terminal:

    <info> app: Inside main
    <debug> app: In nrf_bootloader_init
    <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    <warning> nrf_dfu_settings: Resetting bootloader settings since neither the settings page nor the backup are valid (CRC error).
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 0
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 0
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x2000A730, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x2000AAB0, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0
    <debug> app: Enter nrf_bootloader_fw_activate
    <info> app: No firmware to activate.
    <info> app: Boot validation failed. No valid app to boot.
    <debug> app: DFU mode because app is not valid.
    <info> nrf_bootloader_wdt: WDT is not enabled
    <debug> app: in weak nrf_dfu_init_user
    <debug> app: timer_stop (0x2000599C)
    <debug> app: timer_activate (0x2000599C)
    <info> app: Entering DFU mode.
    <debug> app: Initializing transports (found: 2)
    <debug> nrf_dfu_ble: Initializing BLE DFU transport
    <debug> nrf_dfu_ble: Setting up vector table: 0x000E0000
    <debug> nrf_dfu_ble: Enabling SoftDevice.
    <error> app: Received a fault! id: 0x00004002, pc: 0x00000000, info: 0x2003FF30

    Seams like the Softdevice is not being enabled. I don't know what is the problem, though. 

  • Another update:

    I've added this part of the code to the bootloader's main.c (line 2 and line 3):

     NRF_LOG_INFO("Inside main");
        nrf_drv_clock_init();
        nrf_drv_power_init(NULL);
        ret_val = nrf_bootloader_init(dfu_observer);
        APP_ERROR_CHECK(ret_val);

    BLE transport gets initialized, but the USB transport won't initialize now, with the following log in terminal:

    <info> app: Inside main
    <debug> app: In nrf_bootloader_init
    <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    <debug> nrf_dfu_settings: Using settings page.
    <debug> nrf_dfu_settings: Copying forbidden parts from backup page.
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    <debug> app: Enter nrf_bootloader_fw_activate
    <info> app: No firmware to activate.
    <info> app: Boot validation failed. No valid app to boot.
    <debug> app: DFU mode because app is not valid.
    <info> nrf_bootloader_wdt: WDT is not enabled
    <debug> app: in weak nrf_dfu_init_user
    <debug> app: timer_stop (0x2000599C)
    <debug> app: timer_activate (0x2000599C)
    <info> app: Entering DFU mode.
    <debug> app: Initializing transports (found: 2)
    <debug> nrf_dfu_ble: Initializing BLE DFU transport
    <debug> nrf_dfu_ble: Setting up vector table: 0x000E0000
    <debug> nrf_dfu_ble: Enabling SoftDevice.
    <debug> nrf_dfu_ble: Configuring BLE stack.
    <debug> nrf_dfu_ble: Enabling the BLE stack.
    <debug> nrf_dfu_ble: No advertising name found
    <debug> nrf_dfu_ble: Using default advertising name
    <debug> nrf_dfu_ble: Advertising...
    <debug> nrf_dfu_ble: BLE DFU transport initialized.
    <debug> nrf_dfu_serial_usb: Initializing drivers.
    <debug> app: Failed to initialize transport 1, error 133
    <error> app: Could not initalize DFU transport: 0x00000085
    <error> app: C:\SDKs\nRF5_SDK_17.0.2_d674dde\examples\dfu\secure_bootloader\main.c:150
     

  • I'm beginning to think this is due to order of transport initialization. Program initializes BLE transport first. Is there any elegant way to force initialize USB transport first?

Related