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

NRF52840 DK - Connecting to Windows with x2 different dev boards results in the same COM port being assigned

The issue:

1) Program x2 NRF52840 dev boards 

2) comment board A to windows, windows reports COM n

3) unplug board A and connect board B

4) windows reports the same COM port as board A

5) I have to have x2 boards connected to the same PC in order to test an NRF52840 based product, each board is switched on/off independently so 

 

Is there any way of programming a unique serial number into the NRF52840 Dev board for the USB serial device so windows assign a different Com Port for each device?

Please note I am using the correct port (the one on the side), Serial comms is working OK its just that all boards appear as the same number when connected.

Parents
  • Hello,

    Windows should enumerate the different COM devices to different COM ports, so if it doesn't, I guess you have to look this up in a Windows forum. 

    I found a couple of links that you can look into:

    https://superuser.com/questions/1587613/windows-10-two-serial-usb-devices-were-given-an-identical-port-number

    https://www.rbdinstruments.com/blog/resolving-usb-conflicts-with-virtual-com-ports/

    Try to change the com port manually using Device Manager, right click the device you want to change, select properties, go to the port settings tab, select "Advanced", change the COM port Number, click OK:

    Best regards,

    Edvin

  • @Edvin Have you seen my replies?  For information I called app_usbd_serial_num_generate(void) but it does not create a unique USB serial number.  Just the VID and PID exist when connecting the device as before.  

    Could you confirm if my understanding of this app_usbd_serial_num_generate(void) API is correct?  i.e. calling it should generate a USB Serial number?

  • We use the USB port on the long side of the NRF52840 dev board:

    The settings for this port are done programmatically within the application using the API

    static const app_usbd_config_t usbd_config = {
    .ev_isr_handler = usb_new_event_isr_handler,
    .ev_state_proc = usbd_user_ev_handler
    };

    ret = app_usbd_init(&usbd_config);

    We also Call app_usbd_serial_num_generate(void)

    If this Comm Port belongs to the programming chip why are there API's in the SDK to control the Com Port?

    Our intention was to eventually use application on the smaller Dongle without the Debugger, The Com port appearing when the dongle (below) is connected.

  • DaveC said:
    If this Comm Port belongs to the programming chip why are there API's in the SDK to control the Com Port?

     No, sorry. I assumed you meant the other USB port. This is the nRF's USB peripheral COM port.

    I am not sure exactly what you mean is missing in the COM settings. If you program an unmodified version of the SDK17.0.2\examples\peripheral\usbd_cdc_acm to two different DKs, do they not appear as two different COM ports?

    The reason I brought up the windows links in the first reply was that at one point my home computer also got the same COM port on two different programmer chip USB ports (two different DKs), but I changed one of them, and then it was fine. 

     

    DaveC said:
    Our intention was to eventually use application on the smaller Dongle without the Debugger, The Com port appearing when the dongle (below) is connected.

     The COM port will also change depending on the USB descriptor in the application. You have maybe noticed that the Dongle will have a different COM port when it is in bootloader mode and when it is running an application.

    Best regards,

    Edvin

  • The issue seems to be with function void app_usbd_serial_num_generate(void), this sets a global variable uint8_t g_extern_serial_number[SERIAL_NUMBER_STRING_SIZE + 1];

    This Variable is Not referenced anywhere in the sdk_config.h file, though some example code does show it referenced in 

    sdk_config.h (6,400)
    // <i> Note: This value is not editable in Configuration Wizard.
    // <i> Serial number that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
    #ifndef APP_USBD_STRING_SERIAL
    #define APP_USBD_STRING_SERIAL g_extern_serial_number
    #endif

  • What example do you refer to?

    The usbd_cdc_acm example doesn't have this define on that line number, but I'll use that example as reference for now.

    sdk_config.h line 1304:

    // <s> APP_USBD_STRING_SERIAL - String descriptor for the serial number.
    
    // <i> Note: This value is not editable in Configuration Wizard.
    // <i> Serial number that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
    #ifndef APP_USBD_STRING_SERIAL
    #define APP_USBD_STRING_SERIAL g_extern_serial_number
    #endif

    g_extern_serial-number is defined in app_usbd_serial_num.c, line 54:

    uint8_t g_extern_serial_number[SERIAL_NUMBER_STRING_SIZE + 1];

    SERIAL_NUMBER_STRING_SIZE is defined in the same file, line 48:

    uint8_t g_extern_serial_number[SERIAL_NUMBER_STRING_SIZE + 1];

    The function app_usbd_serial_num_generate() generates the serial number based on the FICR->DEVICEADDR[0] and [1]:

    void app_usbd_serial_num_generate(void)
    {
        char serial_number_string[SERIAL_NUMBER_STRING_SIZE + 1];
        const uint16_t serial_num_high_bytes = (uint16_t)NRF_FICR->DEVICEADDR[1] | 0xC000; // The masking makes the address match the Random Static BLE address.
        const uint32_t serial_num_low_bytes  = NRF_FICR->DEVICEADDR[0];
    
        (void)snprintf(serial_number_string,
                       SERIAL_NUMBER_STRING_SIZE + 1,
                       "%04"PRIX16"%08"PRIX32,
                       serial_num_high_bytes,
                       serial_num_low_bytes);
    
        string_create(serial_number_string);
    }

    And the last function call in app_usbd_serial_num_generate(), string_create() copies this string to the g_extern_serial_number:

    static void string_create(char * p_serial_number_string)
    {
    
        for (uint32_t i = 0; i < strlen(p_serial_number_string); i++)
        {
            g_extern_serial_number[i] = (uint8_t)p_serial_number_string[i];
        }
    }

    Does it not do that in your case? If so, what SDK version are you using? As mentioned, I am using SDK17.0.2.

    I am sorry if this is already obvious for you, but in that case, I failed to understand your question. I am sorry.

    Best regards,

    Edvin

  • No problem, I appreciate your help.  We are on V16.0.0 of the SDK. I have got as far as:

    1) Call app_usbd_serial_num_generate().  This generates a serial number and copies it to  g_extern_serial_number

    2) This works OK,  g_extern_serial_number is referenced by several #defines, eventually ends up being mapped to #define APP_USBD_STRING_ID_SERIAL 

    3) #define APP_USBD_STRING_ID_SERIAL is referenced inside app_usbd_core.c, this library being enabled with #define APP_USBD_ENABLED (which I have done)

    3) Inside app_usbd_core.c #define APP_USBD_CORE_DEVICE_DESCRIPTION references define APP_USBD_STRING_ID_SERIAL along with many other USB configuration parameters.

    So, having created a unique serial number in step 1) how do I use the library functions in app_usbd_core.c to update the USB serial number on the driver?

Reply
  • No problem, I appreciate your help.  We are on V16.0.0 of the SDK. I have got as far as:

    1) Call app_usbd_serial_num_generate().  This generates a serial number and copies it to  g_extern_serial_number

    2) This works OK,  g_extern_serial_number is referenced by several #defines, eventually ends up being mapped to #define APP_USBD_STRING_ID_SERIAL 

    3) #define APP_USBD_STRING_ID_SERIAL is referenced inside app_usbd_core.c, this library being enabled with #define APP_USBD_ENABLED (which I have done)

    3) Inside app_usbd_core.c #define APP_USBD_CORE_DEVICE_DESCRIPTION references define APP_USBD_STRING_ID_SERIAL along with many other USB configuration parameters.

    So, having created a unique serial number in step 1) how do I use the library functions in app_usbd_core.c to update the USB serial number on the driver?

Children
  • I agree that it is a bit difficult to see how/where it is used, but I believe it is something like:

    app_usbd_core_event_handler()

    case APP_USBD_EVT_DRV_SETUP:

    app_usbd_core_setup_req_handler()

    setup_device_req_std_handler()

    setup_device_req_get_descriptor()

    app_usbd_string_desc_get()

    app_usbd_prepare_string()

    m_string_dsc[], which uses 

    APP_USBD_STRING_SERIAL

    which is defined as g_extern_serial_number, 

    which is set by app_usbd_serial_num_generate().

    Have you checked that this behavior is replicateable on several computers? As mentioned, I do not see the same behavior on my Windows 10 machine. Each nRF has different COM ports, which stay the same accross power cycles.

    BR,
    Edvin

  • That's what I have, though to get it to build I had to declare "extern int g_extern_serial_number[]" in app_usbd_string_desc,c to avoid a compiler error.  g_extern_serial_number is not defined as extern in any header file.

    I'm looking at speading the tests which use the Dongle accross several PC's to avoid the port conflict issue.

Related