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. 

Parents
  • 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. 

  • Hi, I managed to implement DFU over USB using CDC ACM in Serial Recovery mode (nRF connect SDK v3.0.0 and toolchain version v3.0.2)

    I had two problems : 

    1: The person who did our schematic for our custom board put 3.3V at the VBUS entry of the nRF52840. This low voltage compared to the lower USB threshold (approximately 4.3V) made the USB not avaliable/work properly on our board.

    2: Using a nRF52840 DK (dev. kit), we managed to perform DFU over USB but the Nordic Lesson 9 (Exercise 4 – DFU over USB - Nordic Developer Academy) alone isn't sufficient to perform DFU over USB even with the nRF52840 DK (due to missing configurations that are not properly stated). For the next person who wants to implement it, here are the files and files content that were required in our side:

    First, the steps in Lesson 8, Sysbuild, Exercice 1 (Exercise 1 - Configuring extra image - Nordic Developer Academy) need to be done in order to have a MCBboot image functionnal, have the sysbuild.conf file, and the mcuboot.conf file. However, set CONFIG_SERIAL in mcuboot.conf to yes ! (i.e.: CONFIG_SERIAL=y) . Add also mcuboot.overlay the same way mcuboot.conf was added in the folder sysbuild. At the end, you should be left with a workspace folder that looks like that (if you are using VSCode):




    Second, configure the above added files with the following content:


    sysbuild.conf:

    SB_CONFIG_BOOTLOADER_MCUBOOT=y
    SB_CONFIG_MCUBOOT_MODE_SINGLE_APP=y

    mcuboot.conf:
    CONFIG_LOG=y
    CONFIG_MCUBOOT_LOG_LEVEL_INF=y
    CONFIG_UART_CONSOLE=n
    CONFIG_MCUBOOT_INDICATION_LED=y
    CONFIG_MCUBOOT_SERIAL=y
    CONFIG_BOOT_SERIAL_UART=y
    CONFIG_BOOT_SERIAL_CDC_ACM=y
    CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x10000
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PRODUCT="Zephyr CDC ACM sample"
    CONFIG_USB_DEVICE_PID=0x0001
    CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
    CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
    CONFIG_SERIAL=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_UART_LINE_CTRL=y

    CONFIG_USB_CDC_ACM=y
    CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n


    mcuboot.overlay:
    / {
        aliases {
            mcuboot-button0 = &button3;
            mcuboot-led0 = &led2;
        };
    };

    /* STEP 2.1 - Configure CDC ACM */
    &zephyr_udc0 {
        cdc_acm_uart0: cdc_acm_uart0 {
            compatible = "zephyr,cdc-acm-uart";
        };
    };

    For our custom board, we also addded the following node in our board default dts file:
    zephyr_udc0: &usbd {
    compatible = "nordic,nrf-usbd";
     status = "okay";
    };
    (those lines are not required in the Dev. Kit., only for custom board, since the nRF52840DK board dts file is already configured with proper nodes)
    Again, for a custom board, don't forget to add the node for the button and led responsible for going into MCUboot (button3) and display that we are in the boot image (led2) in the board dts file (DO NOT ADD THEM IN THE MAIN APP OVERLAY, THIS SHOULD BE ADDED IN THE BOARD DTS FILE, since the app overlay is not shared with the MCUboot build image):
    leds {
    compatible = "gpio-leds";

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

    };
    buttons {
    compatible = "gpio-keys";

    button3: button_3 {
    gpios = <&gpio0 25 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    label = "Push button switch 3";
    zephyr,code = <INPUT_KEY_3>;
    };
    };
    aliases {
    led2 = &led2;
    sw3 = &button3;
    };

    Thank you Oyvind for suggesting to use the devkit and thank you for your answers to my questions ! 
Reply
  • Hi, I managed to implement DFU over USB using CDC ACM in Serial Recovery mode (nRF connect SDK v3.0.0 and toolchain version v3.0.2)

    I had two problems : 

    1: The person who did our schematic for our custom board put 3.3V at the VBUS entry of the nRF52840. This low voltage compared to the lower USB threshold (approximately 4.3V) made the USB not avaliable/work properly on our board.

    2: Using a nRF52840 DK (dev. kit), we managed to perform DFU over USB but the Nordic Lesson 9 (Exercise 4 – DFU over USB - Nordic Developer Academy) alone isn't sufficient to perform DFU over USB even with the nRF52840 DK (due to missing configurations that are not properly stated). For the next person who wants to implement it, here are the files and files content that were required in our side:

    First, the steps in Lesson 8, Sysbuild, Exercice 1 (Exercise 1 - Configuring extra image - Nordic Developer Academy) need to be done in order to have a MCBboot image functionnal, have the sysbuild.conf file, and the mcuboot.conf file. However, set CONFIG_SERIAL in mcuboot.conf to yes ! (i.e.: CONFIG_SERIAL=y) . Add also mcuboot.overlay the same way mcuboot.conf was added in the folder sysbuild. At the end, you should be left with a workspace folder that looks like that (if you are using VSCode):




    Second, configure the above added files with the following content:


    sysbuild.conf:

    SB_CONFIG_BOOTLOADER_MCUBOOT=y
    SB_CONFIG_MCUBOOT_MODE_SINGLE_APP=y

    mcuboot.conf:
    CONFIG_LOG=y
    CONFIG_MCUBOOT_LOG_LEVEL_INF=y
    CONFIG_UART_CONSOLE=n
    CONFIG_MCUBOOT_INDICATION_LED=y
    CONFIG_MCUBOOT_SERIAL=y
    CONFIG_BOOT_SERIAL_UART=y
    CONFIG_BOOT_SERIAL_CDC_ACM=y
    CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x10000
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PRODUCT="Zephyr CDC ACM sample"
    CONFIG_USB_DEVICE_PID=0x0001
    CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
    CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
    CONFIG_SERIAL=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_UART_LINE_CTRL=y

    CONFIG_USB_CDC_ACM=y
    CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n


    mcuboot.overlay:
    / {
        aliases {
            mcuboot-button0 = &button3;
            mcuboot-led0 = &led2;
        };
    };

    /* STEP 2.1 - Configure CDC ACM */
    &zephyr_udc0 {
        cdc_acm_uart0: cdc_acm_uart0 {
            compatible = "zephyr,cdc-acm-uart";
        };
    };

    For our custom board, we also addded the following node in our board default dts file:
    zephyr_udc0: &usbd {
    compatible = "nordic,nrf-usbd";
     status = "okay";
    };
    (those lines are not required in the Dev. Kit., only for custom board, since the nRF52840DK board dts file is already configured with proper nodes)
    Again, for a custom board, don't forget to add the node for the button and led responsible for going into MCUboot (button3) and display that we are in the boot image (led2) in the board dts file (DO NOT ADD THEM IN THE MAIN APP OVERLAY, THIS SHOULD BE ADDED IN THE BOARD DTS FILE, since the app overlay is not shared with the MCUboot build image):
    leds {
    compatible = "gpio-leds";

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

    };
    buttons {
    compatible = "gpio-keys";

    button3: button_3 {
    gpios = <&gpio0 25 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    label = "Push button switch 3";
    zephyr,code = <INPUT_KEY_3>;
    };
    };
    aliases {
    led2 = &led2;
    sw3 = &button3;
    };

    Thank you Oyvind for suggesting to use the devkit and thank you for your answers to my questions ! 
Children
No Data
Related