Data corruption when using code based on XUD_CDC AN00184

Technical questions regarding the xTIMEcomposer, xSOFTip Explorer and Programming with XMOS.
NelsonB
Member
Posts: 11
Joined: Fri Aug 19, 2016 2:56 pm

Data corruption when using code based on XUD_CDC AN00184

Postby NelsonB » Thu Feb 21, 2019 4:11 pm

Dear All,
I am currently using code based on the AN00184 to exchange data with a Win10 PC laptop via USB. I am observing data loss on the PC side. I tried to increase MAX_EP_SIZE from 512 to 1024 (increasing wMaxPacketSize accordingly in the descriptors too).
I observe data loss or data corruption usually after the 1024 first bytes. Please can I have some hints about what to do to ensure data transmission integrity?

Nelson.
User avatar
mon2
XCore Legend
Posts: 1500
Joined: Thu Jun 10, 2010 11:43 am

Postby mon2 » Sat Feb 23, 2019 7:34 pm

Hi. Just some ideas to share on this project:

1) where is the data corruption surfacing? is it at the USB side of communication OR the CDC UART side with an external mated product?

2) Have you tested to just loopback the CDC pins (TX & RX) on the same XMOS CPU? Does that work without erorrs?

3) You could consider to install a USB packet analyzer (s/w - some are free) or better yet, a USB hardware bus analyzer to review the details of the data flow

4) Consider to apply a known good UART widge (perhaps by ST or Silabs, FTDI etc.) so that you can monitor the details of the known good product and then repeat your testing to determine where the corruption occurs.

The Endpoint Size values that are adjusted is for the USB packet transfers so it is possible that the issue is with the USB CDC UART side of things where the external product cannot keep up with the baud rate and/or buffered data? That is, USB CDC often lacks hardware flow control (ie. RTS/CTS lines) so one UART will keep spewing out data without care if the other side is receiving or not. Eventually the remote side may not be able to digest the data quick enough and end up with a buffer overflow = data corruption.

What baud rates are you testing that is failing? Does this setup work if you slow down the baud rates? Try 1200 baud, 9600 baud in a loop back test and see if that can keep up for xx hours or a day or two without corruption.
User avatar
akp
Respected Member
Posts: 314
Joined: Thu Nov 26, 2015 11:47 pm

Postby akp » Mon Feb 25, 2019 1:59 pm

I am not getting any data loss with the CDC interface on the PC side with Windows 10 on a laptop. Are you calling the put_char() or the write() function? I did find that I needed to change the max ep size to 64 in case of a full speed connection rather than high speed.

You know if you use the write() function it returns the number of bytes it was actually able to transfer, if it's less than the number of bytes you wanted to write. So perhaps that's the problem? I just use the put_char() function, and I actually added a put_char_nb() function that doesn't block and just errors if it can't write the byte (so the caller doesn't block).
NelsonB
Member
Posts: 11
Joined: Fri Aug 19, 2016 2:56 pm

Postby NelsonB » Mon Feb 25, 2019 4:07 pm

Hi, here are some answers to your ideas:

1) Currently I just see the data corruption /loss on the win10 PC side, where I have a custom program listening to the USB virtual COM port.

2) No, I didn't, I am not even sure about the way to do that.

3) Yes, I'll try some low level USB analyser to see if the loss is already visible there.

I checked the bandwitdh I was trying to send, I am around 480 Kbytes/second, which is far under the 60 MBytes we could achieve on a USB 2.0 port.

I am currently building a test where I can steer the XMOS output bandwidth on the CDC. Thanks for the advices.
User avatar
akp
Respected Member
Posts: 314
Joined: Thu Nov 26, 2015 11:47 pm

Postby akp » Mon Feb 25, 2019 4:15 pm

480 kB/sec is more than I have achieved with Windows 10. Do you need that high of a data rate?
NelsonB
Member
Posts: 11
Joined: Fri Aug 19, 2016 2:56 pm

Postby NelsonB » Mon Feb 25, 2019 4:25 pm

akp: I am currently using the write() function, will check the return value, didn't pay attention to that.
Do you mean lowering the EP size from 512 to 64 may help increasing the output bandwidth?
I 'll try to use the put_char instead, and see how to implement a non blocking version of it.
User avatar
akp
Respected Member
Posts: 314
Joined: Thu Nov 26, 2015 11:47 pm

Postby akp » Mon Feb 25, 2019 4:32 pm

Reducing the EP size will not increase the output bandwidth. It is just something I needed to do when I tried using XUD_SPEED_FS ('full speed') instead of XUD_SPEED_HS ('high speed'). I think you'll find if you check the return value for write you'll probably fix your problem. e.g. if you tried to send 100 bytes but only 10 got sent you'll have to try resending the remaining 90 bytes before bashing more bytes through.
NelsonB
Member
Posts: 11
Joined: Fri Aug 19, 2016 2:56 pm

Postby NelsonB » Mon Feb 25, 2019 4:38 pm

akp wrote:480 kB/sec is more than I have achieved with Windows 10. Do you need that high of a data rate?
I am building a low level ethernet network sniffer, so I am targeting 12 MB/sec. As USB full speed is 60 MB/sec, I thought this shall work without problem. I am not a USB expert, so I may have miss something.
NelsonB
Member
Posts: 11
Joined: Fri Aug 19, 2016 2:56 pm

Postby NelsonB » Thu Jun 06, 2019 4:11 pm

I made a mistake measuring the data rate I can obtain on windows 10 with the serial profile. Currently I reach 62KB/s
I switched to "Vendor specific" profile. I currently have around 9MB/s bandwidth, a bit far from the 60 MB/s theoretically offered by USB 2.0, but it shall fit my needs.

Who is online

Users browsing this forum: No registered users and 3 guests