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 0
8 
9 /*********************
10  *      INCLUDES
11  *********************/
12 #include "lv_port_disp_template.h"
13 #include <stdbool.h>
14 
15 /*********************
16  *      DEFINES
17  *********************/
18 #ifndef MY_DISP_HOR_RES
19     #warning Please define or replace the macro MY_DISP_HOR_RES with the actual screen width, default value 320 is used for now.
20     #define MY_DISP_HOR_RES    320
21 #endif
22 
23 #ifndef MY_DISP_VER_RES
24     #warning Please define or replace the macro MY_DISP_HOR_RES with the actual screen height, default value 240 is used for now.
25     #define MY_DISP_VER_RES    240
26 #endif
27 
28 /**********************
29  *      TYPEDEFS
30  **********************/
31 
32 /**********************
33  *  STATIC PROTOTYPES
34  **********************/
35 static void disp_init(void);
36 
37 static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
38 //static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
39 //        const lv_area_t * fill_area, lv_color_t color);
40 
41 /**********************
42  *  STATIC VARIABLES
43  **********************/
44 
45 /**********************
46  *      MACROS
47  **********************/
48 
49 /**********************
50  *   GLOBAL FUNCTIONS
51  **********************/
52 
53 void lv_port_disp_init(void)
54 {
55     /*-------------------------
56      * Initialize your display
57      * -----------------------*/
58     disp_init();
59 
60     /*-----------------------------
61      * Create a buffer for drawing
62      *----------------------------*/
63 
64     /**
65      * LVGL requires a buffer where it internally draws the widgets.
66      * Later this buffer will passed to your display driver's `flush_cb` to copy its content to your display.
67      * The buffer has to be greater than 1 display row
68      *
69      * There are 3 buffering configurations:
70      * 1. Create ONE buffer:
71      *      LVGL will draw the display's content here and writes it to your display
72      *
73      * 2. Create TWO buffer:
74      *      LVGL will draw the display's content to a buffer and writes it your display.
75      *      You should use DMA to write the buffer's content to the display.
76      *      It will enable LVGL to draw the next part of the screen to the other buffer while
77      *      the data is being sent form the first buffer. It makes rendering and flushing parallel.
78      *
79      * 3. Double buffering
80      *      Set 2 screens sized buffers and set disp_drv.full_refresh = 1.
81      *      This way LVGL will always provide the whole rendered screen in `flush_cb`
82      *      and you only need to change the frame buffer's address.
83      */
84 
85     /* Example for 1) */
86     static lv_disp_draw_buf_t draw_buf_dsc_1;
87     static lv_color_t buf_1[MY_DISP_HOR_RES * 10];                          /*A buffer for 10 rows*/
88     lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/
89 
90     /* Example for 2) */
91     static lv_disp_draw_buf_t draw_buf_dsc_2;
92     static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10];                        /*A buffer for 10 rows*/
93     static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10];                        /*An other buffer for 10 rows*/
94     lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/
95 
96     /* Example for 3) also set disp_drv.full_refresh = 1 below*/
97     static lv_disp_draw_buf_t draw_buf_dsc_3;
98     static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*A screen sized buffer*/
99     static lv_color_t buf_3_2[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*Another screen sized buffer*/
100     lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2,
101                           MY_DISP_VER_RES * LV_VER_RES_MAX);   /*Initialize the display buffer*/
102 
103     /*-----------------------------------
104      * Register the display in LVGL
105      *----------------------------------*/
106 
107     static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
108     lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/
109 
110     /*Set up the functions to access to your display*/
111 
112     /*Set the resolution of the display*/
113     disp_drv.hor_res = MY_DISP_HOR_RES;
114     disp_drv.ver_res = MY_DISP_VER_RES;
115 
116     /*Used to copy the buffer's content to the display*/
117     disp_drv.flush_cb = disp_flush;
118 
119     /*Set a display buffer*/
120     disp_drv.draw_buf = &draw_buf_dsc_1;
121 
122     /*Required for Example 3)*/
123     //disp_drv.full_refresh = 1;
124 
125     /* Fill a memory array with a color if you have GPU.
126      * Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.
127      * But if you have a different GPU you can use with this callback.*/
128     //disp_drv.gpu_fill_cb = gpu_fill;
129 
130     /*Finally register the driver*/
131     lv_disp_drv_register(&disp_drv);
132 }
133 
134 /**********************
135  *   STATIC FUNCTIONS
136  **********************/
137 
138 /*Initialize your display and the required peripherals.*/
139 static void disp_init(void)
140 {
141     /*You code here*/
142 }
143 
144 volatile bool disp_flush_enabled = true;
145 
146 /* Enable updating the screen (the flushing process) when disp_flush() is called by LVGL
147  */
148 void disp_enable_update(void)
149 {
150     disp_flush_enabled = true;
151 }
152 
153 /* Disable updating the screen (the flushing process) when disp_flush() is called by LVGL
154  */
155 void disp_disable_update(void)
156 {
157     disp_flush_enabled = false;
158 }
159 
160 /*Flush the content of the internal buffer the specific area on the display
161  *You can use DMA or any hardware acceleration to do this operation in the background but
162  *'lv_disp_flush_ready()' has to be called when finished.*/
163 static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
164 {
165     if(disp_flush_enabled) {
166         /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
167 
168         int32_t x;
169         int32_t y;
170         for(y = area->y1; y <= area->y2; y++) {
171             for(x = area->x1; x <= area->x2; x++) {
172                 /*Put a pixel to the display. For example:*/
173                 /*put_px(x, y, *color_p)*/
174                 color_p++;
175             }
176         }
177     }
178 
179     /*IMPORTANT!!!
180      *Inform the graphics library that you are ready with the flushing*/
181     lv_disp_flush_ready(disp_drv);
182 }
183 
184 /*OPTIONAL: GPU INTERFACE*/
185 
186 /*If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color*/
187 //static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
188 //                    const lv_area_t * fill_area, lv_color_t color)
189 //{
190 //    /*It's an example code which should be done by your GPU*/
191 //    int32_t x, y;
192 //    dest_buf += dest_width * fill_area->y1; /*Go to the first line*/
193 //
194 //    for(y = fill_area->y1; y <= fill_area->y2; y++) {
195 //        for(x = fill_area->x1; x <= fill_area->x2; x++) {
196 //            dest_buf[x] = color;
197 //        }
198 //        dest_buf+=dest_width;    /*Go to the next line*/
199 //    }
200 //}
201 
202 #else /*Enable this file at the top*/
203 
204 /*This dummy typedef exists purely to silence -Wpedantic.*/
205 typedef int keep_pedantic_happy;
206 #endif
207