2024-03-13 05:25 AM
Hi,
I need help on MMC operations.
My project is using STM32U575 to access MMC chip (EMMC16G-IB29). It uses SDMMC1 on 4B bus (MMC 4bit wide bus). The U575 is running on 90MHz. The initialization sub is:
static void MX_SDMMC1_MMC_Init(void)
{
hmmc1.Instance = SDMMC1;
hmmc1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
hmmc1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
hmmc1.Init.BusWide = SDMMC_BUS_WIDE_4B;
hmmc1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
hmmc1.Init.ClockDiv = 3;// less than 3 won't work
if (HAL_MMC_Init(&hmmc1) != HAL_OK)
{
Error_Handler();
}
}
I can perform erase, write, and read operations on this chip without issues using the HAL_MMC_WriteBlocks() and HAL_MMC_ReadBlocks() function calls. However, when I switch to using HAL_MMC_WriteBlocks_DMA() and HAL_MMC_ReadBlocks_DMA(), the program halts at SDMMC_GetCmdResp1().
Interestingly, if I insert a break-point after HAL_MMC_WriteBlocks_DMA(), then continue, the MMC operation succeeds. It seems like there might be some timing issues, although HAL_MMC_WriteBlocks_DMA() returns HAL_OK, indicating a successful operation.
The testing function is
uint8_t Test_eMMC(void)
{
uint8_t ret = HAL_OK;
if(Wait_MMCCARD_Ready() != HAL_OK)
{
_eMMC_Error_Handler();
}
if(HAL_MMC_Erase(&hmmc1, ADDRESS, ADDRESS + MMC_LOG_BUFSIZE) != HAL_OK)
{
_eMMC_Error_Handler();
}
if(Wait_MMCCARD_Ready() != HAL_OK)
{
_eMMC_Error_Handler();
}
/* Fill the buffer with 0, 1, 2, ... */
for (uint16_t i = 0; i < MMC_LOG_BUFSIZE; i++)
{
MMC_Log_Buf[i] = (i & 0xff);
}
if(Wait_MMCCARD_Ready() != HAL_OK)
{
_eMMC_Error_Handler();
}
if(HAL_MMC_WriteBlocks_DMA(&hmmc1, MMC_Log_Buf, ADDRESS, MMC_LOG_BUFSIZE/MMC_SECTOR_SIZE)!= HAL_OK)
{
_eMMC_Error_Handler();
}
if(Wait_MMCCARD_Ready() != HAL_OK)
{
_eMMC_Error_Handler();
}
/* Clear buffer */
for (uint16_t i = 0; i < MMC_LOG_BUFSIZE; i++)
{
MMC_Log_Buf[i] = 0;
}
/* read back from MMC */
if (HAL_MMC_ReadBlocks_DMA(&hmmc1, MMC_Log_Buf, ADDRESS, MMC_LOG_BUFSIZE/MMC_SECTOR_SIZE) != HAL_OK)
{
_eMMC_Error_Handler();
}
return HAL_OK;
}
uint8_t Wait_MMCCARD_Ready(void)
{
uint32_t loop = MMC_TIMEOUT;
while(loop > 0)
{
loop--;
if(HAL_MMC_GetCardState(&hmmc1) == HAL_MMC_CARD_TRANSFER)
{
return HAL_OK;
}
}
return HAL_ERROR;
}
Did I miss something for the MMC DMA operations? Thanks.
Regards
HGUAN