How to use Mynewt's blehci with drag and drop bootloader on nRF52840-Donlge

Mynewt has a possibility of using drag and drop bootloader, which allows to flash images to the device with simply copying them via USB. This post shows how to configure blehci application with drag and drop flashing feature for nRF52840-Dongle.

Bootloader target configuration

Start with creating new bootloader target in your Newt project:

~/dev/mynewt$ newt target create nordic_pca10059_boot

Target targets/nordic_pca10059_boot successfully created

~/dev/mynewt$ newt target set nordic_pca10059_boot bsp=@apache-mynewt-core/hw/bsp/nordic_pca10059

Target targets/nordic_pca10059_boot successfully set target.bsp to @apache-mynewt-core/hw/bsp/nordic_pca10059

~/dev/mynewt$ newt target set nordic_pca10059_boot app=@mcuboot/boot/mynewt

Target targets/nordic_pca10059_boot successfully set target.app to @mcuboot/boot/mynewt

~/dev/mynewt$ newt target set nordic_pca10059_boot build_profile=optimized

Target targets/nordic_pca10059_boot successfully set target.build_profile to optimized

This is going to be target for drag and drop bootloader for nRF52840-Dongle. Now you have to configure your target. To do so go into it's directory. In this example target location is:

~/dev/mynewt/targets/nordic_pca10059-boot

You'll have to modify pkg.yml and syscfg.yml files.

pkg.yml should contain:

pkg.name: targets/nordic_pca10059-boot
pkg.type: target
pkg.description: 
pkg.author: 
pkg.homepage: 

pkg.deps:
    - "@apache-mynewt-core/hw/usb/tinyusb/msc_fat_view"

Drag and drop bootloader uses tinyusb package, so it has to be added to dependencies.

In syscfg.yml file you should configure settings related to USB descriptor and msc_fat_view package:

syscfg.vals:
    #Use standard USB descriptor generated by Mynewt
    USBD_STD_DESCRIPTORS: 1
    #Set usb descriptor values
    USBD_VID: 0xC0CA
    USBD_PID: 0xC01B
    USBD_VENDOR_STRING: '"Codecoup"'
    USBD_PRODUCT_STRING: '"Mynewt dongle"'

    #GPIO pin to check during boot for DFU activation.
    MSC_FAT_BOOT_PIN: BUTTON_1
    #GPIO pin value required for DFU activation.
    MSC_FAT_BOOT_PIN_VALUE: 0
    #Set to 1 if boot pin needs internal pull-up resistor.
    #Set to 2 if boot pin needs internal pull-down resistor.
    MSC_FAT_BOOT_PIN_PULL: 1
    #FAT volume name.
    MSC_FAT_VIEW_VOLUME_NAME: '"MYNEWT_BOOT"'
    #Add 'MYNEWT.HTM' file that will redirect to mynewt web page.
    MSC_FAT_VIEW_MYNEWT_SHORTCUT: 1
    #Add git hashes into README.TXT.
    MSC_FAT_VIEW_DEFAULT_README_INCLUDE_HASHES: 1
    #Simulated disk size in kB (Only FAT16 is supported!).
    MSC_FAT_VIEW_DISK_SIZE: 4000
    #Simulated disk sectors per cluster (Only FAT16 is supported!).
    MSC_FAT_VIEW_SECTORS_PER_CLUSTER: 1
    #Add 'Drop image here' file.
    MSC_FAT_VIEW_DROP_IMAGE_HERE: 1
    #Show image from slot 0 as a file 'FIRMWARE.IMG'.
    MSC_FAT_VIEW_SLOT0_IMAGE: 1
    #Enable DFU.
    BOOT_PREBOOT: 1

Editing project.yml

To make drag and drop bootloader work, you'll have to change two things in your project.yml file. You can find this file in your main Newt project directory (in this tutorial it is "~/dev/mynewt/").

First you'll have to add tinyusb repository to your project:

repository.apache-mynewt-core:
    type: github
    vers: 0-dev
    user: apache
    repo: mynewt-core

repository.tinyusb:
    type: github
    vers: 0.0.0
    user: hathach
    repo: tinyusb

Second step is to change apache-mynewt-core repository version to master branch:

repository.apache-mynewt-core:
    type: github
    vers: 0-dev
    user: apache
    repo: mynewt-core

This is needed, because the changes in source code required for drag and drop bootloader to work are currently only on the master branch. This will be changed in the future.

