1 /**
2  * @file lv_hal_disp.h
3  *
4  * @description Display Driver HAL interface header file
5  *
6  */
7 
8 #ifndef LV_HAL_DISP_H
9 #define LV_HAL_DISP_H
10 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
15 /*********************
16  *      INCLUDES
17  *********************/
18 #include <stdint.h>
19 #include <stdbool.h>
20 #include "lv_hal.h"
21 #include "../lv_misc/lv_color.h"
22 #include "../lv_misc/lv_area.h"
23 #include "../lv_misc/lv_ll.h"
24 #include "../lv_misc/lv_task.h"
25 
26 /*********************
27  *      DEFINES
28  *********************/
29 #ifndef LV_INV_BUF_SIZE
30 #define LV_INV_BUF_SIZE 32 /*Buffer size for invalid areas */
31 #endif
32 
33 #ifndef LV_ATTRIBUTE_FLUSH_READY
34 #define LV_ATTRIBUTE_FLUSH_READY
35 #endif
36 
37 /**********************
38  *      TYPEDEFS
39  **********************/
40 
41 struct _disp_t;
42 struct _disp_drv_t;
43 
44 /**
45  * Structure for holding display buffer information.
46  */
47 typedef struct {
48     void * buf1; /**< First display buffer. */
49     void * buf2; /**< Second display buffer. */
50 
51     /*Internal, used by the library*/
52     void * buf_act;
53     uint32_t size; /*In pixel count*/
54     lv_area_t area;
55     /*1: flushing is in progress. (It can't be a bit field because when it's cleared from IRQ Read-Modify-Write issue might occur)*/
56     volatile int flushing;
57     /*1: It was the last chunk to flush. (It can't be a bi tfield because when it's cleared from IRQ Read-Modify-Write issue might occur)*/
58     volatile int flushing_last;
59     volatile uint32_t last_area         : 1; /*1: the last area is being rendered*/
60     volatile uint32_t last_part         : 1; /*1: the last part of the current area is being rendered*/
61 } lv_disp_buf_t;
62 
63 /**
64  * Display Driver structure to be registered by HAL
65  */
66 typedef struct _disp_drv_t {
67 
68     lv_coord_t hor_res; /**< Horizontal resolution. */
69     lv_coord_t ver_res; /**< Vertical resolution. */
70 
71     /** Pointer to a buffer initialized with `lv_disp_buf_init()`.
72      * LVGL will use this buffer(s) to draw the screens contents */
73     lv_disp_buf_t * buffer;
74 
75 #if LV_ANTIALIAS
76     uint32_t antialiasing : 1; /**< 1: antialiasing is enabled on this display. */
77 #endif
78     uint32_t rotated : 1; /**< 1: turn the display by 90 degree. @warning Does not update coordinates for you!*/
79 
80 #if LV_COLOR_SCREEN_TRANSP
81     /**Handle if the the screen doesn't have a solid (opa == LV_OPA_COVER) background.
82      * Use only if required because it's slower.*/
83     uint32_t screen_transp : 1;
84 #endif
85 
86     /** DPI (dot per inch) of the display.
87      * Set to `LV_DPI` from `lv_Conf.h` by default.
88      */
89     uint32_t dpi : 10;
90 
91     /** MANDATORY: Write the internal buffer (VDB) to the display. 'lv_disp_flush_ready()' has to be
92      * called when finished */
93     void (*flush_cb)(struct _disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
94 
95     /** OPTIONAL: Extend the invalidated areas to match with the display drivers requirements
96      * E.g. round `y` to, 8, 16 ..) on a monochrome display*/
97     void (*rounder_cb)(struct _disp_drv_t * disp_drv, lv_area_t * area);
98 
99     /** OPTIONAL: Set a pixel in a buffer according to the special requirements of the display
100      * Can be used for color format not supported in LittelvGL. E.g. 2 bit -> 4 gray scales
101      * @note Much slower then drawing with supported color formats. */
102     void (*set_px_cb)(struct _disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
103                       lv_color_t color, lv_opa_t opa);
104 
105     /** OPTIONAL: Called after every refresh cycle to tell the rendering and flushing time + the
106      * number of flushed pixels */
107     void (*monitor_cb)(struct _disp_drv_t * disp_drv, uint32_t time, uint32_t px);
108 
109     /** OPTIONAL: Called periodically while lvgl waits for operation to be completed.
110      * For example flushing or GPU
111      * User can execute very simple tasks here or yield the task */
112     void (*wait_cb)(struct _disp_drv_t * disp_drv);
113 
114     /** OPTIONAL: Called when lvgl needs any CPU cache that affects rendering to be cleaned */
115     void (*clean_dcache_cb)(struct _disp_drv_t * disp_drv);
116 
117     /** OPTIONAL: called to wait while the gpu is working */
118     void (*gpu_wait_cb)(struct _disp_drv_t * disp_drv);
119 
120 #if LV_USE_GPU
121 
122     /** OPTIONAL: Blend two memories using opacity (GPU only)*/
123     void (*gpu_blend_cb)(struct _disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length,
124                          lv_opa_t opa);
125 
126     /** OPTIONAL: Fill a memory with a color (GPU only)*/
127     void (*gpu_fill_cb)(struct _disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
128                         const lv_area_t * fill_area, lv_color_t color);
129 #endif
130 
131     /** On CHROMA_KEYED images this color will be transparent.
132      * `LV_COLOR_TRANSP` by default. (lv_conf.h)*/
133     lv_color_t color_chroma_key;
134 
135 #if LV_USE_USER_DATA
136     lv_disp_drv_user_data_t user_data; /**< Custom display driver user data */
137 #endif
138 
139 } lv_disp_drv_t;
140 
141 struct _lv_obj_t;
142 
143 /**
144  * Display structure.
145  * @note `lv_disp_drv_t` should be the first member of the structure.
146  */
147 typedef struct _disp_t {
148     /**< Driver to the display*/
149     lv_disp_drv_t driver;
150 
151     /**< A task which periodically checks the dirty areas and refreshes them*/
152     lv_task_t * refr_task;
153 
154     /** Screens of the display*/
155     lv_ll_t scr_ll;
156     struct _lv_obj_t * act_scr;   /**< Currently active screen on this display */
157     struct _lv_obj_t * prev_scr;  /**< Previous screen. Used during screen animations */
158     struct _lv_obj_t * top_layer; /**< @see lv_disp_get_layer_top */
159     struct _lv_obj_t * sys_layer; /**< @see lv_disp_get_layer_sys */
160 
161 uint8_t del_prev  :
162     1;        /**< 1: Automatically delete the previous screen when the screen load animation is ready */
163 
164     lv_color_t bg_color;          /**< Default display color when screens are transparent*/
165     const void * bg_img;       /**< An image source to display as wallpaper*/
166     lv_opa_t bg_opa;              /**<Opacity of the background color or wallpaper */
167 
168     /** Invalidated (marked to redraw) areas*/
169     lv_area_t inv_areas[LV_INV_BUF_SIZE];
170     uint8_t inv_area_joined[LV_INV_BUF_SIZE];
171     uint32_t inv_p : 10;
172 
173     /*Miscellaneous data*/
174     uint32_t last_activity_time; /**< Last time there was activity on this display */
175 } lv_disp_t;
176 
177 
178 typedef enum {
179     LV_DISP_SIZE_SMALL,
180     LV_DISP_SIZE_MEDIUM,
181     LV_DISP_SIZE_LARGE,
182     LV_DISP_SIZE_EXTRA_LARGE,
183 } lv_disp_size_t;
184 
185 /**********************
186  * GLOBAL PROTOTYPES
187  **********************/
188 
189 /**
190  * Initialize a display driver with default values.
191  * It is used to have known values in the fields and not junk in memory.
192  * After it you can safely set only the fields you need.
193  * @param driver pointer to driver variable to initialize
194  */
195 void lv_disp_drv_init(lv_disp_drv_t * driver);
196 
197 /**
198  * Initialize a display buffer
199  * @param disp_buf pointer `lv_disp_buf_t` variable to initialize
200  * @param buf1 A buffer to be used by LVGL to draw the image.
201  *             Always has to specified and can't be NULL.
202  *             Can be an array allocated by the user. E.g. `static lv_color_t disp_buf1[1024 * 10]`
203  *             Or a memory address e.g. in external SRAM
204  * @param buf2 Optionally specify a second buffer to make image rendering and image flushing
205  *             (sending to the display) parallel.
206  *             In the `disp_drv->flush` you should use DMA or similar hardware to send
207  *             the image to the display in the background.
208  *             It lets LVGL to render next frame into the other buffer while previous is being
209  * sent. Set to `NULL` if unused.
210  * @param size_in_px_cnt size of the `buf1` and `buf2` in pixel count.
211  */
212 void lv_disp_buf_init(lv_disp_buf_t * disp_buf, void * buf1, void * buf2, uint32_t size_in_px_cnt);
213 
214 /**
215  * Register an initialized display driver.
216  * Automatically set the first display as active.
217  * @param driver pointer to an initialized 'lv_disp_drv_t' variable (can be local variable)
218  * @return pointer to the new display or NULL on error
219  */
220 lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver);
221 
222 /**
223  * Update the driver in run time.
224  * @param disp pointer to a display. (return value of `lv_disp_drv_register`)
225  * @param new_drv pointer to the new driver
226  */
227 void lv_disp_drv_update(lv_disp_t * disp, lv_disp_drv_t * new_drv);
228 
229 /**
230  * Remove a display
231  * @param disp pointer to display
232  */
233 void lv_disp_remove(lv_disp_t * disp);
234 
235 /**
236  * Set a default screen. The new screens will be created on it by default.
237  * @param disp pointer to a display
238  */
239 void lv_disp_set_default(lv_disp_t * disp);
240 
241 /**
242  * Get the default display
243  * @return pointer to the default display
244  */
245 lv_disp_t * lv_disp_get_default(void);
246 
247 /**
248  * Get the horizontal resolution of a display
249  * @param disp pointer to a display (NULL to use the default display)
250  * @return the horizontal resolution of the display
251  */
252 lv_coord_t lv_disp_get_hor_res(lv_disp_t * disp);
253 
254 /**
255  * Get the vertical resolution of a display
256  * @param disp pointer to a display (NULL to use the default display)
257  * @return the vertical resolution of the display
258  */
259 lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp);
260 
261 /**
262  * Get if anti-aliasing is enabled for a display or not
263  * @param disp pointer to a display (NULL to use the default display)
264  * @return true: anti-aliasing is enabled; false: disabled
265  */
266 bool lv_disp_get_antialiasing(lv_disp_t * disp);
267 
268 /**
269  * Get the DPI of the display
270  * @param disp pointer to a display (NULL to use the default display)
271  * @return dpi of the display
272  */
273 lv_coord_t lv_disp_get_dpi(lv_disp_t * disp);
274 
275 /**
276  * Get the size category of the display based on it's hor. res. and dpi.
277  * @param disp pointer to a display (NULL to use the default display)
278  * @return LV_DISP_SIZE_SMALL/MEDIUM/LARGE/EXTRA_LARGE
279  */
280 lv_disp_size_t lv_disp_get_size_category(lv_disp_t * disp);
281 
282 //! @cond Doxygen_Suppress
283 
284 /**
285  * Call in the display driver's `flush_cb` function when the flushing is finished
286  * @param disp_drv pointer to display driver in `flush_cb` where this function is called
287  */
288 LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv);
289 
290 /**
291  * Tell if it's the last area of the refreshing process.
292  * Can be called from `flush_cb` to execute some special display refreshing if needed when all areas area flushed.
293  * @param disp_drv pointer to display driver
294  * @return true: it's the last area to flush; false: there are other areas too which will be refreshed soon
295  */
296 LV_ATTRIBUTE_FLUSH_READY bool lv_disp_flush_is_last(lv_disp_drv_t * disp_drv);
297 
298 //! @endcond
299 
300 /**
301  * Get the next display.
302  * @param disp pointer to the current display. NULL to initialize.
303  * @return the next display or NULL if no more. Give the first display when the parameter is NULL
304  */
305 lv_disp_t * lv_disp_get_next(lv_disp_t * disp);
306 
307 /**
308  * Get the internal buffer of a display
309  * @param disp pointer to a display
310  * @return pointer to the internal buffers
311  */
312 lv_disp_buf_t * lv_disp_get_buf(lv_disp_t * disp);
313 
314 /**
315  * Get the number of areas in the buffer
316  * @return number of invalid areas
317  */
318 uint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp);
319 
320 /**
321  * Pop (delete) the last 'num' invalidated areas from the buffer
322  * @param num number of areas to delete
323  */
324 void _lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num);
325 
326 /**
327  * Check the driver configuration if it's double buffered (both `buf1` and `buf2` are set)
328  * @param disp pointer to to display to check
329  * @return true: double buffered; false: not double buffered
330  */
331 bool lv_disp_is_double_buf(lv_disp_t * disp);
332 
333 /**
334  * Check the driver configuration if it's TRUE double buffered (both `buf1` and `buf2` are set and
335  * `size` is screen sized)
336  * @param disp pointer to to display to check
337  * @return true: double buffered; false: not double buffered
338  */
339 bool lv_disp_is_true_double_buf(lv_disp_t * disp);
340 
341 /**********************
342  *      MACROS
343  **********************/
344 
345 #ifdef __cplusplus
346 } /* extern "C" */
347 #endif
348 
349 #endif
350