Slow USB MSC transfer speed on nRF5340 with SD card

In our design, we wired the SD card in SPI mode on SPI bus 4 wich a maximum SPI frequency of 50 MHz or 25 MHz as these are supported by the SD card. We used FAT32 file system, but later enabled support for exFAT and formated the SD card with exFAT. For internal logging from our device to the SD card, there is no issue. However, when we try to offload the data from SD card to a host machine, we are having an extremely slow transfer speed: When offloading a 10.5 MB binary file, it takes around 420 seconds, which effectively is only 90 KB/s. We have tried both 25 and 50 MHz SPI frequency but the result is very similar.

We are using USB legacy stack with NCS 3.0.2. I attached here our Kconfigs related to USB.

# Configure USB device
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_PRODUCT="BORUS"
CONFIG_USB_DEVICE_PID=0x0001
CONFIG_USB_DEVICE_VID=0x0001
CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
CONFIG_SERIAL=n
CONFIG_USB_CDC_ACM=n
CONFIG_UART_INTERRUPT_DRIVEN=n
CONFIG_UART_LINE_CTRL=n
CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n

# Configure USB device to appear as DFU class
# Configure DFU autoupdate and reset
CONFIG_USB_DFU_CLASS=y
CONFIG_USB_REQUEST_BUFFER_SIZE=128
CONFIG_USB_DFU_ENABLE_UPLOAD=y
CONFIG_USB_DFU_PERMANENT_DOWNLOAD=y
CONFIG_USB_DFU_REBOOT=y
CONFIG_IMG_MANAGER=y
CONFIG_STREAM_FLASH=y
CONFIG_BOOTLOADER_MCUBOOT=y

# Configure file system 
CONFIG_FLASH_MAP=y
CONFIG_FLASH=y
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=n
CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_FS_FATFS_LFN=y
CONFIG_FS_FATFS_EXFAT=y
CONFIG_FS_LOG_LEVEL_INF=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y
CONFIG_NORDIC_QSPI_NOR=y
CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096

