cancel
Showing results for 
Search instead for 
Did you mean: 

SDIO DMA Timeout

mailmail9116
Associate II
Posted on June 24, 2013 at 15:13

Hi All ,

Till now i worked with the STM3240G-EVAL , At the beginning i had a problem that i received DMA timeout when i tried to write to the sd-card. The was due to a problem that the DMA interrupt , i.e the 3 next lines :

SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE);
SDIO_DMACmd(ENABLE);
SD_LowLevel_DMA_TxConfig((uint32_t *)writebuff, (NumberOfBlocks * BlockSize));

which enable the DMA were after the DMA request was sent , causing me to go into DMA timeout , i fixed this issue by moving this 3 lines before the DMA request is sent and everything was fine. Now i started working with STM3220G-EVAL which is basically the same evaluation board with the same peripherals and drivers ,the main difference is that is Cortex M3 instead of Cortex M4 , i fixed this issue the same i did on the first evaluation board, But for some reason it does not solve the issue , and i am receiving DMA timeout , i.e i never get to here :

void SD_ProcessDMAIRQ(void)
{
if(DMA2->LISR & SD_SDIO_DMA_FLAG_TCIF)
{
DMAEndOfTransfer = 0x01; //<---Here

DMA_ClearFlag(SD_SDIO_DMA_STREAM, SD_SDIO_DMA_FLAG_TCIF|SD_SDIO_DMA_FLAG_FEIF);
}
}

I don't have any clue why does it happen , maybe some one here can help me with the issue ? Thanks Michael
10 REPLIES 10
Amel NASRI
ST Employee
Posted on June 26, 2013 at 12:26

Hello Michael,

Are you using the same frequency for both of them (F2 and F4)? If not, is the workaround still resolving the issue for F4 with same frequency?

Can you check if the DMA starts to transfer some data then the timeout occurs?

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

mailmail9116
Associate II
Posted on June 26, 2013 at 18:40

Hi Mayla ,

Not they are not on the same frequency , the F4 is 186 mhz ,and the f2 is 120 mhz .

As far as i checked , the DMA works fine ,when its read (i.e Peripheral to memory) , but it timeouts on the opposite direction ( i.e memory to peripheral) .

So maybe the SDIO frequency is not adjusted correctly for 120 mhz ??

Thanks

Michael

Posted on June 26, 2013 at 18:57

The primary SDIO transfer clock comes from the Q tap of the PLL, usually used for USB. For USB to function this has to be 48 MHz, but can be significantly higher if not. For SDIO to function the PLL must be running. The secondary SDIO clock comes from the APB to which it is attached.

Make sure that the interrupts are enabled in the NVIC, and handler routines call the respective SD support routines.

My observation is that the DMA interrupt is not required, just the SDIO one, but there are a heap of race conditions in the example code, and a lack of understanding about how the SDIO peripheral behaves on the write path. The observed behaviour will also change based on the type of cards used, and the rate at which they can accept data and process it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mailmail9116
Associate II
Posted on June 27, 2013 at 08:07

Hi ,

So any suggestions on how to fix the issue? i am using the drivers that came with the evaluation board.

Michael

Amel NASRI
ST Employee
Posted on June 27, 2013 at 10:43

Hi Michael,

Could you check if it works when you select the peripheral as flow controller?

DMA_FlowControllerConfig(DMAx_Streamy, DMA_FlowCtrl_Peripheral);

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

mailmail9116
Associate II
Posted on June 27, 2013 at 11:43

Hi Mayla ,

It allready there , so its not the problem :

void SD_LowLevel_DMA_TxConfig(uint32_t *BufferSRC, uint32_t BufferSize)
{
DMA_InitTypeDef SDDMA_InitStructure;
DMA_ClearFlag(SD_SDIO_DMA_STREAM, SD_SDIO_DMA_FLAG_FEIF | SD_SDIO_DMA_FLAG_DMEIF | SD_SDIO_DMA_FLAG_TEIF | SD_SDIO_DMA_FLAG_HTIF | SD_SDIO_DMA_FLAG_TCIF);
/* DMA2 Stream3 or Stream6 disable */
DMA_Cmd(SD_SDIO_DMA_STREAM, DISABLE);
/* DMA2 Stream3 or Stream6 Config */
DMA_DeInit(SD_SDIO_DMA_STREAM);
SDDMA_InitStructure.DMA_Channel = SD_SDIO_DMA_CHANNEL;
SDDMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDRESS;
SDDMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)BufferSRC;
SDDMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
SDDMA_InitStructure.DMA_BufferSize = 0;
SDDMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
SDDMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
SDDMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
SDDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
SDDMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
SDDMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
SDDMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
SDDMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
SDDMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;
SDDMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4;
DMA_Init(SD_SDIO_DMA_STREAM, &SDDMA_InitStructure);
DMA_ITConfig(SD_SDIO_DMA_STREAM, DMA_IT_TC, ENABLE);
DMA_FlowControllerConfig(SD_SDIO_DMA_STREAM, DMA_FlowCtrl_Peripheral);
/* DMA2 Stream3 or Stream6 enable */
DMA_Cmd(SD_SDIO_DMA_STREAM, ENABLE);
}

But I found something that maybe wierd : for stm32f2

SD_Error SD_PowerON(void)
{
__IO SD_Error errorstatus = SD_OK;
uint32_t response = 0, count = 0, validvoltage = 0;
uint32_t SDType = SD_STD_CAPACITY;
/*!< Power ON Sequence -----------------------------------------------------*/
/*!< Configure the SDIO peripheral */
/*!< SDIO_CK = SDIOCLK / (SDIO_INIT_CLK_DIV + 2) */

/*!< on STM32F2xx devices, SDIOCLK is fixed to 48MHz */

/*!< SDIO_CK for initialization should not exceed 400 KHz */ 
SDIO_InitStructure.SDIO_ClockDiv = SDIO_INIT_CLK_DIV;

for stm32f4

SD_Error SD_PowerON(void)
{
__IO SD_Error errorstatus = SD_OK;
uint32_t response = 0, count = 0, validvoltage = 0;
uint32_t SDType = SD_STD_CAPACITY;
/*!< Power ON Sequence -----------------------------------------------------*/
/*!< Configure the SDIO peripheral */
/*!< SDIO_CK = SDIOCLK / (SDIO_INIT_CLK_DIV + 2) */

/*!< on STM32F4xx devices, SDIOCLK is fixed to 48MHz */

/*!< SDIO_CK for initialization should not exceed 400 KHz */ 
SDIO_InitStructure.SDIO_ClockDiv = SDIO_INIT_CLK_DIV;

for both evaluation boards the clock is set to the same speed if i understand correctly? the sdio clock frequency is not depended on the cortex frequency? thanks Michael
GHITH.Abdelhamid
Associate II
Posted on June 28, 2013 at 12:31

are you using latest version of standard Library for STM32F2?

mailmail9116
Associate II
Posted on June 29, 2013 at 06:28

Yes i do...

mailmail9116
Associate II
Posted on June 29, 2013 at 07:50

One more thing, it seems that i am having also the exact same issue with the audio codec, when trying to play something , i am never receive the ''done interrupt'' , so i guess that this is the same problem ,when trying to use DMA in memory -> peripheral direction