Transplantation of LVGL V8 on STM32F429

LVGL is a good thing to use. Now there are more and more tutorials on the Internet, many of which are for V7 and below, but the upgrade of V8 for V7 is still very large, and the use methods of many controls are different, so there needs to be a suitable migration project to use.

I've been trying to transplant these two days, and there have been many problems, but I finally succeeded. I'll record the process for your reference.
First, the Apollo development board for punctual atoms. The core is STM32F429IGT6, and the display screen is an RGB capacitive touch screen with a resolution of 480 * 272.

Look at the renderings first

Then talk about the general transplantation process and the solution of the problems in the process.
At the beginning, I directly downloaded the official lvgl source code and transplanted it with the touch screen routine of punctual atom, but there are too many errors in this process, and countless will come out if one is solved. I guess this is also the reason why there are not many V8 transplantation tutorials so far.

Then I found the migration routine for F429 on the official website: paste the address https://github.com/lvgl

It's LV in the figure above_ port_ stm32f429_ disco. Use git to pull the content. Be sure to pull out the corresponding sub modules under the lvgl folder. Use the command: git clone -- recurse submodules https://github.com/lvgl/lv_port_stm32f429_disco.git
The premise of this method is that you have no problem surfing the Internet scientifically. If the network speed is not good, you can directly download the package provided by me.

The contents of the document are shown in the following figure

What we need to use is the four in the red box. Why not use this project directly? Because this project is edited based on CUBEIDE, I am more familiar with Keil, so I must migrate it to the past.

Next, prepare the official touch routine of punctual atom. This main figure saves trouble, and the screen and touch initialization are done, avoiding a lot of trouble. Create a new folder "lvgl" under the project directory to store the above four files. Then copy the above four files to the lvgl folder. The path should be placed correctly, because the internal file depends on this path to find the header file. Where to put it, see the figure below


Well, the most troublesome thing is basically over, because you have got the portable files. This has bothered me for a long time, because many source files can't be transplanted at all, and it's also because I'm too delicious.

Then open the project and create three directories under the directory, as shown below

A brief explanation: lvgl/src is used to store. c source files; lvgl/ports is used to store display and touch interfaces; lvgl/app is used to store the official demo routine and your future display code.

The file path stored in lvgl/src is shown in the following figure

When you open this folder, you can add as many c files as there are in it, including the contents in subfolders.

The file path stored in lvgl/ports is shown in the following figure

c file added, remember to add the library path! Then compile it once. Some errors will be reported

The above figure is cut from lv_port_disp_template.c. The definition in the red box will report that it cannot be found, so it needs to go to Lv_ These two quantities are defined in the conf.h file and can be defined with a macro

#define MY_DISP_HOR_RES 480
#define MY_DISP_VER_RES 272

Is to determine the resolution of your screen. The library reports error will also be reported when compiling after the modification. Library reports error:__ use_ no_ Semihosting was requested if you encounter this error, you can refer to this article: https://blog.csdn.net/baidu_37973494/article/details/81168704
My verification is that method 3 is available; Use this method to solve this error, but a new error will be introduced.
If you have any errors about GPU, go LV first_ In conf.h, change the following macro definition to 0. We do not use GPU

/*-------------
 * GPU
 *-----------*/

/*Use STM32's DMA2D (aka Chrom Art) GPU*/
#define LV_USE_GPU_STM32_DMA2D  0
#if LV_USE_GPU_STM32_DMA2D

The big problems seem to be the above. There may be scattered small problems. If there are omissions, you can check them yourself.
Then there are some code modifications for LVGL.

int main(void)
{
    HAL_Init();                     //Initialize HAL Library   
    Stm32_Clock_Init(360,25,2,8);   //Set clock, 180Mhz
    delay_init(180);                //Initialization delay function
    uart_init(115200);              //Initialize USART
	TIM3_Init(999,89);
    LED_Init();                     //Initialize LED 
    KEY_Init();                     //Initialization key
    SDRAM_Init();                   //Initialize SDRAM
   // LCD_Init();                     // Initialize LCD
	//tp_dev.init(); 				    // Touch screen initialization 
	lv_init();
	
	lv_port_disp_init();
	lv_port_indev_init();
  	
	lv_demo_widgets();
		while (1)
	{
		tp_dev.scan(0);
		lv_task_handler();
	}
}

The main function is actually very simple. After the hardware of stm32 is initialized, it starts to initialize LVGL. The two lines commented out in the code initialize LCD and touch screen, and I moved them to LV below_ port_ disp_ Init and lv_port_indev_init is initialized, because I found that the initialization screen will not be displayed.

lv_port_disp_init is as follows

void lv_port_disp_init(void)
{
    /*-------------------------
     * Initialize your display
     * -----------------------*/
    disp_init();

    /*-----------------------------
     * Create a buffer for drawing
     *----------------------------*/

    /* Example for 1) */
    static lv_disp_draw_buf_t draw_buf_dsc_1;
    static lv_color_t buf_1[MY_DISP_HOR_RES * 10];                          /*A buffer for 10 rows*/
    lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/

    /*-----------------------------------
     * Register the display in LVGL
     *----------------------------------*/
    static 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 = MY_DISP_HOR_RES;
    disp_drv.ver_res = MY_DISP_VER_RES;

    /*Used to copy the buffer's content to the display*/
    disp_drv.flush_cb = disp_flush;

    /*Set a display buffer*/
    disp_drv.draw_buf = &draw_buf_dsc_1;

    /*Finally register the driver*/
    lv_disp_drv_register(&disp_drv);
}
/*Initialize your display and the required peripherals.*/
static void disp_init(void)
{
    /*You code here*/
	    LCD_Init();                     //Initialize LCD
	if(lcdltdc.pwidth!=0)		
		LCD_Display_Dir(1);//If it is an RGB screen, it is still very important to force it to be set to horizontal screen display. It was not added at the beginning, and it was not displayed on the screen
}

lv_port_indev_init is as follows

void lv_port_indev_init(void)
{
    static lv_indev_drv_t indev_drv;

    /*------------------
     * Touchpad
     * -----------------*/
    /*Initialize your touchpad if you have*/
    touchpad_init();
    /*Register a touchpad input device*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = touchpad_read;
    indev_touchpad = lv_indev_drv_register(&indev_drv);
}

/*Initialize your touchpad*/
static void touchpad_init(void)
{
    /*Your code comes here*/
		tp_dev.init();				    //Touch screen initialization 
}

/*Will be called by the library to read the touchpad*/
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
    static lv_coord_t last_x = 0;
    static lv_coord_t last_y = 0;

    /*Save the pressed coordinates and the state*/
	if(tp_dev.sta&TP_PRES_DOWN)//Touch pressed
		{
			last_x = tp_dev.x[0];
			last_y = tp_dev.y[0];
			data->point.x = last_x;
			data->point.y = last_y;
			data->state = LV_INDEV_STATE_PR;
		}else{
			data->point.x = last_x;
			data->point.y = last_y;
			data->state = LV_INDEV_STATE_REL;
		}
}

Then add the official demo

Note that these four files should be added, otherwise an error will be reported and the file cannot be found.
There should be no problem with this compilation. Just download and verify.
The above is my summary in the process of transplanting LVGL8. Please move to QQ group: 795010850 for related projects. You are welcome to correct.

Tags: Single-Chip Microcomputer stm32 ARM LVGL

Posted on Tue, 07 Dec 2021 03:55:35 -0500 by harristweed