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