This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

USB Bulk IN performance

Hi,

I'm getting bad performance with an FTDI serial to USB device, due to the fact that I'm only getting one bulk IN request scheduled per (micro) frame, with back-to-back calls to USBHCDPipeRead.

Bulk in auto request 

Section 16.3.8.2.2.1.1 in the AM335x TRM says to use USB_0_AUTO_REQ instead of USB_RXCSRH1_AUTORQ when using DMA (which I am).

Setting USB_0_AUTO_REQ inside USBHostEndpointConfig for the endpoint in question doesn't make any difference though.  I suspect things may need to be done differently in USBHCDPipeRead too, regarding the sequence of enable/disable DMA and sending the IN token.

Any ideas?

DMA 

Is it possible to have a static schedule of several linked DMA descriptors instead of having them consumed after being completed?

Failing that, is it possible to "restart" bulk traffic processing inside a frame?  I.e., do software intervention after each transaction to set up the next, but at least being able to submit more than one IN request in a frame.

Thanks,

Orjan 

  • Just to follow up on what I ended up doing:

    I never understood the auto request thing, and never got it working.

    Having USBHCDPipeRead using DMA but blocking was inefficient in my use case so I made it nonblocking by only submitting the first DMA read request.  The subsequent DMA transfers are then setup inside the USB interrupt handler (keeping track of the total amount of bytes I am expecting) after calling dmaRxCompletion for the previous transfer.  I then modified the interrupt handler to only invoke the driver callback once the full amount of data is received.

    I also modified the driver to put the DMA data directly in the user buffer to avoid a memcpy, though I don't know if it made much difference for performance.

    Finally, I made use of the DMA completion interrupt (RX_PKT_CMP) which allowed me to turn off the SOF interrupt (since that will fire once every 125 us regardless of whether there is traffic or not).

     

    Ideally, I would have liked to submit all DMA transfers at once and set the DMA threshold to only fire the completion interrupt after all transfers have finished, but it seems I still have to send the USB IN request somehow (which could potentially be solved by the auto request feature).  However, the user data still won't be contiguous as the FTDI chip begins every USB packet with a 2 byte status. 

    (Needless to say, these changes may not be beneficial or even work in another use case.)