STM32H7 SDMMC2 Init Fails -- Get Status Data Reads fail to populate FIFO
I've developed my own PCB using an STM32H723ZGT6 microcontroller. I'd like to store data to a microSD card that's onboard, and I've designed it to use SDMMC2 for the better transmission rate. I have no external pullup resistors, but I have enabled the internal pullup resistors (found to be 38kOhms using a multimeter) on each of the data lines and the CMD line. I have ESD protection inline using the EMIF04-1005M8. The bus is configured in 1-bit mode until successful connection is made. Additionally, I've tried two different micro SD cards, a 32GB SanDisk, and an 8GB Gigastone micro SD card.
I run into issues in HAL_SD_Init, which is called in the MX_SDMMC2_SD_Init. I've stepped through the code using the ST-Link and have found the issue to be in this loop:
while (!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) { if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) { for (count = 0U; count < 8U; count++) { *pData = SDMMC_ReadFIFO(hsd->Instance); pData++; } }
if ((HAL_GetTick() - tickstart) >= SDMMC_SWDATATIMEOUT) { return HAL_SD_ERROR_TIMEOUT; } }
The while loop never reads true, so it always executes the while loop. The first if statement never reads true, so it skips to this line: if ((HAL_GetTick() - tickstart) >= SDMMC_SWDATATIMEOUT). It repeatedly just executes that getTick line.
I changed the MX_SDMMC2_SD_Init code to bypass the GetCardStatus function. When I do that, I get hung up in this function, which loops endlessly:
static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx) { /* 8 is the number of required instructions cycles for the below loop statement. The SDMMC_CMDTIMEOUT is expressed in __ms__ */ uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U);
do { if (count-- == 0U) { return SDMMC_ERROR_TIMEOUT; }
} while (!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDSENT));
/* Clear all the static flags */ __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS);
return SDMMC_ERROR_NONE; }
I could just continue to bypass these functions, but that seems to be useless and only detrimental in the long term. Any help figuring out why these get status reads are failing would be magnificent and greatly appreciated! I've attached images of my circuitry, in the off chance it's an issue with my board design.