After applying this two changes you can run newt upgrade command. It might take a while to download quite big tinyusb repository.

Now you can build bootloader with newt build nordic_pca10059_boot command.

Flashing and working with drag and drop bootloader

To flash new bootloader to nRF52840-Dongle you have to connect it to a programmer via Tag-Connect cable.

RF52840-Dongle connected to the programmer via Tag-Connect cable. Jumper wires are connected to the J-Link programmer.

After connecting the board to the programmer you can load bootloader with newt load nordic_pca10059_boot command.

When loading bootloader is finished it will be safe to unplug the dongle from your computer. Now if you want to flash new app, using drag and drop functionality you just have keep the user button pressed while plugging the device into your computer's USB port. Then the device should be recognized as MSD. Now you can copy and paste the application image you want to flash on the device. After copying it the device will be automatically rebooted and new app will be running on it. If you set the appropriate config in syscfg.yml (MSC_FAT_VIEW_SLOT0_IMAGE), you will see a currently loaded image when you plug in the device with user button pressed. Thanks to this you can backup your previous image, before replacing it with another one.

Mynewt's blehci application configuration

Create new target for blehci app:

~/dev/mynewt$ newt target set blehci bsp=@apache-mynewt-core/hw/bsp/nordic_pca10059


Target targets/blehci successfully set target.bsp to @apache-mynewt-core/hw/bsp/nordic_pca10059


~/dev/mynewt$ newt target set blehci app=@apache-mynewt-nimble/apps/blehci


Target targets/blehci successfully set target.app to @apache-mynewt-nimble/apps/blehci


~/dev/mynewt$ newt target set blehci build_profile=optimized


Target targets/blehci successfully set target.build_profile to optimized

Application target also has to be configured. Go into it's directory (in this tutorial it's "~/dev/mynewt/targets/blehci") and edit syscfg.yml and pkg.yml files.

In pkg.yml file you just have to add tinyusb package dependencies:

pkg.deps:
- "@apache-mynewt-core/hw/usb/tinyusb"
- "@apache-mynewt-core/hw/usb/tinyusb/std_descriptors"

File syscfg.yml can be configured like this:

syscfg.vals:
    USBD_VID: 0xC0CA
    USBD_PID: 0xC01A
    USBD_VENDOR_STRING: '"Codecoup"'
    USBD_PRODUCT_STRING: '"NimBLE 1.5"'
    USBD_BTH_DESCRIPTOR_STRING: '"NimBLE 1.5"'
    USBD_BTH: 1

    BLE_TRANSPORT_HS: usb

    #Enable reset button
    GPIO_AS_PIN_RESET: 1

    CONSOLE_MODE: stub

    #Fake dual mode to make BLE-only device work on Windows
    BLE_LL_HBD_FAKE_DUAL_MODE: 0

syscfg.vals.BLE_LL_HBD_FAKE_DUAL_MODE:
    BLE_TRANSPORT_EVT_SIZE: 257
    BLE_LL_PUBLIC_DEV_ADDR: 0xC0CAC01A1983
    USBD_PRODUCT_STRING: '"NimBLE 1.5 (Fake dual)"'
    USBD_BTH_DESCRIPTOR_STRING: '"NimBLE 1.5 (Fake dual)"'

MS Windows requires connected Bluetooth device to support Bluetooth Classic, so you will have to configure fake dual mode if you are using Windows. Configs below the line syscfg.vals.BLE_LL_HBD_FAKE_DUAL_MODE: will only be included if BLE_LL_HBD_FAKE_DUAL_MODE is set to 1. These are additional configs required for the fake dual mode.

When everything is configured you can finally build your blehci app image with newt create-image blehci 1.0.0 command. Now you can connect nRF52-Dongle to your USB port while keeping user button pressed. When the device will be recognized as MSD, you can simply drag and drop your application image to the device. After doing so the device should no longer be seen as MSD, but should work as Bluetooth dongle from now on. However if you want to flash new image on the board you can do it with unplugging it and plugging it again with the user button pressed. If the user button won't be pressed while plugging in the device, it should be detected as Bluetooth controller dongle.

Any questions?

Do not hesitate to contact us.

    Codecoup sp. z o.o.
    ul. Strzegomska 138
    54-429 Wrocław
    Poland
    +48 660 540 140
    hello@codecoup.pl
    Copyright © 2021 
    crossmenu