Cannot perform DFU over USB with MCUboot using USB CDC ACM and a nRF52840

I'm trying to implement DFU over USB through Serial Recovery, for a custom board using a nRF52840, following the nRF Connect SDK Intermediate Lesson 9: Exercise 4 – DFU over USB - Nordic Developer Academy.

My goal would be to update the firmware by connecting a USB Type-C cable to my receptor on my PCB and to my computer hosting the new firmware.

I'm using VS Code as my editor with the nRF Connect Extension, the nRF connect SDK v3.0.0 and the toolchain version v3.0.2.

So far, i managed to have two build images (one for the main app and one for MCUboot) and flash them inside my PCB custom board with sysbuild. Using an external button connected to my nRF52840 on my Printed Circuit Board (PCB), when i reboot the board (and hold the external button pressed down), i manage to launch the MCUboot image (i can see that it worked because a LED is configured to be turned ON when MCUboot is in Serial Recovery mode, again following Lesson 9 Exercice 1: Exercise 1 - DFU over UART - Nordic Developer Academy).

My problem comes when i try to connect a USB cable from my USB Type-C connector on my PCB to my computer (when the board is running MCUboot in Serial recovery mode). Nothing is recognised by my computer host (no COM port visible and no audio sound from connecting something in the commputer USB port). 


Here is my workspace:

 .

pb0167_tuto is my board file and tuto_custom is the file holding my application (with sysbuild file for MCUboot). Here are the following content of the files on my workspace:

sysbuild.conf:

 .

prj.conf:

pb0167_tuto_nrf52840.overlay:

mcuboot.conf:

mcuboot.overlay:

 .

Since i'm using a custom board, i also configured my proper dts file for my board file (and thus shared by my main app build image and MCUboot build image):

/dts-v1/;
#include <nordic/nrf52840_qiaa.dtsi>
#include "pb0167_tuto-pinctrl.dtsi"

/ {
    model = "pb0167 tuto";
    compatible = "home,pb0167-tuto";

    chosen {
        zephyr,sram = &sram0;
        zephyr,flash = &flash0;
        zephyr,code-partition = &slot0_partition;
    };

    leds {
        compatible = "gpio-leds";

        led0: led_0 {
            gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
            label = "Red LED";
            status = "okay";
        };

        led1: led_1 {
            gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
            label = "Orange LED";
            status = "okay";
        };

        led2: led_2 {
            gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
            label = "Blue LED";
            status = "okay";
        };
    };

    buttons {
        compatible = "gpio-keys";

        button0: button_0 {
            gpios = <&gpio0 17 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
            label = "Push button switch 0";
            zephyr,code = <INPUT_KEY_0>;
        };
    };

    aliases {
        led0 = &led0;
        led1 = &led1;
        led2 = &led2;
        sw0 = &button0;
        mcuboot-button0 = &button0;
        mcuboot-led0 = &led1;
    };
};

&flash0 {
    partitions {
        compatible = "fixed-partitions";
        #address-cells = <1>;
        #size-cells = <1>;

        boot_partition: partition@0 {
            label = "mcuboot";
            reg = <0x00000000 DT_SIZE_K(48)>;
        };

        slot0_partition: partition@c000 {
            label = "image-0";
            reg = <0x0000c000 DT_SIZE_K(472)>;
        };

        slot1_partition: partition@82000 {
            label = "image-1";
            reg = <0x00082000 DT_SIZE_K(472)>;
        };

        storage_partition: partition@f8000 {
            label = "storage";
            reg = <0x000f8000 DT_SIZE_K(32)>;
        };
    };
};

&gpiote {
    status = "okay";
};

&gpio0 {
    status = "okay";
};

zephyr_udc0: &usbd {
    compatible = "nordic,nrf-usbd";
    status = "okay";
};

The associated pinctrl.dtsi for the board file as the following content:

&pinctrl {
    i2c0_default: i2c0_default{
        group1 {
            psels = <NRF_PSEL(TWIM_SDA, 0, 26)>,
                    <NRF_PSEL(TWIM_SCL, 0, 27)>;
        };
    };
};

All of the above, when using nRF Connect extensino can be build and results as the following output from VS Code:

 .


My Questions are: If MCUboot seems to be working on my board, why my computer does not recognise the USB on my custom PCB when i connect a USB type-C connector from my PCB to my computer ? Why I cannot see a COM port appearing on my host computer ? Does everything presented hereabove, in my implementation and files, seems right to perform Serial Recovery for DFU over USB using AuTerm (recommanded by nRF in Exercise 4 – DFU over USB) ?

Many thanks in advance for the persons reading this. 

  • Hello, 

    Just to verify, the USB C connection does work as expected? I see that you have configured CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n in both mcuboot.conf and prj.conf, which means that you do not initialize USB device support at boot.



    Have you had a free PCB review of your board to verify the nRF52840 connections? Have you tried the same code using the development kti? Do you have any logs from your device that you can provide us over RTT? 

    Kind regards,
    Øyind

  • Hi, thank you for your feedback.

    First, the USB Type-C connector traces to the D+/D- pin were reviewed and everything seems fine. The layout is almost the same as the nRF52840DK, the only difference is that no Pi-matching network for VBUS was implemented in our custom board (for EMC reasons regarding the ferrite bead).

    Second, i implemented the change regarding CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT in the mcuboot.conf file (=y):

     .

    I also included the dependencies CONFIG_USB_CDC_ACM=y and the three configurations: 

    CONFIG_USE_SEGGER_RTT=y
    CONFIG_CONSOLE=
    CONFIG_RTT_CONSOLE=y

    in order to allowed RTT in MCUboot.
    I reckon, correct me if i'm wrong, that enabling CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y in my prj.conf (from my main app) is not required since I only want to use the USB Type-C connector (and thus D+/D-) in MCUboot for DFU over USB using CDC ACM ?
    Everything regading the USB configurations that you can see in my prj.conf are configuration "remainders" from the fact that i followed the Nordic Lesson 9 (Exercice 1 and 4) in my first attempt at configuring my USB stack and MCUBoot. In any case, i want to perform DFU over USB from my main application nor having USB capabilities in my main app for data exchange !
    After the modifications in my mcuboot.conf file, and a pristine build, no USB could be detected by my computer. The RTT from MCUBoot displays the following lines but nothing more:
    Still no USB or COM port detection from my computer.
    After browsing some example in the sdk-zephyr github (sdk-zephyr/samples/subsys/usb/dfu/prj.conf at main · nrfconnect/sdk-zephyr · GitHub), i found a dfu example in the samples. Do you think any of the following configuration needs to be added to my mcuboot.conf ? (again, not in prj.conf since USB for my main app is not required):
      ?

    Regards
    Loris

  • Hello, 

    Øyvind said:
    Have you tried the same code using the development kti?

    Did you test your code on the nRF52840DK? This is just to verify that it actually does work as described in DevAcademy. You can use the nRF USB to verify functionality. 
    Have you verified that you USB actually works i.e. have you tested a USB sample or USB-C sample alone? Please note that the nRF52840DK has the interface MCU which generates COM ports for you. 

    Logs are always good to capture and to use for debugging.

    LorisRT said:
    I reckon, correct me if i'm wrong, that enabling CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y in my prj.conf (from my main app) is not required since I only want to use the USB Type-C connector (and thus D+/D-) in MCUboot for DFU over USB using CDC ACM ?

    Yes, this sounds correct.

    LorisRT said:
    Do you think any of the following configuration needs to be added to my mcuboot.conf ?

    We recommend testing on the DK to be sure. 

Related