Description
Porting LCD ST7586S(118X281) to LVGL7.11, I have an array[118X281] for screen pixels, a pixel each byte.
for now , I have LCD ST7586S work fine with LVGL7.11 by implementing flush function below,
lcd_fbx[118X281] = {0xAA,0xAA};//screen buffer, a pixel for each byte
void st7586s_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
/*Return if the area is out the screen*/
if(x2 < 0) return;
if(y2 < 0) return;
if(x1 > ST7565_HOR_RES - 1) return;
if(y1 > ST7565_VER_RES - 1) return;
/*Truncate the area to the screen*/
int32_t act_x1 = x1 < 0 ? 0 : x1;
int32_t act_y1 = y1 < 0 ? 0 : y1;
int32_t act_x2 = x2 > ST7565_HOR_RES - 1 ? ST7565_HOR_RES - 1 : x2;
int32_t act_y2 = y2 > ST7565_VER_RES - 1 ? ST7565_VER_RES - 1 : y2;
int32_t x, y;
uint8_t row1 = y1;
uint8_t row2 = y2;
uint8_t *buf = (uint8_t*) color_p;
/*Refresh frame buffer*/
for(y = y1; y <= y2; y++) {
for(x = x1; x <= x2; x++) {
if(lv_color_to1(*color_p) != 0) {
lcd_fbx[281*y + x] = 1;
} else {
lcd_fbx[281*y + x] = 0;
}
color_p ++;
}
}
write_com(0x2A);// Column Address Setting
write_data(0x00);
write_data(0x00);
write_data(0x00);
write_data(0x5D);
write_com(0x2B);// Row Address Setting
write_data(0x00);
write_data(y1);
write_data(0x00);
write_data(y2);
write_com(0x2C); //Write Display DATA
uint8_t*xbuf = NULL;
uint8_t out[96] = {0x00};
for(uint8_t row = row1; row <= row2; row++)
{
memset(out,0,sizeof(out));
xbuf = &lcd_fbx[281*row];
memset(out,0,sizeof(out));
write_281byte_281pixel_ST7586S(xbuf,out);
write_data_dma(out,94);
}
}
in this case, however, it is discovered that screen flushing slow when switching screens, so I want to use callback functions below,
disp_drv.set_px_cb = st7586s_set_px_cb
disp_drv.rounder_cb = st7586s_rounder_cb
code implementation is below,
void st7586s_set_px_cb(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)
{
/* Write to the buffer as required for the display.
* Write only 1-bit for monochrome displays mapped vertically:*/
buf += (281 * y + x);//as 281 pixel each row, and buf equals lcd_fbx defined below
if (color.full)
{
(*buf) =1;
}
else
{
(*buf) =0;
}
}
void st7586s_rounder_cb(struct _disp_drv_t * disp_drv, lv_area_t *area)
{
//area->y1;
//area->y2;
//for now do nothing
}
void lv_port_disp_init(void)
{
/* Example for 1) */
static lv_disp_buf_t disp_buf_1;
lv_disp_buf_init(&disp_buf_1, lcd_fbx, NULL, LV_HOR_RES_MAX * LV_VER_RES_MAX); /*Initialize the display buffer*/
/*-----------------------------------
* Register the display in LVGL
*----------------------------------*/
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
/*Set the resolution of the display*/
disp_drv.hor_res = 281;//128;
disp_drv.ver_res = 118;//64;
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = disp_flush;
disp_drv.set_px_cb = st7586s_set_px_cb;
disp_drv.rounder_cb = st7586s_rounder_cb;
/*Set a display buffer*/
disp_drv.buffer = &disp_buf_1;
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
}
however, when code running , the screen displayed but not as expected, I can see the labels with strings are not placed in the expected position(should be in the center of the LCD screen) and label’s background is broken displayed.
disp_drv.set_px_cb = st7586s_set_px_cb;
void st7586s_set_px_cb(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)
In function void st7586s_set_px_cb, set 1 or 0 in the right position in the buffer (lcd_fbx[118X281] , so only parameter x and y were made use of, but as a result, I didn’t get what I was expecting on the screen.
and it seems that I am using the parameters below the wrong way.
uint8_t * buf
lv_coord_t buf_w
lv_coord_t x
lv_coord_t y
could you please help me with this?
A full screen(118X281) buffer(lcd_fbx[118X281]) used.and it is a byte for a pixel on screen.
Implementing function void st7586s_set_px_cb for speeding up flush ( next step I want to squash buffer size.)
What MCU/Processor/Board and compiler are you using?
MIMXRT1051
What LVGL version are you using?
LVGL V7.11
What do you want to achieve?
To make st7586s_set_px_cb() and st7586s_rounder_cb() work fine with LCD ST7586S just as expected
What have you tried so far?
For a porting without st7586s_set_px_cb() and st7586s_rounder_cb() , LVGLV7.11 works fine with LCD ST7586S, because of performance I want to make use of st7586s_set_px_cb() and st7586s_rounder_cb() but not work yet.
The code block(s) below:
lcd_fbx[118X281] = {0xAA,0xAA};//screen buffer, a pixel for each byte
void st7586s_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
/*Return if the area is out the screen*/
if(x2 < 0) return;
if(y2 < 0) return;
if(x1 > ST7565_HOR_RES - 1) return;
if(y1 > ST7565_VER_RES - 1) return;
/*Truncate the area to the screen*/
int32_t act_x1 = x1 < 0 ? 0 : x1;
int32_t act_y1 = y1 < 0 ? 0 : y1;
int32_t act_x2 = x2 > ST7565_HOR_RES - 1 ? ST7565_HOR_RES - 1 : x2;
int32_t act_y2 = y2 > ST7565_VER_RES - 1 ? ST7565_VER_RES - 1 : y2;
int32_t x, y;
uint8_t row1 = y1;
uint8_t row2 = y2;
uint8_t *buf = (uint8_t*) color_p;
/*Refresh frame buffer*/
for(y = y1; y <= y2; y++) {
for(x = x1; x <= x2; x++) {
if(lv_color_to1(*color_p) != 0) {
lcd_fbx[281*y + x] = 1;
} else {
lcd_fbx[281*y + x] = 0;
}
color_p ++;
}
}
write_com(0x2A);// Column Address Setting
write_data(0x00);
write_data(0x00);
write_data(0x00);
write_data(0x5D);
write_com(0x2B);// Row Address Setting
write_data(0x00);
write_data(y1);
write_data(0x00);
write_data(y2);
write_com(0x2C); //Write Display DATA
uint8_t*xbuf = NULL;
uint8_t out[96] = {0x00};
for(uint8_t row = row1; row <= row2; row++)
{
memset(out,0,sizeof(out));
xbuf = &lcd_fbx[281*row];
memset(out,0,sizeof(out));
write_281byte_281pixel_ST7586S(xbuf,out);
write_data_dma(out,94);
}
}
void st7586s_set_px_cb(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)
{
/* Write to the buffer as required for the display.
* Write only 1-bit for monochrome displays mapped vertically:*/
buf += (281 * y + x);//as 281 pixel each row, and buf equals lcd_fbx defined below
if (color.full)
{
(*buf) =1;
}
else
{
(*buf) =0;
}
}
void st7586s_rounder_cb(struct _disp_drv_t * disp_drv, lv_area_t *area)
{
//area->y1;
//area->y2;
//for now do nothing
}
void lv_port_disp_init(void)
{
/* Example for 1) */
static lv_disp_buf_t disp_buf_1;
lv_disp_buf_init(&disp_buf_1, lcd_fbx, NULL, LV_HOR_RES_MAX * LV_VER_RES_MAX); /*Initialize the display buffer*/
/*-----------------------------------
* Register the display in LVGL
*----------------------------------*/
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
/*Set the resolution of the display*/
disp_drv.hor_res = 281;//128;
disp_drv.ver_res = 118;//64;
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = disp_flush;
disp_drv.set_px_cb = st7586s_set_px_cb;
disp_drv.rounder_cb = st7586s_rounder_cb;
/*Set a display buffer*/
disp_drv.buffer = &disp_buf_1;
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
}
Screenshot and/or video
If possible, add screenshots and/or videos about the current state.