cancel
Showing results for 
Search instead for 
Did you mean: 

Display Rotation Issue with GUIDRV_LIN_OSY_16 and Custom DMA2D FillRect Function

mfrank9
Associate III

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);
  }
}

 

 

 

 

 

 

 

 

 

 

0 REPLIES 0