USB-CDC to UARTs with RTS/CTS flow control on Kinetis

cancel
Showing results for 
Search instead for 
Did you mean: 

USB-CDC to UARTs with RTS/CTS flow control on Kinetis

3,886 Views
mjbcswitzerland
Specialist V

Hi All

I have configured USB-CDC as composite device to 5 connections. That is, the device appears as 5 virtual COM ports, each connected to a different UART (single USB to 5 serial interfaces).

This allows me to communicate via 5 UARTs of a Kinetis (such as the K60) via the single USB device cable - it looks like this:

5xUSB_ser.PNG.png

Up to now I have quite limited experience with composite devices (and interface association (IAD) that is needed to allow usbser.sys on Windows PCs to be able to work with multiple interfaces on the single connection) but the enumeration and communication is otherwise fairly straightforward.

There are however three things that are limiting ideal operation and I would like to ask whether there are more experienced people who may like to offer a little advice so that the these may possibly be overcome.?

1. Since the interface shares endpoint 0 for CDC commands, handling the SET LINE CODING when the PC hosts sets the Baud rate is presently only working for all UARTs in parallel. This is because there is no information in the command to know which of the UARTs is actually to be configured.I do wonder whether there is some information in the IAD that is not absolutely correct that could help control this or whether usbser.sys is basically flawed (and that is why no USB-SERIAL manufacturer seems to use it?)

2. Related to 1) is the fact that the RTS control (HW flow control) suffers the same problem (which UART does it belong to??)

3. I suspect that usbser.sys doesn''t support XON/XOFF flow control due to the fact that I have never found any mention of it in the USB-CDC specifications and also because I never found a USB-CDC device (such as the embed or P&E debuggers on Freescale development board with USB-UART function) based on usbser.sys that can do XON/XOFF flow control. Commercial USB-SERIAL cables do support it but they seem to supply their own PC drivers and I see the control taking place as what look like proprietary commands.

So essentially I would like to certainly overcome 1) (and probably 2, if 1 is possible) so that usbser.sys can be used in the majority of cases. It would be great to somehow also solve 3) (seems an issue with single interface USB-CDC generally too (?)).

Any experts or experienced developers who can comment?

Regards

Mark

0 Kudos
9 Replies

268 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Mark,

I would recommend you implementing different interface for each COM port, so that when PC Host send request with code of SET_LINE_CODING, the firmware in K60 would know which UART is going to be configured, and also for RTS(hardware flow control), there is another code for it, SET_CONTROL_LINE_STATE, and the firmware may know the interface as well from this request, so that control the RTS signal assosiated with the specfic interface(UART).

Hope that helps,


Have a great day,
B.R
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

268 Views
mjbcswitzerland
Specialist V

Hi Kan

As far as I know I am implementing as 5 interfaces. During initial installation it shows up as "int 1", "int 2", "int 3", "int 4" and "int 5" until each interface has been associated to usbser.sys (which takes place one at a time - that is, each interface installs the driver for itself).

In all documents I have seen all  interfaces share a common endpoint 0 (control).

If you know of another method do you have a reference to it (eg. how the descriptor is constructed)?

Regards

Mark

0 Kudos

268 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Mark,

Yes, you may refer to Freescale_BM_USB_Stack_v5.0 for more details. There are two demo related with CDC application, one can be found in "C:\Freescale\Freescale_BM_USB_Stack_v5.0\Src\example\device\cdc\virtual_com", and the other resides in "C:\Freescale\Freescale_BM_USB_Stack_v5.0\Src\example\device\composite\msd_cdc".

The Freescale_BM_USB_Stack_v5.0 can be downloaded from Freescale bare metal (no OS) USB Stack.

Hope that helps,


Have a great day,
B.R
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

268 Views
mjbcswitzerland
Specialist V

Hi Kan

Although the examples don't actually work with multiple CDC interfaces I did see that the interface reference is specified by the SETUP tokens "wIndex" value (rather than in the command itself). This is what I previously missed, meaning that it looks like it is possible to solve 1) and 2) with this information field.

This still leaves XON/XOFF (how to command the mode from the host?) - although I will probabyl resort to a user setting to define whether XON/XOFF is used or not.

Regards

Mark

0 Kudos

268 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Mark,

Actually XON/XOFF is a software control protocol, and in my understanding , USB CDC doesn't need such protocol because of the transfer rate, and so that CDC spec doesn't have a specific request for it, but you may add a custom request for it.

For your application, it looks like a USB to UART bridge, so if it is, there is no need to add support for the software flow control, because PC host and the device connected with UART will handle the XON/XOFF protocol automatically.

You may refer to Software flow control - Wikipedia, the free encyclopedia for more details.

Hope that helps,


Have a great day,
B.R
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

268 Views
mjbcswitzerland
Specialist V

Kan

The following is the problem with XON/XOFF:

If the USB-CDC interface is performing a bridge function is can be doing this for a variety of programs - often for a terminal emulator running on the computer. When the program (eg. the terminal emulator) is started it will be configured to either no-flow-control, HW flow control or XON/XOFF flow control. The USB-UART bridge needs to know what this setting is because it needs to do the actually XON/XOFF flow control. When the setting is changed to XON/XOFF flow control (eg. from no-flow-control) there is no information passed from the host USB-CDC (and when set back to no-flow-control there is no information).

The result is that the program on the PC may want to work with XON/XOFF because it know that the device it is connected to needs it but, if the USB-CDC brige doesn't know this it won't be able to perform the flow control.The program doesn't do it because it expect the driver to be doing it (that is the USB-CDC bridge itself in this case). The result is that XON/XOFF doesn't do anything and if one side needs to stop the flow the other side will still send and cause overflows.

You can test this very easily with the virtual COM ports on the freescale development boards. Connect the virtual COM port to a terminal emulator and send some data - it is sent out by the USB-UART bridge (eg. by the K20 in the OpenSDA device). Switch the terminal emulator setting to XON/XOFF flow control and continue sending test data - it correctly is sends this out of the USD-CDC bridge (its UART Tx outout). Now send XOFF to the UART side of the bridge (from teh connected device that can no longer accept data) and the PC's data will still continue to be sent and overruns the device that wanted the flow control to stop. This shows that XON/XOFF is not working correctly and the USB-CDC bridge must do it (stop reading the USB bulk pipe from the PC so that it stops too, and don't pass any queued data to the UART output).

In my USB-CDC SW I can program the USB-CDC bridge to do any flow control and it operates correctly but I need to program this setting by an alternatrive communication path (eg. a board setting) due to the fact that I can't see that the terminal emulator setting has been changed to this (as I can see whenever its Baud rate is adjusted in by terminal emulator program - using SET_LINE_CODING).

Now if I take a USB-SERIAL cable for a PC (commerical one) the XON/XOFF flow control works in its USB-UART bridge and I can control it from the terminal emulator program (it follows the program's setting). If the device connected to the UART end sends XOFF there is no more data sent out of the bridge's UART until the connected device sends XON again (no overruns at the connected device take place). What I see is that there is information send to the USB-SERIAL bridge when the terminal emultaor's XON/XOFF mode is changed so that it knows that it must do this. But, these devices look to always supply a special driver (they don't use USBSER.SYS).

>>but you may add a custom request for it

Do you know how to do this without needing a different host driver to USBSER.SYS?

Regards

Mark

0 Kudos

268 Views
matthewkendall
Contributor V

XON/XOFF is typically implemented at the end-points, surely? If it were implemented in the middle of the communications path, that point would have to have an infinitely large buffer. Surely the XOFF sequence must be sent by the ultimate sink when it can no longer accept data, and must be received by the original source so it can stop sending further data.

0 Kudos

268 Views
mjbcswitzerland
Specialist V

Matthew

I believe that XON/XOFF is typically implemented in the UART driver. Often the UART driver will send XOFF if its input buffer becomes critically full [high water mark] (say 80% full) and XON will be sent again when the receiving application (sink) reads the queue and its content falls below a low water threshold (say 20%). A transmitting application will configure the UART driver for the mode but it won't be involved with checking for the XON/XOFF characters since these will be filtered by the UART driver. If the output buffer of the UART driver has no space to accept more data from its application (source) the applicatuion thread will normally be suspended until there is more space available to complete a write. The result is end to end flow control and a finite buffer controlling it.

At the moment I am not absolutely sure about the virtual COM case but I would have thought the best place for this flow control would be between the application and the USB-CDC driver and then the USB/serial converter wouldn't be involved - if it received data it can always accdept it and send it. However this doesn't look to be the case due to the fact that I can take a terminal emulator and set its mode to XON/XOFF with two USB-serial converters. With one (all commerical ones that I have) it works [if the serial input receives XOFF it will not transmit any more data until XON is received, after which it transmits all queued data that it may have collected in the meantime] but with the virtual COM ports on the development boards (OSJTAG, OpenSDA from P&E or mbed) the flow doesn't stop. This suggest that the USB/Serial converter is doing the XON/XOFF work otherwise both would have been identical. In this working case I expect that the USB-CDC is not accepting any more data from the host (NAKing) when it stops the flow and the terminal emulator will pause any further transmission until the flow starts again (when testing file transfers the transfer count will simply freeze until it can continue).

Regards

Mark

0 Kudos

268 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Mark,

I agree implementing most of XON/XOFF protocol in driver layer should be more effective, but I also think the application should be notified of such event so that it may suspend/resume the transmisstion at that point. and I think there is no way other than changing USBSER.SYS to add support for flow control, because you have to custom the class request such as SET_LINE_CODING request, you know, there is a structure for such code, and you may extend this structure with option of flow control, but this needs you change the firmware in Kinetis device as well as the PC driver.

Hope that helps,


Have a great day,
B.R
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos