cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F429I-DISCO: flickering with DMA2D

floppes
Associate
Posted on June 08, 2014 at 22:51

I am working with the STM32F429I-DISCO board and trying to get a flicker-free display.

I am using double buffering to draw into one buffer while displaying the other. When done drawing all elements, I switch buffers. These buffers are in RGB565 and so is LTDC configured. The following function draws an ARGB8888 image with alpha channel onto the current buffer (the one that is not displayed) with blending and color mode conversion:

static
void
gfx_draw_img_argb8888 (gfx_image_t* img, gfx_coord_t* coord)
{
DMA2D_InitTypeDef DMA2D_InitStruct;
DMA2D_FG_InitTypeDef DMA2D_FG_InitStruct;
DMA2D_BG_InitTypeDef DMA2D_BG_InitStruct;
uint32_t dest_address;
uint32_t source_address;
uint32_t offset;
uint16_t picture_width;
uint16_t picture_height;
picture_width = img->width;
picture_height = img->height;
// check for dimensions
if
(coord->source_w == 0) 
return
;
if
(coord->source_h == 0) 
return
;
if
(coord->source_x + coord->source_w > picture_width) 
return
;
if
(coord->source_y + coord->source_h > picture_height) 
return
;
if
(coord->dest_x + coord->source_w > LCD_MAX_X) 
return
;
if
(coord->dest_y + coord->source_h > LCD_MAX_Y) 
return
;
// target address in display RAM
dest_address = lcd_frame_buffer + 2 * (LCD_MAX_X * coord->dest_y + coord->dest_x);
// source address in image
offset = 4 * (picture_width * coord->source_y + coord->source_x);
source_address = (uint32_t)&img->pixel_data[offset];
DMA2D_DeInit ();
DMA2D_StructInit (&DMA2D_InitStruct);
DMA2D_InitStruct.DMA2D_Mode = DMA2D_M2M_BLEND;
DMA2D_InitStruct.DMA2D_CMode = DMA2D_RGB565;
DMA2D_InitStruct.DMA2D_OutputMemoryAdd = dest_address;
DMA2D_InitStruct.DMA2D_OutputGreen = 0;
DMA2D_InitStruct.DMA2D_OutputBlue = 0;
DMA2D_InitStruct.DMA2D_OutputRed = 0;
DMA2D_InitStruct.DMA2D_OutputAlpha = 0;
DMA2D_InitStruct.DMA2D_OutputOffset = LCD_MAX_X - coord->source_w;
DMA2D_InitStruct.DMA2D_NumberOfLine = coord->source_h;
DMA2D_InitStruct.DMA2D_PixelPerLine = coord->source_w;
DMA2D_Init (&DMA2D_InitStruct);
DMA2D_FG_StructInit (&DMA2D_FG_InitStruct);
DMA2D_FG_InitStruct.DMA2D_FGMA = source_address;
DMA2D_FG_InitStruct.DMA2D_FGO = picture_width - coord->source_w;
DMA2D_FG_InitStruct.DMA2D_FGCM = CM_ARGB8888;
DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_MODE = NO_MODIF_ALPHA_VALUE;
DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_VALUE = 0x00;
DMA2D_FGConfig (&DMA2D_FG_InitStruct);
DMA2D_BG_StructInit (&DMA2D_BG_InitStruct);
DMA2D_BG_InitStruct.DMA2D_BGMA = dest_address;
DMA2D_BG_InitStruct.DMA2D_BGO = LCD_MAX_X - coord->source_w;
DMA2D_BG_InitStruct.DMA2D_BGCM = CM_RGB565;
DMA2D_BG_InitStruct.DMA2D_BGPFC_ALPHA_MODE = NO_MODIF_ALPHA_VALUE;
DMA2D_BG_InitStruct.DMA2D_BGPFC_ALPHA_VALUE = 0x00;
DMA2D_BGConfig (&DMA2D_BG_InitStruct);
DMA2D_StartTransfer ();
while
(DMA2D_GetFlagStatus (DMA2D_FLAG_TC) == RESET);
}

I switch buffers every 30 ms to get a smooth animation and it already looks great. But I noticed flickering every time I call the function. Debugging it shows that DMA2D_StartTransfer() until the end of the function takes about 9 ms. During this time the screen flickers once. It seems that while DMA2D is running the LTDC does not properly refresh the screen. Maybe because memory is locked during transfer? My double buffers and the images are stored in SDRAM. Any ideas how to avoid the flickering? #dma2d-flicker-stm32f429-ltdc #ltdc-flicker-dma2d
5 REPLIES 5
tino2
Associate
Posted on March 29, 2016 at 14:27

Push,

Same Problem at STM32F7, any solution found?

tino2
Associate
Posted on May 10, 2016 at 08:05

to any one finding this post, I got the solution!

Problem: using a 7'' display (800x480)

how it seems is the FSMC the bottleneck! The external SD Ram (including both frame buffers) is connected through the fsmc. If I take both frame buffers with 32bpp (ARGB8888), it seems that the transfer of new data takes to much time transfering all the data, while reading it (from the ltdc). So some kind of bus bandwith limitation.

so anyway, taking one buffer of 16bpp (RGB565) and one buffer of 32bpp (ARGB) solved the problem for me and my 800x480 display.

The problem might also be possible to be solved, connecting more parallel data lines to ext. SDRam. But if the hardware is already fixed, you need to downsize the color depth of your layers!

AndyJT
Associate III
Posted on May 26, 2016 at 11:59

I have the same issue with 800x480 display on the STM32F7

We are using EmCraft SOM which only has 16 bit data bus and runs at 100Mhz and I think this is the bottleneck.... for high LTDC refresh rates it would seem you need very fast RAM that will run at 216Mhz.

At the moment, to get rid of flickering when making DMA2D transfers, we have to reduce the clock to the LCD... it should be running around 30Mhz but we've had to lower it to 20Mhz.

If anyone can think of a way around this, I'd be grateful.

As the FMC shares the SDRAM and there isn't enough internal memory for a 800x480 framebuffer, I don't know how else the LTDC could run without interference from other SDRAM operations ??

My current thoughts are toward a dedicated graphics chip with it's own framebuffer and parallel RGB output..any suggestions for that and how we would talk to such a device (if one exists) ?

troy1818
Senior
Posted on August 14, 2016 at 14:16

I also got this same problem. My setup is however a little different where I have 200Mhz SDRAM and the same for MCU. I am running SVGA (40Mhz pixel clock) so the strain on the bus is very high. However, I only have one layer active and just running with 8bit LUT without any fancy effects and whatnot so I thought it would work. I think ST should really try and explain this limitation more clearly in spec and not just write that up to XVGA resolution is supported.

troy1818
Senior