USB Full-Speed Transfer

Hello

I am looking to use [as much as possible of] the full-speed USB bandwidth of 12 Mbps (or 1.5 MBps).

I have been able to use the USB MSC for my initial testing (with the only modification of expanding the file system size to the full 8 MB of the MX25R64 chip) on the nrf5340 DK.

I am successful in my attempts to generate a 4 MB file, and test the transfer from the board (as a FAT32 fs) to a Windows machine or Linux machine.

Using the article  RE: USB speed issue on nRF52840, I am observing a transfer speed of only 395 KBps, or 0.395 MBps. This is only a fraction of the full-speed capability.

Here is my output when I plug in the DK to a Raspberry Pi  4 Model B and run the "sudo dd" command. I made sure to plug the DK via USB into the USB 2 port as well as the USB 3 port (this resulted in a transfer speed of 391 KBps).

Note also that I tested the transfer speed on a windows machine with both the PowerShell command,

Measure-Command { Copy-Item D:/test_file.txt . } # Copy from the removable drive (D:) to this directory

as well as a simple python script:

import time, shutil, os

def file_transfer_test():
    filename = "test_file.txt"
    source = "D:/"
    destination = "C:/Users/Robert.deBrum/"

    print("deleting file")
    os.unlink(destination + filename)

    print("copying file")
    startTime = time.time()
    shutil.copy(source + filename, destination)
    diff = time.time() - startTime

    print("file transfer time = " + str(diff))
    print("file transfer speed = " + str(1 / diff) + " MB/s")

    return diff

Both testing procedures reported transfer speeds of ~0.3 MBps as well, so I am seeing consistent results.

Are there any considerations or configurations that I can employ to use the full bandwidth of the supported Full-Speed USB protocol?

Thanks

Parents
  • Hi,

     

    You're reaching speeds of 400 kByte/s, ie. 8 MByte transferred after 22 sec -> ~0.38 MByte per sec. Your dd command tries to read 32MB, by the way. So if you want to reverse the command, ie. copy to the flash, you'll have to adjust the size.

    Actual throughput is probably lower, as you're not running "sync" after the dd command.

     

    What's your requirement towards speed?

     

    Kind regards,

    Håkon

Reply
  • Hi,

     

    You're reaching speeds of 400 kByte/s, ie. 8 MByte transferred after 22 sec -> ~0.38 MByte per sec. Your dd command tries to read 32MB, by the way. So if you want to reverse the command, ie. copy to the flash, you'll have to adjust the size.

    Actual throughput is probably lower, as you're not running "sync" after the dd command.

     

    What's your requirement towards speed?

     

    Kind regards,

    Håkon

