pololu / libusbp

The Pololu USB Library (also known as libusbp) is a cross-platform C library for accessing USB devices.
Other
106 stars 34 forks source link

FTDI port number cannot be retrieved on Windows #10

Closed jporcher closed 1 year ago

jporcher commented 1 year ago

I'm plugging an FTDI based device, under Windows 10. When I plug it and use windows API SetupDiGetClassDevs/SetupDiEnumDeviceInfo/SetupDiGetDeviceRegistryProperty, I find device named FTDIBUS\COMPORT&VID_0403&PID_6001 with port name "COM8".

Now, when I use libusbp/lsport, the device is found (0403:6001 AR0JFBPE) but its port name cannot be identified, all call to try_print_port_name returns false. I even changed the loop parameter to test the 256 possible interface_number with no success.

DavidEGrayson commented 1 year ago

FTDI has their own proprietary drivers and they might do things differently from what libusbp is expecting. You should have a USB device somewhere in your device manager with a "Device instance path" that is something like "USB\VID_0403&PID_6001". In the Device Manager, please open the "View" menu and select "Devices by Connection". Then send screenshots showing both the USB device and all its descendants, and also the FTDIBUS device that you mentioned. I would like to see how these devices are related in the hierarchy.

jporcher commented 1 year ago

Here it is. "USB serial controller" is USB\VID_0403&PID_6001\AR0JFBPE "USB serial port (COM8)" is FTDIBUS\VID_0403+PID_6001+AR0JFBPEA\0000

Only the first one is enumerated by libusbp::list_connected_devices

ftdi

DavidEGrayson commented 1 year ago

OK, thanks for the info. The other USB-serial drivers I've seen do not make two different device nodes just to represent a single serial port. I'm not really sure why FTDI is doing that or if it is necessary.

When finding a serial port, libusbp on Windows calls the internal libusbp function get_interface, which can behave in two different ways: 1) Non-composite: It returns a handle to the USB device itself. 2) Composite: The USB device node will have a child node whose device instance ID matches the pattern USB\\VID_%*4x&PID_%*4x&MI_%2x\\, and the number after MI_ tells us the interface number from the device's USB descriptors. It returns a handle to the matching child node.

This works for the other USB-serial drivers I've tried but it wouldn't work for you, because the FTDI driver you are using has decided to not name the child device after a USB interface (and I don't even know if there is a USB interface to name it after because I haven't seen your descriptors).

I do want to work on this but it might take some time to find an FTDI device that is acting the way yours is, and also test the behavior on Linux and macOS so I can make the behavior of libusbp be the same across all platforms.

DavidEGrayson commented 1 year ago

As a temporary workaround for your problem, you should try changing the code here so that it has the right pattern for your particular device instance ID, or just remove it:

https://github.com/pololu/libusbp/blob/d31102e/src/windows/interface_windows.c#L179-L186

jporcher commented 1 year ago

Hello, Thank you for the update. I don't actually need a workaround because I tested with an FTDI device waiting for the real device I wanted to use to be available and I now received it. This device is not FTDI, and it just works fine (thank for that by the way). But I can help if you need. Send you any information you need to try to fix this, and test your git master when you want me to. However, I only have access to Windows and Linux platform here, no MacOS.

DavidEGrayson commented 1 year ago

I was able to reproduce this problem with an FT232RL. The solution is not as simple as I thought it would be, but I found this Python script which successfully identifies the FTDI COM port, so I should be able to get libusbp to do the same thing:

https://github.com/pyserial/pyserial/blob/master/serial/tools/list_ports_windows.py

DavidEGrayson commented 1 year ago

I got it working in commit 3dce49abf.

jporcher commented 1 year ago

Just tested 1.3.0 and it works fine now! Thanks a lot.