cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F412 SDIO Tx Underrun error when DMA is enabled.

LLOLO.1
Associate II

Hi!

I am working on a project where I have to drive a SD Card. So far I have successfully implemented the initialization and reading data with DMA part. I am not using HAL libraries. The code to write to external flash is shown below. I did everything according to reference manual.

 
 
 
 

 

void SDIO_MEM_Write_SingleBlock512(uint32_t Address, uint32_t* Buffer)
{
	//Single Block Transfer

	//uint8_t Result = 0xFF;
	uint8_t tempCardState;

	SDIO->DLEN = 512;
	SDIO->DTIMER = 0xFFFFFFFF;

	//Configure DMA
	DMA2->LIFCR |= DMA_LIFCR_CTCIF3 | DMA_LIFCR_CHTIF3 | DMA_LIFCR_CTEIF3 | DMA_LIFCR_CFEIF3; //Clear Interrupt Flag

	DMA2_Stream3->CR = 0;
	DMA2_Stream3->CR |= (0b11 << DMA_SxCR_PL_Pos) | DMA_SxCR_MINC | (0b01 << DMA_SxCR_DIR_Pos) | (4 << DMA_SxCR_CHSEL_Pos) | (0b01<<DMA_SxCR_MBURST_Pos) | (0b01<<DMA_SxCR_PBURST_Pos) | (0b10 << DMA_SxCR_MSIZE_Pos) | (0b10 << DMA_SxCR_PSIZE_Pos) | (0b1<<DMA_SxCR_PFCTRL_Pos);
	DMA2_Stream3->PAR  = (uint32_t) &SDIO->FIFO;
	DMA2_Stream3->M0AR = (uint32_t) Buffer; //Memory Address which data will be copied
	DMA2_Stream3->NDTR = 128; // Data to be transfered
	DMA2_Stream3->CR |= DMA_SxCR_EN;

	//Write Single Block Command issued by using CMD24
	SDIO_SendCMD(Address, 24, WAIT_SHRTRESPONS, 0);

	if(SDIO_WaitCMDResponse() != 0xFF)
	{
		while(1);//Error Occurred
	}

	//Get R1 for Analysis
	if((SDIO->RESP1) & 0xFDFFE008) //Card Status
	{
		while(1);//Error Occurred
	}


	SDIO->DCTRL = 0;
	SDIO->DCTRL |= ((BLKSIZE_512 << SDIO_DCTRL_DBLOCKSIZE_Pos) | (TRSFRDIR_HtC << SDIO_DCTRL_DTDIR_Pos) | (TRSFRMOD_BLK << SDIO_DCTRL_DTMODE_Pos) | SDIO_DCTRL_DTEN | SDIO_DCTRL_DMAEN);

	while((SDIO->STA & (SDIO_STA_DBCKEND)) == 0);

	SDIO->ICR = (SDIO_ICR_DBCKENDC | SDIO_ICR_DATAENDC);

	//Wait until write Operation is finished
	do
	{
		if(SDIO_FetchCardState(&tempCardState) != 0xFF)
		{
			while(1);//Error Occurred
		}
	}while(tempCardState == 0x04); //Check Transfer State

	//return Result;
}




 

 

 

The problem is as soon as I enable DMA and SDIO (Line 37) I get Tx FIFO underrun error in SDIO STA register and FIFO error in DMA ISR register. I changed the order of enabling DMA/SDIO but nothing seems to work.

Has anyone encountered this problem?

 

Thanks.

1 REPLY 1
nouirakh
ST Employee

Hello @LLOLO.1 

This can happen if the DMA is not set up correctly or if there is a timing issue between the SDIO and DMA.
To resolve the issue you can start by ensuring that the DMA configuration is correct for the SDIO peripheral. This includes checking the stream and channel selection, memory and peripheral data sizes, and the direction of data transfer. Another point I want to mention is that the order in which you enable the DMA and SDIO matters. you should(Configure the DMA. Enable the DMA. Issue the write command to the SD card. Enable the SDIO data path).
Finlay, I can think that it could be an issue of uncleared interrupt flags before starting the transfer. Any pending interrupts might cause the SDIO to behave unexpectedly.