cancel
Showing results for 
Search instead for 
Did you mean: 

USB VCP - How to know if host COM port is open?

Clonimus74
Senior II
Posted on June 25, 2018 at 13:44

Hi all,

Is there a way to know if the host PC's COM port is open?

My application looks if the USB state is USBD_STATE_CONFIGURED and then starts sending data. In this case my PC application (CVI) cannot open the COM port until I stop sending data.

I want to solve this by knowing if the host COM port is open, is there a method to do this?

I use STM32L476, CubeMX VCP code

Thanks

#host #com-port #usb-vcp
1 ACCEPTED SOLUTION

Accepted Solutions
Clonimus74
Senior II
Posted on June 26, 2018 at 13:00

Found the solution in this forum,

https://community.st.com/0D50X00009XkgdmSAB

.

Add the following toCDC_Control_FS:

case CDC_SET_CONTROL_LINE_STATE:

USBD_SetupReqTypedef * req = (USBD_SetupReqTypedef *)pbuf;

if(req->wValue &0x0001 != 0)

host_com_port_open = 1;

else

host_com_port_open = 0;

break;

View solution in original post

10 REPLIES 10
Clonimus74
Senior II
Posted on June 26, 2018 at 11:09

Anyone has any ideas?

Clonimus74
Senior II
Posted on June 26, 2018 at 13:00

Found the solution in this forum,

https://community.st.com/0D50X00009XkgdmSAB

.

Add the following toCDC_Control_FS:

case CDC_SET_CONTROL_LINE_STATE:

USBD_SetupReqTypedef * req = (USBD_SetupReqTypedef *)pbuf;

if(req->wValue &0x0001 != 0)

host_com_port_open = 1;

else

host_com_port_open = 0;

break;

Bob S
Principal
Posted on June 26, 2018 at 17:38

Presuming that you have control of the PC application - the easiest way is to have your PC app send something to the embedded system saying 'I'm ready for data'.  And then obviously, 'I'm shutting down' when the app closes.

If you can't modify the PC app to do that, something I have done is hook into the CDC_SET_LINE_CODING request (usbd_cdc_if.c) and look for a specific baud rate (or perhaps some unique combination of baud rate and stop bits) that is NOT likely to be a Windows (or Linux or whatever) default.  Your PC application opens the COM port and sets the baud rate, etc. to there unique values and then your STM32 app knows that it can start sending data.  You can use some other baud rate/etc. setting to signal that your application is closing.  For example, when opening the COM port have the PC app set the baud rate to 300 baud or 1200 baud that no modern device would ever use.  Or perhaps 115200 baud and 2 stop bits (an unusual combination).  Or if you have the flexibility to choose ANY baud rate, something like 88888 baud which is non-standard and likely to never appear in any other app.

When using USB virtual COM ports, as long as the data never has to go over a physical serial port (i.e. only USB virtual COM between PC and embedded device but not a UART/USART), it doesn't matter WHAT the baud rate setting is.  Data gets transferred as fast as each end can send and receive it.

Posted on June 27, 2018 at 09:06

Bob S wrote:

Presuming that you have control of the PC application - the easiest way is to have your PC app send something to the embedded system saying 'I'm ready for data'.  And then obviously, 'I'm shutting down' when the app closes.

If you can't modify the PC app to do that, something I have done is hook into the CDC_SET_LINE_CODING request (usbd_cdc_if.c) and look for a specific baud rate (or perhaps some unique combination of baud rate and stop bits) that is NOT likely to be a Windows (or Linux or whatever) default.  Your PC application opens the COM port and sets the baud rate, etc. to there unique values and then your STM32 app knows that it can start sending data.  You can use some other baud rate/etc. setting to signal that your application is closing.  For example, when opening the COM port have the PC app set the baud rate to 300 baud or 1200 baud that no modern device would ever use.  Or perhaps 115200 baud and 2 stop bits (an unusual combination).  Or if you have the flexibility to choose ANY baud rate, something like 88888 baud which is non-standard and likely to never appear in any other app.

