cancel
Showing results for 
Search instead for 
Did you mean: 

DMA Word to HalfWord with memory inc disabled data loss

unparagoned
Associate II
Posted on June 04, 2011 at 20:48

Application: Displaying bmp pictures stored on a uSD card.

Board: STM3210E-eval

Edit: I've narrowed down the problem. DMA transfer, where the source buffer is SDIO FIFO which must be Word size (32bit), destination is LCD, which must be halfWord(16bit), and memory incriment needs to be disabled for the destination. Basically the first 16bits are transmitted then the rest are lost instead of being sent. How do I fix this? Example code is a couple posts down. (Source can be anything, including SRAM as long as it's set as Word size.

So far I have this working fine with SDIO, DMA transfer to SRAM, and then DMA transfer to LCD.

But there doesn't seem to be any point in having the SRAM. So I've tried to modfily my program so the information is transfered directly from the SDIO over DMA to the LCD.

The problem is the a bit weird. The picture is displayed in a quarter of the screen, with a copy of it next to it. So only half the screen is filled. I tried reading and displaying one sector at a time and that just makes things more confusing.

I'm really stuck trying to debug this, i've changed every DMA option to see if any would help...

So the main problem I'm having is that I don't know how to start debuging the DMA transfer when memory increment is disabled. Watchpoints don't work...
2 REPLIES 2
xzhang2
Associate II
Posted on June 05, 2011 at 00:17

seems you have some problems I had. check my post in last week.

I guess it caused by FSMC DMA speed is too slow. try to debug your code if any SD_ERROR happens. In my case, I got SDIO TX_FIFO underrun error when it write data from external memory to SD card with DMA.

JZ

unparagoned
Associate II
Posted on June 05, 2011 at 19:21

Jeffrey, thanks but I'm not getting any errors like that.

I think I've worked out what the problem is. Essentially the SDIO FIFO stores 32bit words. The LCD needs 16bit halfWords. It looks like when a word is taken out of the FIFO buffer the first 16bits are sent to the lcd but the second 16bits are just lost. 

Here is the function that I'm using.

void SD_LCD_DMA_RxConfig(uint16_t *BufferDST, uint32_t BufferSize)

{

DMA_InitTypeDef DMA_InitStructure;

 

DMA_ClearFlag(DMA2_FLAG_TC4 | DMA2_FLAG_TE4 | DMA2_FLAG_HT4 | DMA2_FLAG_GL4);

 

/*!< DMA2 Channel4 disable */

DMA_Cmd(DMA2_Channel4, DISABLE);

/*!< DMA2 Channel4

Config

*/

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDRESS;

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)BufferDST;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

DMA_InitStructure.DMA_BufferSize =0xFFFF;// BufferSize /4; //this doesn't do much

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //chaning this to half word doesn't fix the problem

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA2_Channel4, &DMA_InitStructure);

DMA_Cmd(DMA2_Channel4, ENABLE);

}