Children
  • Hello

    Thanks for the clarification. Could you elaborate on "sync", I am not familiar with that command.

    The requirement for transfer speed is to simply be as fast as possible -> the nrf5340 supports 12 Mbps (full speed). How can I accomplish this?

    Thanks again.

  • Hello again,

    I wanted to reach out again regarding some topics that I spoke about with a local FAE. In short summary, I am searching for what would be the bottleneck in why I am experiencing a USB speed of 0.3 MBps instead of the theoretical 1.5 MBps.

    1. Using the basic USB MSC Sample, if I increase the sck-frequency, I assume the USB transfer speed would speed up.
      1. The default frequency was 8 MHz, and I was able to bump this up to 32 MHz. I saw that the transfer speed went from 383 KBps to 407 KBps.
      2. I notice that I am unable to set a sck-frequency of > 32 MHz even though it is supposed to be able to go up to 96 MHz. I am hoping that setting to the full speed of 96 MHz will help with my USB transfer speeds.
      3. &qspi {
        	status = "okay";
        	pinctrl-0 = <&qspi_default>;
        	pinctrl-1 = <&qspi_sleep>;
        	pinctrl-names = "default", "sleep";
        	mx25r64: mx25r6435f@0 {
        		compatible = "nordic,qspi-nor";
        		reg = <0>;
        		/* MX25R64 supports only pp and pp4io */
        		writeoc = "pp4io";
        		/* MX25R64 supports all readoc options */
        		readoc = "read4io";
        		sck-frequency = <32000000>;
        		label = "MX25R64";
        		jedec-id = [c2 28 17];
        		sfdp-bfp = [
        			e5 20 f1 ff  ff ff ff 03  44 eb 08 6b  08 3b 04 bb
        			ee ff ff ff  ff ff 00 ff  ff ff 00 ff  0c 20 0f 52
        			10 d8 00 ff  23 72 f5 00  82 ed 04 cc  44 83 68 44
        			30 b0 30 b0  f7 c4 d5 5c  00 be 29 ff  f0 d0 ff ff
        		];
        		size = <67108864>;
        		has-dpd;
        		t-enter-dpd = <10000>;
        		t-exit-dpd = <35000>;
        	};
        };
    2. I am also looking to verify that the flash chip is set to QSPI mode to enable all 4 IO channels.
      1. Specifically, I am pursuing the 80 MHz FAST_READ capability of the MX25R64 chip.

    Can you let me know what your input on these topics are? I am sure that I should be able to use the 1.5 MBps USB speed easily, however I am seeing in this blog (despite the different platform and SDK) that only a speed of 4Mbps can be achieved. ( nRF52840 USB throughput ). Is that relevant to ncs 2.0.0 and the nrf5340?

    Thanks

  • As a note, this is my code - adapted from the USB MSC and flash sample.mass.zip

  • Hi,

     

    Robert de Brum said:
    the nrf5340 supports 12 Mbps (full speed). How can I accomplish this?

    Well, the PHY can technically do this.

    However, with a restriction of 64 bytes on a non-isochronous EP, you're limited to sending 64 bytes each microframe (125 us).

    This gives: 64b / 0.125 ms = 500 kB/s.

    Given that there's also a filesystem + external flash in the loop here, it is safe to assume that you're reaching the roof of what the USBD peripheral can do on a generic bulk EP. I was able to see similar readings as you, ranging up to 400 kB/s.

    Robert de Brum said:
    Is that relevant to ncs 2.0.0 and the nrf5340?

    Yes, it is the same USBD peripheral that is present in both the nRF52840 and nRF5340.

    Robert de Brum said:
    Thanks for the clarification. Could you elaborate on "sync", I am not familiar with that command.

    "sync" ensures that any on-going transfers between disks or other mediums are actually finished, and not a cached operation.

    What filesystems can do is to copy the content to a temp location, and schedule the operation "in-the-background". This is one of the reasons why you should never unplug a USB stick without first clicking the "safely eject" option.

    *edit* Striked out the incorrect part. Sorry for misinforming you!

     

    Kind regards,

    Håkon

  • Hello Hakon,

    Thanks very much for your help on this. I appreciate your time.

    Could you advise/elaborate a little further on some of these topics then? I would love to be able to make some progress as quickly as possible:

    1. We went with the nrf5340 thinking that we could utilize the Full-Speed USB bus to transfer up to 230MB in under 6 minutes (This is  232 / (6*60) = 0.640 MBps). The specification of 12Mbps was very appealing to us. Is there is any hope that we can achieve 640+ KBps USB speeds?
    2. How fast can we expect transfer speeds to be with an HID or CDC USB sample running on the n4f5340? This would get us away from the Bulk Endpoint, correct?
    3. According to the USB Developers Guide (https://doc.lagout.org/science/0_Computer%20Science/9_Others/9_Misc/USB%20Complete%20The%20Developer%27s%20Guide%204th%20Ed.pdf - page 74), Full-Speed USB should be able to achieve up to 1.2 MBps. This is calculated by the same 64B per frame that you mentioned, so where does the 125 us that you mention come into play? It is also mentioned in here that Full-Speed does not use microframes.
    4. At the very least, could we implement DPPI or EasyDMA in any way to get closer to the calculated max speed of 500KBps? How would you propose we implement these components?

Related