2024-03-26 05:36 AM - edited 2024-03-26 05:52 AM
I configured a FATFS project using STM32CUBEMX to write 248 bytes of data every 1ms, with a buffer accumulating up to 1024 bytes before writing to the SD card. However, I encountered significant blocking issues with f_write. To troubleshoot, I replaced BSP_SD_WriteBlocks_DMA with BSP_SD_WriteBlocks, but after running for about 1 second, I started getting errors when trying to write to the file. The errors stopped when I enabled hardware flow control. Using a logic analyzer, I noticed that the SDMMC_WriteFIFO sometimes had intervals of tens to hundreds of milliseconds in the middle of writing a sector, leading to a very low write rate. What could be causing such long intervals in the write FIFO?
The position of the logic analyzer probe in the code:
HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, const uint8_t *pData, uint32_t BlockAdd,
uint32_t NumberOfBlocks, uint32_t Timeout){
...
/* Write block(s) in polling mode */
dataremaining = config.DataLength;
HAL_GPIO_WritePin(LED_Port, LED_0_Pin, GPIO_PIN_SET);
while (!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT |
SDMMC_FLAG_DATAEND))
{
HAL_GPIO_WritePin(LED_Port, LED_4_Pin, GPIO_PIN_SET);
if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= 32U))
{
/* Write data to SDMMC Tx FIFO */
for (count = 0U; count < 8U; count++)
{
data = (uint32_t)(*tempbuff);
tempbuff++;
data |= ((uint32_t)(*tempbuff) << 8U);
tempbuff++;
data |= ((uint32_t)(*tempbuff) << 16U);
tempbuff++;
data |= ((uint32_t)(*tempbuff) << 24U);
tempbuff++;
HAL_GPIO_WritePin(LED_Port, LED_1_Pin, GPIO_PIN_SET);
(void)SDMMC_WriteFIFO(hsd->Instance, &data);
HAL_GPIO_WritePin(LED_Port, LED_1_Pin, GPIO_PIN_RESET);
}
dataremaining -= 32U;
}
HAL_GPIO_WritePin(LED_Port, LED_4_Pin, GPIO_PIN_RESET);
if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
{
/* Clear all the static flags */
__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
hsd->ErrorCode |= errorstate;
hsd->State = HAL_SD_STATE_READY;
hsd->Context = SD_CONTEXT_NONE;
printf("1\n");
return HAL_TIMEOUT;
}
}
HAL_GPIO_WritePin(LED_Port, LED_0_Pin, GPIO_PIN_RESET);
__SDMMC_CMDTRANS_DISABLE(hsd->Instance);
...
}
DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
{
...
if(BSP_SD_WriteBlocks((uint32_t*)buff,
(uint32_t)(sector),
count, 1000) == MSD_OK)
{
}
timeout = HAL_GetTick();
while((HAL_GetTick() - timeout) < SD_TIMEOUT)
{
HAL_GPIO_WritePin(LED_Port, LED_3_Pin, GPIO_PIN_SET);
if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
{
res = RES_OK;
HAL_GPIO_WritePin(LED_Port, LED_3_Pin, GPIO_PIN_RESET);
break;
}
HAL_GPIO_WritePin(LED_Port, LED_3_Pin, GPIO_PIN_RESET);
}
...
}
2024-06-05 07:27 AM
Hi! See my post, it might be related: https://community.st.com/t5/stm32-mcus-embedded-software/stm32h7-with-fatfs-on-emmc-sometimes-failing/m-p/637240#M44829
Even if it's a SD card, the controller is the same as the eMMC so I guess it can be a similar issue... are you getting a consistent delay in each writing operation? has the SD card been used for many writings or seems to be independent of its usage?