How to port disp_drv.set_px_cb and disp_drv.rounder_cb in ST7586S monochrome LCD

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.

Can you share the initialization code.