Skip to main content
Visitor II
December 11, 2024
Question

Display Rotation Issue with GUIDRV_LIN_OSY_16 and Custom DMA2D FillRect Function

  • December 11, 2024
  • 0 replies
  • 405 views

Hi everyone,

I encountered a challenging issue while using GUIDRV_LIN_OSY_16 with STemWin on an STM32 project. After much debugging, I found a solution and wanted to share it here to help others.

I changed the driver to rotated the display. From GUIDRV_LIN_16 to GUIDRV_LIN_OSY_16.

The problem was related to the framebuffer width (layer_prop[LayerIndex].xSize).

When the display is rotated using GUIDRV_LIN_OSY_16, layer_prop[LayerIndex].xSize is automatically updated from the original 800 (XSIZE_PHYS) to 480.
However, the framebuffer itself does not rotate, meaning its width in memory remains 800 (XSIZE_PHYS).
As a result, using layer_prop[LayerIndex].xSize in calculations caused incorrect framebuffer address computations, leading to drawing errors and background refresh issues.

Solution:
I fixed the issue by replacing layer_prop[LayerIndex].xSize with XSIZE_PHYS in both the framebuffer address calculation and the DMA2D_FillBuffer() call.

 

Here is the corrected version of my CUSTOM_FillRect() function.


Note:
CUSTOM_FillRect is called in LCD_X_Config via LCD_SetDevFunc.
In addition, the function is called LCD_LL_FillRect in newer STM32Cube packages.
However, the problem still exists here because nothing has changed in this logic.

 

 

/*
 Note:
 CUSTOM_FillRect is called in LCD_X_Config via LCD_SetDevFunc.
 In addition, the function is called LCD_LL_FillRect in newer STM32Cube packages. 
 However, the problem still exists here because nothing has changed in this logic.
*/

static void CUSTOM_FillRect(int32_t LayerIndex, int32_t x0, int32_t y0, int32_t x1, 
int32_t y1,uint32_t PixelIndex)
{
 uint32_t BufferSize, AddrDst;
 int32_t xSize, ySize;

 if (GUI_GetDrawMode() == GUI_DM_XOR)
 {
 LCD_SetDevFunc(LayerIndex, LCD_DEVFUNC_FILLRECT, NULL);
 LCD_FillRect(x0, y0, x1, y1);
 LCD_SetDevFunc(LayerIndex, LCD_DEVFUNC_FILLRECT, (void(*)(void))CUSTOM_FillRect);
 }
 else
 {
 xSize = x1 - x0 + 1;
 ySize = y1 - y0 + 1;
 BufferSize = GetBufferSize(LayerIndex);

 //Old:
 // AddrDst = layer_prop[LayerIndex].address +
 // BufferSize * layer_prop[LayerIndex].buffer_index +
 // y0 * layer_prop[LayerIndex].xSize + x0) * layer_prop[LayerIndex].BytesPerPixel;
 //New:
 AddrDst = layer_prop[LayerIndex].address +
 BufferSize * layer_prop[LayerIndex].buffer_index +
 (y0 * XSIZE_PHYS + x0) * layer_prop[LayerIndex].BytesPerPixel;
 //Old:
 //DMA2D_FillBuffer(LayerIndex, (void *)AddrDst, xSize, ySize, layer_prop[LayerIndex].xSize - xSize, PixelIndex);

 //New:
 DMA2D_FillBuffer(LayerIndex, (void *)AddrDst, xSize, ySize, XSIZE_PHYS - xSize, PixelIndex);
 }
}

 

 

 

 

 

 

 

 

 

 

    This topic has been closed for replies.