简体   繁体   中英

C++ USB communication

I have a problem regarding communication with a USB device on Windows. I can't use libusb or WinUSB as I have a specific driver for that (Silabs USB to UART, which is a USB-to-serial bridge). This is how I initialize a device file, send&read data and close the handle.

HANDLE hDevFile = CreateFile(L"\\??\\USB#VID_10C4&PID_EA60#0001#{a5dcbf10-6530-11d2-901f-00c04fb951ed}",
    GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
PurgeComm(hDevFile, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

DCB dcbInitState;
GetCommState(hDevFile, &dcbInitState);

DCB dcbNewState = dcbInitState;
dcbNewState.BaudRate = 57600;
dcbNewState.Parity = NOPARITY;
dcbNewState.ByteSize = 8;
dcbNewState.StopBits = ONESTOPBIT;

if (SetCommState(hDevFile, &dcbNewState) == 0)
{
    printf("Could not set COM state. Error: %i", GetLastError());
    return -1;
}

Sleep(60);

BYTE outData[8];
outData[0] = 0x53;
outData[1] = 0x10;
outData[2] = 0x04;
outData[3] = 0x10;
outData[4] = 0x40;
outData[5] = outData[3] ^ outData[4];
outData[6] = 0xAA;
outData[7] = 0x00;
DWORD dwWritten;

if (!WriteData(hDevFile, outData, 8, &dwWritten))
{
    printf("Could not write data. Error: %i", GetLastError());
    return -1;
}

BYTE inData[8];
DWORD dwRead;

if (!ReadData(hDevFile, inData, 8, &dwRead, 2000))
{
    printf("Could not read data. Error: %i", GetLastError());
    return -1;
}

SetCommState(hDevFile, &dcbInitState);
Sleep(60);
CloseHandle(hDevFile);
hDevFile = INVALID_HANDLE_VALUE;

(I get the device symbolic name from the registry but I've skipped that part to make my question concise. WriteData() and ReadData() are custom functions that write and read accordingly.)

The problem is that SetCommState() returns a zero-value. GetLastError() returns 122, which is ERROR_INSUFFICIENT_BUFFER .

The problem now is that PurgeComm() generates ERROR_INSUFFICIENT_BUFFER, too. CreateFile() gives ERROR_SUCCESS, so it must be opened properly.

What's wrong? Did I miss something?

Edit: I tried enumerating COM ports and found an interesting thing - there are no COM ports on my computer. Even though the device is connected and enabled, with the driver present and all that stuff. I also tried forcefully putting \\\\.\\COM1, \\\\.\\COM2, and so on as the file name for CreateFile, but with no luck. Everytime got an ERROR_FILE_NOT_FOUND.

Please, help. This is very important to me.

Because this is a CP210x device, it's a virtual COM port, so you should be opening it as such in CreateFile. You had it right when you said that you tried using \\.\\COMx, you just need to find out which COM port your CP210x device has been assigned and you will not get the ERROR_FILE_NOT_FOUND error. You can find this by looking in device manager:

在此处输入图片说明

Take a look a the Serial Communications Guide for the CP210x , this explains how to make these types of calls to your device, there's even a COM port discovery function that will help you find the COMxx name dynamically. It also has accompanying software, AN197SW.zip .

You can use the Win32 Communication Functions just fine with a handle gotten from passing the device interface path to CreateFile . I do this all the time. Ignore the people telling you that you must use COMx .

However, it is important that you use the device interface path corresponding to the (virtual) serial port device ( GUID_DEVINTERFACE_COMPORT ). Many drivers are implemented as a pair of (USB device, serial port device), where the serial port is a child of the USB device. Opening the USB device ( GUID_DEVINTERFACE_USB_DEVICE ) will not give you working communication functions, such as PurgeCommState . (And this is exactly what you're trying now, note that the tail end of your device interface path exactly matches the GUID documented on MSDN )

If you don't have anything listed under the Ports section in Device Manager, you either don't have the driver correctly installed, or the device is not connected.

Once you get a port device found, you can use CM_Get_Parent to pair up the GUID_DEVINTERFACE_COMPORT instance with the GUID_DEVINTERFACE_USB_DEVICE , solving your question of "What serial port is attached to USB in this particular way?"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM