hathach / tinyusb

An open source cross-platform USB stack for embedded system
https://www.tinyusb.org
MIT License
4.98k stars 1.05k forks source link

dcd_transdimension ISO transfer #904

Closed HiFiPhile closed 2 years ago

HiFiPhile commented 3 years ago

I took out my 5 years old LPC4357 board to have some fun with USB & SGPIO...

I saw there are some TODO, It seems like ISO transfer is not supported yet ?

PS. I measured a raw bulk out throughput of 14MB/s maybe due to slow Flash access time.

hathach commented 3 years ago

yeah, it is not yet supported. I don't actually implement any ISO transfer myself since It has no application/audio driver to test with until recently. I have a bad habit of not writing code that aren't run yet.

PS. I measured a raw bulk out throughput of 14MB/s maybe due to slow Flash access time.

How did you carry out the test ? I haven't done much of speed optimization just yet.

HiFiPhile commented 3 years ago

How did you carry out the test ? I haven't done much of speed optimization just yet.

Just a simple test, running cdc example, I measured the elapsed time of 100*4096b packets.

            var port = new SerialPort();
            port.PortName = "COM9";
            port.Open();
            byte[] data = new byte[4096];
            for (var i = 0; i < 4096; i++)
            {
                unchecked
                {
                    data[i] = (byte)i;
                }
            }
            MicroStopwatch stopwatch = new MicroStopwatch();
            stopwatch.Start();
            for (var i = 0; i < 100; i++)
                port.Write(data, 0, data.Length);
            stopwatch.Stop();
            var t = stopwatch.ElapsedMicroseconds;
            Console.WriteLine("Throughput: {0}", Convert.ToDouble(4096 * 100) / t);
hathach commented 3 years ago

what is your CFG_TUD_CDC_RX_BUFSIZE/CFG_TUD_CDC_TX_BUFSIZE, as always, since the transfer need to wait for tud_task() called in main loop, and low buffer size can cause slow throughput.

HiFiPhile commented 3 years ago

CFG_TUD_CDC_RX_BUFSIZE/CFG_TUD_CDC_TX_BUFSIZE

It's 512 as default.

With 1024 I got 19MB/s and 23MB/s for 2048. If I remove all fifo r/w calls it's 6MB/s quicker.

I haven't done much of speed optimization just yet.

Seems the throughput is already good (a tud_task() call while idle still need ~250 cycles).

HiFiPhile commented 3 years ago

For ISO it seems there is a catch in queue management:

For ISO, when a dTD is retired, the next dTD is primed for the next frame. For 
continuous (micro) frame to (micro) frame operation the DCD should ensure that the dTD 
linked-list is out ahead of the device controller by at least two (micro) frames.

Actually in audio_device we finish the current one before schedule the next one.

hathach commented 3 years ago

yeah,like said before, these dcd is capable of queuing multiple transfers at once, however, writing usbd in such a way is not portable. This applies to other transfer as well. We can come back to this later on when it become an issue.

PanRe commented 3 years ago

Mh within dcd_edpt_xfer_fifo() you could buffer two frames before scheduling them. The first two ISO IN requests from the host may be answered by zero length packets according to the UAC2 specs i.e. when there is nothing to send.

hathach commented 3 years ago

@PanRe that is great suggestion, I need to spend more time to standardize the xfer_fifo(), there is quite some driver enhancement (for supported mcus) that we could do with it.