/** * @file lv_port_disp_templ.c * */ /*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/ #if 1 /********************* * INCLUDES *********************/ #include #include "lv_port_disp.h" #include /********************* * DEFINES *********************/ #ifndef MY_DISP_HOR_RES #warning Please define or replace the macro MY_DISP_HOR_RES with the actual screen width, default value 320 is used for now. #define MY_DISP_HOR_RES 240 #endif #ifndef MY_DISP_VER_RES #warning Please define or replace the macro MY_DISP_HOR_RES with the actual screen height, default value 240 is used for now. #define MY_DISP_VER_RES 240 #endif #if (PKG_LVGL_VER_NUM >= 0x090000) #define LV_DISP_TYPE lv_display_t #define lv_COLOR_TYPE uint8_t #else #define LV_DISP_TYPE lv_disp_drv_t #define lv_COLOR_TYPE lv_color_t #endif /********************** * TYPEDEFS **********************/ /********************** * STATIC PROTOTYPES **********************/ static void disp_init(void); static void disp_flush(LV_DISP_TYPE * disp_drv, const lv_area_t * area, lv_COLOR_TYPE * color_p); /********************** * STATIC VARIABLES **********************/ /********************** * MACROS **********************/ /********************** * GLOBAL FUNCTIONS **********************/ void lv_port_disp_init(void) { /*------------------------- * Initialize your display * -----------------------*/ disp_init(); /*----------------------------- * Create a buffer for drawing *----------------------------*/ /** * LVGL requires a buffer where it internally draws the widgets. * Later this buffer will passed to your display driver's `flush_cb` to copy its content to your display. * The buffer has to be greater than 1 display row * * There are 3 buffering configurations: * 1. Create ONE buffer: * LVGL will draw the display's content here and writes it to your display * * 2. Create TWO buffer: * LVGL will draw the display's content to a buffer and writes it your display. * You should use DMA to write the buffer's content to the display. * It will enable LVGL to draw the next part of the screen to the other buffer while * the data is being sent form the first buffer. It makes rendering and flushing parallel. * * 3. Double buffering * Set 2 screens sized buffers and set disp_drv.full_refresh = 1. * This way LVGL will always provide the whole rendered screen in `flush_cb` * and you only need to change the frame buffer's address. */ /*GCC*/ #if defined ( __GNUC__ ) static lv_color_t buf_1[MY_DISP_HOR_RES * MY_DISP_HOR_RES / 2] __attribute__((section(".LVGLccm"))); /*A buffer for 10 rows*/ /*MDK*/ #elif defined ( __CC_ARM ) __attribute__((at(0x10000000))) lv_color_t buf_1[LCD_H * LCD_W / 2]; #endif /*----------------------------------- * Register the display in LVGL *----------------------------------*/ #if (PKG_LVGL_VER_NUM >= 0x090000) lv_display_t *display = lv_display_create(MY_DISP_HOR_RES, MY_DISP_VER_RES); lv_display_set_buffers(display, buf_1, NULL, sizeof(buf_1), LV_DISPLAY_RENDER_MODE_PARTIAL); /*Initialize the display buffer.*/ lv_display_set_flush_cb(display, disp_flush); #else /* Example for 1) */ static lv_disp_draw_buf_t draw_buf_dsc_1; 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*/ /*----------------------------------- * Register the display in LVGL *----------------------------------*/ static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/ lv_disp_drv_init(&disp_drv); /*Basic initialization*/ /*Set the resolution of the display*/ disp_drv.hor_res = MY_DISP_HOR_RES; disp_drv.ver_res = MY_DISP_VER_RES; /*Used to copy the buffer's content to the display*/ disp_drv.flush_cb = disp_flush; /*Set a display buffer*/ disp_drv.draw_buf = &draw_buf_dsc_1; /*Finally register the driver*/ lv_disp_drv_register(&disp_drv); #endif } /********************** * STATIC FUNCTIONS **********************/ /*Initialize your display and the required peripherals.*/ static void disp_init(void) { /*You code here*/ } volatile bool disp_flush_enabled = true; /* Enable updating the screen (the flushing process) when disp_flush() is called by LVGL */ void disp_enable_update(void) { disp_flush_enabled = true; } /* Disable updating the screen (the flushing process) when disp_flush() is called by LVGL */ void disp_disable_update(void) { disp_flush_enabled = false; } /*Flush the content of the internal buffer the specific area on the display *You can use DMA or any hardware acceleration to do this operation in the background but *'lv_disp_flush_ready()' has to be called when finished.*/ static void disp_flush(LV_DISP_TYPE * disp_drv, const lv_area_t * area, lv_COLOR_TYPE * color_p) { 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); lcd_fill_array(area->x1, area->y1, area->x2, area->y2, color_p); lv_disp_flush_ready(disp_drv); } #else /*Enable this file at the top*/ /*This dummy typedef exists purely to silence -Wpedantic.*/ typedef int keep_pedantic_happy; #endif