Breaking objects on change

Description

Objects on lcd shows ok in default state (arc and switch tested)
but if switch has for example toggled state - it will break the picture.

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

stm32 h750

What LVGL version are you using?

v7.11.0

Code to reproduce

common init code.

lv_obj_t *sw1 = lv_switch_create(lv_scr_act(), NULL);
lv_obj_align(sw1, NULL, LV_ALIGN_CENTER, 0, -50);
lv_obj_set_event_cb(sw1, event_handler);	
/*Copy the first switch and turn it ON*/
lv_obj_t *sw2 = lv_switch_create(lv_scr_act(), sw1);
lv_switch_on(sw2, LV_ANIM_ON);
lv_obj_align(sw2, NULL, LV_ALIGN_CENTER, 0, 50);

lv_obj_t * arc = lv_arc_create(lv_scr_act(), NULL);
lv_arc_set_bg_angles(arc, 0, 360);
lv_arc_set_angles(arc, 0, 299);
lv_obj_align(arc, NULL, LV_ALIGN_CENTER, 0, 15);	

Screenshot and/or video

https://drive.google.com/drive/folders/1_covsEg7KSbJsqUvWnIYZn2GF6A3VKg-?usp=sharing
3 video files (1 for arc that is changing after i was created, 2 for switches, 3 for both arc and switches)

it looks like wrong coordinates are used by lvgl after creating an object.

This usually indicates a bug in your display driver.

lcd works with 16 bit fmc interface.
if i use my functions that sets pixel adr and draws pixels - all works fine.
also i can fill proper rectangle with my api and driver.
and lvgl works fine with default objects, but then when something needs to change (button has toggled state for example) - comes this glitch.
now i am on the way to implement spi st7735 - i will try to get different result by spi to figure - what is causing this glitch.

if spi lcd will work fine, i dont know even where to search.
here is some code

lv_disp_t * disp=NULL;
lv_disp_drv_t disp_data_regv;      
lv_disp_buf_t disp_buf;
lv_color_t buf_1[LV_HOR_RES_MAX * 20];
#define LCD_RAM_ADR 0x60010000

#define LCD_REG (*((volatile uint8_t*) 0x60000000))
#define LCD_RAM (*((volatile uint8_t*) LCD_RAM_ADR))
#define LCD_WriteCommand(cmd) { LCD_REG = cmd; }
#define LCD_WriteData(data) { LCD_RAM = data; }
static void tft_flush(lv_disp_drv_t *data_regv, const lv_area_t *area, lv_color_t *color_p)
{
    /*Return if the area is out the screen*/
    if(area->x2 < 0) return;
    if(area->y2 < 0) return;
    if(area->x1 > TFT_HOR_RES - 1) return;
    if(area->y1 > TFT_VER_RES - 1) return;

    uint32_t x=0, y=0;
	
    LCD_SetAddrWindow(area->x1, area->y1, area->x2, area->y2);  
   // SetAddata_regessWindow(area->x1, area->y1, area->x2, area->y2);
	LCD_SendCommand(0x2C);   
    for(y=area->y1;y<=area->y2;y++)
    {
        for(x=area->x1;x<=area->x2;x++)
        {
            //uint8_t data[] = { color_p->full >> 8, color_p->full & 0xFF };
						LCD_WriteData(color_p->full >> 8);
            LCD_WriteData(color_p->full & 0xFF);//, sizeof(data));
            color_p++;
        }
    }
   

    lv_disp_flush_ready(&disp_data_regv);
}

inline void LCD_SetAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
    w = w + x ;
    h = h + y ;
    LCD_WriteCommand(ILI9341_CASET);
    LCD_WriteData(x >> 8);
    LCD_WriteData(x);
    LCD_WriteData(w >> 8);
    LCD_WriteData(w);
    LCD_WriteCommand(ILI9341_PASET);
    LCD_WriteData(y >> 8);
    LCD_WriteData(y);
    LCD_WriteData(h >> 8);
    LCD_WriteData(h);
LCD_WriteCommand(ILI9341_RAMWR);
}
void lv_lcd_init8080(void)
{
LCD_Init();
LCD_Fill(0,0,320,240,COLOR_BLACK);
lv_disp_buf_init(&disp_buf, buf_1, NULL, LV_HOR_RES_MAX * 10);   /*Initialize the display buffer*/
lv_disp_drv_init(&disp_data_regv);                  
disp_data_regv.hor_res = TFT_HOR_RES;
disp_data_regv.ver_res = TFT_VER_RES;
disp_data_regv.flush_cb = tft_flush;
disp_data_regv.buffer = &disp_buf;
disp = lv_disp_drv_register(&disp_data_regv);
}


128x128 spi lcd seems works fine with same settings.

cant understand what is happening on refresh with 8080 interface…

Got problem solved - the problem was with “set adress window”
window is x,y, w,h
and lvgl got area coordinates and not wide and height, lcd registers have x0, y0,.wide,height

prototype :  inline void LCD_SetAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
actual call: 	  LCD_SetAddrWindow(area->x1, area->y1, area->x2-area->x1, area->y2-area->y1);  
instead of :   LCD_SetAddrWindow(area->x1, area->y1,area->x2, area->y2); 

The problem to get this bug is that first time lcd got filled with proper image.
so when lvgl fills lcd first time - it works with all height and width.
Then, tft_flush called only for a small object that is changed, here ive got my error.

got hard fault in 10 minutes of toggling button… :neutral_face:

changed position of lv_task_handler(); from timer handle to while(1){} - seems working.
in timer handle it would be much comfortable.

I hope you weren’t running lv_task_handler in an interrupt handler! I’m pretty sure this won’t work unless you disable interrupts whenever you call an LVGL API besides lv_task_handler.