From 008a9d1cf54c977b70954b1d2d89d1d2e372240e Mon Sep 17 00:00:00 2001 From: "Kwabena W. Agyeman" Date: Fri, 14 Aug 2026 13:55:16 -0700 Subject: [PATCH] stm32/sdcard: Keep SDIO HW flow control disabled on STM32F4. Hardware flow control was enabled for the SD bus in the 2021 SDIO DMA rework to avoid FIFO under/overruns, but on STM32F4 the SDIO hardware flow control is broken: per the STM32F4 errata sheets, enabling it causes glitches on SDIOCLK that corrupt data written to the card. The failure only occurs when flow control actually engages, so it depends on the card: on an OpenMV Cam M4 with a UHS-I class 64GB SDXC card every write failed with a data CRC error (single block) or data timeout (multi block) while reads worked perfectly. Keep hardware flow control disabled on STM32F4 only, matching the errata workaround ("do not use HW flow control"), and leave it enabled on F7/H7/N6 where it works. Verified on the failing board: with this change single and multi-block writes complete and verify correctly (7.9MB/s file writes on the same card), and SD regression runs on STM32F765 and STM32H743 boards are unaffected. Signed-off-by: Kwabena W. Agyeman --- ports/stm32/sdcard.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ports/stm32/sdcard.c b/ports/stm32/sdcard.c index 95128190b71..4c298ca1b61 100644 --- a/ports/stm32/sdcard.c +++ b/ports/stm32/sdcard.c @@ -278,7 +278,14 @@ static HAL_StatusTypeDef sdmmc_init_sd(void) { #endif sdmmc_handle.sd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_ENABLE; sdmmc_handle.sd.Init.BusWide = SDIO_BUS_WIDE_1B; + #if defined(STM32F4) + // The STM32F4 SDIO hardware flow control is broken (see the errata sheets: + // glitches occur on SDIOCLK when it is enabled, corrupting data written to + // the card), so it must be kept disabled here. + sdmmc_handle.sd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; + #else sdmmc_handle.sd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE; + #endif sdmmc_handle.sd.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV; // init the SD interface, with retry if it's not ready yet