2024-01-11 09:09 AM
I have been working on a STM32L496VGT6 using a 2GB sd card. I have the interface set to 4bit bus, no flow control and a clock divider of 4. I have a demo application that uses SDMMC, FreeRtos and FatFs and works perfectly. When i move the exact firmware to my real application with several tasks and other interrupt driven communication, I can still communicate in a READ only fashion, but as I try to implement simple writes, they always fail with the following error SDMMC_ERROR_TX_UNDERRUN.
I have read several threads that suggest solutions, and I believe it is because the SDCard wants data prior to the DMA being ready, but I have not found any solution that works. I have increased the clock divide, increased the DMA priority from high to very high, but nothing seems to work. I would appreciate any suggestions.
I am using STMCubeIde STM32Cube FW_L4 V1.18.0, FatFS R0.12c and FreeRtos 10.3.1 with CMSIS V2.00
2024-01-11 09:53 AM
This happens if the communication is too slow, which can happen if the code doesn't keep up with what is expected on the bus.
As a quick fix, you can try compiling in Release configuration or slowing down the clock. If you're already doing so, the fix is a bit more complicated. By what factor did you try slowing down the clock? Try the max possible. If it still fails, something else is going on.
2024-01-11 10:29 AM
Definitely want to be using DMA, make sure the code you're using doesn't have any race conditions.
ST over the years had shipped code that sends the SDMMC device a command before the DMA is configured.
Their polled mode code also has had issues, one where they addressed buffer/pointer alignment with the least efficient method, always. ie not just in the cases that actually needed action.
The FATFS version is very old.
Buffers and interactions with the file system should be aligned and as large as possible.
A lot of small f_read() / f_write() / f_seek() action will be very detrimental to performance, causing significant churn.
2024-01-11 10:51 AM
The SDMMC clock is 48Mz with a SDMMC clock divide factor of 4. This works fine with DMA on my test application without all the other peripherals and comm running. On my real application I have the same configuration. I have also increased the divider to 100 and 200, all with the same underrun error.