2012-11-22 02:09 AM
Hi, I'm developing on STM3240G-Eval board and I'm trying to use DMA for displaying an image from the SRAM memory on the LCD.
This is the code that I wrote: void DMA_Write() { uint32_t skippedCycles = 0; DMA_InitTypeDef DMA_InitStructure;/* 1. Enable DMA Controllers */
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA1, ENABLE); /* 2. Enable and configure Peripheral DMA_Stream (not required by SRAM).*/ LCD_WriteReg(LCD_REG_3, 0x1008); LCD_WriteRAM_Prepare(); /* 3. DMA_Init().*/ DMA_DeInit(DMA1_Stream0); while(DMA_GetCmdStatus(DMA1_Stream0) != DISABLE); DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (0x64000000); // SRAM memory address DMA_InitStructure.DMA_Memory0BaseAddr = ((uint32_t)(0x60000000 | 0x60020000)); // LCD memory address DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory; DMA_InitStructure.DMA_BufferSize = (uint32_t) (76800); DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_PeripheralBurst_Single;DMA_Init(DMA1_Stream0, &DMA_InitStructure);
/* I'm not going to use DMA interrupts so I've commented this line... */
// DMA_ITConfig(DMA1_Stream0, DMA_IT_TC, ENABLE);/* 6. Enable the DMA stream using the DMA_Cmd() function. */
DMA_Cmd(DMA1_Stream0, ENABLE); while(DMA_GetCmdStatus(DMA1_Stream0) == DISABLE) { // Wait DMA Start... skippedCycles++; } skippedCycles = 0; while( DMA_GetFlagStatus(DMA1_Stream0, DMA_FLAG_TCIF0) == RESET) { // waiting DMA completes transfer... DMA_ClearFlag(DMA1_Stream0, DMA_FLAG_TCIF0); skippedCycles++; } return; }At the moment the code compiles but seems that DMA1_Stream0 doesn't become ENABLE after the line DMA_Cmd(DAM1_Stream0, ENABLE) is called.
Did I make some mistakes? #stm3240g #lcd #dma #dma #stm3240g2012-11-22 03:19 AM
> /* 1. Enable DMA Controllers */
> RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA1, ENABLE); You need to enable the DMA controller's clock before you reset it. I know you used the description from the ''library''. Well, it's wrong. JW2012-11-22 03:44 AM
Thank you so much!
I've added the code line: RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); after the reset, but still I don't get it work. Where can I find some samples on the DMA ? Because I cannot figure out how to fix the code if the description inside the library is wrong...2012-11-22 04:09 AM
Couple of potential issues.
a) Don't you need to be using DMA2 for memory-to-memory RM0090 ''Only the DMA2 controller is able to perform memory-to-memory transfers.'' b) The transfer length is 16-bit, so max 65535 memory units (8, 16, or 32-bit, as defined by increment)2012-11-22 09:03 AM
Hi Clive1,
I switched on DMA 2 stream and checked the size of data to send. Now code is working fine: #define DMA_STREAM DMA2_Stream0 #define DMA_CHANNEL DMA2_Channel_0/* 1. Enable DMA Controllers and reset them.*/
RCC_AHB1PeriphClockCmd(DMA_STREAM_CLOCK, ENABLE); /* 2. Enable and configure Peripheral DMA_Stream (not required by SRAM).*/ /* 3. For a given Stream, program the required configuration through following parameters: Source and Destination addresses, Transfer Direction, Transfer size, Source and Destination data formats, Circular or Normal mode, Stream Priority level, Source and Destination Incrementation mode, FIFO mode and its Threshold (if needed), Burst mode for Source and/or Destination (if needed) using the DMA_Init().*/ DMA_DeInit(DMA_STREAM); while(DMA_GetCmdStatus(DMA_STREAM) != DISABLE);DMA_InitStructure.DMA_Channel = DMA_CHANNEL;
DMA_InitStructure.DMA_PeripheralBaseAddr = srcAddress; DMA_InitStructure.DMA_Memory0BaseAddr = destAddress; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory; DMA_InitStructure.DMA_BufferSize = (uint32_t) (size); DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC8; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC8;DMA_Init(DMA_STREAM, &DMA_InitStructure);
/* 4. Enable the NVIC and the corresponding interrupt(s)
using the function DMA_ITConfig() if you need to use DMA interrupts.*/ DMA_ITConfig(DMA_STREAM, DMA_IT_TC, ENABLE);/* 5. Optionally, if the Circular mode is enabled, you can use the
Double buffer by configuring the second Memory address and the first Memory to be used through the function DMA_DoubleBufferModeConfig(). Then enable the Double buffer mode through the function DMA_DoubleBufferModeCmd(). These operations must be done before step 6.*//* 6. Enable the DMA stream using the DMA_Cmd() function. */
DMA_Cmd(DMA_STREAM, ENABLE); Thank you so much!