Skip to content

Commit 161b49c

Browse files
thinkyheadGHGiampy
andcommitted
Fix SDIO for STM32
Followup to MarlinFirmware#24271 Co-Authored-By: GHGiampy <[email protected]>
1 parent 62c0ab0 commit 161b49c

File tree

1 file changed

+79
-25
lines changed

1 file changed

+79
-25
lines changed

Marlin/src/HAL/STM32/sdio.cpp

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
// SDIO Max Clock (naming from STM Manual, don't change)
5757
#define SDIOCLK 48000000
5858

59-
#if defined(STM32F1xx)
59+
#ifdef STM32F1xx
6060
DMA_HandleTypeDef hdma_sdio;
6161
extern "C" void DMA2_Channel4_5_IRQHandler(void) {
6262
HAL_DMA_IRQHandler(&hdma_sdio);
@@ -116,7 +116,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef *hsd) {
116116
HAL_NVIC_EnableIRQ(SDIO_IRQn);
117117

118118
// DMA Config
119-
#if defined(STM32F1xx)
119+
#ifdef STM32F1xx
120120
__HAL_RCC_DMA2_CLK_ENABLE();
121121
HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
122122
hdma_sdio.Instance = DMA2_Channel4;
@@ -172,7 +172,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef *hsd) {
172172
}
173173

174174
void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) {
175-
#if !defined(STM32F1xx)
175+
#ifndef STM32F1xx
176176
__HAL_RCC_SDIO_FORCE_RESET();
177177
delay(10);
178178
__HAL_RCC_SDIO_RELEASE_RESET();
@@ -181,7 +181,7 @@ void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) {
181181
}
182182

183183
static uint32_t clock_to_divider(uint32_t clk) {
184-
#if defined(STM32H7xx)
184+
#ifdef STM32H7xx
185185
// SDMMC_CK frequency = sdmmc_ker_ck / [2 * CLKDIV].
186186
uint32_t sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
187187
return sdmmc_clk / (2U * SDIO_CLOCK) + (sdmmc_clk % (2U * SDIO_CLOCK) != 0);
@@ -221,43 +221,97 @@ bool SDIO_Init() {
221221
return (sd_state == HAL_OK) ? true : false;
222222
}
223223

224-
bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) {
225-
uint32_t timeout = HAL_GetTick() + SD_TIMEOUT;
224+
bool SDIO_IsReady() {
225+
return hsd.State == HAL_SD_STATE_READY;
226+
}
226227

227-
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) {
228-
if (HAL_GetTick() >= timeout) return false;
228+
static bool SDIO_ReadWriteBlock_SingleDMAChannel(uint32_t block, const uint8_t *src, uint8_t *dst) {
229+
if (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) return false;
230+
231+
hal.watchdog_refresh();
232+
233+
HAL_StatusTypeDef ret;
234+
if (src) {
235+
hdma_sdio.Init.Direction = DMA_MEMORY_TO_PERIPH;
236+
HAL_DMA_Init(&hdma_sdio);
237+
ret = HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)src, block, 1);
238+
}
239+
else {
240+
hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY;
241+
HAL_DMA_Init(&hdma_sdio);
242+
ret = HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t *)dst, block, 1);
229243
}
230244

231-
waitingRxCplt = 1;
232-
if (HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t *)dst, block, 1) != HAL_OK)
245+
if (ret != HAL_OK) {
246+
HAL_DMA_Abort_IT(&hdma_sdio);
247+
HAL_DMA_DeInit(&hdma_sdio);
233248
return false;
249+
}
250+
251+
uint32_t timeout = HAL_GetTick() + SD_TIMEOUT;
252+
253+
// Wait the transfer
254+
while (!SDIO_IsReady()) {
255+
if (HAL_GetTick() > timeout) {
256+
HAL_DMA_Abort_IT(&hdma_sdio);
257+
HAL_DMA_DeInit(&hdma_sdio);
258+
return false;
259+
}
260+
}
261+
262+
while (__HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_sdio)) != 0
263+
|| __HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma_sdio)) != 0) { /* nada */ }
264+
265+
HAL_DMA_Abort_IT(&hdma_sdio);
266+
HAL_DMA_DeInit(&hdma_sdio);
234267

235268
timeout = HAL_GetTick() + SD_TIMEOUT;
236-
while (waitingRxCplt)
237-
if (HAL_GetTick() >= timeout) return false;
269+
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) if (HAL_GetTick() > timeout) return false;
238270

239271
return true;
240272
}
241273

242-
bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
243-
uint32_t timeout = HAL_GetTick() + SD_TIMEOUT;
274+
bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) {
275+
#ifdef STM32F1xx
276+
return SDIO_ReadWriteBlock_SingleDMAChannel(block, nullptr, dst);
277+
#else
278+
uint32_t timeout = HAL_GetTick() + SD_TIMEOUT;
244279

245-
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
246-
if (HAL_GetTick() >= timeout) return false;
280+
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) {
281+
if (HAL_GetTick() >= timeout) return false;
282+
}
247283

248-
waitingTxCplt = 1;
249-
if (HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)src, block, 1) != HAL_OK)
250-
return false;
284+
waitingRxCplt = 1;
285+
if (HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t *)dst, block, 1) != HAL_OK)
286+
return false;
251287

252-
timeout = HAL_GetTick() + SD_TIMEOUT;
253-
while (waitingTxCplt)
254-
if (HAL_GetTick() >= timeout) return false;
288+
timeout = HAL_GetTick() + SD_TIMEOUT;
289+
while (waitingRxCplt)
290+
if (HAL_GetTick() >= timeout) return false;
255291

256-
return true;
292+
return true;
293+
#endif
257294
}
258295

259-
bool SDIO_IsReady() {
260-
return hsd.State == HAL_SD_STATE_READY;
296+
bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
297+
#ifdef STM32F1xx
298+
return SDIO_ReadWriteBlock_SingleDMAChannel(block, src, nullptr);
299+
#else
300+
uint32_t timeout = HAL_GetTick() + SD_TIMEOUT;
301+
302+
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
303+
if (HAL_GetTick() >= timeout) return false;
304+
305+
waitingTxCplt = 1;
306+
if (HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)src, block, 1) != HAL_OK)
307+
return false;
308+
309+
timeout = HAL_GetTick() + SD_TIMEOUT;
310+
while (waitingTxCplt)
311+
if (HAL_GetTick() >= timeout) return false;
312+
313+
return true;
314+
#endif
261315
}
262316

263317
uint32_t SDIO_GetCardSize() {

0 commit comments

Comments
 (0)