When using USB virtual COM ports, as long as the data never has to go over a physical serial port (i.e. only USB virtual COM between PC and embedded device but not a UART/USART), it doesn't matter WHAT the baud rate setting is.  Data gets transferred as fast as each end can send and receive it.

This solution is not ideal, as you don't always control the PC application. It required additional state in the PC application and firmware. It also assumes that the PC application exits normally every time, and so you might not know if the COM port was closed.

The baud rate solution is practically the same as the 'I'm ready for data' solution, only a bit more complicated, if I didn't have any other solution I would have went with the 

'I'm ready for data' and pray for the best 

I find the solution I posted above, taken from the link I posted, is the best solution for me as it allows the firmware to know for sure when the port is open and closed.

Posted on June 28, 2018 at 13:23

While this works most of the time, keep in mind that the host can choose not to toggle DTR (0x01), eg if you

stty -hup < /dev/port

on linux.

For best results, also update your assumed port-open state when the host tries to read from the port (issues endpoint transfer token), or doesn't read for several usb frames.

There's no existing signal that specifically and reliably tells you that the host has opened the port.

Posted on June 28, 2018 at 14:37

Michael Moon wrote:

While this works most of the time, keep in mind that the host can choose not to toggle DTR (0x01), eg if you

stty -hup < /dev/port

on linux.

Yes that is true, but in the case where the communication is mostly unidirectional, I can't close the port using a timeout if not receiving anything.

Isn't the DTR handling part of the ST driver? In case a 3rd party will have to do a PC application DTR will have to be enabled.

For best results, also update your assumed port-open state when the host tries to read from the port (issues endpoint transfer token), or doesn't read for several usb frames.

Do I get endpoint transfer token from host even if the communication is only STM32L4 to PC direction?

There's no existing signal that specifically and reliably tells you that the host has opened the port.

Unless DTR is enabled, no?

Posted on June 29, 2018 at 07:45

Isn't the DTR handling part of the ST driver? In case a 3rd party will have to do a PC application DTR will have to be enabled.

ST has its own driver? Most 'drivers' for CDC-ACM serial are simply a magic text file that tells windows to use its builtin driver because windows isn't smart enough to realise it already has a driver for CDC devices.

On Linux (and I assume OSX), the kernel uses its builtin driver when a device says it's a CDC serial port.

DTR toggle is performed by the driver, but it can be enabled or disabled as required.

Do I get endpoint transfer token from host even if the communication is only STM32L4 to PC direction?

Yes, USB uses host-issued tokens for all data transfers - a device cannot initiate data transfer all by itself.

If the host is issuing read tokens, then it's interested in what your device has to send.

Unless DTR is enabled, no?

While developing

http://smoothieware.org

, we encountered some OSes (certain versions of OSX from memory) that didn't change any  control pins (ie DTR) if the host software requested no hardware flow control, so to reliably detect when to flush our send buffer or drop data we had to simply keep an eye on when we received read tokens.

Initially we used DTR toggle to flush buffers, but on the hosts which didn't toggle DTR it caused stale data to be sent when the port was reopened

If the host can decide to not toggle DTR, then DTR toggle is not a reliable indication of host software opening the port.

Posted on July 01, 2018 at 09:47

ST has its own driver? Most 'drivers' for CDC-ACM serial are simply a magic text file that tells windows to use its builtin driver because windows isn't smart enough to realise it already has a driver for CDC devices.

It does, though I have no idea if it is just a 'magic text'. How can I know?

Yes, USB uses host-issued tokens for all data transfers - a device cannot initiate data transfer all by itself.

How is it called? what kind of interrupt am I looking for?, is it the same interrupt that will happen for host to device communication?

If the host can decide to not toggle DTR, then DTR toggle is not a reliable indication of host software opening the port.

I can simply instruct any 3rd party developer to enable DTR, though I don't think it will come to that, I think we will supply all apps.

Many thanks, you've been very helpful

Posted on July 02, 2018 at 02:03

The should be an .INF file associating the VID/PID with drivers, control panel applets, etc.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..