Lvgl Version
v8.01
Initial Question
Before I get into a long discussion I would like to ask is it allowable to refresh only a portion of the screen on a mono display or must one always refresh the whole screen?
Problem
I have a SSD1306 display which is 128 columns by 64 rows (8 pages). I have created a driver for this display and I have implemented rounder_cb and set_px_cb. I have a couple dynamic labels on the screen. When the screen is first displayed I place dummy text ("—") for the labels. The screen is properly displayed when first drawn with the dummy text. For testing I only updated one of the labels and when I do the refresh this label includes some garbage.
Details
I have a section on the screen which has a label. The label section is y1=40, y2=49, x1=56, x2=95.
The y axis is the has 2 pages one full page (y=40 to y=47) and one partial page (y=48 to y=49). When I do the refresh of the label the display_flush_cb correctly identifies y1, y2, x1, x2.
When I examine set_px_cb on the refresh of the label it is using a draw area based on y=0, x=0 and not the display area of y=40, x=56. So set_px_cb is updating display_buffer at location y=0, x=0 and not y=40, x=56. Now the old remaining pixels in display (y=10 to y=15) will be used to update the label not y=50 to y=55. These pixels are causing the garbage on the updated label because the display can only be updated using full page boundaries.
Question
Is there a way the modify set_px_cb to write to the correct pixel location of the display buffer.
set_px_cb
// in buf (video display buffer) from supplied x,y coordinates
void IRAM_ATTR DisplayDriver::set_px_cb(struct _lv_disp_drv_t* disp_drv,
uint8_t* buf,
lv_coord_t buf_w,
lv_coord_t x,
lv_coord_t y,
lv_color_t color,
lv_opa_t opa)
{
uint16_t buf_index;
uint8_t bit_index;
// landscape
buf_index = x + (buf_w * (y >> 3));
bit_index = y & 0x07;
if ((color.full == 0) && (LV_OPA_TRANSP != opa))
{
// clear the bit
buf[buf_index] &= static_cast<uint8_t>(~(1 << bit_index));
}
else
{
// set the bit
buf[buf_index] |= static_cast<uint8_t>(1 << bit_index);
}
// Debug code
if((x==0) & (y==0))
{
Log::warning(TAG, "set px cb x={}, y={}", x, y);
//Log::warning(TAG, "set px cb buf_addr={:#04x}", buf);
std::cout << reinterpret_cast<void *>(buf) << std::endl;
}
}
rounder_cb
void IRAM_ATTR DisplayDriver::rounder_cb(struct _lv_disp_drv_t* disp_drv, lv_area_t* area)
{
//Log::info(TAG, "rounder");
area->x1 = area->x1 & (~0x7); // round down to page byte bounder
area->x2 = area->x2 | 0x07; // round up to page byte bounder
}