'How does GetCommState populate the DCB struct in Windows 10 when using usbser.sys CDC ACM driver
I am building a embedded device that will communicate to the outside world by virtual COM. I have the descriptor and all the callbacks for the USB set up correctly and COM is working - well kind of. The problem is that when I issue the GetCommState command for the COM I get a semi valid struct back and when one fixes only couple of parameters (like setting the speed and 8N1) and try to reconfigure the port by calling SetCommState the actions fails with: 'A device attached to the system is not functioning.'
If one continues to use the port it just work - all writes and reads - without a problem. But the issue is that most libraries try to reconfigure the port by first issuing the GetCommState and then SetCommState - pyserial and C# both do it in this way.
My question is where do the "default" configuration for COM comes form?
In the USB ACM CDC standard there are (optional) class requests for SET and GET COMM feature but I can see (from USB sniffer) that they are never called (I tried with capabilities for USB ACM CDC set to 0x06 (that is without SET/GET COMM) and 0x07 (with SET/GET COMM) but in no case I get a class request from the driver). So the driver must take the config from somewhere else, does anybody knows from where or how?
I am using an NXP LPC and Windows 10 with usbser.sys driver on other end.
What I already checked is:
- compared the USB descriptor to the working one - they are the same
- checked the USB traffic - the enumeration and communication looks the same
- without doing GetCommState and SetCommState the COM is working without problem
I attached the content of the DCB struct for working sample (left) and my (right). I do not understand where do the marked values come from? Who sets them?
Solution 1:[1]
The settings should come from the port driver - you can view and set default values in the Windows Device Manager. In your case, it would seem that flow control with RTS/CTS is enabled (left picture), which might be something that your USB adapter uses internally. If it works, then leave those settings as they were.
I'd advise to do like this:
- Always check the result of each API function you call!
- Call
CreateFileto get the port handle. - Optionally call
GetCommTimeoutsand store the result in a zero-initialized struct likeCOMMTIMEOUTS com_timeouts = {0};. Change members of the struct as needed, then callSetCommTimeouts. - Create an (almost) zero-initialized struct
DCB dcb = { .DCBlength = sizeof(DCB) }. - Call
GetCommStateon this struct. - Set baudrate, parity, stop bits etc as required. Leave other members as they were.
- Call
SetCommState.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Lundin |

