cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 USB High Speed read SD card only 1 MB/s

dzikos
Associate II

Hello!

I am using STM32F427VGT with USB3300 as USB high speed device mass storage class. I want to read data from SD card to a PC and I am only able to get transfer speed about 1 MB/s. What is the real maximum read speed that I can get with this hardware configuration?

MCU provides USB3300 with 24 MHz clock and I am using BSP_SD_ReadBlocks_DMA() in STORAGE_Read_HS(). Transfer speed only slightly depends on SDIO clock divider - changing divider from 1 to 5 reduces the transfer by only about 20%. My code is generated with STM32CubeMX.

Here is my STORAGE_Read_HS():

int8_t STORAGE_Read_HS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
 /* USER CODE BEGIN 13 */
	uint8_t readResult;
	uint32_t timeout = 100000;
 
    readResult = BSP_SD_ReadBlocks_DMA((uint32_t *) buf, blk_addr, blk_len);
 
    while (BSP_SD_GetCardState() != SD_TRANSFER_OK)
    {
        if (timeout-- == 0)
        {
          return USBD_FAIL;
        }
    }
 
	if (readResult == MSD_OK)
	{
		return USBD_OK;
	}
	else
	{
		return USBD_FAIL;
	}
 /* USER CODE END 13 */
}

Any ideas why I am not able to achieve greater read speed?

Kind regards

Bartosz

2 REPLIES 2

Perhaps it is doing single block transfers, they are slow, instrument the code to see what's happening real time

Check settings for MSC_MEDIA_PACKET, 512 will be a sloth..

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dzikos
Associate II

I tried changing MSC_MEDIA_PACKET to 1024, 2048, 4096, 8192, ..., but none of these settings even worked. USB drive was not properly recognized by the PC. Do i have to change the value somewhere else as well?

Also, I found this in stm32f4xx_hal_sd.c:

  *** SD Card Read operation ***
  ==============================
  [..]
    (+) You can read from SD card in polling mode by using function HAL_SD_ReadBlocks().
        This function support only 512-bytes block length (the block size should be
        chosen as 512 bytes).
        You can choose either one block read operation or multiple block read operation
        by adjusting the "NumberOfBlocks" parameter.
        After this, you have to ensure that the transfer is done correctly. The check is done
        through HAL_SD_GetCardState() function for SD card state.
 
    (+) You can read from SD card in DMA mode by using function HAL_SD_ReadBlocks_DMA().
        This function support only 512-bytes block length (the block size should be
        chosen as 512 bytes).
        You can choose either one block read operation or multiple block read operation
        by adjusting the "NumberOfBlocks" parameter.
        After this, you have to ensure that the transfer is done correctly. The check is done
        through HAL_SD_GetCardState() function for SD card state.
        You could also check the DMA transfer process through the SD Rx interrupt event.
 
    (+) You can read from SD card in Interrupt mode by using function HAL_SD_ReadBlocks_IT().
        This function support only 512-bytes block length (the block size should be
        chosen as 512 bytes).
        You can choose either one block read operation or multiple block read operation
        by adjusting the "NumberOfBlocks" parameter.
        After this, you have to ensure that the transfer is done correctly. The check is done
        through HAL_SD_GetCardState() function for SD card state.
        You could also check the IT transfer process through the SD Rx interrupt event.

Does it mean I am stuck with MSC_MEDIA_PACKET = 512, or does it only limit MSC_MEDIA_PACKET to be a multiply of 512?