Need help finding documentation or tutorial that explains USB CDC ACM.

I want to create a virtual com port on my pc from my nRF52840 dongle program. And direct the output of printx statements to it so I can monitor it with putty.

I have tried very diligently to search for this information on your website; I get covered up with hits, all, seemingly irrelevant. For the life of me I don't understand how anyone ever finds anything in your documentation.  I can search on terms like "nRF52 USB CDC ACM tutorial" and your search engine ignores the quotes and I get over 700 hits.

I have also tried to search your examples for this information with no success.  Why is it so dang hard to find information here?

Jerry

  • The following is a program from the BLE tutorial; I post it here because it does what I want to in that it causes the device driver on my PC to create a virtual com port, COM10, and directs the output of the printk statements to it.  I have carefully gone through the code but I can't figure out how it works, can someone explain how this works?

    /*
    * Copyright (c) 2023 Nordic Semiconductor ASA
    *
    * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    */


    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/gap.h>
    #include <dk_buttons_and_leds.h>

    /* STEP 2.1 - Declare the Company identifier (Company ID) */
    #define COMPANY_ID_CODE 0x0059

    /* STEP 2.2 - Declare the structure for your custom data */
    typedef struct adv_mfg_data {
    uint16_t company_code; /* Company Identifier Code. */
    uint16_t number_press; /* Number of times Button 1 is pressed*/
    } adv_mfg_data_type;

    #define USER_BUTTON DK_BTN1_MSK

    /* STEP 1 - Create an LE Advertising Parameters variable */
    static struct bt_le_adv_param *adv_param = BT_LE_ADV_PARAM(BT_LE_ADV_OPT_NONE, /* No options spesified*/
    800, /*Min Advertising Interval 500ms (800*0.625ms) */
    801, /*Max Advertising Interval 500.625ms (801*0.625ms)*/
    NULL); /* Set to NULL for undirected advertising*/

    /* STEP 2.3 - Define and initialize a variable of type adv_mfg_data_type */
    static adv_mfg_data_type adv_mfg_data = {COMPANY_ID_CODE,0x00};

    static unsigned char url_data[] ={0x17,'/','/','a','c','a','d','e','m','y','.','n','o','r','d','i','c','s'
    LOG_MODULE_REGISTER(Lesson2_Exercise2, LOG_LEVEL_INF);

    #define DEVICE_NAME CONFIG_BT_DEVICE_NAME
    #define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)

    #define RUN_STATUS_LED DK_LED1
    #define RUN_LED_BLINK_INTERVAL 1000

    static const struct bt_data ad[] = {
    BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR),
    BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
    /* STEP 3 - Include the Manufacturer Specific Data in the advertising packet. */
    BT_DATA(BT_DATA_MANUFACTURER_DATA,(unsigned char *)&adv_mfg_data, sizeof(adv_mfg_data)),
    };

    static const struct bt_data sd[] = {
    BT_DATA(BT_DATA_URI, url_data,sizeof(url_data)),
    };
    /* STEP 5 - Add the definition of callback function and update the advertising data dynamically */
    static void button_changed(uint32_t button_state, uint32_t has_changed)
    {
    printk("Button Pressed, button_state = %d, has_changed = %d USER_BUTTON = %d, adv_mfg_data.number_pres
    if (has_changed & button_state & USER_BUTTON) {
    adv_mfg_data.number_press += 1;
    bt_le_adv_update_data(ad, ARRAY_SIZE(ad),
    sd, ARRAY_SIZE(sd));
    }
    }
    /* STEP 4.1 - Define the initialization function of the buttons and setup interrupt. */
    static int init_button(void)
    {
    int err;

    err = dk_buttons_init(button_changed);
    if (err) {
    printk("Cannot init buttons (err: %d)\n", err);
    }

    return err;
    }

    void main(void)
    {
    int blink_status = 0;
    int err;

    LOG_INF("Starting Lesson 2 - Exercise 1 \n");

    err = dk_leds_init();
    if (err) {
    LOG_ERR("LEDs init failed (err %d)\n", err);
    return;
    }
    /* STEP 4.2 - Setup buttons on your board */
    err = init_button();
    if (err) {
    printk("Button init failed (err %d)\n", err);
    return;
    }

    err = bt_enable(NULL);
    if (err) {
    LOG_ERR("Bluetooth init failed (err %d)\n", err);
    return;
    }

    LOG_INF("Bluetooth initialized\n");

    err = bt_le_adv_start(adv_param, ad, ARRAY_SIZE(ad),
    sd, ARRAY_SIZE(sd));
    if (err) {
    LOG_ERR("Advertising failed to start (err %d)\n", err);
    return;
    }

    LOG_INF("Advertising successfully started\n");

    for (;;) {
    dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
    k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
    }
    }

  • Hi, I will look into this case and return with more information tomorrow

    Regards,
    Sigurd Hellesvik

  • Jerry Easley said:
    he following is a program from the BLE tutorial

    Which BLE tutorial?

    I can search on terms like "nRF52 USB CDC ACM tutorial" and your search engine ignores the quotes and I get over 700 hits.

    As an alternative, you can use google with "site". It sometimes returns better results.

    To create a sample which might be useful to you, I did the following:

    nRF Connect SDK v2.3.0.

    Use the Hello World sample as a base.

    Copy the app.overlay and prj.conf from Console over CDC ACM UART Sample into Hello World.
    Add usb_enable() to hello world.
    Add hello world printk into loop

    I tested this on a DK, so I think that it should work on the dongle as well:

    hello_world_over_cdc_acm.zip

    Regards,
    Sigurd Hellesvik

  • The BLE tutorial, "

    Bluetooth Low Energy Fundamentals

    " is here: https://academy.nordicsemi.com/topic/blefund-lesson-2-exercise-1/

    You can get the example programs here: https://github.com/NordicDeveloperAcademy/bt-fund.git

    Each Lesson Exercise comes with two source files a student working copy and a solution copy; I am working with the solution copy.

    I am sure the solution you provided will work for me; I haven't had a chance to try it; I'll try it straight away and give you some feedback. Thank you so much for your efforts.

    Regards,

    Jerry

  • Hi Sigurd,

    Your example works great! Thank You ever so much!

    Regards,

    Jerry

Related