BG color of button is flickering

Description

I convert rgb565 to rgb666 to use 18b interface, almost seems to be true except the background color of the button. Its flickering.

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

MCU: STM32F769NI
LCD controller: ili9341
Interface: 18b Parallel

What do you want to achieve?

What is reason can make this issue

What have you tried so far?

Code to reproduce

Flush function:

/*You code here*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
    typedef union
    {
        struct
        {
            uint16_t blue : 6;
            uint16_t green : 6;
            uint16_t red : 6;
            uint16_t padding : 14;
        };
        uint32_t full;
    }lv_color18_t;

    int32_t x;
    int32_t y;
    extern void lcd_set_pos(unsigned char x0,unsigned char x1,unsigned int y0,unsigned int y1);
    extern void write_data_18(unsigned long y);

    if(area->x2 < 0) return;
    if(area->y2 < 0) return;
    if(area->x1 > LV_HOR_RES_MAX - 1) return;
    if(area->y1 > LV_VER_RES_MAX - 1) return;

    SCB_CleanInvalidateDCache();
    SCB_InvalidateICache();

    lcd_set_pos(area->x1, area->x2, area->y1, area->y2);
    for(y = area->y1; y <= area->y2; y++) {
        for(x = area->x1; x <= area->x2; x++) {
            /* Put a pixel to the display. For example: */
            /* put_px(x, y, *color_p)*/
            lv_color18_t pixel;
            pixel.full = 0;
            pixel.green = (uint16_t)(color_p->ch.green & 0x3F);
            pixel.red = (uint16_t)((color_p->ch.red & 0x1F) << 1 | (color_p->ch.red & 0x1F) >> 4);
            pixel.blue = (uint16_t)((color_p->ch.blue & 0x1F) << 1 | (color_p->ch.blue & 0x1F) >> 4);

            pixel.full = pixel.full & 0x3FFFF;
            write_data_18(pixel.full);
            color_p++;
        }
    }

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

Main code:

  lv_init();

  lv_port_disp_init();

    static lv_style_t style_btn;
    static lv_style_t style_btn_red;

    /*Create a simple button style*/
    lv_style_init(&style_btn);
    lv_style_set_radius(&style_btn, LV_STATE_DEFAULT, 10);
    lv_style_set_bg_opa(&style_btn, LV_STATE_DEFAULT, LV_OPA_COVER);
    lv_style_set_bg_color(&style_btn, LV_STATE_DEFAULT, LV_COLOR_SILVER);
    lv_style_set_bg_grad_color(&style_btn, LV_STATE_DEFAULT, LV_COLOR_GRAY);
    lv_style_set_bg_grad_dir(&style_btn, LV_STATE_DEFAULT, LV_GRAD_DIR_VER);

    /*Swap the colors in pressed state*/
    lv_style_set_bg_color(&style_btn, LV_STATE_PRESSED, LV_COLOR_GRAY);
    lv_style_set_bg_grad_color(&style_btn, LV_STATE_PRESSED, LV_COLOR_SILVER);

    /*Add a border*/
    lv_style_set_border_color(&style_btn, LV_STATE_DEFAULT, LV_COLOR_WHITE);
    lv_style_set_border_opa(&style_btn, LV_STATE_DEFAULT, LV_OPA_70);
    lv_style_set_border_width(&style_btn, LV_STATE_DEFAULT, 2);

    /*Different border color in focused state*/
    lv_style_set_border_color(&style_btn, LV_STATE_FOCUSED, LV_COLOR_BLUE);
    lv_style_set_border_color(&style_btn, LV_STATE_FOCUSED | LV_STATE_PRESSED, LV_COLOR_NAVY);

    /*Set the text style*/
    lv_style_set_text_color(&style_btn, LV_STATE_DEFAULT, LV_COLOR_WHITE);

    /*Make the button smaller when pressed*/
    lv_style_set_transform_height(&style_btn, LV_STATE_PRESSED, -5);
    lv_style_set_transform_width(&style_btn, LV_STATE_PRESSED, -10);
