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