1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-10-18     Meco Man     The first version
9  */
10 #include <lvgl.h>
11 #include <board.h>
12 #include <drv_lcd.h>
13 
14 #define LCD_DEV_NAME "lcd"
15 // #define MY_DISP_HOR_RES LCD_W
16 // #define DISP_BUFFER_LINES 70
17 
18 /*A static or global variable to store the buffers*/
19 static lv_disp_draw_buf_t disp_buf;
20 
21 /*Descriptor of a display driver*/
22 static lv_disp_drv_t disp_drv;
23 
24 /*Static or global buffer(s). The second buffer is optional*/
25 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
26 #pragma location=0x68000000
27 lv_color_t buf_1[LCD_H * LCD_W];
28 #elif defined ( __CC_ARM )  /* MDK ARM Compiler */
29 __attribute__((at(0x68000000))) lv_color_t buf_1[LCD_H * LCD_W];
30 #elif defined ( __clang__ ) /* MDK ARM Compiler v6 */
31 __attribute__((section(".ARM.__at_0x68000000"))) lv_color_t buf_1[LCD_H * LCD_W];
32 #elif defined ( __GNUC__ ) /* GNU Compiler */
33 lv_color_t buf_1[LCD_H * LCD_W] __attribute__((section(".MCUlcdgrambysram")));
34 #ifdef RT_USING_MEMHEAP_AS_HEAP
35 #error "You should modify this logic, such as use 'rt_malloc' to create lvgl buf"
36 #endif
37 #endif
38 
39 /*Flush the content of the internal buffer the specific area on the display
40  *You can use DMA or any hardware acceleration to do this operation in the background but
41  *'lv_disp_flush_ready()' has to be called when finished.*/
disp_flush(lv_disp_drv_t * disp_drv,const lv_area_t * area,lv_color_t * color_p)42 static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
43 {
44     /* color_p is a buffer pointer; the buffer is provided by LVGL */
45     lcd_fill_array(area->x1, area->y1, area->x2, area->y2, color_p);
46 
47     /*IMPORTANT!!!
48      *Inform the graphics library that you are ready with the flushing*/
49     lv_disp_flush_ready(disp_drv);
50 }
51 
lv_port_disp_init(void)52 void lv_port_disp_init(void)
53 {
54     /*Initialize `disp_buf` with the buffer(s). With only one buffer use NULL instead buf_2 */
55     lv_disp_draw_buf_init(&disp_buf, buf_1, NULL, LCD_H * LCD_W);
56 
57     lv_disp_drv_init(&disp_drv); /*Basic initialization*/
58 
59     /*Set the resolution of the display*/
60     disp_drv.hor_res = LCD_W;
61     disp_drv.ver_res = LCD_H;
62 
63     /*Set a display buffer*/
64     disp_drv.draw_buf = &disp_buf;
65 
66     /*Used to copy the buffer's content to the display*/
67     disp_drv.flush_cb = disp_flush;
68 
69     /*Init lcd device*/
70     rt_device_t lcd_dev = rt_device_find(LCD_DEV_NAME);
71     rt_device_open(lcd_dev, RT_DEVICE_FLAG_STANDALONE);
72     disp_drv.user_data = lcd_dev;
73 
74     /*Finally register the driver*/
75     lv_disp_drv_register(&disp_drv);
76 }
77