#if LV_USE_ANIMATION
    /*Add a transition to the size change*/
    static lv_anim_path_t path;
    lv_anim_path_init(&path);
    lv_anim_path_set_cb(&path, lv_anim_path_overshoot);

    lv_style_set_transition_prop_1(&style_btn, LV_STATE_DEFAULT, LV_STYLE_TRANSFORM_HEIGHT);
    lv_style_set_transition_prop_2(&style_btn, LV_STATE_DEFAULT, LV_STYLE_TRANSFORM_WIDTH);
    lv_style_set_transition_time(&style_btn, LV_STATE_DEFAULT, 300);
    lv_style_set_transition_path(&style_btn, LV_STATE_DEFAULT, &path);
#endif

    /*Create a red style. Change only some colors.*/
    lv_style_init(&style_btn_red);
    lv_style_set_bg_color(&style_btn_red, LV_STATE_DEFAULT, LV_COLOR_RED);
    lv_style_set_bg_grad_color(&style_btn_red, LV_STATE_DEFAULT, LV_COLOR_MAROON);
    lv_style_set_bg_color(&style_btn_red, LV_STATE_PRESSED, LV_COLOR_MAROON);
    lv_style_set_bg_grad_color(&style_btn_red, LV_STATE_PRESSED, LV_COLOR_RED);
    lv_style_set_text_color(&style_btn_red, LV_STATE_DEFAULT, LV_COLOR_WHITE);
#if LV_USE_BTN
    /*Create buttons and use the new styles*/
    lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL);     /*Add a button the current screen*/
    lv_obj_set_pos(btn, 10, 10);                            /*Set its position*/
    lv_obj_set_size(btn, 120, 50);                          /*Set its size*/
    lv_obj_reset_style_list(btn, LV_BTN_PART_MAIN);         /*Remove the styles coming from the theme*/
    lv_obj_add_style(btn, LV_BTN_PART_MAIN, &style_btn);

    lv_obj_t * label = lv_label_create(btn, NULL);          /*Add a label to the button*/
    lv_label_set_text(label, "Button");                     /*Set the labels text*/

    /*Create a new button*/
    lv_obj_t * btn2 = lv_btn_create(lv_scr_act(), btn);
    lv_obj_set_pos(btn2, 10, 80);
    lv_obj_set_size(btn2, 120, 50);                             /*Set its size*/
    lv_obj_reset_style_list(btn2, LV_BTN_PART_MAIN);         /*Remove the styles coming from the theme*/
    lv_obj_add_style(btn2, LV_BTN_PART_MAIN, &style_btn);
    lv_obj_add_style(btn2, LV_BTN_PART_MAIN, &style_btn_red);   /*Add the red style on top of the current */
    lv_obj_set_style_local_radius(btn2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); /*Add a local style*/

    label = lv_label_create(btn2, NULL);          /*Add a label to the button*/
    lv_label_set_text(label, "Button 2");                     /*Set the labels text*/
#endif

Screenshot and/or video

Hmm, shouldn’t it be 32-bit instead of 16-bit?

  typedef union
    {
        struct
        {
            uint32_t blue    :  6;
            uint32_t green   :  6;
            uint32_t red     :  6;
            uint32_t padding : 14;
        };
        uint32_t full;
    }lv_color18_t;

What do you mean, Robe. I just get 18b from this

Can you send the link where you bought this monitor from?

Hmm, I think 18 bits are not fitting into 16 bits.

I used this formula:


You can buy from: buydisplay dot com

Third try:

6 bits + 6 bits = 12 bits + 6 bits = 18 bits

Do 18 bits fit into a 16 bit type (uint16_t) variable? No they don’t.
You can’t squeeze 18 bits into a 16 bits variable.
For this reason you have to take a 32-bit type when you define the lv_color18_t

When you take uint16_t types when you define the bitfields you will get the following:

First 16 bit:    xxxx gggg ggbb bbbb
Second 16 bit :  xxxx xxxx xxrr rrrr
Third 16 bit:    xxpp pppp pppp pppp

When you take uint32_t:

Only one 32-bit: pppp pppp pppp pprr rrrr gggg ggbb bbbb

Of course, as you do not need the padding bits, you can omit them.

1 Like