I'm trying to talk to a an usb device connected to an EasySync USB2-H-5004-M USB to RS485 converter at baud rate 3750000 but on OSX.
I've some c++ code working on Windows and have just managed to get it to compile on OSX (using the D2XX dylib instead of the dll) but I have an issue with communication somewhere and I'm not sure where to start and how to resolve this.
I'm using openFrameworks/c++ and the method to list devices looks like this:
int FTDI::enumerateDevices(){
DWORD numDevs;
FT_STATUS ftStatus = FT_CreateDeviceInfoList(&numDevs);
numPortsFound = 0;
if (ftStatus == FT_OK) {
ofLog(OF_LOG_NOTICE, "Number of FTDI devices is %d",numDevs);
devicesList = (FT_DEVICE_LIST_INFO_NODE*)malloc(sizeof(FT_DEVICE_LIST_INFO_NODE)*numDevs);
ftStatus = FT_GetDeviceInfoList(devicesList, &numDevs);
if (ftStatus == FT_OK) {
printf("\n");
for (int i = 0; i < numDevs; i++) {
ofLog(OF_LOG_VERBOSE, "Dev %d:",i);
ofLog(OF_LOG_VERBOSE, " Flags=0x%x",devicesList[i].Flags);
ofLog(OF_LOG_VERBOSE, " Type=0x%x",devicesList[i].Type);
ofLog(OF_LOG_VERBOSE, " ID=0x%x",devicesList[i].ID);
ofLog(OF_LOG_VERBOSE, " LocId=0x%x",devicesList[i].LocId);
ofLog(OF_LOG_VERBOSE, " SerialNumber=%s",devicesList[i].SerialNumber);
ofLog(OF_LOG_VERBOSE, " Description=%s",devicesList[i].Description);
ofLog(OF_LOG_VERBOSE, " ftHandle=0x%x\n",devicesList[i].ftHandle);
}
numPortsFound = numDevs;
} else {
ofLog(OF_LOG_ERROR, "FTD2XX::FT_GetDeviceInfoList() failed");
}
} else {
ofLog(OF_LOG_ERROR, "FTD2XX::FT_CreateDeviceInfoList() failed");
}
return numPortsFound;
}
The problem is on OSX I get this output:
[notice ] Number of FTDI devices is 4
[verbose] Dev 0:
[verbose] Flags=0x1
[verbose] Type=0x3
[verbose] ID=0x0
[verbose] LocId=0x0
[verbose] SerialNumber=
[verbose] Description=
[verbose] ftHandle=0x0
[verbose] Dev 1:
[verbose] Flags=0x1
[verbose] Type=0x3
[verbose] ID=0x0
[verbose] LocId=0x0
[verbose] SerialNumber=
[verbose] Description=
[verbose] ftHandle=0x0
[verbose] Dev 2:
[verbose] Flags=0x1
[verbose] Type=0x3
[verbose] ID=0x0
[verbose] LocId=0x0
[verbose] SerialNumber=
[verbose] Description=
[verbose] ftHandle=0x0
[verbose] Dev 3:
[verbose] Flags=0x1
[verbose] Type=0x3
[verbose] ID=0x0
[verbose] LocId=0x0
[verbose] SerialNumber=
[verbose] Description=
[verbose] ftHandle=0x0
[ error ] failed to register FTDI device with serial FTWVZVEBA in internal register
[ error ] error opening port with serial: FTWVZVEBA
which doesn't look right. For example on Windows, on port A/channel 1/device index 0 I see this:
[verbose] Dev 0:
[verbose] Flags=0x2
[verbose] Type=0x7
[verbose] ID=0x4036011
[verbose] LocId=0x02111
[verbose] SerialNumber=FTWVZVEBA
[verbose] Description=USB2-H-5004-M A
[verbose] ftHandle=0x0
Having a quick look in /dev things look ok:
ls /dev/tty.*
/dev/tty.Bluetooth-Incoming-Port /dev/tty.usbserial-FTWVZVEBB
/dev/tty.Bluetooth-Modem /dev/tty.usbserial-FTWVZVEBC
/dev/tty.usbmodemfa131 /dev/tty.usbserial-FTWVZVEBD
and through System Information I get:
USB2-H-5004-M:
Product ID: 0x6011
Vendor ID: 0x0403 (Future Technology Devices International Limited)
Version: 8.00
Serial Number: FTWVZVEB
Speed: Up to 480 Mb/sec
Manufacturer: FTDI
Location ID: 0xfd120000 / 4
Current Available (mA): 500
Current Required (mA): 200
I have installed the D2XX driver as instructed on the FTDI OSX Installation Guide (pdf link) but I'm not sure what I'm missing/doing wrong.
How can I correctly communicate to the device using the FTDI D2XX library ?
To flesh out my comment, since it seems to have answered the core question here: Mac OS 10.9 (Mavericks) now ships with a kernel extension that acts like FTDI's VCP drivers did. It creates a virtual comm port for FTDI USB-to-serial devices it detects, and means that you no longer have to install the VCP driver if you needed it before.
This has an unfortunate side-effect, though, in that it breaks any application using FTDI's D2XX library. This exhibits itself as a failure for the D2XX functions to connect to the FTDI device, even though they can see it. As a work-around, you can manually unload the kext:
but it will reload itself on next boot.
As a more permanent solution, I've been having my applications detect if this kext is loaded (by trying to connect via the D2XX functions and seeing if they fail), and using the more traditional
open()
, etc. calls for connecting to the serial port as a fallback.I'm not sure if the VCP-style kext they use allows for as much flexibility in terms of baud rates as the D2XX one does, though.