Skip to content

Commit

Permalink
feat(drivers): add STM32 LTDC support (lvgl#7059)
Browse files Browse the repository at this point in the history
  • Loading branch information
liamHowatt authored Oct 15, 2024
1 parent 4a75a62 commit 09d9c57
Show file tree
Hide file tree
Showing 8 changed files with 483 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1871,6 +1871,15 @@ menu "LVGL configuration"
bool "Use Renesas GLCDC driver"
default n

config LV_USE_ST_LTDC
bool "Driver for ST LTDC"
default n

config LV_ST_LTDC_USE_DMA2D_FLUSH
bool "Only used for created partial mode LTDC displays"
default n
depends on LV_USE_ST_LTDC && !LV_USE_DRAW_DMA2D

config LV_USE_WINDOWS
bool "Use LVGL Windows backend"
depends on LV_OS_WINDOWS
Expand Down
1 change: 1 addition & 0 deletions docs/integration/driver/display/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ Display
st7789
st7796
renesas_glcdc
st_ltdc
102 changes: 102 additions & 0 deletions docs/integration/driver/display/st_ltdc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
=================
STM32 LTDC Driver
=================

Some STM32s have a specialized peripheral for driving
displays called LTDC (LCD-TFT display controller).

Usage Modes With LVGL
*********************

The driver within LVGL is designed to work with an
already-configured LTDC peripheral. It relies on the
HAL to detect information about the configuration.
The color format of the created LVGL display will
match the LTDC layer's color format. Use STM32CubeIDE
or STM32CubeMX to generate LTDC initialization code.

There are some different use cases for LVGL's driver.
All permutations of the below options are well supported.

- single or double buffered
- direct or partial render mode
- OS and no OS
- paralellized flushing with DMA2D (only for partial render mode)

If OS is enabled, a synchronization primitive will be used to
give the thread a chance to yield to other threads while blocked,
improving CPU utilization. See :c:macro:`LV_USE_OS` in your lv_conf.h

LTDC Layers
***********

This driver creates an LVGL display
which is only concerned with a specific layer of the LTDC peripheral, meaning
two LVGL LTDC displays can be created and operate independently on the separate
layers.

Direct Render Mode
******************

For direct render mode, invoke :cpp:func:`lv_st_ltdc_create_direct` like this:

.. code-block:: c
void * my_ltdc_framebuffer_address = (void *)0x20000000u;
uint32_t my_ltdc_layer_index = 0; /* typically 0 or 1 */
lv_display_t * disp = lv_st_ltdc_create_direct(my_ltdc_framebuffer_address,
optional_other_full_size_buffer,
my_ltdc_layer_index);
``my_ltdc_framebuffer_address`` is the framebuffer configured for use by
LTDC. ``optional_other_full_size_buffer`` can be another buffer which is the same
size as the default framebuffer for double-buffered
mode, or ``NULL`` otherwise. ``my_ltdc_layer_index`` is the layer index of the
LTDC layer to create the display for.

For the best visial results, ``optional_other_full_size_buffer`` should be used
if enough memory is available. Single-buffered mode is what you should use
if memory is very scarce. If there is almost enough memory for double-buffered
direct mode, but not quite, then use partial render mode.

Partial Render Mode
*******************

For partial render mode, invoke :cpp:func:`lv_st_ltdc_create_partial` like this:

.. code-block:: c
static uint8_t partial_buf1[65536];
static uint8_t optional_partial_buf2[65536];
uint32_t my_ltdc_layer_index = 0; /* typically 0 or 1 */
lv_display_t * disp = lv_st_ltdc_create_partial(partial_buf1,
optional_partial_buf2,
65536,
my_ltdc_layer_index);
The driver will use the information in the LTDC layer configuration to find the
layer's framebuffer and flush to it.

Providing a second partial buffer can improve CPU utilization and increase
performance compared to
a single buffer if :c:macro:`LV_ST_LTDC_USE_DMA2D_FLUSH` is enabled.

DMA2D
*****

:c:macro:`LV_ST_LTDC_USE_DMA2D_FLUSH` can be enabled to use DMA2D to flush
partial buffers in parallel with other LVGL tasks, whether or not OS is
enabled. If the display is not partial, then there is no need to enable this
option.

It must not be enabled at the same time as :c:macro:`LV_USE_DRAW_DMA2D`.
See the :ref:`DMA2D support <dma2d>`.

Further Reading
***************

You may be interested in enabling the :ref:`Nema GFX renderer <stm32_nema_gfx>`
if your STM32 has a GPU which is supported by Nema GFX.

`lv_port_riverdi_stm32u5 <https://github.com/lvgl/lv_port_riverdi_stm32u5>`__
is a way to quick way to get started with LTDC on LVGL.
7 changes: 7 additions & 0 deletions lv_conf_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,13 @@
/** Driver for Renesas GLCD */
#define LV_USE_RENESAS_GLCDC 0

/** Driver for ST LTDC */
#define LV_USE_ST_LTDC 0
#if LV_USE_ST_LTDC
/* Only used for partial. */
#define LV_ST_LTDC_USE_DMA2D_FLUSH 0
#endif

/** LVGL Windows backend */
#define LV_USE_WINDOWS 0

Expand Down
Loading

0 comments on commit 09d9c57

Please sign in to comment.