1 /**
2  * @file lv_port_disp_templ.c
3  *
4  */
5 
6 /*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
7 #if 1
8 
9 /*********************
10  *      INCLUDES
11  *********************/
12 #include <lv_conf.h>
13 #include "lv_port_disp.h"
14 #include <stdbool.h>
15 
16 /*********************
17  *      DEFINES
18  *********************/
19 #ifndef MY_DISP_HOR_RES
20     #warning Please define or replace the macro MY_DISP_HOR_RES with the actual screen width, default value 320 is used for now.
21     #define MY_DISP_HOR_RES    240
22 #endif
23 
24 #ifndef MY_DISP_VER_RES
25     #warning Please define or replace the macro MY_DISP_HOR_RES with the actual screen height, default value 240 is used for now.
26     #define MY_DISP_VER_RES    240
27 #endif
28 
29 #if (PKG_LVGL_VER_NUM >= 0x090000)
30     #define LV_DISP_TYPE    lv_display_t
31     #define lv_COLOR_TYPE   uint8_t
32 #else
33     #define LV_DISP_TYPE    lv_disp_drv_t
34     #define lv_COLOR_TYPE   lv_color_t
35 #endif
36 
37 /**********************
38  *      TYPEDEFS
39  **********************/
40 
41 /**********************
42  *  STATIC PROTOTYPES
43  **********************/
44 static void disp_init(void);
45 
46 static void disp_flush(LV_DISP_TYPE * disp_drv, const lv_area_t * area, lv_COLOR_TYPE * color_p);
47 
48 /**********************
49  *  STATIC VARIABLES
50  **********************/
51 
52 /**********************
53  *      MACROS
54  **********************/
55 
56 /**********************
57  *   GLOBAL FUNCTIONS
58  **********************/
59 
lv_port_disp_init(void)60 void lv_port_disp_init(void)
61 {
62     /*-------------------------
63      * Initialize your display
64      * -----------------------*/
65     disp_init();
66 
67     /*-----------------------------
68      * Create a buffer for drawing
69      *----------------------------*/
70 
71     /**
72      * LVGL requires a buffer where it internally draws the widgets.
73      * Later this buffer will passed to your display driver's `flush_cb` to copy its content to your display.
74      * The buffer has to be greater than 1 display row
75      *
76      * There are 3 buffering configurations:
77      * 1. Create ONE buffer:
78      *      LVGL will draw the display's content here and writes it to your display
79      *
80      * 2. Create TWO buffer:
81      *      LVGL will draw the display's content to a buffer and writes it your display.
82      *      You should use DMA to write the buffer's content to the display.
83      *      It will enable LVGL to draw the next part of the screen to the other buffer while
84      *      the data is being sent form the first buffer. It makes rendering and flushing parallel.
85      *
86      * 3. Double buffering
87      *      Set 2 screens sized buffers and set disp_drv.full_refresh = 1.
88      *      This way LVGL will always provide the whole rendered screen in `flush_cb`
89      *      and you only need to change the frame buffer's address.
90      */
91 
92     /*GCC*/
93 #if defined ( __GNUC__ )
94     static lv_color_t buf_1[MY_DISP_HOR_RES * MY_DISP_HOR_RES / 2] __attribute__((section(".LVGLccm")));                          /*A buffer for 10 rows*/
95     /*MDK*/
96 #elif defined ( __CC_ARM )
97     __attribute__((at(0x10000000))) lv_color_t buf_1[LCD_H * LCD_W / 2];
98 #endif
99 
100     /*-----------------------------------
101      * Register the display in LVGL
102      *----------------------------------*/
103 
104 #if (PKG_LVGL_VER_NUM >= 0x090000)
105 
106     lv_display_t *display = lv_display_create(MY_DISP_HOR_RES, MY_DISP_VER_RES);
107     lv_display_set_buffers(display, buf_1, NULL, sizeof(buf_1), LV_DISPLAY_RENDER_MODE_PARTIAL);  /*Initialize the display buffer.*/
108     lv_display_set_flush_cb(display, disp_flush);
109 
110 #else
111 
112     /* Example for 1) */
113     static lv_disp_draw_buf_t draw_buf_dsc_1;
114 
115     lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * MY_DISP_HOR_RES / 2);   /*Initialize the display buffer*/
116 
117     /*-----------------------------------
118      * Register the display in LVGL
119      *----------------------------------*/
120     static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
121     lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/
122 
123     /*Set the resolution of the display*/
124     disp_drv.hor_res = MY_DISP_HOR_RES;
125     disp_drv.ver_res = MY_DISP_VER_RES;
126 
127     /*Used to copy the buffer's content to the display*/
128     disp_drv.flush_cb = disp_flush;
129 
130     /*Set a display buffer*/
131     disp_drv.draw_buf = &draw_buf_dsc_1;
132 
133     /*Finally register the driver*/
134     lv_disp_drv_register(&disp_drv);
135 
136 #endif
137 
138 }
139 
140 /**********************
141  *   STATIC FUNCTIONS
142  **********************/
143 
144 /*Initialize your display and the required peripherals.*/
disp_init(void)145 static void disp_init(void)
146 {
147     /*You code here*/
148 }
149 
150 volatile bool disp_flush_enabled = true;
151 
152 /* Enable updating the screen (the flushing process) when disp_flush() is called by LVGL
153  */
disp_enable_update(void)154 void disp_enable_update(void)
155 {
156     disp_flush_enabled = true;
157 }
158 
159 /* Disable updating the screen (the flushing process) when disp_flush() is called by LVGL
160  */
disp_disable_update(void)161 void disp_disable_update(void)
162 {
163     disp_flush_enabled = false;
164 }
165 
166 /*Flush the content of the internal buffer the specific area on the display
167  *You can use DMA or any hardware acceleration to do this operation in the background but
168  *'lv_disp_flush_ready()' has to be called when finished.*/
disp_flush(LV_DISP_TYPE * disp_drv,const lv_area_t * area,lv_COLOR_TYPE * color_p)169 static void disp_flush(LV_DISP_TYPE * disp_drv, const lv_area_t * area, lv_COLOR_TYPE * color_p)
170 {
171     extern void lcd_fill_array(rt_uint16_t x_start, rt_uint16_t y_start, rt_uint16_t x_end, rt_uint16_t y_end, void *pcolor);
172     lcd_fill_array(area->x1, area->y1, area->x2, area->y2, color_p);
173     lv_disp_flush_ready(disp_drv);
174 }
175 
176 
177 #else /*Enable this file at the top*/
178 
179 /*This dummy typedef exists purely to silence -Wpedantic.*/
180 typedef int keep_pedantic_happy;
181 #endif