Skip to main content
Clonimus74
Senior II
June 25, 2018
Solved

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

  • June 25, 2018
  • 3 replies
  • 6491 views
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
This topic has been closed for replies.
Best answer by Clonimus74
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;

3 replies

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

Anyone has any ideas?

Clonimus74
Clonimus74AuthorBest answer
Senior II
June 26, 2018
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;

Michael Moon
Associate II
June 28, 2018
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.

Clonimus74
Senior II
June 28, 2018
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?

Bob S
Super User
June 26, 2018
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.

Clonimus74
Senior II
June 27, 2018
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.