# Configure mass storage
CONFIG_USB_MASS_STORAGE=y
CONFIG_DISK_ACCESS=y
CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y
CONFIG_DISK_LOG_LEVEL_DBG=y
CONFIG_DISK_DRIVERS=y
CONFIG_DISK_DRIVER_SDMMC=y
CONFIG_DISK_DRIVER_FLASH=y
CONFIG_MASS_STORAGE_DISK_NAME="SD"

  • Hi,

    Which SD card do you use?

    Can you show your SPI related configuration?

    You can try to increase the value of CONFIG_SPI_NRFX_RAM_BUFFER_SIZE. What is the result?

    Best regards,
    Dejan

  • Hi,

    We are using the ZDSD32 (this one here). It is basically a SD card without being able to plug in or out. 

    Below is our current SPI configuration on the SPI4 bus in device tree

    &spi4 {
        compatible = "nordic,nrf-spim";
        status = "okay";
        pinctrl-0 = <&spi4_default>;
        pinctrl-1 = <&spi4_sleep>;
        pinctrl-names = "default", "sleep";
        cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
    
        sdhc0: sdhc@0 {
            compatible = "zephyr,sdhc-spi-slot";
            reg = <0>;
            status = "okay";
            mmc {
                compatible = "zephyr,sdmmc-disk";
                status = "okay";
                disk-name = "SD"; 
            };
            spi-max-frequency = <50000000>;
        };
    };
    and the pin control 
    	spi4_default: spi4_default {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK, 0, 8)>,
    				<NRF_PSEL(SPIM_MOSI, 0, 9)>,
    				<NRF_PSEL(SPIM_MISO, 0, 10)>;
    			nordic,drive-mode = <NRF_DRIVE_H0H1>;
    		};
    	};
    
    	spi4_sleep: spi4_sleep {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK, 0, 8)>,
    				<NRF_PSEL(SPIM_MOSI, 0, 9)>,
    				<NRF_PSEL(SPIM_MISO, 0, 10)>;
    			low-power-enable;
    		};
    	};
     

    We will try to increase the buffer size as you recommended tmr to test the result.

    Best

    Shuhao

  • Hello,

    I have tried to increase the buffer size to 128 or 1024. I can confirm this has limited help on increasing transfer speed. Specifically, when copy 10.5 MB file, the time is decreased from previous 131 seconds to now 125 seconds (buffer size = 1024). There is an increase here but not a game changer. Can you suggest other posibilities to debug this issue?

  • Hi,

    Can you share your complete project configuration?

    Best regards,
    Dejan

  • Hi, 

    Please find the complete one here

    # Enable GPIO
    CONFIG_GPIO=y
    # Enable I2C
    CONFIG_I2C=y
    # Enable SPI
    CONFIG_SPI=y
    
    # Enable log and use it via Jlink RTT rather than CDC ACM 
    CONFIG_LOG=y
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_LOG_BACKEND_RTT=y    
    CONFIG_LOG_BACKEND_UART=n
    CONFIG_RTT_CONSOLE=n    
    CONFIG_STDOUT_CONSOLE=n 
    CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=4096  
    CONFIG_LOG_BUFFER_SIZE=8192
    CONFIG_UART_CONSOLE=n
    CONFIG_CONSOLE=n
    
    # Enable Bluetooth LE
    CONFIG_BT=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_DEVICE_NAME="BORUS"
    CONFIG_BT_BROADCASTER=y
    CONFIG_BT_OBSERVER=y
    CONFIG_BT_FILTER_ACCEPT_LIST=y
    # Extended BLE 
    CONFIG_BT_EXT_ADV=y
    CONFIG_BT_EXT_ADV_MAX_ADV_SET=2
    
    # Enale floating point unit for float point calculation 
    CONFIG_FPU=y
    CONFIG_CBPRINTF_FP_SUPPORT=y
    
    # Enable debugging 
    CONFIG_DEBUG_THREAD_INFO=y
    CONFIG_DEBUG_OPTIMIZATIONS=y
    
    # Enable multithread
    CONFIG_MULTITHREADING=y
    
    # Enable battery voltage monitoring
    CONFIG_SENSOR=y
    CONFIG_PWM=n
    CONFIG_ADC=y
    CONFIG_VOLTAGE_DIVIDER=y
    CONFIG_NRFX_SAADC=y
    
    # Configure USB device
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PRODUCT="BORUS"
    CONFIG_USB_DEVICE_PID=0x0001
    CONFIG_USB_DEVICE_VID=0x0001
    CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
    CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
    CONFIG_SERIAL=n
    CONFIG_USB_CDC_ACM=n
    CONFIG_UART_INTERRUPT_DRIVEN=n
    CONFIG_UART_LINE_CTRL=n
    CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n
    CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
    
    # Configure USB device to appear as DFU class
    # Configure DFU autoupdate and reset
    CONFIG_USB_DFU_CLASS=y
    CONFIG_USB_REQUEST_BUFFER_SIZE=128
    CONFIG_USB_DFU_ENABLE_UPLOAD=y
    CONFIG_USB_DFU_PERMANENT_DOWNLOAD=y
    CONFIG_USB_DFU_REBOOT=y
    CONFIG_IMG_MANAGER=y
    CONFIG_STREAM_FLASH=y
    CONFIG_BOOTLOADER_MCUBOOT=y
    
    # Configure file system 
    CONFIG_FLASH_MAP=y
    CONFIG_FLASH=y
    CONFIG_FILE_SYSTEM=y
    CONFIG_FILE_SYSTEM_LITTLEFS=n
    CONFIG_FAT_FILESYSTEM_ELM=y
    CONFIG_FS_FATFS_LFN=y
    CONFIG_FS_FATFS_EXFAT=y
    CONFIG_FS_LOG_LEVEL_INF=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_MPU_ALLOW_FLASH_WRITE=y
    CONFIG_NORDIC_QSPI_NOR=y
    CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    
    # Configure SPI RAM buffer size
    CONFIG_SPI_NRFX_RAM_BUFFER_SIZE=128
    
    # Configure mass storage
    CONFIG_USB_MASS_STORAGE=y
    CONFIG_DISK_ACCESS=y
    CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y
    CONFIG_DISK_LOG_LEVEL_DBG=y
    CONFIG_DISK_DRIVERS=y
    CONFIG_DISK_DRIVER_SDMMC=y
    CONFIG_DISK_DRIVER_FLASH=y
    CONFIG_MASS_STORAGE_DISK_NAME="SD"
    
    # Configure BLE encryption
    CONFIG_NRF_SECURITY=y
    CONFIG_MBEDTLS_PSA_CRYPTO_C=y
    CONFIG_PSA_CRYPTO_DRIVER_CC3XX=y
    CONFIG_PSA_CRYPTO_DRIVER_OBERON=n
    CONFIG_PSA_WANT_KEY_TYPE_AES=y
    CONFIG_PSA_WANT_ALG_CTR=y
    CONFIG_HEAP_MEM_POOL_SIZE=4096
    CONFIG_MBEDTLS_ENABLE_HEAP=y
    CONFIG_MBEDTLS_HEAP_SIZE=8192
    CONFIG_TEST_RANDOM_GENERATOR=y
    
    # Configure Settings subsystem
    CONFIG_SETTINGS=y
    CONFIG_SETTINGS_RUNTIME=y
    CONFIG_NVS=y
    CONFIG_SETTINGS_NVS=y
    CONFIG_MPU_ALLOW_FLASH_WRITE=y
    
    # Configure Watchdog
    CONFIG_WATCHDOG=y
    CONFIG_WDT_DISABLE_AT_BOOT=n
    
    # Enable State Machine Framework
    CONFIG_SMF=y
    
    # Enable DSP
    CONFIG_CMSIS_DSP=y
    CONFIG_CMSIS_DSP_FILTERING=y
    CONFIG_CMSIS_DSP_TRANSFORM=y
    CONFIG_CMSIS_DSP_STATISTICS=y
    CONFIG_CMSIS_DSP_FASTMATH=y
    CONFIG_REQUIRES_FULL_LIBC=y
    CONFIG_RING_BUFFER=y
    
    # Power management
    CONFIG_PM_DEVICE=y
    CONFIG_RAM_POWER_DOWN_LIBRARY=y
    CONFIG_POWEROFF=y
    
    CONFIG_BMI270=y
    CONFIG_BMI270_TRIGGER_GLOBAL_THREAD=y
    CONFIG_BMP388=y
    CONFIG_BMP388_TRIGGER_GLOBAL_THREAD=y
    CONFIG_BMP388_ODR_RUNTIME=y
    CONFIG_BMP388_OSR_RUNTIME=y 
    
    # ------------------- Edge ML -------------------
    CONFIG_CPP=y                
    CONFIG_STD_CPP11=y
    CONFIG_FP16=n
    CONFIG_EDGE_IMPULSE=y
    CONFIG_EDGE_IMPULSE_URI="/Users/gw23523/Downloads/test-cpp-mcu-v3.zip"
    CONFIG_EI_WRAPPER=y
    
    # ------------------- Turn below ON for Optimisation -------------------
    # Stack sizes (This needs to be optimised using the thread analyzer below)
    # CONFIG_MAIN_STACK_SIZE=1024
    # CONFIG_ISR_STACK_SIZE=1536
    # CONFIG_IDLE_STACK_SIZE=256
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
    
    # Thread analyser for debug purposes
    # CONFIG_THREAD_ANALYZER=y
    # CONFIG_THREAD_ANALYZER_USE_LOG=y
    # CONFIG_THREAD_ANALYZER_AUTO=y
    # CONFIG_THREAD_ANALYZER_AUTO_INTERVAL=10
    # CONFIG_THREAD_NAME=y
    # ----------------------------------------------------------------------

Related