UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Contributor
Contributor
9,556 Views
Registered: ‎06-09-2014

Is this a USBPS bug?

I think I've found a bug in the usbps component of the Xilinx library and was hoping somebody can confirm this.

 

I have a revD ZedBoard, Vivado v2014.2 and a WinXP host PC.

 

I've been trying to develop a USB-CDC device end driver on the ZedBoard.  Currently I'm still working on the control endpoint 0 - haven't got to the other endpoints yet.

 

I have no problems receiving the setup command and descriptor requests from the host over the OUT endpoint, but haven't been able to get the IN endpoint working reliably to transmit responses to the requests.  I often get error 1412 returned from the EpBufferSend... calls, which is means that there are no transfer descriptors available (XST_USB_NO_DESC_AVAILABLE) when there are actually plenty available.

 

On further investigation, this is returned from XUsbPs_EnQueueRequest() when XUsbPs_dTDIsActive() returns true for the first transfer descriptor it checks, indicating that the TD is "active".  The requirement is that available TDs should be marked inactive for available IN (transmit) descriptors.

 

The problem appears to be that when configuring the device with XUsbPs_ConfigureDevice(), the XUsbPs_dTDInit() function is called to initialise the TDs, which correctly initialises OUT TDs, but neglects to initialise the "active" bits of the IN TDs into the correct (inactive) state.

 

This would be a glaring bug, which would show that nobody actually seems to use the Zynq USB ports.  The paucity of USB related forum topics appears to confirm this.

 

Steve

 

Tags (2)
0 Kudos
11 Replies
Scholar norman_wong
Scholar
9,527 Views
Registered: ‎05-28-2012

Re: Is this a USBPS bug?

I would not say nobody uses the Zynq USB ports. I would say nobbody uses the USB ports using bare metal code. I think most people use the USB driver in u-boot or linux.

That said, I took a quick look at the bare metal code. I think the driver assumes that the TD memory space is initialized to zero before first use. That would make the TD flag set to 0 or inactive.

drivers/usbps/examples/xusbps_intr_example.c
UsbIntrExample()
MemPtr = (u8 *)&Buffer[0];
memset(MemPtr,0,MEMORY_SIZE);
DeviceConfig.DMAMemPhys = (u32) MemPtr;
Status = XUsbPs_ConfigureDevice(UsbInstancePtr, &DeviceConfig);

0 Kudos
Contributor
Contributor
9,505 Views
Registered: ‎06-09-2014

Re: Is this a USBPS bug?

Thanks Norman.  I agree it assumes the memory has been zeroed, but that confirms to me it is a bug, for 2 reasons:

 

1. I was seeing the problem even though I did initialise the memeory to zero.  I traced it to the cache invalidation/flushing in XUsbPs_dTDInit().  I think that the zeroing of memory was still in cache and not flushed when it got trashed by the invalidation.  This was only fixed when I did the zeroing in chunks in a loop and then did cache flushed immediately.  There's no warning about this anywhere.

 

2. When there are alternate configurations it is possible for the host to request an alternate configuration, leading to calling XUsbPs_ReconfigureEp(), which in turn calls XUsbPs_dQHReinitEp() and XUsbPs_dTDReinitEp().  These behave the same as the ...Init() functions, except they will no longer be acting on zeroed memory.

 

Do you disagree?

 

0 Kudos
Scholar norman_wong
Scholar
9,497 Views
Registered: ‎05-28-2012

Re: Is this a USBPS bug?

I don't think I know enough to provide an informed opinion. I always though cache flash was included with cache invalidate. Guess not. It sounds like you have found some oversights in the code. Hopefully some Xilinx guys will comment.

0 Kudos
Explorer
Explorer
8,908 Views
Registered: ‎02-05-2008

Re: Is this a USBPS bug?

Hi,

 

I am also facing similar situation. The EP1 end point receives data from host. When I try to read from host, the IN end point does not respond? Did you solve it?

 

Jothi

 

 

0 Kudos
Contributor
Contributor
8,899 Views
Registered: ‎06-09-2014

Re: Is this a USBPS bug?

