STM32L496 - SD Card SDIO write speeds (FreeRTOS, FATFS and USB), how to get "fast" (> 100kbytes/sec) throughput?
Hi all,
I need to stream data into an SD card, at about 25KBytes/sec max. Currently I'm stuck at 11kBytes/sec, but the SDIO data transfer works, kind of. I'm using an STM32L496 board, FATFS and FreeRTOS, as well as USB.
The USB part works actually really well. Every time I plug in I'm able to download at ~400kBytes/sec and copy to the SD card at say ~200Kbytes/sec. I don't need more than that.
When the USB is unplugged, I copy data from different sensors onto a StreamBuffer (FreeRTOS), and once I get 512 bytes, I copy them over to the SD card using f_write(...) through an additional buffer. I have several issues with this:
- If I set the clock on the SD card to be less than 2, it fails very often, seconds after it starts
hsd1.Init.ClockDiv = 2;- If I set the bus to be 4 bits wide with the clock 2 or more, f_write returns 1 (DISK ERROR) after about 6 seconds.
- If I set the bus to be 1 bit wide with clock 2 or more, f_write returns 1 after a few minutes, 3-5.
- My SD write function for FatFS is below:
DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
{
DRESULT res = RES_ERROR;
uint32_t timeout;
uint32_t time;
HAL_StatusTypeDef retval;
HAL_SD_CardStateTypedef cardState;
bool sd_wait = true;
timeout = count * 500; //Timeout in MS per block
sd_wait = true;
if(true == sd_card_ready)
{
retval = HAL_SD_WriteBlocks(&hsd1, (uint8_t *)buff, sector, count, timeout);
cardState = HAL_SD_GetCardState(&hsd1);
if (HAL_OK == retval)
{
time = HAL_GetTick();
while(true == sd_wait)
{
cardState = HAL_SD_GetCardState(&hsd1);
if(HAL_SD_CARD_TRANSFER == cardState)
{
sd_wait = false;
res = RES_OK;
}
if((HAL_GetTick() - time) > timeout)
{
sd_wait = false;
HAL_SD_Abort(&hsd1);
}
}
}
}
return res;
}The above code is the same for the USB transfer.
I'm at a loss a bit, I thought writing a block (512bytes) of data would increase the data throughput to the SD card, and I have a lot of contiguous data blocks, all the time. Data is constantly read in at about 11 KBytes/sec.
I read somewhere else that doing a pre-check on the data alignment before the "HAL_SD_WriteBlocks" call would help. I might need to try that out.
If anyone can point me in the right direction with examples, links, explanations, etc, I'd really appreciate it. I am able to buffer up to ~500ms of data if necessary... maybe more, how can I detect or recover from a slow (250ms or so) write cycle?
Cheers,
Alberto
