2021-08-19 09:30 AM
Hello,
I am working with the SDMMC peripheral on a STM32L4S9 chip to interface with an SD card on a custom board using the HAL SD card driver. I am performing reads and writes using `HAL_SD_WriteBlocks` and `HAL_SD_ReadBlocks`.
Everything is working well, until an SD card timeout occurs. I have noticed in this case some serious failures in our application. I reduced the timeout duration to something low (10ms) to reproduce the issue. After debugging, I have tracked the issue down to the SD card remaining in the RECEIVING state when a write timeout occurs. This makes sense, because `HAL_SD_WriteBlocks` stops in the middle of the transmission in the event of a timeout, and the SD card is waiting to receive more data. According to the SD card spec, CMD12 should be sent in the event that a transmission should be aborted.
I saw that `HAL_SD_Abort` will send CMD12, so I call that if a timeout occurs. However, following the timeout, `HAL_SD_Abort` always fails due to a timeout in when getting the SDMMC response. I hooked up a logic analyzer to the CMD line on the SD card, and discovered that the call to `HAL_SD_GetCardState` never puts CMD13 on the CMD line, leading to the response timeout. I've also tried bypassing the card state check, and calling `SDMMC_CmdStopTransfer` directly, and the result is the same: the command is not put on the CMD line.
I'm suspecting that when timeouts occur and the `HAL_SD_Write/ReadBlocks` decides to exit, it leaves the CPSM/DPSM in a weird state and doesn't clean up properly. From what I've been reading on the reference manual, it seems like CMD12 is required in the case of a timeout to put the CPSM/DPSM back in the idle state. Lastly, I've discovered that if I disable SDMMC hardware flow control the command following the timeout will show up on the command line, but it also causes every read to time out: the DCNT register is never decremented and so the code never pulls anything out of the FIFO even though I can clearly see data coming in on the logic analyzer.
Does anyone have any similar experiences with this? What could I be doing wrong here?