diff --git a/examples/porting/lv_port_disp_template.c b/examples/porting/lv_port_disp_template.c index c75463919..9c3a4c1c5 100644 --- a/examples/porting/lv_port_disp_template.c +++ b/examples/porting/lv_port_disp_template.c @@ -34,9 +34,7 @@ **********************/ static void disp_init(void); -static void disp_flush(lv_disp_t * disp_drv, const lv_area_t * area, lv_color_t * color_p); -//static void gpu_fill(lv_disp_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width, -// const lv_area_t * fill_area, lv_color_t color); +static void disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p); /********************** * STATIC VARIABLES @@ -57,78 +55,31 @@ void lv_port_disp_init(void) * -----------------------*/ disp_init(); - /*----------------------------- - * Create a buffer for drawing - *----------------------------*/ + /*------------------------------------ + * Create a display and set a flush_cb + * -----------------------------------*/ + lv_disp_t * disp = lv_disp_create(MY_DISP_HOR_RES, MY_DISP_VER_RES); + lv_disp_set_flush_cb(disp, disp_flush); - /** - * 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. - */ + /* Example 1 + * One buffer for partial rendering*/ + static lv_color_t buf_1_1[MY_DISP_HOR_RES * 10]; /*A buffer for 10 rows*/ + lv_disp_set_draw_buffers(disp, buf_1_1, NULL, sizeof(buf_1_1), LV_DISP_RENDER_MODE_PARTIAL); - /* Example for 1) */ - static lv_disp_draw_buf_t draw_buf_dsc_1; - static lv_color_t buf_1[MY_DISP_HOR_RES * 10]; /*A buffer for 10 rows*/ - lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10); /*Initialize the display buffer*/ + /* Example 2 + * Two buffers for partial rendering + * In flush_cb DMA or similar hardware should be used to update the display in the background.*/ + static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10]; + static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10]; + lv_disp_set_draw_buffers(disp, buf_2_1, buf_2_2, sizeof(buf_2_1), LV_DISP_RENDER_MODE_PARTIAL); - /* Example for 2) */ - static lv_disp_draw_buf_t draw_buf_dsc_2; - static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10]; /*A buffer for 10 rows*/ - static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10]; /*An other buffer for 10 rows*/ - lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10); /*Initialize the display buffer*/ + /* Example 3 + * Two buffers screen sized buffer for double buffering. + * Both LV_DISP_RENDER_MODE_DIRECT and LV_DISP_RENDER_MODE_FULL works, see their comments*/ + static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES]; + static lv_color_t buf_3_2[MY_DISP_HOR_RES * MY_DISP_VER_RES]; + lv_disp_set_draw_buffers(disp, buf_3_1, buf_3_2, sizeof(buf_3_1), LV_DISP_RENDER_MODE_DIRECT); - /* Example for 3) also set disp_drv.full_refresh = 1 below*/ - static lv_disp_draw_buf_t draw_buf_dsc_3; - static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES]; /*A screen sized buffer*/ - static lv_color_t buf_3_2[MY_DISP_HOR_RES * MY_DISP_VER_RES]; /*Another screen sized buffer*/ - lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2, - MY_DISP_VER_RES * LV_VER_RES_MAX); /*Initialize the display buffer*/ - - /*----------------------------------- - * Register the display in LVGL - *----------------------------------*/ - - static lv_disp_t disp_drv; /*Descriptor of a display driver*/ - lv_disp_drv_init(&disp_drv); /*Basic initialization*/ - - /*Set up the functions to access to your display*/ - - /*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; - - /*Required for Example 3)*/ - //disp_drv.full_refresh = 1; - - /* Fill a memory array with a color if you have GPU. - * Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL. - * But if you have a different GPU you can use with this callback.*/ - //disp_drv.gpu_fill_cb = gpu_fill; - - /*Finally register the driver*/ - lv_disp_drv_register(&disp_drv); } /********************** @@ -181,25 +132,6 @@ static void disp_flush(lv_disp_t * disp_drv, const lv_area_t * area, lv_color_t lv_disp_flush_ready(disp_drv); } -/*OPTIONAL: GPU INTERFACE*/ - -/*If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color*/ -//static void gpu_fill(lv_disp_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width, -// const lv_area_t * fill_area, lv_color_t color) -//{ -// /*It's an example code which should be done by your GPU*/ -// int32_t x, y; -// dest_buf += dest_width * fill_area->y1; /*Go to the first line*/ -// -// for(y = fill_area->y1; y <= fill_area->y2; y++) { -// for(x = fill_area->x1; x <= fill_area->x2; x++) { -// dest_buf[x] = color; -// } -// dest_buf+=dest_width; /*Go to the next line*/ -// } -//} - - #else /*Enable this file at the top*/ /*This dummy typedef exists purely to silence -Wpedantic.*/ diff --git a/examples/porting/lv_port_indev_template.c b/examples/porting/lv_port_indev_template.c index 88b055757..4a6ec2028 100644 --- a/examples/porting/lv_port_indev_template.c +++ b/examples/porting/lv_port_indev_template.c @@ -10,7 +10,6 @@ * INCLUDES *********************/ #include "lv_port_indev_template.h" -#include "../../lvgl.h" /********************* * DEFINES @@ -25,25 +24,25 @@ **********************/ static void touchpad_init(void); -static void touchpad_read(lv_indev_t * indev_drv, lv_indev_data_t * data); +static void touchpad_read(lv_indev_t * indev, lv_indev_data_t * data); static bool touchpad_is_pressed(void); static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y); static void mouse_init(void); -static void mouse_read(lv_indev_t * indev_drv, lv_indev_data_t * data); +static void mouse_read(lv_indev_t * indev, lv_indev_data_t * data); static bool mouse_is_pressed(void); static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y); static void keypad_init(void); -static void keypad_read(lv_indev_t * indev_drv, lv_indev_data_t * data); +static void keypad_read(lv_indev_t * indev, lv_indev_data_t * data); static uint32_t keypad_get_key(void); static void encoder_init(void); -static void encoder_read(lv_indev_t * indev_drv, lv_indev_data_t * data); +static void encoder_read(lv_indev_t * indev, lv_indev_data_t * data); static void encoder_handler(void); static void button_init(void); -static void button_read(lv_indev_t * indev_drv, lv_indev_data_t * data); +static void button_read(lv_indev_t * indev, lv_indev_data_t * data); static int8_t button_get_pressed_id(void); static bool button_is_pressed(uint8_t id); @@ -81,7 +80,6 @@ void lv_port_indev_init(void) * You should shape them according to your hardware */ - static lv_indev_t indev_drv; /*------------------ * Touchpad @@ -91,10 +89,9 @@ void lv_port_indev_init(void) touchpad_init(); /*Register a touchpad input device*/ - lv_indev_drv_init(&indev_drv); - indev_drv.type = LV_INDEV_TYPE_POINTER; - indev_drv.read_cb = touchpad_read; - indev_touchpad = lv_indev_drv_register(&indev_drv); + indev_touchpad = lv_indev_create(); + lv_indev_set_type(indev_touchpad, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev_touchpad, touchpad_read); /*------------------ * Mouse @@ -104,10 +101,9 @@ void lv_port_indev_init(void) mouse_init(); /*Register a mouse input device*/ - lv_indev_drv_init(&indev_drv); - indev_drv.type = LV_INDEV_TYPE_POINTER; - indev_drv.read_cb = mouse_read; - indev_mouse = lv_indev_drv_register(&indev_drv); + indev_mouse = lv_indev_create(); + lv_indev_set_type(indev_mouse, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev_mouse, mouse_read); /*Set cursor. For simplicity set a HOME symbol now.*/ lv_obj_t * mouse_cursor = lv_img_create(lv_scr_act()); @@ -122,10 +118,10 @@ void lv_port_indev_init(void) keypad_init(); /*Register a keypad input device*/ - lv_indev_drv_init(&indev_drv); - indev_drv.type = LV_INDEV_TYPE_KEYPAD; - indev_drv.read_cb = keypad_read; - indev_keypad = lv_indev_drv_register(&indev_drv); + indev_keypad = lv_indev_create(); + lv_indev_set_type(indev_keypad, LV_INDEV_TYPE_KEYPAD); + lv_indev_set_read_cb(indev_keypad, keypad_read); + /*Later you should create group(s) with `lv_group_t * group = lv_group_create()`, *add objects to the group with `lv_group_add_obj(group, obj)` @@ -140,10 +136,9 @@ void lv_port_indev_init(void) encoder_init(); /*Register a encoder input device*/ - lv_indev_drv_init(&indev_drv); - indev_drv.type = LV_INDEV_TYPE_ENCODER; - indev_drv.read_cb = encoder_read; - indev_encoder = lv_indev_drv_register(&indev_drv); + indev_encoder = lv_indev_create(); + lv_indev_set_type(indev_encoder, LV_INDEV_TYPE_ENCODER); + lv_indev_set_read_cb(indev_touchpad, encoder_read); /*Later you should create group(s) with `lv_group_t * group = lv_group_create()`, *add objects to the group with `lv_group_add_obj(group, obj)` @@ -158,10 +153,9 @@ void lv_port_indev_init(void) button_init(); /*Register a button input device*/ - lv_indev_drv_init(&indev_drv); - indev_drv.type = LV_INDEV_TYPE_BUTTON; - indev_drv.read_cb = button_read; - indev_button = lv_indev_drv_register(&indev_drv); + indev_touchpad = lv_indev_create(); + lv_indev_set_type(indev_touchpad, LV_INDEV_TYPE_BUTTON); + lv_indev_set_read_cb(indev_touchpad, button_read); /*Assign buttons to points on the screen*/ static const lv_point_t btn_points[2] = { diff --git a/examples/porting/lv_port_indev_template.h b/examples/porting/lv_port_indev_template.h index 8a142bac4..197956660 100644 --- a/examples/porting/lv_port_indev_template.h +++ b/examples/porting/lv_port_indev_template.h @@ -17,7 +17,11 @@ extern "C" { /********************* * INCLUDES *********************/ +#if defined(LV_LVGL_H_INCLUDE_SIMPLE) +#include "lvgl.h" +#else #include "lvgl/lvgl.h" +#endif /********************* * DEFINES diff --git a/src/core/lv_disp.h b/src/core/lv_disp.h index cece36928..e20ced6c1 100644 --- a/src/core/lv_disp.h +++ b/src/core/lv_disp.h @@ -52,9 +52,15 @@ typedef enum { /** * The buffer(s) has to be screen sized and LVGL will render into the correct location of the buffer. - * This way the buffer always contain the whole image. + * This way the buffer always contain the whole image. Only the changed ares will be updated. + * With 2 buffers the buffers' content are kept in sync automatically and in flush_cb only address change is required. */ LV_DISP_RENDER_MODE_DIRECT, + + /** + * Always redraw the whole screen even if only one pixel has been changed. + * With 2 buffers in flush_cb only and address change is required. + */ LV_DISP_RENDER_MODE_FULL, } lv_disp_render_mode_t;