From 6b23f7d3011ce89aeb00bc510eba97e5e36cd180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Meri=C3=A7=20SARII=C5=9EIK?= Date: Mon, 7 Feb 2022 15:41:17 +0100 Subject: [PATCH] stm32/sdio: Use runtime calculation for clock divider of sdio on H7. STM32H7 family has a different calculation compared to the current one for the SDMMC clock divider configuration. --- ports/stm32/sdio.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ports/stm32/sdio.c b/ports/stm32/sdio.c index bedafcb138..99d05a5155 100644 --- a/ports/stm32/sdio.c +++ b/ports/stm32/sdio.c @@ -96,6 +96,19 @@ static volatile uint8_t *sdmmc_buf_top; #define MICROPY_HW_SDIO_CMD (pin_D2) #endif +#if defined(STM32H7) +static uint32_t safe_divide(uint32_t denom) { + uint32_t num = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC); + uint32_t divres; + + divres = num / (2U * denom); + if ((num % (2U * denom)) > denom) { + divres++; + } + return divres; +} +#endif + void sdio_init(uint32_t irq_pri) { // configure IO pins mp_hal_pin_config_alt_static(MICROPY_HW_SDIO_D0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC_D0); @@ -110,6 +123,8 @@ void sdio_init(uint32_t irq_pri) { SDMMC_TypeDef *SDIO = SDMMC; #if defined(STM32F7) SDIO->CLKCR = SDMMC_CLKCR_HWFC_EN | SDMMC_CLKCR_PWRSAV | (120 - 2); // 1-bit, 400kHz + #elif defined(STM32H7) + SDIO->CLKCR = SDMMC_CLKCR_HWFC_EN | SDMMC_CLKCR_PWRSAV | safe_divide(400000U); // 1-bit, 400kHz #else SDIO->CLKCR = SDMMC_CLKCR_HWFC_EN | SDMMC_CLKCR_PWRSAV | (120 / 2); // 1-bit, 400kHz #endif @@ -157,6 +172,8 @@ void sdio_enable_high_speed_4bit(void) { mp_hal_delay_us(10); #if defined(STM32F7) SDIO->CLKCR = SDMMC_CLKCR_HWFC_EN | SDMMC_CLKCR_WIDBUS_0 | SDMMC_CLKCR_BYPASS /*| SDMMC_CLKCR_PWRSAV*/; // 4-bit, 48MHz + #elif defined(STM32H7) + SDIO->CLKCR = SDMMC_CLKCR_HWFC_EN | SDMMC_CLKCR_WIDBUS_0 | safe_divide(48000000U); // 4-bit, 48MHz #else SDIO->CLKCR = SDMMC_CLKCR_HWFC_EN | SDMMC_CLKCR_WIDBUS_0; // 4-bit, 48MHz #endif