AnsweredAssumed Answered

stm32f429 freertos fatfs with sdio and dma

Question asked by li jinqiu on Sep 9, 2017

I use the cubemx to create the project(cubemx 4.22 and stm32CubeF4 1.16),it always occurs FIFO Error Interrupt,when I use dma to write sdio. And It stopes.,when write serveral times.But there is no sdio error interrupt happened.

This is my dma configtion:

/* SDIO DMA Init */
/* SDIO_RX Init */
hdma_sdio_rx.Instance = DMA2_Stream3;
hdma_sdio_rx.Init.Channel = DMA_CHANNEL_4;
hdma_sdio_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_sdio_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdio_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdio_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdio_rx.Init.Mode = DMA_PFCTRL;
hdma_sdio_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_sdio_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sdio_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sdio_rx.Init.MemBurst = DMA_MBURST_INC4;
hdma_sdio_rx.Init.PeriphBurst = DMA_PBURST_INC4;
if (HAL_DMA_Init(&hdma_sdio_rx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

__HAL_LINKDMA(sdHandle,hdmarx,hdma_sdio_rx);

/* SDIO_TX Init */
hdma_sdio_tx.Instance = DMA2_Stream6;
hdma_sdio_tx.Init.Channel = DMA_CHANNEL_4;
hdma_sdio_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_sdio_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdio_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdio_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdio_tx.Init.Mode = DMA_PFCTRL;
hdma_sdio_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_sdio_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sdio_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sdio_tx.Init.MemBurst = DMA_MBURST_INC4;
hdma_sdio_tx.Init.PeriphBurst = DMA_PBURST_INC4;
if (HAL_DMA_Init(&hdma_sdio_tx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

__HAL_LINKDMA(sdHandle,hdmatx,hdma_sdio_tx);

/* SDIO interrupt Init */
HAL_NVIC_SetPriority(SDIO_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SDIO_IRQn);
/* USER CODE BEGIN SDIO_MspInit 1 */

 

and fatfs driver

/* USER CODE BEGIN BeforeWriteDMABlocksSection */
/* can be used to modify previous code / undefine following code / add code */
/* USER CODE END BeforeWriteDMABlocksSection */
/**
* @brief Writes block(s) to a specified address in an SD card, in DMA mode.
* @param pData: Pointer to the buffer that will contain the data to transmit
* @param WriteAddr: Address from where data is to be written
* @param NumOfBlocks: Number of SD blocks to write
* @retval SD status
*/
uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
{
uint8_t sd_state = MSD_OK;
uint8_t *buf = (uint8_t *)pData;
uint8_t n;
uint32_t timeout = 100000;
if ((uint32_t)pData%4!=0) {
for(n=0;n<NumOfBlocks;n++){
memcpy(SDIO_DATA_BUFFER,buf,512);
/* Write block(s) in DMA transfer mode */
if (HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)SDIO_DATA_BUFFER, WriteAddr+512*n, 1) != HAL_OK)
{
sd_state = MSD_ERROR;
}
while(SD_TxCplt == 0){
if (timeout -- == 0){
sd_state = MSD_ERROR;
break;
}
}
SD_TxCplt = 0;
buf += 512;
}
}
else {
/* Write block(s) in DMA transfer mode */
if (HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)pData, WriteAddr, NumOfBlocks) != HAL_OK)
{
sd_state = MSD_ERROR;
}
while(SD_TxCplt == 0){
if (timeout -- == 0){
sd_state = MSD_ERROR;
break;
}
osDelay(4);
}
SD_TxCplt = 0;
}

return sd_state;
}

Outcomes