Display Corruption when Enabling Touchscreen with LVGL+RTX5 - Need Solutions

Important: unclear posts may not receive useful answers.

Before posting

  • Get familiar with Markdown to format and structure your post
  • Be sure to update lvgl from the latest version from the master branch.
  • Be sure you have checked the FAQ and read the relevant part of the documentation.
  • If applicable use the Simulator to eliminate hardware related issues.

Delete this section if you read and applied the mentioned points.

Description

When I change a switch state,there is a mistake display

What MCU/Processor/Board and compiler are you using?

STM32H750

What LVGL version are you using?

LVGL 9.3

What do you want to achieve?

What have you tried so far?

I have try to display a cont. Its OK

Code to reproduce

Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.

The code block(s) should be formatted like:

/*You code here*/
lv_obj_t* screen = lv_obj_create(NULL);
lv_screen_load(screen);

//static lv_style_t style_rect;
//lv_style_init(&style_rect);
//lv_style_set_bg_color(&style_rect, lv_color_hex(0xFF0000)); // 红色
//lv_obj_t * rect = lv_obj_create(lv_scr_act());
//lv_obj_add_style(rect, &style_rect, 0);
//lv_obj_set_size(rect, 300, 200);
lv_obj_t* sw = lv_switch_create(screen);
lv_obj_set_size(sw, 300, 200);
lv_obj_add_state(sw,LV_STATE_CHECKED);

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.

Please share your flush_cb. Probably there is an off by one issue there is width calculation.

OK.This is the flush code.
static void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * px_map) {
int32_t width = area->x2 - area->x1 + 1;
int32_t height = area->y2 - area->y1 + 1;
uint32_t line_offset = (MY_DISP_HOR_RES - width); // Display stride adjustment
uint32_t fb_addr = 0xD0000000 + (MY_DISP_HOR_RES * area->y1 + area->x1) * 2; // FB address calculation

// Clean CPU cache to ensure data coherence  
SCB_CleanDCache_by_Addr((uint32_t*)px_map, width * height * 2); // RGB565=2 bytes/pixel  

// Invoke DMA2D copy  
_DMA2D_Copy((uint32_t*)px_map, (void*)fb_addr, width, height, 0, line_offset);  
lv_display_flush_ready(disp_drv); // Critical: Notify LVGL flush completion  

}

void _DMA2D_Copy(void *pSrc, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t SrcOffset, uint32_t DstOffset) {
// Configure DMA2D for Memory-to-Memory (RGB565)
DMA2D->CR = 0x00000000UL | (1 << 9); // Mode: Memory-to-memory
DMA2D->FGMAR = (uint32_t)pSrc; // Source address
DMA2D->OMAR = (uint32_t)pDst; // Destination address
DMA2D->FGOR = SrcOffset; // Source line offset
DMA2D->OOR = DstOffset; // Destination line offset
DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_RGB565; // Input format
DMA2D->OPFCCR = LTDC_PIXEL_FORMAT_RGB565; // Output format
DMA2D->NLR = (xSize << 16) | ySize; // Set region size (width/height)

// Invalidate cache for destination before DMA transfer  
SCB_InvalidateDCache_by_Addr(pDst, xSize * ySize * 2);  

// Start blocking transfer  
DMA2D->CR |= DMA2D_CR_START;  
while (DMA2D->CR & DMA2D_CR_START) {} // Wait until completion  

}

I have tried other widgets, such as Label. It looks normal. The switch looks normal too before it changes state. But once it changes its state, it looks wrong.

Try correct this

uint32_t line_offset = (MY_DISP_HOR_RES - width); // Display stride adjustment

i mean you miss here

Do you mean this? I used it if I am right, but it is not useful.
x = area->x2 - area->x1 +1;
y = area->y2 - area->y1 +1;
int32_t width = area->x2 - area->x1 + 1;
int32_t height = area->y2 - area->y1 + 1;
uint32_t line_offset = (MY_DISP_HOR_RES - width); // Display stride adjustment
uint32_t addr = (0xD0000000 + (MY_DISP_HOR_RES*area->y1 + area->x1)2);
// Clean CPU cache to ensure data coherence |
|SCB_CleanDCache_by_Addr((uint32_t
)px_map, width * height * 2); // RGB565=2 bytes/pixel |

it will be easier to read your code if you wrap it in triple back ticks.

```

Some code

```



It comes out

Some code
1 Like

I’m sorry, I’m new to the forum and don’t fully understand some of the procedures. I’ll fix it.

static void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * px_map)
{

int32_t x;
 int32_t y;
	
	x = area->x2 - area->x1 +1;  
	y = area->y2 - area->y1 +1;
	int32_t width = area->x2 - area->x1 + 1;
	int32_t height = area->y2 - area->y1 + 1;
//	uint32_t OffLineDst = (MY_DISP_HOR_RES - (area->x2 - area->x1 +1));
	uint32_t line_offset = (MY_DISP_HOR_RES - width); // Display stride adjustment
	uint32_t addr = (0xD0000000 + (MY_DISP_HOR_RES*area->y1 + area->x1)*2);
	// Clean CPU cache to ensure data coherence  
	SCB_CleanDCache_by_Addr((uint32_t*)px_map, width * height * 2); // RGB565=2 bytes/pixel 

	_DMA2D_Copy((uint32_t*)px_map, 
(void *)addr, 
 x, 
 y, 
 0, 
line_offset) ;

    /*IMPORTANT!!!
     *Inform the graphics library that you are ready with the flushing*/
    lv_display_flush_ready(disp_drv);
}

void _DMA2D_Copy(void * pSrc, 
                 void * pDst, 
                 uint32_t xSize, 
                 uint32_t ySize, 
                 uint32_t OffLineSrc, 
                 uint32_t OffLineDst) 
{
    // Calculate buffer size for RGB565 format (2 bytes per pixel)
    uint32_t bufferSize = xSize * ySize * 2; 
    
    // Clean CPU cache to ensure data is written to physical memory [4,5](@ref)
    SCB_CleanDCache_by_Addr(pSrc, bufferSize);
    
    /* Configure DMA2D in memory-to-memory mode (foreground layer as input) */
    DMA2D->CR = 0x00000000UL | (1 << 9);       // Set bit 9 for register-to-memory mode
    DMA2D->FGMAR = (uint32_t)pSrc;            // Set source memory address
    DMA2D->OMAR = (uint32_t)pDst;             // Set destination memory address
    DMA2D->FGOR = OffLineSrc;                 // Source line offset (pixels)
    DMA2D->OOR = OffLineDst;                  // Destination line offset (pixels)
    
    /* Set color format for foreground layer and output to RGB565 */
    DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_RGB565;  // Input format: RGB565
    DMA2D->OPFCCR = LTDC_PIXEL_FORMAT_RGB565;    // Output format: RGB565
    
    // Configure image dimensions: NLR[31:16]=xSize, NLR[15:0]=ySize
    DMA2D->NLR = (uint32_t)(xSize << 16) | (uint16_t)ySize;
    
    // Invalidate D-Cache before starting transfer for data consistency [4](@ref)
    SCB_InvalidateDCache_by_Addr(pDst, bufferSize);
    
    /* Initiate DMA2D transfer */
    DMA2D->CR |= DMA2D_CR_START;               // Set START bit
    
    /* Poll until transfer completes */
    while (DMA2D->CR & DMA2D_CR_START) {}      // Wait for START bit to clear
}

thank you

When I try to use “Two buffers screen sized buffer for double buffering”, the widget disappears after changing state.