I'm trying to get the DMA + SDMMC to write to an SD Card using the HAL_SD_WriteBlocks_DMA() function.
After I call the function, the HAL_DMA_GetState() function never returns HAL_DMA_STATE_READY, and the same is true for HAL_SD_GetState(), meaning all subsequent calls to the SDMMC fail.
I attached Data, Clock and Cmd to an Oscilloscope (the wires from the board to SD card), and I don't register any activity on the Data and Cmd lines in the above case.
So no data is written.
Firmware: Using Cube, 1.8.1, SDMMC is clocked at 48Mhz, the DMA at 80Mhz. Transfer using 1 Data line. Interrupts are set for both TX, RX and there is a global SDMMC interrupt with a higher priority than TX and RX.
DMA: TX uses DMA2 Channel 4, RX uses DMA2 Channel 5.
HAL_SD_ReadBlocks_DMA, HAL_SD_ReadBlocks, and HAL_SD_WriteBlocks all work.
I modified the BSP_SD_WriteBlocks_DMA function to wait for the DMA and SDMMC to finish before returning.
This is my test code (nothing important here):
In the ERRATA Datasheet I found a note saying the WAITRESP register doesn't work correctly when no response is expected. I don't think this applies here; But I tried it anyway by setting sdmmc_cmdinit.Response = SDMMC_RESPONSE_NO; in the function SDMMC_CmdWriteMultiBlock(). Errorstate will be bad after I do that.
I recompiled the project using MXCube and switched the DMA2 Channels for RX and TX, now RX is on Channel 4, TX is on Channel 5.
Now Writing is working without issues, but reading hangs.
I changing the priority of one channel over the other doesn't change anything either.
So as a workaround, I just don't use the DMA to write for now.
Now I have a new issue:
The SDMMC doesn't go back to HAL_SD_STATE_READY if I call the DMA to fast.
If I put a delay between the write commands they work without issue.
ST Support suggested following solution:
[C] SDMMC DMA STM32-L476RG - Pastebin.com
I didn't verify it because I migrated to firmware 1.9 by now, but maybe it helps someone else.