STM32H743 unreliable micro SD transfers
Hello all,
I have worked through a number of issues with the SDMMC system and am currently stuck with not being able to reliably transfer from micro SD. I wrote test code to repeatedly read a file from the external card. In some cases HAL_SD_ErrorCallback is called with error code SDMMC_ERROR_CMD_CRC_FAIL.
Here are some things I have tried:
1) Slowing down the clock speed
2) Redesigning the board to improve the signal integrity of the micro SD lines
3) Using SDMMC2 instead of SDMMC1
4) Using 1-bit mode
5) Upgrading to Cube 1.3
6) Switching the pullup mode on the pins on and off
Here is a code excerpt:
SD_HandleTypeDef hsd1;
void SDMgr::Init()
{
memset(&hsd1, 0, sizeof(hsd1));
hsd1.Instance = SDMMC1;
hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
// This assumes an incoming clock of 400MHz / 16 = 25MHz
// Based on measurements, this results in a 50MHz micro SD clock. We get checksum errors
// hsd1.Init.ClockDiv = 2;
// Based on measurements, this results in a 25MHz micro SD clock. We get checksum errors
hsd1.Init.ClockDiv = 4;
memset(&m_SDFatFs, 0, sizeof(m_SDFatFs));
memset(&m_SDPath, 0, sizeof(m_SDPath));
// It is not necessary to cal BSP_SD_Init() here. It is already being called
// through FatFS at the appropriate time.
Mount();
}
void SDMgr::Mount()
{
FATFS_UnLinkDriver(m_SDPath);
/*##-1- Link the micro SD disk I/O driver ##################################*/
if (FATFS_LinkDriver(&SD_Driver, m_SDPath) != 0)
{
Logger::Print("Unable to FATFS_LinkDriver\n");
return;
}
/*##-2- Register the file system object to the FatFs module ##############*/
if(f_mount(&m_SDFatFs, (TCHAR const*)m_SDPath, 0) != FR_OK)
{
/* FatFs Initialization Error */
Logger::Print("Unable to f_mount\n");
Error_Handler();
}
}
void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hsd->Instance==SDMMC1)
{
/* Peripheral clock enable */
__HAL_RCC_SDMMC1_CLK_ENABLE();
/**SDMMC1 GPIO Configuration
PC10 ------> SDMMC1_D2
PC11 ------> SDMMC1_D3
PC12 ------> SDMMC1_CK
PD2 ------> SDMMC1_CMD
PC8 ------> SDMMC1_D0
PC9 ------> SDMMC1_D1
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_8
|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
__HAL_RCC_SDMMC1_FORCE_RESET();
__HAL_RCC_SDMMC1_RELEASE_RESET();
/* NVIC configuration for SDIO interrupts */
HAL_NVIC_SetPriority(SDMMC1_IRQn, IRQ_PRIORITY_SD, 0);
HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
}
}Any ideas? Thank you very much.
UPDATE: I am using FreeRTOS and followed the FatFs_uSD_DMA_RTOS sample.
