Isochronous endpoints on XMEGA

24 views
Skip to first unread message

erik....@cba.mit.edu

unread,
Dec 16, 2018, 12:09:19 AM12/16/18
to LUFA Library Support List
Hi all,

I modified the audio input example to run on an ATxmega128A4U, and it's working. But I don't understand why it works.

In particular I'm using a 128 byte endpoint, which according to the XMEGA datasheet is only available for isochronous transfers (table 20-5). And LUFA claims not to support isochronous transfers on XMEGA, nor endpoints larger than 64 bytes. So based on the docs it looks like my code shouldn't work. This has also come up on this list before, and the conclusion then was that this shouldn't work. And yet it does (so far).

My modifications are here. Besides changing the board definition and porting the AVR8 timer code, all I did was change some buffer/endpoint sizes (as discussed on AvrFreaks). 
  • In Descriptors.h I changed "#define AUDIO_STREAM_EPSIZE 256" to #define AUDIO_STREAM_EPSIZE 128"
  • In Endpoint_XMEGA.h I changed the size of Data[] in Endpoint_FIFO_t from 64 to 128
  • Also in Endpoint_XMEGA.h I changed the test on line 236 to "if (Size > 128)"
The code also works if I change these three numbers to 64. If I change them to 256, endpoint configuration succeeds and the XMEGA tries to write samples, but I don't see them on the host.

Can someone help me understand what's going on here?

Thanks,
Erik

Dean Camera

unread,
Dec 22, 2018, 10:14:00 PM12/22/18
to lufa-s...@googlegroups.com, erik....@cba.mit.edu

There's two reasons Isochronous endpoints aren't going to work out of the box for audio applications - the common endpoint buffer size, and the lack of double banking.

When I originally made LUFA, I wasn't thinking at all about portability, just overall compiled binary size and RAM usage (given the very limited space in the targeted ICs). That meant I designed the API to be a thin abstraction around the USB controller in the USB AVR8 devices. It's unfortunate that what makes it simple, also makes it a poor candidate to port (e.g. the global endpoint selection, which doesn't gel with RTOSes and the like very well).

The API meant that I had to cut some corners for XMEGA, where the USB controller expects the endpoint buffers to be user-provided in regular RAM rather than internal to the controller from its own DPRAM space. This forced me to pick a common maximum endpoint size (64 bytes, as you found) for all endpoints, which I felt was a good choice given it's the maximum size for all endpoint types other than Isochronous. If you increase the buffer size as you have done, it will allow you to use larger Isochronous endpoint sizes at the expense of using more RAM. This will actually work in a limited fashion as you've already found.

The other issue is the lack of double buffering, which is crucial for isochronous transfers. Unlike all other USB endpoint types, Isochronous endpoints do not re-transmit data if the recipient isn't ready to receive it or if it wasn't received correctly. Any missed traffic is simply dropped, as the sender assumes that the data (in this case audio, but also commonly video) is time critical and anything missed should be discarded permanently as there will be more up-to-date streaming data to take its place. That makes Isochronous transfers useless for anything where data integrity is important, but it's fantastic for streams where a dropped frame or sample or two doesn't really matter.

Because I haven't coded in the double banking, the XMEGA USB controller will discard traffic once it has filled up the single endpoint bank, while you process it and release it back to the stack. On the USB AVR8 devices where double banking is supported, the controller will continue to receive data into a second bank while you're processing the first, so that no data is lost. Without the double banking, you will find that you will miss audio samples which were sent while you're processing the last received endpoint bank.

Cheers!

- Dean

--
You received this message because you are subscribed to the Google Groups "LUFA Library Support List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lufa-support...@googlegroups.com.
To post to this group, send email to lufa-s...@googlegroups.com.
Visit this group at https://groups.google.com/group/lufa-support.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages