Accessing Multiple USB-Serial Devices using the Device Instance Path – KBA228257
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
Version: **
Translation - Japanese: デバイス インスタンス パスを使用した複数のUSBシリアル デバイスへのアクセス– KBA228257- Community Translated (JA)
Question:
How can a USB Serial Device be accessed when multiple devices are connected?
Answer:
When a USB-Serial part configured as I2C, SPI, or UART in vendor mode is connected to USB host, one or more devices will be enumerated based on the configuration.
Windows OS will assign a specific device enumeration index for each device during the device enumeration process. Also, this USB device enumeration process will create a unique Device Instance Path for every USB device. This Device Instance Path can be used to differentiate the devices with the same VID and PID by mapping the instance path of a device to its respective device enumeration index, with the help of the function defined in this article.
The GetDevicePath() function, defined below, takes the device enumeration index of a Cypress Device as a parameter, similar to the CyOpen and CyGetDeviceInfo APIs, and prints the Device Instance Path of that device using windows APIs.
Note: The setupapi library should be linked to the project. You can do this by adding setupapi.lib to the property page → Linker → Input → Additional Dependencies.
Code:
// Additional header file to be added
#include <setupapi.h>
// GetDevicePath Function
void GetDevicePath(int deviceNumber)
{
//Initialization
GUID CyDrvGuid = { 0xae18aa60, 0x7f6a, 0x11d4, 0x97, 0xdd, 0x0, 0x1, 0x2, 0x29, 0xb9, 0x59 }; // cyusb3 guid
SP_DEVINFO_DATA devInfoData;
SP_DEVICE_INTERFACE_DATA devInterfaceData;
PSP_INTERFACE_DEVICE_DETAIL_DATA functionClassDeviceData;
ULONG requiredLength = 0;
HDEVINFO hwDeviceInfo = SetupDiGetClassDevs((LPGUID)& CyDrvGuid, //Returns a handle to the device information set
NULL,
NULL,
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
if (hwDeviceInfo != INVALID_HANDLE_VALUE) { //checks if the handle is invalid
devInterfaceData.cbSize = sizeof(devInterfaceData); //get the size of devInterfaceData structure
//enumerates the device interfaces that are contained in a device information set
if (SetupDiEnumDeviceInterfaces(hwDeviceInfo, 0, (LPGUID)& CyDrvGuid,
deviceNumber, &devInterfaceData)) {
SetupDiGetInterfaceDeviceDetail(hwDeviceInfo, &devInterfaceData, NULL, 0,
&requiredLength, NULL);
ULONG predictedLength = requiredLength;
functionClassDeviceData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(predictedLength);
functionClassDeviceData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
devInfoData.cbSize = sizeof(devInfoData);
//Retrieve the information from Plug and Play including the device path
if (SetupDiGetInterfaceDeviceDetail(hwDeviceInfo,
&devInterfaceData,
functionClassDeviceData,
predictedLength,
&requiredLength,
&devInfoData)) {
wprintf(L"%ls\n", functionClassDeviceData->DevicePath); //Prints the device path of the required device
}
}
}
SetupDiDestroyDeviceInfoList(hwDeviceInfo);
}