I reported the bug to Xilinx (I've attached the emails) along with suggested fixes.  I have received no response.  They don't appear to have any interest in getting bug reports, let alone fixing them.

 

The work-around I used is what I suggested in point 1 od my second message here: manually zero the memory, then manually flush the cache for that memory before (re)initializing.

0 Kudos
Contributor
Contributor
8,895 Views
Registered: ‎06-09-2014

Re: Is this a USBPS bug?

0 Kudos
6,034 Views
Registered: ‎04-09-2008

Re: Is this a USBPS bug?

Hey Steve,

 Thanks for your post. I am also having similar troubles when attempting to BULK_IN data at high rates.

As I increase the throughput above 5MBytes/second, parts of my data stream vanish. Pushing it a little harder yields XST_USB_NO_DESC_AVAILABLE which seems non-recoverable. That errors persists no matter how many retries of XUsbPs_EpBufferSend().

After poking around I too hard concerns about cache coherency. Also variables being shared inside/outside of the IRQ context without the volatile attribute - seemed kind of wierd.

 

Steve - you last posted about this about a month ago. Any further insights?

 

Thanks

    Jeff

 

 

0 Kudos
Contributor
Contributor
5,985 Views
Registered: ‎06-09-2014

Re: Is this a USBPS bug?

 

I posted last about 13 months ago and don't remember much about it, except that both the problem and a suggested solution are in the emails I attached.  I basically manually zeroed the memory and manually flushed the cache before calling the init functions.

 

0 Kudos
Visitor joris
Visitor
4,212 Views
Registered: ‎07-19-2016

Re: Is this a USBPS bug?

Dear Jeff/Community

 

I am planning to use the same driver. Where you able to get the bare-metal driver to work correctly?

And if so, did you use the solution swawryk was suggesting, or did you need to fix something else as well?

 

0 Kudos
1,868 Views
Registered: ‎04-09-2008

Re: Is this a USBPS bug?

Just an update about how this all turned out for me.


The usbps code inside Vivado 2015.4 already includes the zero'ing of the memory buffer
that is passed in DeviceConfig.DMAMemPhys thru the XUsbPs_ConfigureDevice() call.
Cache coherence seemed ok for Zynq device to PC host but I never did derive anything
sensible from the USB DMA queueing code.

 

The USB feature is actually fairly stable now that I've fixed my code. (Sorry to Xilinx for my complaint.)

---

The big trouble we were having is, we missed the documentation warning with EpBufferSend().

 

You can not re-use the memory buffer submitted to EpBufferSend().


EpBufferSend() submits memory pointers of the submitted buffer to the USB DMA engine.
The upshot is if you re-use the buffer (say with the next chunk of user data) before
the DMA engine has finished its transfer, the data stream will be corrupted.

As a crude illustration...
- "ABCD" into EpBufferSend()
- DMA starts in the background...
- DMA manages to send "AB" just before your code re-uses the data buffer with "EFGH"..
- "EFGH" into EpBufferSend()

What can go out of the USB port is "ABGH" "EFGH".

 

Whoops.

 

Our project was using only the on-chip BRAM's so we were very memory constrained.
Hence, the odd desire to re-use memory buffers as early as possible.

 

I end-ed up hacking EpBufferSend() to block on 'DMA not complete' when I set a flag.
Most sane people won't need this feature.

 

---

 

Something else to watch out for was misaligned long word accesses to the BRAM controller
which resulted in DMA bus faults. The Xilinx bare metal USB sample code works when the
data is sourced from buffers located in DRAM (which uses the ARM block DDR memory controller).
That controller seems ok with mis-aligned long word fetches.

 

---

 

Happy USB'ing! ...and of course take all of this with 'a grain of salt'. Nobody's perfect.

 

   Jeff

 

 

642 Views
Registered: ‎04-01-2019

Re: Is this a USBPS bug?

Hi Jeff

I encounter the similar problem as you had.

My application is described as following:

PC software is host, in normal mode it sends read/write command to device (motor drives), and drive replies with data in 1 string. As for in graph mode the PC software sends read command to drive and drive needs to reply with data in 64 consecutive string. And my problem happens at replying 64 consecutive string in graph mode.

I configure the endpoint2 for IN (transmit) and endpoint3 for OUT (receive). I register xusb_cdc_ep2_irq_handler() as callback function for endpoint 2, but actually do nothing in this callback function even though I add the case XUSBPS_EP_EVENT_DATA_TX in xusb_cdc_ep2_irq_handler().

I set breakpoints after calling XUsbPs_EpBufferSend(), get the function's return value abnormal with XST_USB_NO_DESC_AVAILABLE code. I tried what you suggest to use different buffer to store data and then send the stored data into EpBufferSend(), but XST_USB_NO_DESC_AVAILABLE keeps happening. I also try to poll DMA hardware bit (XDMAPS_DBGSTATUS_OFFSET bit 0, is that right??) to check if DMA is busy or not, but It appears to be always busy even though I don't start the USB connection between PC software and drive.

Could you help me on this problem? Thanks in advance.

0 Kudos