cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H723 SDMMC FIFO blocks while write data

Blowind
Associate

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);
}

...

}

0 REPLIES 0