/** * @file lv_hal_disp.h * * @description Display Driver HAL interface header file * */ #ifndef LV_HAL_DISP_H #define LV_HAL_DISP_H #ifdef __cplusplus extern "C" { #endif /********************* * INCLUDES *********************/ #include #include #include "lv_hal.h" #include "../lv_misc/lv_color.h" #include "../lv_misc/lv_area.h" #include "../lv_misc/lv_ll.h" /********************* * DEFINES *********************/ #ifndef LV_INV_BUF_SIZE #define LV_INV_BUF_SIZE 32 /*Buffer size for invalid areas */ #endif #ifndef LV_ATTRIBUTE_FLUSH_READY # define LV_ATTRIBUTE_FLUSH_READY #endif /********************** * TYPEDEFS **********************/ struct _disp_t; typedef struct { void * buf1; void * buf2; /*Used by the library*/ void * buf_act; uint32_t size; /*In pixel count*/ lv_area_t area; uint32_t flushing :1; }lv_disp_buf_t; /** * Display Driver structure to be registered by HAL */ typedef struct _disp_drv_t { /*Horizontal and vertical resolution*/ lv_coord_t hor_res; lv_coord_t ver_res; /* Pointer to a buffer initialized with `lv_disp_buf_init()`. * LittlevGL will use this buffer(s) to draw the screens contents */ lv_disp_buf_t * buffer; /* MANDATORY: Write the internal buffer (VDB) to the display. 'lv_flush_ready()' has to be called when finished */ void (*flush_cb)(struct _disp_t * disp, const lv_area_t * area, lv_color_t * color_p); lv_disp_user_data_t flush_user_data; /* OPTIONAL: Called after every refresh cycle to tell the rendering and flushing time + the number of flushed pixels */ void (*monitor_cb)(struct _disp_t * disp, uint32_t time, uint32_t px); lv_disp_user_data_t monitor_user_data; /* OPTIONAL: Extend the invalidated areas to match with the display drivers requirements * E.g. round `y` to, 8, 16 ..) on a monochrome display*/ void (*rounder_cb)(struct _disp_t * disp, lv_area_t * area); lv_disp_user_data_t rounder_user_data; /* OPTIONAL: Set a pixel in a buffer according to the special requirements of the display * Can be used for color format not supported in LittelvGL. E.g. 2 bit -> 4 gray scales * Note: Much slower then drawing with supported color formats. */ void (*set_px_cb)(struct _disp_t * disp, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa); lv_disp_user_data_t set_px_user_data; #if USE_LV_GPU /*OPTIONAL: Blend two memories using opacity (GPU only)*/ void (*mem_blend)(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa); /*OPTIONAL: Fill a memory with a color (GPU only)*/ void (*mem_fill)(lv_color_t * dest, uint32_t length, lv_color_t color); #endif } lv_disp_drv_t; struct _lv_obj_t; typedef struct _disp_t { lv_disp_drv_t driver; lv_ll_t scr_ll; struct _lv_obj_t * act_scr; struct _lv_obj_t * top_layer; struct _lv_obj_t * sys_layer; lv_area_t inv_areas[LV_INV_BUF_SIZE]; uint8_t inv_area_joined[LV_INV_BUF_SIZE]; uint32_t inv_p :10; } lv_disp_t; /********************** * GLOBAL PROTOTYPES **********************/ /** * Initialize a display driver with default values. * It is used to surly have known values in the fields ant not memory junk. * After it you can set the fields. * @param driver pointer to driver variable to initialize */ void lv_disp_drv_init(lv_disp_drv_t * driver); /** * Initialize a display buffer * @param disp_buf pointer `lv_disp_buf_t` variable to initialize * @param buf1 A buffer to be used by LittlevGL to draw the image. * Always has to specified and can't be NULL. * Can be an array allocated by the user. E.g. `static lv_color_t disp_buf1[1024 * 10]` * Or a memory address e.g. in external SRAM * @param buf2 Optionally specify a second buffer to make image rendering and image flushing * (sending to the display) parallel. * In the `disp_drv->flush` you should use DMA or similar hardware to send * the image to the display in the background. * It lets LittlevGL to render next frame into the other buffer while previous is being sent. * Set to `NULL` if unused. * @param size size of the `buf1` and `buf2` in pixel count. */ void lv_disp_buf_init(lv_disp_buf_t * disp_buf, void * buf1, void * buf2, uint32_t size); /** * Register an initialized display driver. * Automatically set the first display as active. * @param driver pointer to an initialized 'lv_disp_drv_t' variable (can be local variable) * @return pointer to the new display or NULL on error */ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver); /** * Set a default screen. The new screens will be created on it by default. * @param disp pointer to a display */ void lv_disp_set_default(lv_disp_t * disp); /** * Get the default display * @return pointer to the default display */ lv_disp_t * lv_disp_get_default(void); /** * Get the horizontal resolution of a display * @param disp pointer to a display (NULL to use the default display) * @return the horizontal resolution of the display */ lv_coord_t lv_disp_get_hor_res(lv_disp_t * disp); /** * Get the vertical resolution of a display * @param disp pointer to a display (NULL to use the default display) * @return the vertical resolution of the display */ lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp); /** * Call in the display driver's `flush` function when the flushing is finished */ LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_t * disp); /** * Get the next display. * @param disp pointer to the current display. NULL to initialize. * @return the next display or NULL if no more. Give the first display when the parameter is NULL */ lv_disp_t * lv_disp_get_next(lv_disp_t * disp); /** * Get the internal buffer of a display * @param disp pointer to a display * @return pointer to the internal buffers */ lv_disp_buf_t * lv_disp_get_buf(lv_disp_t * disp); /** * Get the number of areas in the buffer * @return number of invalid areas */ uint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp); /** * Pop (delete) the last 'num' invalidated areas from the buffer * @param num number of areas to delete */ void lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num); /** * Check the driver configuration if it's double buffered (both `buf1` and `buf2` are set) * @param disp pointer to to display to check * @return true: double buffered; false: not double buffered */ bool lv_disp_is_double_buf(lv_disp_t * disp); /** * Check the driver configuration if it's TRUE double buffered (both `buf1` and `buf2` are set and `size` is screen sized) * @param disp pointer to to display to check * @return true: double buffered; false: not double buffered */ bool lv_disp_is_true_double_buf(lv_disp_t * disp); /********************** * MACROS **********************/ #ifdef __cplusplus } /* extern "C" */ #endif #endif