Author Topic: Problem in USB CDC implementation  (Read 13609 times)

Prasad

  • Member
  • ***
  • Posts: 16
Problem in USB CDC implementation
« on: January 12, 2015, 05:51:43 am »
Hi all,

I am working on a USB CDC Virtual COM implementation on my NXP LPC Custom board on the basis of USBD ROM API . I have got all the basic things working and my implementation is to support the USB over ASCII mode as well as serve as a pyhsical layer for a popular Industrial Communication protocol.

The ASCII part that is when there is byte by byte transfers, things are fine with Tx/Rx on the USB Virtual Com port.

1.But when it comes to the providing physical layer support for the Industrial Communication protocol by USB VCOM , I am facing some problems and require some suggestions.

I need to transmit a block of data over USB CDC and in my code, a Tx completed callback notifies the higher layers of the Industrial Communication protocol that Tx got completed

when I test this by executing some Requests using a test tool, the responses for shorter commands are Ok . For a larger data it works but there are delays for example, if 177 event records need to be transmitted at once, it dones not happen quickly, it transmits 27 event records , then there are some delays/pauses/retries after some time another 30 records are transmitted and so on ..

Like this the Tx works and eventually all the records gets tranmitted without any loss of data. But the issue is why is it pausing for a while after transmitting about 30 records everytime before to transmit another 30 records and this cycle continues ( WBVAL () wMaxPacketSize in my descriptors is 64 in this case )
I tried to change the WBVAL ()  wMaxPacketSize field in the descriptor array from 64 to 8 and things start working !!!. all the Tx occurs at one instance itself and this is what I was expecting.But Is this correct way to avoid the delay problem or I am doing some thing wrong ? can the packet size be 8 instead of 64 and there is no problem?

2. I have another problem, I have provided Bulk IN /OUT Handlers where in I am also handling EVT_IN,EVT_OUT and EVT_NAK cases.
I have seen that always the breakpoints is hit in the EVT_NAK case first and then in the EVT_OUT . this is problematic in my case because it causes a delay in response to any commands that a test tool sends to my USB device. Because it always goes back and forth between the NAK and OUT cases in my code and then eventually outputs the response correctly.

this is causing some initial delays before to receive any data through the EVT_OUT handler.

in the NAK case of my handler , I am doing what is being followed in other examples of USB VCOM that is queuing up the read requests  according to the ROM API of NXP LPC.

Can anyone suggest me on this,

Thanks in advance,
pra

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Problem in USB CDC implementation
« Reply #1 on: January 12, 2015, 09:22:17 am »
1. If the long delays and retries follow the endpoint's NAKing requests for data, see if you can improve the device firmware so it NAKs less often.

2. I don't know the reason for a NAK handler; since a NAK results in no data sent or received, there is typically nothing to handle. But again, minimizing NAKs will improve performance.

Prasad

  • Member
  • ***
  • Posts: 16
Re: Problem in USB CDC implementation
« Reply #2 on: January 29, 2015, 06:42:18 am »
Hi,
Thanks for the reply.

I have tried the following things below and it works now faster.

1. Changed the ( WBVAL () wMaxPacketSize in my descriptors from 64 to 0x1C. This actually has made the things faster dramatically.
    Is changing the value from 64 to 0x1C legal and Ok? ( 0x1A,B,C,D,E,F also work and other values dont work and delays happen)

2. Removed the Ring buffering from OUT case in my Bulk OUT handler for Rx and changed it to a direct copy from Rx  buffer into a variable inside a loop. Effectively, processing got faster and the control was seen lesser times in the NAK case than before which I learnt that , control will be in NAK case if Rx is busy or there is nothing to do for the USBD ROM  stack because the USB stack seems to generate many many NAK events ( in case of the LPC USBDROM stack).
   
After these 2 things, the response has greatly improved.

The control goes into NAK case when there is something going on in OUT case of Bulk OUT handler which means when there is nothing to do or Rx is busy , there will be many many NAK events that will be generated by the USB stack. 

As you pointed out, key was to reduce the overhead  on firmware side and speed up so lesser NAKs can occur and consequently delay will get reduced.

Now that the things are fast enough in my firmware and I am satisfied with the USB throughput, I want to know if the change I did in Point 1 above is OK and legal and I haven't messed up anything in that field of my desciptor.

Can you please suggest?

Thanks in advance,

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Problem in USB CDC implementation
« Reply #3 on: January 29, 2015, 09:29:28 am »
Legal wMaxPacketSize for full speed bulk endpoints is

8, 16, 32, or 64

The host isn't required to enforce this, but it's best to comply because any host might do so.

It's odd that you get better performance with smaller packets.

When a full-speed bulk endpoint’s maximum packet size is less than 64, some host controllers schedule no more than one packet per frame even if more bandwidth is available




Prasad

  • Member
  • ***
  • Posts: 16
Re: Problem in USB CDC implementation
« Reply #4 on: January 29, 2015, 11:16:50 am »
Thanks for the reply.

I observe that if I change this WBVAL wMaxPacketSize  to 64 or any other value like 8, 32 etc.. I experience delays in responses and timeouts at the application layer and
I see that control resides most of the time in the NAK case of my OUT handler and somehow cant get out of it and go to the actual OUT case where it should actually be doing Rx.

If I work with the  ASCII mode setting in my device and use a HyperT, then with Packet size of 64 in the descriptor array I dont have any problems , the response is fast.
when does this problem occur?
This problem only occurs when I select the Industrial comms Protocol mode in my device HMI in order to talk to a PC based application that uses this protocol to send and receive protocol specific data ( this proto is similar to modBus).

(The USB CDC I 've written serves also as a physical layer for a Industrial comms protocol. Earlier it was UART which used to be the phy layer  and now I have replaced this with my USB)

then response is only faster with 0x1c  etc.. and not with 64 . this is exactly where the problem comes in.

only in this case there is slower responses and especially for larger types of data ( example: to transmit block of  200 events )

The host isn't required to enforce this, but it's best to comply because any host might do so.
when you say this, do you mean the Windows drivers that are installed on the PC side , provided by the native manufacturer( in my case NXP) .

do we have any means to see whats happen on the Windows driver when we set the maxPacketSize values in the descriptor to 0x1C instead of standard set ( 64,32,8 etcc that you mentioned)
and that driver accepts the packet sizes without any objections.

Thanks,

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Problem in USB CDC implementation
« Reply #5 on: January 29, 2015, 01:54:09 pm »
>The host isn't required to enforce this, but it's best to comply because any host might do so.
[/i]when you say this, do you mean the Windows drivers that are installed on the PC side , provided by the native manufacturer( in my case NXP) .

 the Windows drivers that are installed on the PC side

>do we have any means to see whats happen on the Windows driver when we set the maxPacketSize values in the descriptor to 0x1C instead of standard set ( 64,32,8 etcc that you mentioned)
and that driver accepts the packet sizes without any objections.

A protocol analyzer will show if a transfer was successful, but this would apply only to the particular PC you are testing, no guarantees on others. Use a legal value from the spec.