cancel
Showing results for 
Search instead for 
Did you mean: 

Timing, DMA & SDIO ''Bug'' in Standards Peripherals Examples V3.5.0

Moritz M
Associate II
Posted on March 02, 2012 at 17:12

Hi,

I just spent plenty of days to get the SDIO example (esp. stm32_eval_sdio_sd.c) working with freeRTOS, FatFS and DMA Transfer. There is a problem in the code in SD_Error SD_ReadBlock(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize) and in SD_WriteBlock, too. The problem is, that in the code the read or write_block command is sent first and afterwards the DMA2 is configured and enabled (i skipped the polling mode stuff).


/*!< Send CMD17 READ_SINGLE_BLOCK */

SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)ReadAddr;

SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_READ_SINGLE_BLOCK;

SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;

SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;

SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;

SDIO_SendCommand(&SDIO_CmdInitStructure);


errorstatus = CmdResp1Error(SD_CMD_READ_SINGLE_BLOCK);


if
(errorstatus != SD_OK)

{

return
(errorstatus);

}


#if defined (SD_POLLING_MODE) 

/* 
long
polling mode stuff is 
long
*/

#elif defined (SD_DMA_MODE)

SDIO_ITConfig(SDIO_IT_DATAEND, ENABLE);

SDIO_DMACmd(ENABLE);

SD_LowLevel_DMA_RxConfig((uint32_t *)readbuff, BlockSize);

#endif

In the manual on page 555 the following steps are written to transfer data between SDIO and memory: 1. Do the card identification process 2. Increase the SDIO_CK frequency 3. Select the card by sending CMD7 4. Configure the DMA2 as follows ... 5. Send CMD24 (WRITE_BLOCK) as follows ... In the example the steps 4 and 5 are inverted. That works well in the example, but when there is a small delay line 09 and 21 like

1.
uint16_t nTime = 0x0000;
2.
for
(nTime = 0; nTime <0xFFF; nTime++){}

or a delay be waiting for semaphores, the program will fail (the transfer will stop somewhere, when there are bytes in the FIFO left). The solution for my problem was to put the DMA-stuff before sending the command like stated in the manual, like so:


#if defined (SD_DMA_MODE)

SDIO_ITConfig(SDIO_IT_DATAEND, ENABLE);

SDIO_DMACmd(ENABLE);

SD_LowLevel_DMA_RxConfig((uint32_t *)readbuff, BlockSize);

#endif


/*!< Send CMD17 READ_SINGLE_BLOCK */

SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)ReadAddr;

SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_READ_SINGLE_BLOCK;

SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;

SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;

SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;

SDIO_SendCommand(&SDIO_CmdInitStructure);


errorstatus = CmdResp1Error(SD_CMD_READ_SINGLE_BLOCK);

and disabling the DMA2 in case of error. Hope, that helps anybody ;) Moritz #freertos #dma #fatfs #sdio
4 REPLIES 4
gregoire
Associate II
Posted on May 31, 2012 at 11:12

Hi,

I beleive I face exacly the same issue.

I tried to made a SDIO logger with FATFS

My processor receives an unexpected interrupt when I try to read a block.

I think that It came from the SD_WaitReadOperation function.

I tried to exchange as you mention the order between the DMA and the command 17.

However the result is the same.

do you have other advises?

Thanks in advance,

Greg

Moritz M
Associate II
Posted on May 31, 2012 at 12:08

Hi Greg, 

can you post some code and what kind of interrupt do you receive?

gregoire
Associate II
Posted on May 31, 2012 at 17:42

Hi,

I forgot to add the SDIO and DMA interrupt routines in my stm32f4xx_it.c

Thank you for your help,

And sorry for this stupid mistake...

Should I ask, how you manage the get_fattime function ?

Did you hard code a date as chan or did you use the rtc or something else ?

Thank in advance,

Greg

Moritz M
Associate II
Posted on June 01, 2012 at 16:34

until now it is hardcoded, but later i will use some kind of calendar implementation