Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better Defaults and Compatibility for SDIO in STM32 #20570

Merged
merged 4 commits into from
Dec 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 33 additions & 27 deletions Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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 (;;) {
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions Marlin/src/pins/stm32f1/pins_MKS_ROBIN.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@
#define SPI_DEVICE 2

#define SDIO_SUPPORT
#define SDIO_CLOCK 4500000
#define SDIO_READ_RETRIES 16
rhapsodyv marked this conversation as resolved.
Show resolved Hide resolved
#if ENABLED(SDIO_SUPPORT)
#define SCK_PIN PB13 // SPI2
#define MISO_PIN PB14 // SPI2
Expand Down
1 change: 1 addition & 0 deletions Marlin/src/pins/stm32f4/pins_LERDGE_K.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
// SD support
//
#define SDIO_SUPPORT
#define SDIO_CLOCK 4800000

//
// Misc. Functions
Expand Down
1 change: 1 addition & 0 deletions Marlin/src/pins/stm32f4/pins_LERDGE_S.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Marlin/src/pins/stm32f4/pins_LERDGE_X.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
//
#define SDIO_SUPPORT
#define SD_DETECT_PIN PA8
#define SDIO_CLOCK 4800000

//
// LCD / Controller
Expand Down
8 changes: 4 additions & 4 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

#
Expand Down Expand Up @@ -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
Expand Down