Shop OBEX P1 Docs P2 Docs Learn Events
USB COM Port Assignment — Parallax Forums

USB COM Port Assignment

coryco2coryco2 Posts: 107
edited 2012-01-21 16:46 in Propeller 1
Does anyone know how COM port numbers are assigned to Prop Plugs, USB Protoboards, etc. in Windows XP? I am guessing that the OS is doing it, and that each device retains a different port number? Is there some way to set the Prop Tool or FTDI driver to just use the same COM port for any Prop USB device plugged into it? I saw mention made in the forum that this can be done by editing something in the registry, but I have not been able to find any details about how to do it.

Comments

  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2012-01-21 16:24
    Here are typical registry keys for a FTDI device:
    [SIZE=1][FONT=arial]HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\FTDIBUS\VID_0403+PID_6001+[COLOR=#ff0000]A2002Yej[/COLOR]A
    ---ClassGUID = {[COLOR=#008080]4D36E978-E325-11CE-BFC1-08002BE10318[/COLOR]}
    
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\FTDIBUS\VID_0403+PID_6001+A2002YejA\0000\Device Parameters
    ---PortName=[COLOR=#800000]COM9
    [/COLOR]
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\Vid_0403&Pid_6001\[COLOR=#ff0000]A2002Yej
    [/COLOR]---Driver={4D36E978-E325-11CE-BFC1-08002BE10318}\[COLOR=#800080]0005
    [/COLOR]
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{[COLOR=#008080]4D36E978-E325-11CE-BFC1-08002BE10318[/COLOR]}\[COLOR=#800080]0005
    [/COLOR]---InfPath=oem26.inf
    ---ProviderName=FTDI
    [/FONT][/SIZE]
    
    You can see it gets a little tricky to find the details. I wrote a HTML application which enumerates ports for me and lets me assign unique names for each device.

    attachment.php?attachmentid=88801

    EnumPorts.hta
    <head>
    <title>Enum Ports</title>
    <HTA:APPLICATION 
         APPLICATIONNAME="Enum Ports"
         SCROLL="yes"
         SINGLEINSTANCE="yes"
         SysMenu="yes"
         ShowInTaskbar="yes"
         WindowState="normal"
         ICON="info.ico"
    >
    </head>
    <script language="javascript">
    function newwin(prttag, desc) {
      var nw;
      nw=window.open('','_blank', 'height=600,width=800,status=yes,scrollbars=yes,resizable=yes,toolbar=no,menubar=yes,location=no');
      var tb = document.getElementById(prttag);
      nw.document.write("<html>\n<head>\n<title>Print</title>\n");
    /*
      nw.document.write("<STYLE>A:hover{COLOR: #ff0000}");
      nw.document.write(".desc {FONT-SIZE: 12px; COLOR: dimgray;  FONT-FAMILY: Verdana, Arial, 'MS Sans Serif'}");
      nw.document.write(".desc B {FONT-SIZE: 12px; COLOR: darkred; FONT-WEIGHT: 500;  FONT-FAMILY: Verdana, Arial, 'MS Sans Serif'}");
      nw.document.write(".linkjump {FONT-SIZE: 12px; CURSOR: hand; COLOR: blue; FONT-FAMILY: Verdana; TEXT-DECORATION: underline}");
      nw.document.write("BODY {FONT-SIZE: x-small; FONT-FAMILY: Verdana, Courier, 'MS Sans Serif'}");
      nw.document.write("</STYLE>\n");
    */
      nw.document.write("<script language='javascript'>\nfunction newwin(){\nwindow.print();\n}\n<\/script>\n");
    //  nw.document.write("</head>\n<body bgcolor=blue onload='window.print();'>\n");
      nw.document.write("</head>\n<body bgcolor=white>\n");
      nw.document.write("\n<center><font color=crimson size=3><b><i>" + desc + "</i></b></font>\n");
    //  nw.document.write("&nbsp;&nbsp;<img align=absmiddle onClick='newwin()' alt='print' src='images/print_icon.gif' border=0></center>");
      nw.document.write(tb.innerHTML);
      nw.document.write("\n</body>\n</html>");
    //  nw.document.getElementById('maintab').style.color = 'black';
      nw.document.close();
      nw.status='Print Window';
      nw.focus();
    }
    //-->
    </script>
    <script language="VBScript">
      option explicit
      Const HKEY_CURRENT_USER = &H80000001
      Const HKEY_LOCAL_MACHINE = &H80000002
      Const TemporaryFolder = 2
      Const ForWriting = 2
      Const REG_SZ = 1
      Const REG_EXPAND_SZ = 2
      Const REG_BINARY = 3
      Const REG_DWORD = 4
      Const REG_DWORD_LITTLE_ENDIAN = 4
      Const REG_DWORD_BIG_ENDIAN = 5
      Const REG_LINK = 6
      Const REG_MULTI_SZ = 7
      Const REG_RESOURCE_LIST = 8
      Const REG_FULL_RESOURCE_DESCRIPTOR = 9
      Const REG_RESOURCE_REQUIREMENTS_LIST = 10
      Dim strComputer, oReg, strKeyPath, WSHShell, WinVer
      Dim objDict, objKeys, objArray, loop1, loop2
      Dim hkey, strHTML
      Set WSHShell = CreateObject("WScript.Shell")
      dim lvl 
    Function OsVer 
      dim objWMIService, colOS, objOS
      OsVer = ""
      strComputer = "."
      Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
      Set colOS = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem")
      For Each objOS in colOS
    '    Msgbox objOS.Caption & " " & objOS.Version, 0 + 32,"Window Version " & objOS.OSType
        select case objOS.OSType
          case 17
            OsVer = "98"
            exit function 
          case 18
            OsVer = "XP"
            exit function 
        end select    
      Next 
    end function
    Sub Enum_Ports
      strComputer = "."
      hkey = HKEY_LOCAL_MACHINE
      strKeyPath = "SYSTEM\CurrentControlSet\Enum" 
      Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
      strHTML = strHTML & "<TABLE name=oTab id = oTab border='1' style='border-collapse: collapse; FONT-SIZE: 12px; COLOR: #020FC0; FONT-FAMILY: verdana' width='100%'>"
      strHTML = strHTML & "<THEAD><TR><TH>Port Name</TH><TH>Device Desc</TH><TH>Driver</TH><TH>Friendly Name</TH><TH>Class</TH>" 
      strHTML = strHTML & "</TR></THEAD><TBODY>"
      Set objDict = CreateObject("Scripting.Dictionary")
      Call CreateDictionary
      objKeys = objDict.Keys    
      Call SortDict
       For loop1 = 0 To UBound(objKeys)
          objArray = Split(objDict.Item(objKeys(loop1)) , vbTab, -1, 1)
          strHTML = strHTML & "<TR><TD>" & objKeys(loop1) & "</TD><TD" 
          if objArray(3) <> "" then 
            strHTML = strHTML & " onmouseover=""this.style.cursor='vertical-text'"" id=row" & loop1 & " onclick=""UpdDesc(" & loop1 & ")"">" & objArray(3)  
    '        strHTML = strHTML &  ">" & objArray(3) 
          else
            strHTML = strHTML & ">" & objArray(0)
          end if
          strHTML = strHTML & "&nbsp;</TD><TD>" & objArray(4) & "&nbsp;</TD><TD>" &  objArray(1) & "&nbsp;</TD><TD>" & objArray(2) &  "&nbsp;</TD></TR>"
       Next
      strHTML = strHTML & "</TBODY></TABLE>"
      tbarea.InnerHTML = strHTML
      document.body.style.cursor = "default"
    End Sub
    Sub CreateDictionary
       Dim sPath
       Dim classpath  
       Dim arrClassTypes, arrDevices  
       Dim classType
      oReg.EnumKey hkey, strKeyPath, arrClassTypes
      if vartype(arrClassTypes) = vbNull then
        msgbox strKeyPath, vbcritical, "Null Class type"
      end if
      For Each classType in arrClassTypes                     
         sPath =  strKeyPath & "\" & classType
         oReg.EnumKey hkey, sPath, arrDevices
         if vartype(arrDevices) = vbNull then
         else
           lvl = 0 
           Recurse arrDevices, sPath, classType 
         end if
      Next
    End Sub
    Sub Recurse(arrItems, subPath, classType)
       Dim Item, nxtPath, arrSubItems, rc, USBdesc
       Dim FriendlyName, PortName, DeviceDesc, Classname
       Dim dpath, Driver, INF
       For each Item in arrItems
    '     msgbox subPath & vbcrlf & item, , classType & " >> " & len(item)
    '     if lvl = 0 then
    '       msgbox subPath & vbcrlf & item, , classType & " " & len(item)
    '       if len(item) = 0 then 
    ''         msgbox item, , classType & " " & len(item)
    '         exit sub
    '       end if
    '       if classType = "HID" then
    '         exit sub
    '       end if
    '     end if
         nxtPath =  subPath & "\" & Item
         rc = oReg.GetStringValue(hkey,  nxtPath, "FriendlyName", FriendlyName)
         rc = oReg.GetStringValue(hkey,  nxtPath, "DeviceDesc", DeviceDesc)
         if lvl = 1 then
           rc = oReg.GetStringValue(hkey,  nxtPath, "Driver", Driver)
           dpath = "SYSTEM\CurrentControlSet\Control\Class" & "\" & Driver
           rc = oReg.GetStringValue(hkey,  dpath, "InfPath", INF)
    '       msgbox  dpath & vbcrlf & Driver & vbcrlf & INF, , rc
         end if 
         if classType = "FTDIBUS" then
           if lvl = 1 then
             USBDesc = FTDIDevice(nxtPath)    
           end if
         else
            USBdesc = ""
         end if
         rc = oReg.GetStringValue(hkey,  nxtPath, "Class", ClassName)
         rc = oReg.GetStringValue(hkey,  nxtPath & "\Device Parameters", "PortName", PortName)
         if len(PortName) > 0 then  
           if objDict.Exists(PortName) Then
           else
            objDict.Add PortName, DeviceDesc & vbtab & FriendlyName & vbtab & ClassName & vbtab & USBdesc & vbtab & INF
           end if 
         end if
         oReg.EnumKey hkey, nxtPath, arrSubItems
         if vartype(arrSubItems) = vbNull then
    '        msgbox subPath,vbcritical, "Null SubItems"
         else
           lvl = lvl + 1
           Recurse arrSubItems, nxtPath, classType 
         end if
      Next
      lvl = lvl - 1
    End Sub
    Function FTDIDevice(path)
      dim usb, devid, idx, upath, descrip, rc
      devid = replace(path, "SYSTEM\CurrentControlSet\Enum\FTDIBUS\VID_0403+PID_6001+", "")
      devid = replace(devid, "SYSTEM\CurrentControlSet\Enum\FTDIBUS\VID_0403+PID_BD90+", "")
      devid = replace(devid, "\0000", "") 
      rc = oReg.GetStringValue(HKEY_LOCAL_MACHINE,  "SOFTWARE\FTDI Devices", devid, descrip)
      if rc = 0 then
         FTDIDevice = descrip & " (" & devid & ")"  
      else
         FTDIDevice = "FTDI ????" & " (" & devid & ")"  
      end if
    end function
    '**********************
    Sub SortDict         'bubble sort 
      For loop1 = UBound(objKeys) to  LBound(objKeys) Step -1
        For loop2 =( LBound(objKeys) + 1) to loop1
           If ucase(objKeys(loop2 - 1)) > ucase(objKeys(loop2)) Then
             Call Swap(objKeys(loop2 - 1), objKeys(loop2))
           End If
        Next
      Next 
    End Sub
    Sub Swap(byref item1, byref item2)
      Dim temp 
      temp = item1
      item1 = item2
      item2 = temp
    End Sub
    Sub Window_Onload
      dim iTimerID
      WinVer = OsVer
      if OsVer <> "XP" then
        iebutton.InnerHTML = "&nbsp;"    
      end if
    '  WSHShell.popup "Collecting information" & vbcrlf & "This could take several seconds", 3, "Please Wait",  vbInformation       'wait seconds
      document.body.style.cursor = "wait"
      tbarea.InnerHTML = "<Center>Collecting information<br>This could take several seconds</center>"
      iTimerId=window.setTimeout("Enum_Ports", 5, "VBScript")
    '  Enum_Ports
    End Sub
    Sub UpdDesc(rowid)
      dim keyid, i, j, currdesc, newdesc, rc, devrow
      set devrow = document.getElementById("row" & rowid)          
      currdesc = devrow.innerText
      keyid = currdesc
      i = instr(keyid, "(")
      if i > 0 then
        keyid = mid(keyid, i+1)
        j = instr(keyid, ")")
        if j > 0 then
          keyid = mid(keyid, 1, j-1)
          newdesc = inputbox("Enter description for: " & keyid, "Update FTDI device description", trim(left(currdesc, i-1)))
          if newdesc <> "" then
              rc = oReg.SetStringValue(HKEY_LOCAL_MACHINE,  "SOFTWARE\FTDI Devices", keyid, newdesc)
              if rc = 0 then
                devrow.innerText = newdesc & " (" & keyid & ")"
              end if
          end if 
        end if
      end if       
    End sub
    </script>
    <body>
      <center>
        <br>
        <input type="button" value="Print" onclick="javascript:window.print();">
        <span id=iebutton name=iebutton>
          <input type="button" id=ieopen name=ieopen value="Open in IE" onclick="javascript:newwin('tbarea',  'Ports')">
        </span>
      </center>
      <br>
      <span id=tbarea name=tbarea>&nbsp;</span>
    </body>
    
    

    EnumPorts.jpg
    952 x 388 - 99K
  • Cluso99Cluso99 Posts: 18,069
    edited 2012-01-21 16:35
    Each propplug (actually the FTDI chip) has an inbuilt serial number and windows uses this to define a different port to each propplug. This is by design to allow multiple usb devices which may be the same. Perhaps you can change the device id on the ftdi chip - see the ftdi website app notes.
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2012-01-21 16:46
    Here is a thread that I posted last summer that explains how to re-assign a USB com port number...

    http://forums.parallax.com/showthread.php?133923-DEMO-Microsoft-Word-2010-gt-Propeller-communication ... <-- See "Almost There!!!"
    In the Windows Device Manager Control Panel:
    
    Start --> Control Panel --> System --> Hardware --> Device Manager
    
    ...Click on the &#8220;+&#8221; to Ports (COM & LPT) to expand it. Find the USB serial port that matches what the Propeller IDE indicated.
    
    Right Click on that item and select Properties --> Port Settings --> Advanced
    
    Under the COM Port Number: Change it to something less than or equal to 16 ... ignore the (in use) unless you know it's a specific port that your system is using. (You can always change it back)
    
    Click OK, and ignore the in use warning if applicable.
    
    The Windows Device Manager Control Panel will still probably show the original value until you refresh it (close, and re-open) ... that's ok, we're done with the Device manager.
    



    Note: I just tested it with two different Propeller Demo Boards that by default had enumerated to COM9 and COM10 .... I changed them (ignoring the warning) so that they were both pointing to COM9. As far as the warning is concerned, this should work as long as you don't have them both plugged in at the same time.
Sign In or Register to comment.