Author Topic: Virtual Com port VCP peripheral  (Read 15450 times)

nvd

  • Member
  • ***
  • Posts: 42
Virtual Com port VCP peripheral
« on: September 04, 2012, 06:24:28 am »
Hi,
 I am developing a VCP peripheral.
 The peripheral is enumerated and I can receive data from the host.

 The data exchange happens over the BULK endpoint.
 Device can not send the data to host unless BULK IN token is sent by the host.

 If I needto send data from device to host without host commanding for the data, How do I inform host that the it needs to send IN token to receive data?

Thanks.

Warm regards,
Nitin

Barry Twycross

  • Frequent Contributor
  • ****
  • Posts: 263
Re: Virtual Com port VCP peripheral
« Reply #1 on: September 04, 2012, 02:15:39 pm »
A USB device can only ever send data to the host at the host's request. The driver has to make sure that such a request is outstanding.

nvd

  • Member
  • ***
  • Posts: 42
Re: Virtual Com port VCP peripheral
« Reply #2 on: September 05, 2012, 06:06:16 am »
Yes, Device can't send data unless host sends the IN packet.

How would the host know, when to send the bulk IN packet? How does host knows that the device has some data to send?
There can be data wrapped protocol on bulk endpoint which aids in getting this information from device.
But apart from that, Is there any other way for the host to know about data availability at device end?

Thanks
Nitin

Bret

  • Frequent Contributor
  • ****
  • Posts: 68
Re: Virtual Com port VCP peripheral
« Reply #3 on: September 05, 2012, 12:33:53 pm »
Think about what you are trying to virtualize -- a COM port.  COM ports are not, by nature, "bulk" devices.  They have always had stringent flow control and timing parameters associated with them.

Even back in the earliest days of computers, COM ports have either had to be constantly polled or interrupt driven to work properly without losing incoming data.  You'll need to fundamentally do the same thing.

Barry Twycross

  • Frequent Contributor
  • ****
  • Posts: 263
Re: Virtual Com port VCP peripheral
« Reply #4 on: September 05, 2012, 07:30:59 pm »
Yes, Device can't send data unless host sends the IN packet.

