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

Relating COM port name and Segger ID

Dear Fellow developers

I am developing an application where I need several nrf51 USB dongles (S120) attached to a PC, and I need a way to distinguish one dongle from another. I am using the ble_driver_win_0.3.0 S120 softdevice with unmanaged C++ on a win8 PC.

An easy way of distinguishing the dongles is by their Segger ID, which is needed anyway for resetting the dongle using nrfjprog. Problem is, how do I know which COM port they are on?

In the ‘Master Emulator’ (managed-) dll there is a function called something like ‘Enumerate Dongles’ which I suppose does exactly this, but unfortunately the same function does not exist in the ble_driver_win_0.3.0.

My first idea to solve the problem is to read the MAC address on each dongle by using nrfjprog, and then opening each COM port and read the MAC address using the ble_driver_win_0.3.0 dll, but this seems like a long way around a relative small problem.

Do you have any suggestions to how I relate COM ports and Segger IDs?

Parents
  • One way is to use the Windows Registry:

    SYSTEM\CurrentControlSet\Enum\USB

    Search for "VID_1366" and then take a look at the layout of the Registry tree.

    Here's some sample code in C# to do this:

    public bool getCOMPort(string snr, out string com)
    {
      snr = snr.Trim();
      com = "NOT_SET";
      string segger_id_pidprefix = "";
      Dictionary<string, string> com_ports = new Dictionary<string, string>();
      string ROOT = "SYSTEM\\CurrentControlSet\\Enum\\USB";
    
      using (RegistryKey key = Registry.LocalMachine.OpenSubKey(ROOT))
      {
        foreach (var segger_root_entry in key.GetSubKeyNames())
        {
          // Filter on Segger Vendor ID
          if (! segger_root_entry.StartsWith("VID_1366")) continue;
    
          using (RegistryKey segger_root_key = Registry.LocalMachine.OpenSubKey(ROOT + "\\" + segger_root_entry))
          {
            foreach (var segger_entry in segger_root_key.GetSubKeyNames())
            {
              using (RegistryKey segger_key = Registry.LocalMachine.OpenSubKey(ROOT + "\\" + segger_root_entry + "\\" + segger_entry))
              {
                string service = Convert.ToString(segger_key.GetValue("Service"));
                if (service == "usbccgp")
                {
                  var segger_entry_trimmed = segger_entry.TrimStart('0');
                  Console.WriteLine("usbccgp " + segger_entry_trimmed + " - " + Convert.ToString(segger_key.GetValue("ParentIdPrefix")));
                  if (segger_entry_trimmed.StartsWith(snr))
                  {
                    if (segger_id_pidprefix != "")
                    {
                      Console.WriteLine("Error: Found more than one usbccgp entry for snr");
                    }
                    segger_id_pidprefix = Convert.ToString(segger_key.GetValue("ParentIdPrefix"));
                  }
                }
                if (service == "usbser" || service == "JLinkCDC_x64")
                {
                  using (RegistryKey dev_param_key = Registry.LocalMachine.OpenSubKey(ROOT + "\\" + segger_root_entry + "\\" + segger_entry + "\\Device Parameters"))
                  {
                    if (dev_param_key == null) continue;
    
                    string portname = Convert.ToString(dev_param_key.GetValue("PortName"));
                    com_ports[segger_entry] = portname;
                    Console.WriteLine("usbser " + segger_entry + " - " + portname);
                  }
                }
              }
            }
          }
        }
      }
    
      Console.WriteLine("segger_id_pidprefix " + segger_id_pidprefix);
    
      if (segger_id_pidprefix == "")
      {
        Console.WriteLine("Error: Could not find com port (empty pidprefix) for " + snr);
        return false;
      }
    
      foreach (var item in com_ports)
      {
        if (item.Key.StartsWith(segger_id_pidprefix))
        {
          com = item.Value;
          Console.WriteLine("Found com " + com);
          return true;
        }
      }
      Console.WriteLine("Error: Could not find com port (unknown pidprefix) for " + snr);
      return false;
    }
    

    Carles

  • If you open nRFgo Studio the Device Manager window will tell if the Segger ID is a nRF51 Development board or dongle, so surely there is some mechanism to find out. You should ask on the forum :) EDIT: I've searched the registry and found that the value of VID_1366&PID_1015<Segger_ID>\Capabilities are different between my development board and dongles. On the development board Capabilities has a value of 0x00000090 (144) and on my three dongles Capabilities has a value of 0x00000094 (148). I don't know if this is reliable data, but it is the only thing I can find separating dongles from boards in the registry.

Reply
  • If you open nRFgo Studio the Device Manager window will tell if the Segger ID is a nRF51 Development board or dongle, so surely there is some mechanism to find out. You should ask on the forum :) EDIT: I've searched the registry and found that the value of VID_1366&PID_1015<Segger_ID>\Capabilities are different between my development board and dongles. On the development board Capabilities has a value of 0x00000090 (144) and on my three dongles Capabilities has a value of 0x00000094 (148). I don't know if this is reliable data, but it is the only thing I can find separating dongles from boards in the registry.

Children
No Data
Related