FTDI Community

Please login or register.

Login with username, password and session length.
Advanced Search  


Welcome to the FTDI Community!

Please read our Welcome Note

Technical Support enquires
please contact the team
@ FTDI Support

New Bridgetek Community is now open

Please note that we have created the Bridgetek Community to discuss all Bridgetek products e.g. EVE, MCU.

Please follow this link and create a new user account to get started.

Bridgetek Community

Show Posts

You can view here all posts made by this member. Note that you can only see posts made in areas to which you currently have access.

Messages - earnie

Pages: [1]
I have 11 UART Serial Adapter Cables of the following types that are logging information simultaneously from 11 microcontrollers:


I have written a simple terminal application that can handle 11 com port connections simultaneously and writes all the received ASCII-characters in the same window row-by-row. I sometimes find that ASCII-text from two different microcontrollers are received in the wrong order and I believe this has something to do with the fact that USB likes to wait for a certain amount of bytes before sending the packet. My question is, if I switch from using VCP-driver to the D2XX-driver, would this likely improve so all the text in my terminal window would appear in chronological order?

The D2XX driver is used to program the device parameters like serial number and description.
Using the VCP-driver, I can view the serial number in the Device Manager by right-clicking -> Properties -> Details tab -> choosing Device instance path in the Property combobox. Can I do something similar to view the contents of the description you're referring to, in the Device Manager when using VCP-driver? Everything I'm able to view in the Device Manager, my C# application can view as well. So my idea is that I program the EEPROM using the D2XX-driver, but once the EEPROM is programmed, from then on I only use the VCP-driver.

What you could do is use FT_PROG to change the Product Description of Serial Number.
Then you could create a simple D2XX program to open by serial number or description.
See the D2XX Programmer's Guide for more information.
Note that this Product Description name change won’t be shown in Device Manager but allows you to program a unique description which can be read through the D2XX APIs.
For example:

ftStatus = FT_OpenEx("Mike's 3 MBaud cable",FT_OPEN_BY_DESCRIPTION,&ftHandle);

Note that there is a limit of the number of characters used in the serial number, description, etc.
See section 4 EEPROM Programming Interface Functions in the D2XX Programmer's Guide.
With this approach I can't use the VCP driver during normal cable use (not during writing to the EEPROM), correct?

I guess a workaround would be to use the serial number (see code below) and then have a lookup table for the text description in a file, but if someone has a suggestion for a solution without the need for a lookup table then I'm still very interested.

