feat(doc): Update display-related documentation to new API (#5489)
This commit is contained in:
@@ -108,7 +108,7 @@ follow some coding conventions:
|
||||
argument which is a pointer to widget object itself.
|
||||
- ``struct`` APIs should follow the widgets' conventions. That is to receive a pointer to the ``struct`` as the
|
||||
first argument, and the prefix of the ``struct`` name should be used as the prefix of the
|
||||
function name too (e.g. :cpp:expr:`lv_disp_set_default(lv_disp_t * disp)`)
|
||||
function name too (e.g. :cpp:expr:`lv_display_set_default(lv_display_t * disp)`)
|
||||
- Functions and ``struct``\ s which are not part of the public API must begin with underscore in order to mark them as "private".
|
||||
- Argument must be named in H files too.
|
||||
- Do not ``malloc`` into a static or global variables. Instead declare the variable in ``lv_global_t``
|
||||
|
||||
@@ -37,30 +37,29 @@ If you would rather try LVGL on your own project follow these steps:
|
||||
timing of LVGL. Alternatively, register a ``tick_get_cb`` with
|
||||
:cpp:func:`lv_tick_set_cb` so that LVGL can retrieve the current time directly.
|
||||
- Call :cpp:func:`lv_init`
|
||||
- Create a display.
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_display_t *display = lv_display_create(MY_DISP_HOR_RES, MY_DISP_VER_RES);
|
||||
|
||||
- Create a draw buffer: LVGL will render the graphics here first, and
|
||||
send the rendered image to the display. The buffer size can be set
|
||||
freely but 1/10 screen size is a good starting point.
|
||||
|
||||
.. code:: c
|
||||
|
||||
static lv_disp_draw_buf_t draw_buf;
|
||||
static lv_color_t buf1[MY_DISP_HOR_RES * MY_DISP_VER_RES / 10]; /*Declare a buffer for 1/10 screen size*/
|
||||
lv_disp_draw_buf_init(&draw_buf, buf1, NULL, MY_DISP_HOR_RES * MY_DISP_VER_RES / 10); /*Initialize the display buffer.*/
|
||||
lv_display_set_buffers(display, buf1, NULL, sizeof(buf1)); /*Initialize the display buffer.*/
|
||||
|
||||
- Implement and register a function which can copy the rendered image
|
||||
to an area of your display:
|
||||
|
||||
.. code:: c
|
||||
|
||||
static lv_disp_t disp_drv; /*Descriptor of a display driver*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
disp_drv.flush_cb = my_disp_flush; /*Set your driver function*/
|
||||
disp_drv.draw_buf = &draw_buf; /*Assign the buffer to the display*/
|
||||
disp_drv.hor_res = MY_DISP_HOR_RES; /*Set the horizontal resolution of the display*/
|
||||
disp_drv.ver_res = MY_DISP_VER_RES; /*Set the vertical resolution of the display*/
|
||||
lv_disp_drv_register(&disp_drv); /*Finally register the driver*/
|
||||
lv_display_set_flush_cb(display, my_disp_flush);
|
||||
|
||||
void my_disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p)
|
||||
void my_disp_flush(lv_display_t * disp, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
int32_t x, y;
|
||||
/*It's a very slow but simple implementation.
|
||||
@@ -72,7 +71,7 @@ If you would rather try LVGL on your own project follow these steps:
|
||||
}
|
||||
}
|
||||
|
||||
lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/
|
||||
lv_display_flush_ready(disp); /* Indicate you are ready with the flushing*/
|
||||
}
|
||||
|
||||
- Implement and register a function which can read an input device.
|
||||
|
||||
@@ -42,7 +42,7 @@ the *main.c* file. \* Create some frame buffer(s) as global variables:
|
||||
- In your ``main()`` function, after initialising your CPU,
|
||||
peripherals, and LCD panel, call :cpp:func:`lv_init` to initialise LVGL.
|
||||
You can then create the display driver using
|
||||
:cpp:func:`lv_disp_create`, and register the frame buffers using
|
||||
:cpp:func:`lv_display_create`, and register the frame buffers using
|
||||
:cpp:func:`lv_display_set_buffers`.
|
||||
|
||||
.. code:: c
|
||||
@@ -50,9 +50,9 @@ the *main.c* file. \* Create some frame buffer(s) as global variables:
|
||||
//Initialise LVGL UI library
|
||||
lv_init();
|
||||
|
||||
lv_disp_t * disp = lv_disp_create(WIDTH, HEIGHT); /*Basic initialization with horizontal and vertical resolution in pixels*/
|
||||
lv_display_t * disp = lv_display_create(WIDTH, HEIGHT); /*Basic initialization with horizontal and vertical resolution in pixels*/
|
||||
lv_display_set_flush_cb(disp, my_flush_cb); /*Set a flush callback to draw to the display*/
|
||||
lv_display_set_buffers(disp, buf_1, buf_2, sizeof(buf_1), LV_DISP_RENDER_MODE_PARTIAL); /*Set an initialized buffer*/
|
||||
lv_display_set_buffers(disp, buf_1, buf_2, sizeof(buf_1), LV_DISPLAY_RENDER_MODE_PARTIAL); /*Set an initialized buffer*/
|
||||
|
||||
- Create some dummy objects to test the output:
|
||||
|
||||
@@ -107,7 +107,7 @@ the *main.c* file. \* Create some frame buffer(s) as global variables:
|
||||
|
||||
.. code:: c
|
||||
|
||||
void my_flush_cb(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p)
|
||||
void my_flush_cb(lv_display_t * disp, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
//Set the drawing region
|
||||
set_draw_window(area->x1, area->y1, area->x2, area->y2);
|
||||
@@ -133,7 +133,7 @@ the *main.c* file. \* Create some frame buffer(s) as global variables:
|
||||
|
||||
/* IMPORTANT!!!
|
||||
* Inform the graphics library that you are ready with the flushing*/
|
||||
lv_disp_flush_ready(disp);
|
||||
lv_display_flush_ready(disp);
|
||||
}
|
||||
|
||||
FreeRTOS Example
|
||||
@@ -148,33 +148,21 @@ variables:
|
||||
.. code:: c
|
||||
|
||||
//Frame buffers
|
||||
/*A static or global variable to store the buffers*/
|
||||
static lv_disp_draw_buf_t disp_buf;
|
||||
|
||||
/*Static or global buffer(s). The second buffer is optional*/
|
||||
static lv_color_t buf_1[BUFF_SIZE]; //TODO: Declare your own BUFF_SIZE appropriate to your system.
|
||||
static lv_color_t buf_2[BUFF_SIZE];
|
||||
|
||||
- In your ``main`` function, after your peripherals (SPI, GPIOs, LCD
|
||||
etc) have been initialised, initialise LVGL using :cpp:func:`lv_init`,
|
||||
register the frame buffers using :cpp:func:`lv_disp_draw_buf_init`, and
|
||||
create a new display driver using :cpp:func:`lv_disp_drv_init`.
|
||||
create a new display driver using :cpp:func:`lv_display_create`, and
|
||||
register the frame buffers using :cpp:func:`lv_display_set_buffers`.
|
||||
|
||||
.. code:: c
|
||||
|
||||
//Initialise LVGL UI library
|
||||
lv_init();
|
||||
lv_disp_draw_buf_init(&disp_buf, buf_1, buf_2, BUFF_SIZE);
|
||||
|
||||
static lv_disp_drv_t disp_drv; /*A variable to hold the drivers. Must be static or global.*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
disp_drv.draw_buf = &disp_buf; /*Set an initialized buffer*/
|
||||
disp_drv.flush_cb = my_flush_cb; /*Set a flush callback to draw to the display*/
|
||||
disp_drv.hor_res = WIDTH; /*Set the horizontal resolution in pixels*/
|
||||
disp_drv.ver_res = HEIGHT; /*Set the vertical resolution in pixels*/
|
||||
|
||||
lv_disp_t * disp;
|
||||
disp = lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/
|
||||
lv_display_t *display = lv_display_create(WIDTH, HEIGHT); /*Create the display*/
|
||||
lv_display_set_flush_cb(display, my_flush_cb); /*Set a flush callback to draw to the display*/
|
||||
|
||||
// Register the touch controller with LVGL - Not included here for brevity.
|
||||
|
||||
@@ -242,8 +230,10 @@ variables:
|
||||
|
||||
.. code:: c
|
||||
|
||||
void my_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
|
||||
void my_flush_cb(lv_display_t * display, const lv_area_t * area, uint8_t * px_map);
|
||||
{
|
||||
uint16_t * color_p = (uint16_t *)px_map;
|
||||
|
||||
//Set the drawing region
|
||||
set_draw_window(area->x1, area->y1, area->x2, area->y2);
|
||||
|
||||
@@ -256,7 +246,7 @@ variables:
|
||||
|
||||
//Write colour to each pixel
|
||||
for (int i = 0; i < width * height; i++) {
|
||||
parallel_write(color_p->full);
|
||||
parallel_write(color_p);
|
||||
color_p++;
|
||||
}
|
||||
|
||||
@@ -265,5 +255,5 @@ variables:
|
||||
|
||||
/* IMPORTANT!!!
|
||||
* Inform the graphics library that you are ready with the flushing*/
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
lv_display_flush_ready(display);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ Usage
|
||||
...
|
||||
|
||||
/* initialize X11 display driver */
|
||||
lv_disp_t * disp = lv_x11_window_create("LVGL X11 Simulation", monitor_hor_res, monitor_ver_res);
|
||||
lv_display_t * disp = lv_x11_window_create("LVGL X11 Simulation", monitor_hor_res, monitor_ver_res);
|
||||
|
||||
/* initialize X11 input drivers (for keyboard, mouse & mousewheel) */
|
||||
lv_x11_inputs_create(disp, NULL);
|
||||
@@ -103,7 +103,7 @@ Usage
|
||||
...
|
||||
|
||||
/* initialize X11 display driver */
|
||||
lv_disp_t * disp = lv_x11_window_create("LVGL X11 Simulation", monitor_hor_res, monitor_ver_res);
|
||||
lv_display_t * disp = lv_x11_window_create("LVGL X11 Simulation", monitor_hor_res, monitor_ver_res);
|
||||
lv_display_add_event_cb(disp, on_close_cb, LV_EVENT_DELETE, disp);
|
||||
|
||||
/* initialize X11 input drivers (for keyboard, mouse & mousewheel) */
|
||||
|
||||
@@ -142,7 +142,7 @@ Example
|
||||
lv_color_t * buf1 = NULL;
|
||||
lv_color_t * buf2 = NULL;
|
||||
|
||||
uint32_t buf_size = LCD_H_RES * LCD_BUF_LINES * lv_color_format_get_size(lv_disp_get_color_format(my_disp));
|
||||
uint32_t buf_size = LCD_H_RES * LCD_BUF_LINES * lv_color_format_get_size(lv_display_get_color_format(my_disp));
|
||||
|
||||
buf1 = lv_malloc(buf_size);
|
||||
if(buf1 == NULL) {
|
||||
|
||||
@@ -193,7 +193,7 @@ LVGL doesn't start, randomly crashes or nothing is drawn on the display. What ca
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* Try increasing :c:macro:`LV_MEM_SIZE`.
|
||||
* Be sure :cpp:type:`lv_disp_t`, :cpp:type:`lv_indev_t` and :cpp:type:`lv_fs_drv_t` are global or `static`.
|
||||
* Be sure :cpp:type:`lv_display_t`, :cpp:type:`lv_indev_t` and :cpp:type:`lv_fs_drv_t` are global or `static`.
|
||||
* Be sure your display works without LVGL. E.g. paint it to red on start up.
|
||||
* Enable :ref:`logging`
|
||||
* Enable asserts in ``lv_conf.h`` (`LV_USE_ASSERT_...`)
|
||||
@@ -213,7 +213,7 @@ Learn more in the :ref:`tick` and :ref:`timer` sections.
|
||||
Why is the display driver called only once? Only the upper part of the display is refreshed.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Be sure you are calling :cpp:expr:`lv_disp_flush_ready(drv)` at the end of your "*display flush callback*".
|
||||
Be sure you are calling :cpp:expr:`lv_display_flush_ready(drv)` at the end of your "*display flush callback*".
|
||||
|
||||
|
||||
Why do I see only garbage on the screen?
|
||||
|
||||
@@ -77,7 +77,7 @@ display under the rest of the button too.
|
||||
The difference between buffering modes regarding the drawing mechanism
|
||||
is the following:
|
||||
|
||||
1. **One buffer** - LVGL needs to wait for :cpp:func:`lv_disp_flush_ready` (called from ``flush_cb``) before starting to redraw the next part.
|
||||
1. **One buffer** - LVGL needs to wait for :cpp:func:`lv_display_flush_ready` (called from ``flush_cb``) before starting to redraw the next part.
|
||||
2. **Two buffers** - LVGL can immediately draw to the second buffer when the first is sent to ``flush_cb`` because the
|
||||
flushing should be done by DMA (or similar hardware) in the background.
|
||||
3. **Double buffering** - ``flush_cb`` should only swap the addresses of the frame buffers.
|
||||
|
||||
@@ -246,8 +246,8 @@ Handling multiple displays
|
||||
|
||||
Screens are created on the currently selected *default display*. The
|
||||
*default display* is the last registered display with
|
||||
:cpp:func:`lv_disp_drv_register`. You can also explicitly select a new default
|
||||
display using :cpp:expr:`lv_disp_set_default(disp)`.
|
||||
:cpp:func:`lv_display_create`. You can also explicitly select a new default
|
||||
display using :cpp:expr:`lv_display_set_default(disp)`.
|
||||
|
||||
:cpp:func:`lv_screen_active`, :cpp:func:`lv_screen_load` and :cpp:func:`lv_screen_load_anim` operate
|
||||
on the default display.
|
||||
|
||||
@@ -505,7 +505,7 @@ example shows how to set the "default" theme:
|
||||
false, /*Light or dark mode*/
|
||||
&lv_font_montserrat_10, &lv_font_montserrat_14, &lv_font_montserrat_18); /*Small, normal, large fonts*/
|
||||
|
||||
lv_disp_set_theme(display, th); /*Assign the theme to the display*/
|
||||
lv_display_set_theme(display, th); /*Assign the theme to the display*/
|
||||
|
||||
The included themes are enabled in ``lv_conf.h``. If the default theme
|
||||
is enabled by :c:macro:`LV_USE_THEME_DEFAULT` LVGL automatically initializes
|
||||
|
||||
@@ -54,27 +54,27 @@ Draw buffers
|
||||
------------
|
||||
|
||||
The draw buffers can be set with
|
||||
:cpp:expr:`lv_display_set_buffers(display, buf1, buf2, buf_size_px, render_mode)`
|
||||
:cpp:expr:`lv_display_set_buffers(display, buf1, buf2, buf_size_byte, render_mode)`
|
||||
|
||||
- ``buf1`` a buffer where LVGL can render
|
||||
- ``buf2`` a second optional buffer (see more details below)
|
||||
- ``buf_size_byte`` size of the buffer(s) in bytes
|
||||
- ``render_mode``
|
||||
|
||||
- :cpp:enumerator:`LV_DISP_RENDER_MODE_PARTIAL` Use the buffer(s) to render the
|
||||
- :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_PARTIAL` Use the buffer(s) to render the
|
||||
screen in smaller parts. This way the buffers can be smaller then
|
||||
the display to save RAM. At least 1/10 screen size buffer(s) are
|
||||
recommended. In ``flush_cb`` the rendered images needs to be
|
||||
copied to the given area of the display. In this mode if a button is pressed
|
||||
only the button's area will be redrawn.
|
||||
- :cpp:enumerator:`LV_DISP_RENDER_MODE_DIRECT` The buffer(s) has to be screen
|
||||
- :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT` 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. If two
|
||||
buffer are used the rendered areas are automatically copied to the
|
||||
other buffer after flushing. Due to this in ``flush_cb`` typically
|
||||
only a frame buffer address needs to be changed. If a button is pressed
|
||||
only the button's area will be redrawn.
|
||||
- :cpp:enumerator:`LV_DISP_RENDER_MODE_FULL` The buffer(s) has to be screen
|
||||
- :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_FULL` The buffer(s) has to be screen
|
||||
sized and LVGL will always redraw the whole screen even if only 1
|
||||
pixel has been changed. If two screen sized draw buffers are
|
||||
provided, LVGL's display handling works like "traditional" double
|
||||
@@ -86,7 +86,7 @@ Example:
|
||||
.. code:: c
|
||||
|
||||
static uint16_t buf[LCD_HOR_RES * LCD_VER_RES / 10];
|
||||
lv_display_set_buffers(disp, buf, NULL, sizeof(buf), LV_DISP_RENDER_MODE_PARTIAL);
|
||||
lv_display_set_buffers(disp, buf, NULL, sizeof(buf), LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
|
||||
One buffer
|
||||
^^^^^^^^^^
|
||||
@@ -144,7 +144,7 @@ LVGL supports rotation of the display in 90 degree increments. You can
|
||||
select whether you would like software rotation or hardware rotation.
|
||||
|
||||
The orientation of the display can be changed with
|
||||
``lv_disp_set_rotation(disp, LV_DISPLAY_ROTATION_0/90/180/270)``.
|
||||
``lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_0/90/180/270)``.
|
||||
LVGL will swap the horizontal and vertical resolutions internally
|
||||
according to the set degree. When changing the rotation
|
||||
:cpp:expr:`LV_EVENT_SIZE_CHANGED` is sent to the display to allow
|
||||
@@ -219,13 +219,13 @@ You can do this in the following way:
|
||||
|
||||
|
||||
/*Call this anywhere you want to refresh the dirty areas*/
|
||||
_lv_disp_refr_timer(NULL);
|
||||
_lv_display_refr_timer(NULL);
|
||||
|
||||
If you have multiple displays call :cpp:expr:`lv_disp_set_default(disp1)` to
|
||||
select the display to refresh before :cpp:expr:`_lv_disp_refr_timer(NULL)`.
|
||||
If you have multiple displays call :cpp:expr:`lv_display_set_default(disp1)` to
|
||||
select the display to refresh before :cpp:expr:`_lv_display_refr_timer(NULL)`.
|
||||
|
||||
|
||||
.. note:: that :cpp:func:`lv_timer_handler` and :cpp:func:`_lv_disp_refr_timer` can not run at the same time.
|
||||
.. note:: that :cpp:func:`lv_timer_handler` and :cpp:func:`_lv_display_refr_timer` can not run at the same time.
|
||||
|
||||
|
||||
If the performance monitor is enabled, the value of :c:macro:`LV_DEF_REFR_PERIOD` needs to be set to be
|
||||
|
||||
@@ -220,7 +220,7 @@ Associating with a display
|
||||
|
||||
Every input device is associated with a display. By default, a new input
|
||||
device is added to the last display created or explicitly selected
|
||||
(using :cpp:func:`lv_disp_set_default`). The associated display is stored and
|
||||
(using :cpp:func:`lv_display_set_default`). The associated display is stored and
|
||||
can be changed in ``disp`` field of the driver.
|
||||
|
||||
Buffered reading
|
||||
@@ -256,7 +256,7 @@ You can do this in the following way:
|
||||
/*Call this anywhere you want to read the input device*/
|
||||
lv_indev_read(indev);
|
||||
|
||||
.. note:: that :cpp:func:`lv_indev_read`, :cpp:func:`lv_timer_handler` and :cpp:func:`_lv_disp_refr_timer` can not run at the same time.
|
||||
.. note:: that :cpp:func:`lv_indev_read`, :cpp:func:`lv_timer_handler` and :cpp:func:`_lv_display_refr_timer` can not run at the same time.
|
||||
|
||||
Further reading
|
||||
***************
|
||||
|
||||
@@ -57,7 +57,7 @@ Interrupts
|
||||
----------
|
||||
|
||||
Try to avoid calling LVGL functions from interrupt handlers (except
|
||||
:cpp:func:`lv_tick_inc` and :cpp:func:`lv_disp_flush_ready`). But if you need to do
|
||||
:cpp:func:`lv_tick_inc` and :cpp:func:`lv_display_flush_ready`). But if you need to do
|
||||
this you have to disable the interrupt which uses LVGL functions while
|
||||
:cpp:func:`lv_timer_handler` is running.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ main ``while(1)`` should look like this:
|
||||
|
||||
while(1) {
|
||||
/*Normal operation (no sleep) in < 1 sec inactivity*/
|
||||
if(lv_disp_get_inactive_time(NULL) < 1000) {
|
||||
if(lv_display_get_inactive_time(NULL) < 1000) {
|
||||
lv_task_handler();
|
||||
}
|
||||
/*Sleep after 1 sec inactivity*/
|
||||
@@ -29,5 +29,5 @@ function to signal a wake-up (press, touch or click etc.) has happened:
|
||||
timer_start(); /*Restart the timer where lv_tick_inc() is called*/
|
||||
lv_task_handler(); /*Call `lv_task_handler()` manually to process the wake-up event*/
|
||||
|
||||
In addition to :cpp:func:`lv_disp_get_inactive_time` you can check
|
||||
In addition to :cpp:func:`lv_display_get_inactive_time` you can check
|
||||
:cpp:func:`lv_anim_count_running` to see if all animations have finished.
|
||||
|
||||
@@ -135,7 +135,7 @@ pointer to the active screen.
|
||||
|
||||
If you have multiple displays, it's important to know that the screen
|
||||
functions operate on the most recently created display or the one
|
||||
explicitly selected with :cpp:func:`lv_disp_set_default`.
|
||||
explicitly selected with :cpp:func:`lv_display_set_default`.
|
||||
|
||||
To get an object's screen use the :cpp:expr:`lv_obj_get_screen(obj)` function.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user