How would the host know, when to send the bulk IN packet? How does host knows that the device has some data to send?
There can be data wrapped protocol on bulk endpoint which aids in getting this information from device.
But apart from that, Is there any other way for the host to know about data availability at device end?
The host has to poll in some manner. Quite often the polling is just having a bulk read outstanding on the device. (Again, that's something the driver has to arrange.) That's not very bandwidth efficient as you tend to have lots of NAKs on the bus.

If you want to be more sophisticated, you can use an interrupt endpoint, which is more or less that Bret's suggesting. An interrupt endpoint is still the host polling, its just arranged in a more bandwidth friendly way. If the bandwidth needed will fit within a interrupt transfer, just then endpoint on its own could be sufficient. If the bandwidth needed is more than an interrupt endpoint can supply, the interrupt endpoint can be used to give status, it would return when there is data available, which could be used to trigger a bulk read.

Does the protocol you're implementing allow for this sort of thing. Are you implementing a defined protocol, or rolling your own? What bandwidth do you need? Is it constant or bursty?

nvd

  • Member
  • ***
  • Posts: 42
Re: Virtual Com port VCP peripheral
« Reply #5 on: September 06, 2012, 02:47:42 am »
Yes, Device can't send data unless host sends the IN packet.

How would the host know, when to send the bulk IN packet? How does host knows that the device has some data to send?
There can be data wrapped protocol on bulk endpoint which aids in getting this information from device.
But apart from that, Is there any other way for the host to know about data availability at device end?
The host has to poll in some manner. Quite often the polling is just having a bulk read outstanding on the device. (Again, that's something the driver has to arrange.) That's not very bandwidth efficient as you tend to have lots of NAKs on the bus.

If you want to be more sophisticated, you can use an interrupt endpoint, which is more or less that Bret's suggesting. An interrupt endpoint is still the host polling, its just arranged in a more bandwidth friendly way. If the bandwidth needed will fit within a interrupt transfer, just then endpoint on its own could be sufficient. If the bandwidth needed is more than an interrupt endpoint can supply, the interrupt endpoint can be used to give status, it would return when there is data available, which could be used to trigger a bulk read.

Does the protocol you're implementing allow for this sort of thing. Are you implementing a defined protocol, or rolling your own? What bandwidth do you need? Is it constant or bursty?

Thanks for the replies.

I am implementing a Virtual COM port for demonstrative purpose. Most of my reference is lvr's http://www.janaxelson.com/usb_virtual_com_port.htm
It is stated that the, after enumeration Host immediately starts to poll Bulk IN EP for Data and Interrupt IN EP for status. This is what happens (windows).
As you pointed out this creates lots of NAKs on the bus.
I was hoping that in the status provided on Interrupt IN EP somehow the device should be able to indicate to the host that it wants to transmit data and then Host starts sending Bulk IN packets.
But ACM notifications do not have any such provision.

If I want to implement something like this, It may not work with Windows apps like Hyperterminal or putty.
It will need a custom windows application to handle vendor specific commands or protocol. correct?

Warm Regards,
NVD
« Last Edit: June 29, 2015, 10:26:57 am by Jan Axelson »

Tsuneo

  • Frequent Contributor
  • ****
  • Posts: 145
Re: Virtual Com port VCP peripheral
« Reply #6 on: September 06, 2012, 03:43:46 pm »
Quote
nvd:
It is stated that the, after enumeration Host immediately starts to poll Bulk IN EP for Data and Interrupt IN EP for status. This is what happens (windows).
As you pointed out this creates lots of NAKs on the bus.

"Polling IN transactions" is common implementation of PC class drivers, for asynchronous bulk/interrupt IN transfers on all USB classes until USB3.0. Also it's an easy way for PC class drivers, because host controller automatically issues polling IN transactions, just by keeping TD (Transaction Descriptor) on the queue.

If you don't like this behavior, you have to write your custom COM port driver to cancel it, not just to implement your custom protocol over the Interrupt IN EP.

WDK has examples of a COM port driver and a KMDF WinUSB driver. You may establish your custom USB-COM port driver upon combination of these examples.
C:\WINDDK\7600.16385.1\src\serial\VirtualSerial
C:\WINDDK\7600.16385.1\src\usb\osrusbfx2\kmdf

But, is it really worth to pay such an effort?

"Polling IN transactions" don't hurt bus performance so much.
- Interrupt and Isochronous transfers have priority over bulk transfers. "Polling IN transactions" doesn't disturb these types of transfers at all.
- Control transfer is assigned greater priority in some extent on the bus scheduling of host controller.
- Bulk transfers share equal chance to occur. "Polling IN transactions" reduces performance on other bulk endpoints. But IN-NAK transaction occupies just short time on bus, the performance reduction is trivial.

For example of CDC bulk IN/OUT endpoints,
"Polling IN transactions" occur at the bulk IN endpoint, while a transfer runs on the bulk OUT endpoint. A bus analyzer counts 16-17 bulk OUT transactions per frame, and the same number of IN-NAKs on the bulk IN. If it were without IN-NAKs, bulk OUT could get one more transaction per frame. That is, performance loss is just around 6%.

This is the reason why I ask you, is it really worth?

Tsuneo
« Last Edit: September 06, 2012, 11:59:33 pm by Tsuneo »

nvd

  • Member
  • ***
  • Posts: 42
Re: Virtual Com port VCP peripheral
« Reply #7 on: September 07, 2012, 02:17:45 am »
Thanks for the detailed reply.

I share your opinion that it is not worth the effort for the demo application purpose.
If some windows app was available off the shelf, then it would have been easy to use it directly.
Definitely don't want to put efforts on developing one at the moment.

Thanks.

Warm regards,
Nvd

nvd

  • Member
  • ***
  • Posts: 42
Re: Virtual Com port VCP peripheral
« Reply #8 on: December 20, 2012, 12:59:39 pm »
Hi All,
 I have the VCP demo ready and communicating with the USB host.
 After enumeration Host starts polling the on the BULK IN endpoint and device can send the data.
 
 Only difficulty I have here is that if the terminal application is not yet started when first few messages are sent by USB device, these messages do not get displayed on the terminal.
 This is understandable.

 But with the FTDI Hardware UART to USB transceiver Hyperterminal does show these initial messages.
 How is this achieved in hardware or in Firmware (if any) running on FTDI?

 How can i achieve this in my VCP USB driver? Do I keep accumulating the data until I detect that the application on host is ready to display this data? (Indication of application being ready would be the SET_LINE_CODING command on control endpoint)

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Virtual Com port VCP peripheral
« Reply #9 on: December 20, 2012, 01:10:32 pm »
The FTDI chips have internal buffers that store received serial data. You would need to implement something like that in your device hardware.

nvd

  • Member
  • ***
  • Posts: 42
Re: Virtual Com port VCP peripheral
« Reply #10 on: March 28, 2013, 05:45:57 am »
Hi All,
 Need some more information on VCP.
 
 How do I implement flow control on USB VCP?

 I implemented example which loops back data sent by PC. Data sent by PC (e.g typed over the terminal window) is returned back correctly.
 But my USB VCP driver works ok as long as data sent by host is slow.

 Looks like my driver looses some packets when the data arriving from PC is very fast.(e.g. file transfer using hyperterminal)
 I think my driver needs to somehow tell the PC, to wait till the data is processed.

 Shouldn't  the NYET and NAK will take care of this in the bulk transfers?

Regards,
NVD

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Virtual Com port VCP peripheral
« Reply #11 on: March 28, 2013, 11:13:05 am »
If your firmware is taking data directly from the OUT endpoint's buffer and putting it in the IN endpoint's buffer for sending, NYET and NAK should do the job.

If the firmware puts the received data in a firmware data buffer, then writes the data from the data buffer to the IN endpoint's buffer, you need to be sure that the data buffer doesn't overflow.


« Last Edit: March 28, 2013, 11:48:32 am by Jan Axelson »

nvd

  • Member
  • ***
  • Posts: 42
Re: Virtual Com port VCP peripheral
« Reply #12 on: March 28, 2013, 11:29:03 pm »
Thanks Jan.
 My firmware implements puts the received data in Firmware Buffer.
 Didn't think of the other option, I will give it a try.

NVD