cancel
Showing results for 
Search instead for 
Did you mean: 

SDIO and DMA

pacoblackxx
Associate II
Posted on November 20, 2011 at 11:03

When using the SDIO with DMA, the source code should look like this:

(assume that we refer to a read_single_block command)

1.Enable the DataPath state machine;

2.Enable the CommandPath state machine;

3.Check if command response is free of CRC/Timeout errors;

4.Check if command response R1 is free of errors

5.Enable DMA

6. get in a while() loop and wait until the end of the DMA tranfer.

That is the code tha STM Team uses in the evaluation board.

I am woried for the critical session between states 3-5. If you put some

slow code there(for example USART print), an overrun error will occur because

DMA is enabled when the overrun flag is already set.

Yeah, we know that and that is the reason for which we dont put slow codes between

states 3-5. But i am worrying about what will happen if an interrupt happens between this states. If the interrupt routine has to transfer some data via SPI(slow), It will cause an overrun.

So, i decided to enable DMA before i enable the command state machine:

1.Enable the DataPath state machine;

2.Enable DMA

3.Enable the CommandPath state machine;

4.Check if command response is free of CRC/Timeout errors;

5.Check if command response R1 is free of errors

6. get in a while() loop and wait until the end of the DMA tranfer.

Now, if an interrupt happens, it wont cause any overrun because in the worst case

DMA and CPU share the bus with round-robin, so the interrupt and the DMA tranfer

will be running alongside, and hopefully no overrun will occur.

Everything works great, but is this correct? If the FIFO is empty when i enable the DMA, will it tranfer garbage? Or it will wait until there available data in the FIFO?

As i said, i get valid data but i want to be 100% compliant with the specifications.

Thanks,

Nikos
12 REPLIES 12
pacoblackxx
Associate II
Posted on November 21, 2011 at 17:33

Anyone?

carl2399
Associate II
Posted on November 22, 2011 at 03:35

Hi Nikos,

I've already had problems when flipping the DMA between writing and reading to the SDIO. I can do piles of successive DMA writes without problem, but even invoking DMA read a second time causes problems for me.

What you say makes sense, and I'll let you know how I go once I try it in the next week or two.

I've already had to rewrite bits of the STM32 library code to allow for a 16GB SDHC card, so further changes would not bother me too much.

Testing has been a bit slower than expected, as I'm using custom built hardware with a processor that I've not used before (the STM32F207). I've previously worked with the STM32F103.

tomas239955_stm1_st
Associate II
Posted on November 22, 2011 at 13:10

I have also some diffuculties with SDIO DMA, at the moment i working on it.

But most of all a woried about FREE rtos tasking. Just imagine what can happen if between steps 3-5 task switching occures. :-/... must be a better way how to handle this.

pacoblackxx
Associate II
Posted on November 22, 2011 at 20:49

The activation of 'Hardware flow control' is supposed to solve FIFO overrun errors, but when enabling it i get random Data CRC errors..

It is wrong to enable DMA before the command path state machine? 
tomas239955_stm1_st
Associate II
Posted on November 23, 2011 at 09:41

Read the ERRATA, the SDIO flow controller has some issues by silicon limitations.

tomas239955_stm1_st
Associate II
Posted on November 23, 2011 at 10:15

Now i have a bigger problem, when i enabling DMA for SDIO, it runs just fine, but already configured USART DMA dont send any bytes. If i dont use the SDIO DMA, the USART runs just fine. I have checked the AHB CLK, and it still runs in both cases, so DMA should work. The interesting think is that when i used the SDIO DMA the USART DMA after Transfer Complete normaly calls the DMA1_IRQ, but the peripheral doesnt send any bytes.

The SDIO DMA is configured on: DMA2 Stream 3

The USART DMA is configured on: DMA1 Stream 3

So my question is, is there any limitations between two DMA? I am using the peripheral library and code from examples for USART and SDIO.
tomas239955_stm1_st
Associate II
Posted on November 23, 2011 at 11:03

Found the problem, the SDIO on demoboard STM32-20-21-45-46 G-Eval the pins for SDIO DATA and USART RX/TX are shared (PC10,PC11), thats the reason why USART gets quiet after SDIO usage.

carl2399
Associate II
Posted on November 29, 2011 at 12:28

Hi Nikos,

I've rewritten my SD code to match your recommendation (over the last 2 days) and testing has gone much better that the first time that I tried (with the stock STM32 code).

Reading 100 blocks (of 512 bytes) from the SD card in a single transaction completes in about 9 milliseconds. So that gives me pretty much 100% utilization of the SDIO interface's capabilities.

Woohoo, now to write the rest of my application that uses this capability!

carl2399
Associate II
Posted on November 30, 2011 at 02:47

I did discover one little bug in my travels 🙂

I'm using the GCC compiler. I just added another unrelated variable (1 byte), and it messed up my SD card accesses. I've looked through the data sheet, and can't find any reference, but I think the memory used by the DMA probably needs to be aligned.

So, if you have code like this:

char SDBuffers[512];

then change it to this:

char __attribute__ ((aligned)) SDBuffers[512];