From 2ce9fa4b9c960fef703dc0d5cf31b0d312737a74 Mon Sep 17 00:00:00 2001 From: Victor Oliveira Date: Mon, 28 Dec 2020 02:08:06 -0300 Subject: [PATCH] Better defaults, compatibility for SDIO + STM32 (#20570) --- .../src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp | 60 ++++++++++--------- Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h | 2 + Marlin/src/pins/stm32f4/pins_LERDGE_K.h | 1 + Marlin/src/pins/stm32f4/pins_LERDGE_S.h | 1 + Marlin/src/pins/stm32f4/pins_LERDGE_X.h | 1 + platformio.ini | 8 +-- 6 files changed, 42 insertions(+), 31 deletions(-) diff --git a/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp b/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp index a7b1e8006f..e00fb9b16f 100644 --- a/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp +++ b/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp @@ -88,18 +88,37 @@ MKS Robin board seems to have stable SDIO with BusWide 1bit and ClockDiv 8 i.e. 4.8MHz SDIO clock frequency Additional testing is required as there are clearly some 4bit initialization problems - - Add -DTRANSFER_CLOCK_DIV=8 to build parameters to improve SDIO stability */ - #ifndef TRANSFER_CLOCK_DIV - #define TRANSFER_CLOCK_DIV (uint8_t(SDIO_INIT_CLK_DIV) / 40) - #endif - #ifndef USBD_OK #define USBD_OK 0 #endif + // Target Clock, configurable. Default is 18MHz, from STM32F1 + #ifndef SDIO_CLOCK + #define SDIO_CLOCK 18000000 /* 18 MHz */ + #endif + + // SDIO retries, configurable. Default is 3, from STM32F1 + #ifndef SDIO_READ_RETRIES + #define SDIO_READ_RETRIES 3 + #endif + + // SDIO Max Clock (naming from STM Manual, don't change) + #define SDIOCLK 48000000 + + static uint32_t clock_to_divider(uint32_t clk) { + // limit the SDIO master clock to 8/3 of PCLK2. See STM32 Manuals + // Also limited to no more than 48Mhz (SDIOCLK). + const uint32_t pclk2 = HAL_RCC_GetPCLK2Freq(); + clk = min(clk, (uint32_t)(pclk2 * 8 / 3)); + clk = min(clk, (uint32_t)SDIOCLK); + // Round up divider, so we don't run the card over the speed supported, + // and subtract by 2, because STM32 will add 2, as written in the manual: + // SDIO_CK frequency = SDIOCLK / [CLKDIV + 2] + return pclk2 / clk + (pclk2 % clk != 0) - 2; + } + void go_to_transfer_speed() { SD_InitTypeDef Init; @@ -109,7 +128,7 @@ Init.ClockPowerSave = hsd.Init.ClockPowerSave; Init.BusWide = hsd.Init.BusWide; Init.HardwareFlowControl = hsd.Init.HardwareFlowControl; - Init.ClockDiv = TRANSFER_CLOCK_DIV; + Init.ClockDiv = clock_to_divider(SDIO_CLOCK); /* Initialize SDIO peripheral interface with default configuration */ SDIO_Init(hsd.Instance, Init); @@ -155,38 +174,25 @@ //Initialize the SDIO (with initial <400Khz Clock) tempreg = 0; //Reset value tempreg |= SDIO_CLKCR_CLKEN; // Clock enabled - tempreg |= (uint32_t)0x76; // Clock Divider. Clock = 48000 / (118 + 2) = 400Khz + tempreg |= SDIO_INIT_CLK_DIV; // Clock Divider. Clock = 48000 / (118 + 2) = 400Khz // Keep the rest at 0 => HW_Flow Disabled, Rising Clock Edge, Disable CLK ByPass, Bus Width = 0, Power save Disable SDIO->CLKCR = tempreg; // Power up the SDIO - SDIO->POWER = 0x03; + SDIO_PowerState_ON(SDIO); } void HAL_SD_MspInit(SD_HandleTypeDef *hsd) { // application specific init - UNUSED(hsd); /* Prevent unused argument(s) compilation warning */ + UNUSED(hsd); // Prevent unused argument(s) compilation warning __HAL_RCC_SDIO_CLK_ENABLE(); // turn on SDIO clock } - constexpr uint8_t SD_RETRY_COUNT = TERN(SD_CHECK_AND_RETRY, 3, 1); - bool SDIO_Init() { - //init SDIO and get SD card info - - uint8_t retryCnt = SD_RETRY_COUNT; + uint8_t retryCnt = SDIO_READ_RETRIES; bool status; hsd.Instance = SDIO; - hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET - - /* - hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; - hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; - hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; - hsd.Init.BusWide = SDIO_BUS_WIDE_1B; - hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; - hsd.Init.ClockDiv = 8; - */ + hsd.State = HAL_SD_STATE_RESET; SD_LowLevel_Init(); @@ -258,7 +264,7 @@ bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) { hsd.Instance = SDIO; - uint8_t retryCnt = SD_RETRY_COUNT; + uint8_t retryCnt = SDIO_READ_RETRIES; bool status; for (;;) { @@ -307,7 +313,7 @@ bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) { hsd.Instance = SDIO; - uint8_t retryCnt = SD_RETRY_COUNT; + uint8_t retryCnt = SDIO_READ_RETRIES; bool status; for (;;) { status = (bool) HAL_SD_WriteBlocks(&hsd, (uint8_t*)src, block, 1, 500); // write one 512 byte block with 500mS timeout diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h index ebfb00bfb6..21dad6df3e 100644 --- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h @@ -165,6 +165,8 @@ #define SPI_DEVICE 2 #define SDIO_SUPPORT +#define SDIO_CLOCK 4500000 +#define SDIO_READ_RETRIES 16 #if ENABLED(SDIO_SUPPORT) #define SCK_PIN PB13 // SPI2 #define MISO_PIN PB14 // SPI2 diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_K.h b/Marlin/src/pins/stm32f4/pins_LERDGE_K.h index 48973688a0..ef96eecd74 100644 --- a/Marlin/src/pins/stm32f4/pins_LERDGE_K.h +++ b/Marlin/src/pins/stm32f4/pins_LERDGE_K.h @@ -142,6 +142,7 @@ // SD support // #define SDIO_SUPPORT +#define SDIO_CLOCK 4800000 // // Misc. Functions diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_S.h b/Marlin/src/pins/stm32f4/pins_LERDGE_S.h index 0600ed4338..bd4d1f6618 100644 --- a/Marlin/src/pins/stm32f4/pins_LERDGE_S.h +++ b/Marlin/src/pins/stm32f4/pins_LERDGE_S.h @@ -156,6 +156,7 @@ // SD support // #define SDIO_SUPPORT +#define SDIO_CLOCK 4800000 #define SCK_PIN PC12 //confirmed working #define MISO_PIN PC8 //confirmed working diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_X.h b/Marlin/src/pins/stm32f4/pins_LERDGE_X.h index 6e0b3e14a7..c8f52d6987 100644 --- a/Marlin/src/pins/stm32f4/pins_LERDGE_X.h +++ b/Marlin/src/pins/stm32f4/pins_LERDGE_X.h @@ -127,6 +127,7 @@ // #define SDIO_SUPPORT #define SD_DETECT_PIN PA8 +#define SDIO_CLOCK 4800000 // // LCD / Controller diff --git a/platformio.ini b/platformio.ini index a95647cf42..924da69a74 100644 --- a/platformio.ini +++ b/platformio.ini @@ -973,7 +973,7 @@ board_build.offset = 0x7000 board_build.encrypt = Yes board_build.firmware = Robin.bin build_flags = ${common_stm32.build_flags} - -DENABLE_HWSERIAL3 -DTRANSFER_CLOCK_DIV=8 -DTIMER_SERIAL=TIM5 + -DENABLE_HWSERIAL3 -DTIMER_SERIAL=TIM5 build_unflags = ${common_stm32.build_unflags} -DUSBCON -DUSBD_USE_CDC extra_scripts = ${common.extra_scripts} @@ -1149,7 +1149,7 @@ upload_protocol = jlink [env:flsun_hispeedv1] platform = ${common_stm32.platform} extends = common_stm32 -build_flags = ${common_stm32.build_flags} -DMCU_STM32F103VE -DSS_TIMER=4 -DENABLE_HWSERIAL3 -DTRANSFER_CLOCK_DIV=8 +build_flags = ${common_stm32.build_flags} -DMCU_STM32F103VE -DSS_TIMER=4 -DENABLE_HWSERIAL3 board = genericSTM32F103VE board_build.core = stm32 board_build.variant = MARLIN_F103Vx @@ -1321,7 +1321,7 @@ extra_scripts = ${common.extra_scripts} build_flags = ${common_stm32.build_flags} -DSTM32F4 -DSTM32F4xx -DTARGET_STM32F4 -DDISABLE_GENERIC_SERIALUSB -DARDUINO_ARCH_STM32 -DARDUINO_LERDGE - -DTRANSFER_CLOCK_DIV=8 -DHAL_SRAM_MODULE_ENABLED + -DHAL_SRAM_MODULE_ENABLED build_unflags = ${common_stm32.build_unflags} -DUSBCON -DUSBD_USE_CDC -DUSBD_VID=0x0483 # @@ -1369,7 +1369,7 @@ monitor_speed = 500000 [env:mks_robin_nano35_stm32] platform = ${common_stm32.platform} extends = common_stm32 -build_flags = ${common_stm32.build_flags} -DMCU_STM32F103VE -DSS_TIMER=4 -DENABLE_HWSERIAL3 -DTRANSFER_CLOCK_DIV=8 +build_flags = ${common_stm32.build_flags} -DMCU_STM32F103VE -DSS_TIMER=4 -DENABLE_HWSERIAL3 board = genericSTM32F103VE board_build.core = stm32 board_build.variant = MARLIN_F103Vx