Description
Hello,
I am currently trying to port LvGL to my project, But I have some problems.
I use stm32F476RG, ST7565 for my display and STM32CubeIDE to build and run my code.
I have built my project successfully, but It doesn’t work when I run it. I followed step by step on the docs and also this post but it seems not work as well https://maldus512.medium.com/porting-littlevgl-for-a-monochrome-display-6c7be58851ce.
Here is my code for lv_port_disp_init:
Code to reproduce
void lv_port_disp_init(void)
{
/*-------------------------
* Initialize your display
* -----------------------*/
disp_init();
static lv_disp_buf_t disp_buf_1;
lv_disp_buf_init(&disp_buf_1, st7565_buffer, NULL, LV_HOR_RES_MAX * 8); /*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 up the functions to access to your display*/
/*Set the resolution of the display*/
disp_drv.hor_res = 128;
disp_drv.ver_res = 64;
/*Set a display buffer*/
disp_drv.buffer = &disp_buf_1;
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = disp_flush;
disp_drv.set_px_cb = my_set_px_cb;
disp_drv.rounder_cb = my_rounder_cb;
#if LV_USE_GPU
/*Optionally add functions to access the GPU. (Only in buffered mode, LV_VDB_SIZE != 0)*/
/*Blend two color array using opacity*/
disp_drv.gpu_blend_cb = gpu_blend;
/*Fill a memory array with a color*/
disp_drv.gpu_fill_cb = gpu_fill;
#endif
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
}
My flush function:
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*/
// LREP("\r\n(%d,%d) (%d,%d)",(long)(area->x1), (long)(area->y1), (long)(area->x2), (long)(area->y2));
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing*/
LcdFillRect(area->x1, area->y1, abs(area->x2 - area->x1 +1) , abs(area->y2 - area->y1), color_p->full);
LcdSetBufferPixel(st7565_buffer);
color_p->full++;
lv_disp_flush_ready(disp_drv);
}
My rounder callback:
void my_rounder_cb(lv_disp_drv_t * disp_drv, lv_area_t * area)
{
/* Update the areas as needed. Can be only larger.
* For example to always have lines 8 px height:*/
area->x1 = area->x1 & ~(0x7);
area->x2 = area->x2 | (0x7);
LREP("#");
// area->y1 = area->y1 & 0x07;
// area->y2 = (area->y2 & 0x07) + 8;
}
My set_px_cb:
#define BIT_SET(a,b) ((a) |= (1U<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1U<<(b)))
void my_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:*/
// Set buffer 1024 element 128 * 8
//LREP("^");
uint16_t byte_index = x + (( y>>3 ) * buf_w);
uint8_t bit_index = y & 0x7;
// == 0 inverts, so we get blue on black
if ( color.full == 0 ) {
BIT_SET( buf[ byte_index ] , bit_index );
}
else {
BIT_CLEAR( buf[ byte_index ] , bit_index );
}
}
and this one is my main function:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_USB_DEVICE_Init();
/* USER CODE BEGIN 2 */
LREP("\r\n[LVGL Build Date:<%s>.<%s>]\r\n",BUILD_TIME,BUILD_DATE);
//TestDisplay();
memset(st7565_buffer,0,1024);
#if(1)
lv_init();
LREP("LV init success!!\n");
lv_port_disp_init();
LREP("Lv port disp init ok!! \n");
//lv_theme_t * th = lv_theme_mono_init(LV_COLOR_BLACK, LV_COLOR_BLACK, LV_THEME_MATERIAL_FLAG_DARK, LV_FONT_MONTSERRAT_12,LV_FONT_MONTSERRAT_12,LV_FONT_MONTSERRAT_12,LV_FONT_MONTSERRAT_12);
//lv_obj_t * scr = lv_disp_get_scr_act(NULL);
//lv_theme_set_act(th); // Not run USB CDC
#if(0)
/*Create a label on the button (the 'label' variable can be reused)*/
label2 = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(label2, "Click me!");
lv_obj_set_size(label2, 50, 20);
#endif
// Input device keyboard
// lv_indev_drv_t indev_drv;
// lv_indev_drv_init(&indev_drv); /*Basic initialization*/
// indev_drv.read_cb = button_read;
// /*Register the driver in LVGL and save the created input device object*/
// lv_indev_t * my_indev = lv_indev_drv_register(&indev_drv);
#if(1)
/*Create a Label on the currently active screen*/
lv_style_init(&my_style);
lv_style_set_text_font(&my_style,LV_STATE_DEFAULT,LV_THEME_DEFAULT_FONT_SMALL);
label1 = lv_label_create(lv_scr_act(), NULL);
// lv_obj_set_pos(label1,3, 3); // position, position);
lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_size(label1,15, 15);
lv_label_set_text(label1, "123");
#endif
LREP("\r\n[LVGL Object]\r\n");
// tft_init();
// lv_demo_widgets();
#endif
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
lv_tick_inc(1);
lv_task_handler();
}
/* USER CODE END 3 */
}
Are there any mistake of my functions?? I’m looking forward to seeing your reply. Please reply as soon as possible because I really need this.
Thanks,
Best regards,