I'm building a USB data acquisition process around a CY8CKIT-059 which is producing about 500kB/s of data (via DMA) for about 200ms --- which is 100kB, which is too much to store in RAM. So, obviously I need to stream this via USB.
Reading the forums, this does appear to be possible, just --- it looks like the device maxes at at about 550kB/s. But it looks like its really tricky.
Because it's tricky, does anyone happen to have an example project which does this already, with all the inevitable mistakes made and fixed? It would save me loads of time and let me focus on the interesting part of the problem (the data acquisition bit).
As a future extension, I will need to be able to transfer data from the PC to the device so as to reproduce the same data stream, so if anyone knows how to do that too that'd be great, but mainly right now I need to be able to do the device->PC bit.
Solved! Go to Solution.
Presently, we don't have project exactly matching the requirement.
But these inks may be useful:
You can check the USBFS Audio PSoC3/5LP Code Example available at this link to understand streaming via USB:
It's interesting that people claim to be getting nearly 600kB/s via CDC USBUART; that would be ideal as I would be able to just DMA data from my acquisition block directly to it. However, while I've found plenty of forum posts referring to DMA with USBUART, the datasheets don't mention this at all; and I can't find any examples of how to do it (a couple of posted projects say they do it but there's nothing in the code).
Can you confirm that this is actually possible, and can you point me at any documentation for it?
Aha, that makes things clearer.
So it seems that you can't do DMA into a CDC device --- you can only DMA into a raw USB endpoint. However, a completely brute force approach which just calls USBUART_PutData() lots can still achieve the required bandwidth way higher than I need --- even through a hub I'm getting 500-600kB/s. It never occurred to me this was possible!
This suggests that what people have been suggesting is DMAing from my data acquisition module into RAM, and then pushing each 64 byte frame to the CDC output from software. That has the advantage of being really easy, and also makes it simple to detect underruns (if the CDC device isn't ready to send when the DMA-complete interrupt fires...).
So I'll give this a try, and if this isn't good enough, come back and ask about raw endpoints. Cheers!
(FWIW, CDC works absolutely fine, and I was getting about 550kB/s, but custom endpoints aren't nearly as scary as I thought and with manual DMA mode enabled in the USBFS component I'm getting 800kB/s.)
It's surprisingly trivial. Source code here:
It's all bulk data, which has reliable delivery and checksumming, and just to be sure I have a test routine which integrity tests the data on arrival, and it all looks fine.
The most difficult bit was the WCID stuff to let me use libusb on Windows. (Naturally, it all works fine on Linux.)