Skip to content

Commit

Permalink
Fix SDIO for STM32
Browse files Browse the repository at this point in the history
Followup to #24271

Co-Authored-By: GHGiampy <83699429+GHGiampy@users.noreply.github.com>
  • Loading branch information
thinkyhead and GHGiampy committed Jul 9, 2022
1 parent 62c0ab0 commit 9666ae8
Showing 1 changed file with 85 additions and 29 deletions.
114 changes: 85 additions & 29 deletions Marlin/src/HAL/STM32/sdio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
// SDIO Max Clock (naming from STM Manual, don't change)
#define SDIOCLK 48000000

#if defined(STM32F1xx)
#ifdef STM32F1xx
DMA_HandleTypeDef hdma_sdio;
extern "C" void DMA2_Channel4_5_IRQHandler(void) {
HAL_DMA_IRQHandler(&hdma_sdio);
Expand Down Expand Up @@ -116,7 +116,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef *hsd) {
HAL_NVIC_EnableIRQ(SDIO_IRQn);

// DMA Config
#if defined(STM32F1xx)
#ifdef STM32F1xx
__HAL_RCC_DMA2_CLK_ENABLE();
HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
hdma_sdio.Instance = DMA2_Channel4;
Expand Down Expand Up @@ -172,7 +172,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef *hsd) {
}

void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) {
#if !defined(STM32F1xx)
#ifndef STM32F1xx
__HAL_RCC_SDIO_FORCE_RESET();
delay(10);
__HAL_RCC_SDIO_RELEASE_RESET();
Expand All @@ -181,7 +181,7 @@ void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) {
}

static uint32_t clock_to_divider(uint32_t clk) {
#if defined(STM32H7xx)
#ifdef STM32H7xx
// SDMMC_CK frequency = sdmmc_ker_ck / [2 * CLKDIV].
uint32_t sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
return sdmmc_clk / (2U * SDIO_CLOCK) + (sdmmc_clk % (2U * SDIO_CLOCK) != 0);
Expand Down Expand Up @@ -221,43 +221,99 @@ bool SDIO_Init() {
return (sd_state == HAL_OK) ? true : false;
}

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

#ifdef STM32F1xx
static bool SDIO_ReadWriteBlock_SingleDMAChannel(uint32_t block, const uint8_t *src, uint8_t *dst) {
if (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) return false;

hal.watchdog_refresh();

HAL_StatusTypeDef ret;
if (src) {
hdma_sdio.Init.Direction = DMA_MEMORY_TO_PERIPH;
HAL_DMA_Init(&hdma_sdio);
ret = HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)src, block, 1);
}
else {
hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY;
HAL_DMA_Init(&hdma_sdio);
ret = HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t *)dst, block, 1);
}

if (ret != HAL_OK) {
HAL_DMA_Abort_IT(&hdma_sdio);
HAL_DMA_DeInit(&hdma_sdio);
return false;
}

uint32_t timeout = HAL_GetTick() + SD_TIMEOUT;

// Wait the transfer
while (!SDIO_IsReady()) {
if (HAL_GetTick() > timeout) {
HAL_DMA_Abort_IT(&hdma_sdio);
HAL_DMA_DeInit(&hdma_sdio);
return false;
}
}

while (__HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_sdio)) != 0
|| __HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma_sdio)) != 0) { /* nada */ }

while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) {
if (HAL_GetTick() >= timeout) return false;
HAL_DMA_Abort_IT(&hdma_sdio);
HAL_DMA_DeInit(&hdma_sdio);

timeout = HAL_GetTick() + SD_TIMEOUT;
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) if (HAL_GetTick() > timeout) return false;

return true;
}
#endif

bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) {
#ifdef STM32F1xx
return SDIO_ReadWriteBlock_SingleDMAChannel(block, nullptr, dst);
#else
uint32_t timeout = HAL_GetTick() + SD_TIMEOUT;

while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) {
if (HAL_GetTick() >= timeout) return false;
}

waitingRxCplt = 1;
if (HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t *)dst, block, 1) != HAL_OK)
return false;
waitingRxCplt = 1;
if (HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t *)dst, block, 1) != HAL_OK)
return false;

timeout = HAL_GetTick() + SD_TIMEOUT;
while (waitingRxCplt)
if (HAL_GetTick() >= timeout) return false;
timeout = HAL_GetTick() + SD_TIMEOUT;
while (waitingRxCplt)
if (HAL_GetTick() >= timeout) return false;

return true;
return true;
#endif
}

bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
uint32_t timeout = HAL_GetTick() + SD_TIMEOUT;

while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
if (HAL_GetTick() >= timeout) return false;
#ifdef STM32F1xx
return SDIO_ReadWriteBlock_SingleDMAChannel(block, src, nullptr);
#else
uint32_t timeout = HAL_GetTick() + SD_TIMEOUT;

waitingTxCplt = 1;
if (HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)src, block, 1) != HAL_OK)
return false;
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
if (HAL_GetTick() >= timeout) return false;

timeout = HAL_GetTick() + SD_TIMEOUT;
while (waitingTxCplt)
if (HAL_GetTick() >= timeout) return false;
waitingTxCplt = 1;
if (HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)src, block, 1) != HAL_OK)
return false;

return true;
}
timeout = HAL_GetTick() + SD_TIMEOUT;
while (waitingTxCplt)
if (HAL_GetTick() >= timeout) return false;

bool SDIO_IsReady() {
return hsd.State == HAL_SD_STATE_READY;
return true;
#endif
}

uint32_t SDIO_GetCardSize() {
Expand Down

0 comments on commit 9666ae8

Please sign in to comment.