Description
Trouble using LV_COLOR_FORMAT_L8 - it seems previously drawn items (e.g. label text) are not erased when they are updated or scroll and re-render. I have a custom flush callback that I have successfully working under LV_COLOR_FORMAT_I1 and LV_COLOR_DEPTH=1. My display supports grayscale so I am working to use L8 mode, but I have consistent rendering/flush problems that I have not been able to solve.
I am only testing with LV_RENDER_MODE_FULL at the moment, once that is working I will finish implementing PARTIAL in the flush cb.
What MCU/Processor/Board and compiler are you using?
Raspberry Pi Pico2, Pico SDK C++, small SPI OLED display SH1122 controller chip, 256x64 4bpp grayscale.
What LVGL version are you using?
master from github, also tried rolling back to 9.2 with no change.
What do you want to achieve?
Proper rendering/flushing using L8 mode when items update.
What have you tried so far?
I have confirmed using debug printf() that the data that the flush callback is receiving in the px_map buffer has the problem with prior display items not being erased. I “drew” the contents of the buffer to the serial debug port and could see the same overwriting/smearing effect on changed or scrolling labels for example. Thus, I believe it is not a problem with putting pixels onto the display but something internal to LVGL or some configuration/setup that I’m possibly missing.
Code to reproduce
My init code:
lv_init();
#if LV_COLOR_DEPTH == 1
#define LV_BUFSIZE ((SH1122_HOR_RES * SH1122_VER_RES / 8) + 8)
#define LV_COLOR_FORMAT LV_COLOR_FORMAT_I1
#elif LV_COLOR_DEPTH == 8
#define LV_BUFSIZE (SH1122_HOR_RES * SH1122_VER_RES)
#define LV_COLOR_FORMAT LV_COLOR_FORMAT_L8
#else
#pragma message "Unsupported color depth"
#endif
static uint8_t disp_buf1[LV_BUFSIZE];
lv_display_t* display = lv_display_create(SH1122_HOR_RES, SH1122_VER_RES);
lv_display_set_user_data(display, &oled);
lv_display_set_buffers(display, disp_buf1, NULL, sizeof(disp_buf1), LV_DISPLAY_RENDER_MODE_FULL);
lv_display_set_flush_cb(display, [](lv_display_t * display, const lv_area_t *area, uint8_t* px_map) {
OLED* oled = static_cast<OLED*>(lv_display_get_user_data(display));
oled->lv_sh1122_flush_cb(display, area, px_map);
});
lv_display_set_color_format (display, LV_COLOR_FORMAT);
And my flush callback:
void OLED::lv_sh1122_flush_cb(lv_display_t * display, const lv_area_t * area, uint8_t * px_map)
{
unsigned int xx,yy;
uint8_t* buf = px_map;
#if LV_COLOR_DEPTH == 1
// note this only supports LV_DISPLAY_RENDER_MODE_FULL at the moment
buf += 8;
for(yy=0; yy<64; yy++)
{
Set_Row_Address(yy);
Set_Column_Address(0x10,0x00);
for(xx=0;xx<32;xx++)
{
uint8_t bv = *(buf++);
Data_processing(bv);
}
}
#elif LV_COLOR_DEPTH == 8
for(yy=area->y1; yy<area->y2+1; yy++)
{
Set_Row_Address(yy);
Set_Column_Address(0x10, area->x1 & 0xFF);
for(xx=area->x1; xx<area->x2+1; xx+=2)
{
uint8_t bv1 = *(buf++) >> 4;
uint8_t bv2 = *(buf++) >> 4;
uint8_t bv = (bv1 << 4) | bv2;
Write_Data(bv);
}
}
#else
#pragma message "Unsupported color depth"
#endif
// Inform LVGL that flushing is complete so buffer can be modified again.
lv_display_flush_ready(display);
}
Screenshot and/or video
YouTube link:
working with LV_COLOR_FORMAT_I1
YouTube link:
not working with LV_COLOR_FORMAT_L8
In L8 mode, static text that I only display once and do not update or scroll works as expected with grayscale (note smooth appearance of the font):