STM32F746 - SD Card CRC failing in 4-bit mode, but working fine in 1-bit mode

Viewed 72

Recently, I bought a Nucleo-144 development board for the STM32F746. For the project I'm working on, I need to get consistent >3 MB/s write speeds to the SD card. Using STM32CubeIDE, I've been able to get SD 1-bit mode working with FatFS in both polling and DMA modes at full speed. However, switching to SD 4-bit mode, I start getting lots of IO errors relating to bad data CRCs while reading.

Details

In SD 4-bit polling mode, I can't even get a single block read to process correctly. Calling f_mount returns an IO error, and debugging it further reveals that the first call to HAL_SD_ReadBlocks, reading sector 0, fails with the error code SDMMC_ERROR_DATA_CRC_FAIL:

first read error, including stack trace

Inspecting the 512 byte data buffer it's read to from the card reveals that data is at least partially intact containing some strings you'd expect to see in the first sector:

corrupted data buffer

Importantly, this buffer is corrupted in the exact same manner between each run of the software. If it was some kind of electrical interference problem, I'd expect to see different bytes being corrupted, but I don't. The buffer is identical between runs. Switching back to 1-bit mode and inspecting the data buffer, it's clearly in a lot better shape. The 4-bit buffer clearly has a lot of corrupted bits and bits that are missing entirely, offsetting everything. 4-bit mode is reading mostly junk, but consistently the same junk.

What I've Tried

  1. Polling and DMA mode.
    • Both fail in a similar manner, although it's harder to debug DMA.
  2. Decreasing the SDMMCCLK clock divider all the way down to 255, the highest divider (and lowest clock speed) it'll go.
    • On my older, cheaper, Lexar SD card read/writes in this mode work flawlessly (albeit very slowly).
    • On my newer, more expensive, Samsung SD card read/writes still fail with a SDMMC_ERROR_DATA_CRC_FAIL error. The data buffer appears much more intact, but it's clearly still garbage data.
  3. Transfers with GPIO pull-ups applied to all SD pins (except clock) as well as without pull-ups.
    • No change, at least as far as I could tell.
  4. Using multiple different SD cards.
    • Specifically, a Lexar "300x" 32 GB card and a Samsung "EVO Plus" 128 GB card.
    • As mentioned previously, decreasing the clock speed allowed one of my two cards to work.
    • However, my higher quality card still fails on the first read even at the minimum speed.

Wiring

Not sure how relevant this is, but figured I'd include it for sake of completion. This is how I have my SD card connected while prototyping. All of the cables are the same length, but perhaps they're interfering with each other even over such a short distance? I'm also using an Adafruit SD card breakout adapter for testing.

SD Card GPIO Pin
CLK PC12
D0 PC8
CMD PD2
D3 PC11
D1 PC9
D2 PC10

SD card connected to microcontroller

Summary

It appears that with some cards, even at lower clock speeds, IO errors are incredibly common in SD 4-bit mode only. At higher clock speeds, all cards I'm able to test with start having IO errors in 4-bit mode. In SD 1-bit mode, however, even at the maximum clock speed I'm able to read and write fine.

I'd like to take advantage of the 4-bit mode for faster speeds. What am I doing wrong? Is it something electrical, like for example needing stronger pull-up resistors or shorter wires? Thanks, I really appreciate it!

1 Answers

I had similar issues on a H743ZI Nucleo. My code worked fine on two other H743 boards with onboard sdcard readers, but failed on the Nucleo with Adafruit breakout. I believe it was just due to signal integrity..

I see you tried dropping the clock divider down, but have you tried a slower SDMMC clock? This was what made the difference for me. Was failing at 48MHz, but fine at 24MHz and lower with 0 divider.

Related