2023-05-10 06:07 AM
I'm using an STM32F779 on a known working custom board connected to an EMMC chip (8 wide). I'm using the SDMMC2 peripheral with a DMA channel for Rx as well as Tx and the SDMMC interrupt enabled. My application has two modes, in the first I log data and in the presence of USB it acts as a MSD. When connected via USB the host computer reads out blocks and interprets the file system correctly. However, after some period the SDMMC2 - DATA_TIMEOUT interrupt occurs when it shouldn't and breaks the system (DMA_TX is zeroed and then eventually a hard fault occurs).
The DCTRL register does not self clear after a transaction but is cleared at the beginning of a new read or write. This implies that as long as a read/write is performed at least once before the timer expires there is no issue.
Solved! Go to Solution.
2023-05-10 07:33 AM
Found the problem. Having the SDMMC2 interrupt and the DMA Rx/Tx interrupts enabled at the same time will not work (at least consistently).
The driver will not work without all three (DMA-Rx, DMA-Tx, SDMMCx) enabled. The solution is to remove line 2544 in MMC_DMAReceiveCplt so that the interrupt is correctly handled by the SDMMC ISR.
/* Disable the DMA transfer for transmit request by setting the DMAEN bit
in the MMC DCTRL register */
hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
/* Clear all the static flags */
//__HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
hmmc->State = HAL_MMC_STATE_READY;
2023-05-10 07:33 AM
Found the problem. Having the SDMMC2 interrupt and the DMA Rx/Tx interrupts enabled at the same time will not work (at least consistently).
The driver will not work without all three (DMA-Rx, DMA-Tx, SDMMCx) enabled. The solution is to remove line 2544 in MMC_DMAReceiveCplt so that the interrupt is correctly handled by the SDMMC ISR.
/* Disable the DMA transfer for transmit request by setting the DMAEN bit
in the MMC DCTRL register */
hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
/* Clear all the static flags */
//__HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
hmmc->State = HAL_MMC_STATE_READY;