Code: [Select]
public class ComPortEnumerator
    [DllImport("Setupapi", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SetupDiOpenDevRegKey(IntPtr hDeviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, uint scope,
        uint hwProfile, uint parameterRegistryValueKind, uint samDesired);

    private static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, Int32 MemberIndex, ref  SP_DEVINFO_DATA DeviceInterfaceData);

    [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern bool SetupDiGetDeviceInstanceId(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, StringBuilder DeviceInstanceId, UInt32 DeviceInstanceIdSize, out UInt32 RequiredSize);

    [DllImport("setupapi.dll", SetLastError = true)]
    private static extern IntPtr SetupDiGetClassDevs(ref Guid gClass, UInt32 iEnumerator, IntPtr hParent, UInt32 nFlags);

    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegQueryValueExW", SetLastError = true)]
    private static extern int RegQueryValueEx(IntPtr hKey, string lpValueName, int lpReserved, out uint lpType,
        StringBuilder lpData, ref uint lpcbData);

    [DllImport("advapi32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int RegCloseKey(IntPtr hKey);

    private const UInt32 DIGCF_PRESENT    = 0x00000002;
    private const UInt32 DICS_FLAG_GLOBAL = 0x00000001;
    private const UInt32 DIREG_DEV        = 0x00000001;
    private const UInt32 KEY_QUERY_VALUE  = 0x0001;
    private const string GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR = "4D36E978-E325-11CE-BFC1-08002BE10318";

    private struct SP_DEVINFO_DATA
        public Int32 cbSize;
        public Guid ClassGuid;
        public Int32 DevInst;
        public UIntPtr Reserved;

    public static void logAllUsbToSerialCablesSerialNo()
        Int32 iMemberIndex = 0;
        while (true)
            SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA();
            deviceInfoData.cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
            IntPtr hDeviceInfoSet = SetupDiGetClassDevs(ref guidComPorts, 0, IntPtr.Zero, DIGCF_PRESENT);
            if (hDeviceInfoSet == IntPtr.Zero)
                // Failed to get device information set for the COM ports
            bool success = SetupDiEnumDeviceInfo(hDeviceInfoSet, iMemberIndex, ref deviceInfoData);
            if (!success)
                // No more devices in the device information set
            string comPortName = GetDeviceName(hDeviceInfoSet, deviceInfoData);
            string deviceInstancePath = ComPortEnumerator.getDeviceInstancePath(hDeviceInfoSet, deviceInfoData);
            string serialNo = ComPortEnumerator.extractSerialNoFromDeviceInstancePath(deviceInstancePath);
            Debug.WriteLine(comPortName + " has serial number " + serialNo);

    private static string getDeviceInstancePath(IntPtr hDeviceInfoSet, SP_DEVINFO_DATA deviceInfoData)
        StringBuilder descriptionBuf = new StringBuilder(256);
        uint length = (uint)descriptionBuf.Capacity;
        bool success = SetupDiGetDeviceInstanceId(hDeviceInfoSet, ref deviceInfoData,
          descriptionBuf, length, out length);
        if (!success)
            throw new Exception("Can not read the Device Instance Path for device " + deviceInfoData.ClassGuid);
        return descriptionBuf.ToString();

    public static string extractSerialNoFromDeviceInstancePath(string deviceInstancePath)
        if ((deviceInstancePath.Contains("VID_0403")) && (deviceInstancePath.Contains("PID_6001")))
        { // 3 MBaud USB-to-serial cable
          // Example: FTDIBUS\VID_0403+PID_6001+FT9FPQAKA\0000
          // The serial number is               FT9FPQAK
            return deviceInstancePath.Substring(26, 8);
        else if ((deviceInstancePath.Contains("VID_0403")) && (deviceInstancePath.Contains("PID_6014")))
        { // 12 MBaud USB-to-serial cable
          // Example: FTDIBUS\VID_0403+PID_6014+FT478YLWA\0000
          // The serial number is               FT478YLW
            return deviceInstancePath.Substring(26, 8);
        return "";

    private static string GetDeviceName(IntPtr pDevInfoSet, SP_DEVINFO_DATA deviceInfoData)
        IntPtr hDeviceRegistryKey = SetupDiOpenDevRegKey(pDevInfoSet, ref deviceInfoData,
        if (hDeviceRegistryKey == IntPtr.Zero)
            throw new Exception("Failed to open a registry key for device-specific configuration information");

        StringBuilder deviceNameBuf = new StringBuilder(256);
            uint lpRegKeyType;
            uint length = (uint)deviceNameBuf.Capacity;
            int result = RegQueryValueEx(hDeviceRegistryKey, "PortName", 0, out lpRegKeyType, deviceNameBuf, ref length);
            if (result != 0)
                throw new Exception("Can not read registry value PortName for device " + deviceInfoData.ClassGuid);

        string deviceName = deviceNameBuf.ToString();
        return deviceName;

I have several UART Serial Adapter Cables of the following types:


I would like to make it easier to identify all the different cables from within a home-made Windows application (it's written in C#, but it's capable of calling DLL-files). Is it somehow possible to assign the cables descriptive text strings such as "Mike's 3 MBaud cable", "John's 12 MBaud cable with power switch", "Kevin's UART cable with Tx/Rx tied together", etc in some non-volatile storage inside the cables? I read in the following manual https://ftdichip.com/wp-content/uploads/2020/08/D2XX_Programmers_GuideFT_000071.pdf that many settings can be modified, but I don't have enough USB knowledge to know which settings are safe to modify. It would be a bonus if the text descriptions also would show up in the Device Manager somewhere, either directly in the tree or if you'd go in and look under properties, but it's not a requirement. Typically, I use the standard VCP-drivers, but if there's a very specific reason to do so, I guess I could switch to a different driver and make my home-made Windows application install that driver automatically if it's not present on the computer (I don't like having to supply driver separately).

12       (divider = 0)
8         (divider = 1, special value fixed to 8Mbaud)
6         (divider = 2)
5.647    Sub integer dividers now begin to work

For calculating slower supported Baud rates, please see AN_120 "Aliasing VCP Baud Rates": https://ftdichip.com/wp-content/uploads/2020/08/AN_120_Aliasing_VCP_Baud_Rates.pdf

What Baud rates, except 12 MBaud, does C232HD-DDHSP-0 (https://ftdichip.com/products/c232hd-ddhsp-0/) support?

Pages: [1]