Using ASF USB CDC driver with USB

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm using a Xmega128A1U microcontroller to collect several serial data streams into one USB data stream to a computer. One of the data streams is relatively heavy at ~800 kbits/s thus we want to use a DMA transfer directly from a SRAM buffer into the endpoint buffer. When I implemented the USB driver with a DMA transfer the DMA gets "stuck" with the channel busy flag stuck high and never completes the transaction. Has anyone else seen this behavior when trying to load USB buffers via DMA? I suspect that their is a conflict on the memory bus between the system DMA and the USB DMA. Thoughts? Thanks :) 

This topic has a solution.
Last Edited: Wed. Jun 13, 2018 - 11:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have a look at this code, it uses DMA and sends the results over USB at a few megabits/sec: https://github.com/kuro68k/xrng/...

 

I used by own USB stack... The ASF might be able to do 800kb/sec, from memory that's close to the limit for the CDC layer. https://github.com/kuro68k/xmega...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for your response. I think my first method of attack is going to be a CPU driven memory copy from my main buffers to the Out buffer in the USB. Should only cost 500 cycles or so to transfer a 64 byte buffer and at 100 000KB/s that's only a small fraction of my total number of available cycles. Its a shame ASF doesn't play well with DMA.

 

Also am I correct in saying that in your example you move the data out pointer to the data instead of moving the data to defined buffer?

Last Edited: Tue. Jun 12, 2018 - 10:13 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah, I just point the USB peripheral at the data and it uses it's own internal DMA to transfer it.

 

By the way, if you want a faster memory copy try this: https://github.com/kuro68k/fastmem

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

So I found a solution to the problem. When I originally tried to DMA data into the ASF USB endpoint buffer it cause the system to fall into a state where the DMA busy flag would raise and never clear. The solution to this problem is to split the transfer into multiple transactions. Thus, use repeat mode and load REPCNT with the number of bytes and leave trfcnt at 1. The result is many one byte transactions. Took my a long time to find this solution to hopefully this helps someone. :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The biggest chunk of memory that DMA can handle is 1023 bytes.  You can speed up the data transfer by using chunks up to that size.