mirror of
https://github.com/lvgl/lvgl.git
synced 2024-11-23 01:33:59 +08:00
feat(drivers): add STM32 LTDC support (#7059)
This commit is contained in:
parent
4a75a62fe2
commit
09d9c575b6
9
Kconfig
9
Kconfig
@ -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
|
||||
|
@ -13,3 +13,4 @@ Display
|
||||
st7789
|
||||
st7796
|
||||
renesas_glcdc
|
||||
st_ltdc
|
||||
|
102
docs/integration/driver/display/st_ltdc.rst
Normal file
102
docs/integration/driver/display/st_ltdc.rst
Normal file
@ -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.
|
@ -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
|
||||
|
||||
|
279
src/drivers/display/st_ltdc/lv_st_ltdc.c
Normal file
279
src/drivers/display/st_ltdc/lv_st_ltdc.c
Normal file
@ -0,0 +1,279 @@
|
||||
/**
|
||||
* @file lv_st_ltdc.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
#if LV_USE_ST_LTDC
|
||||
|
||||
#include "lv_st_ltdc.h"
|
||||
#include "../../../display/lv_display_private.h"
|
||||
#include "ltdc.h"
|
||||
|
||||
#if LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
#if LV_USE_DRAW_DMA2D
|
||||
#error cannot use LV_ST_LTDC_USE_DMA2D_FLUSH with LV_USE_DRAW_DMA2D
|
||||
#endif /*LV_USE_DRAW_DMA2D*/
|
||||
|
||||
#include "dma2d.h"
|
||||
#endif /*LV_ST_LTDC_USE_DMA2D_FLUSH*/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
#if LV_USE_OS != LV_OS_NONE
|
||||
typedef lv_thread_sync_t sync_t;
|
||||
#else
|
||||
typedef volatile bool sync_t;
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static lv_display_t * create(void * buf1, void * buf2, uint32_t buf_size, uint32_t layer_idx,
|
||||
lv_display_render_mode_t mode);
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
|
||||
static void flush_wait_cb(lv_display_t * disp);
|
||||
static lv_color_format_t get_lv_cf_from_layer_cf(uint32_t cf);
|
||||
static void reload_event_callback(LTDC_HandleTypeDef * hltdc);
|
||||
|
||||
#if LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
static void transfer_complete_callback(DMA2D_HandleTypeDef * hdma2d);
|
||||
static uint32_t get_dma2d_output_cf_from_layer_cf(uint32_t cf);
|
||||
static uint32_t get_dma2d_input_cf_from_lv_cf(uint32_t cf);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
static struct {
|
||||
bool disp_flushed_in_flush_cb[MAX_LAYER];
|
||||
sync_t sync[MAX_LAYER];
|
||||
volatile bool layer_interrupt_is_owned[MAX_LAYER];
|
||||
#if LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
volatile uint32_t dma2d_interrupt_owner; /*layer_idx + 1, or 0 for none*/
|
||||
#endif
|
||||
} g_data;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#if LV_USE_OS != LV_OS_NONE
|
||||
#define SYNC_INIT(layer_idx) lv_thread_sync_init(&g_data.sync[layer_idx])
|
||||
#define SYNC_WAIT(layer_idx) lv_thread_sync_wait(&g_data.sync[layer_idx])
|
||||
#define SYNC_SIGNAL_ISR(layer_idx) lv_thread_sync_signal_isr(&g_data.sync[layer_idx])
|
||||
#else
|
||||
#define SYNC_INIT(layer_idx) do { g_data.sync[layer_idx] = false; } while(0)
|
||||
#define SYNC_WAIT(layer_idx) do { while(!g_data.sync[layer_idx]); g_data.sync[layer_idx] = false; } while(0)
|
||||
#define SYNC_SIGNAL_ISR(layer_idx) do { g_data.sync[layer_idx] = true; } while(0)
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_st_ltdc_create_direct(void * fb_adr_1, void * fb_adr_2, uint32_t layer_idx)
|
||||
{
|
||||
return create(fb_adr_1, fb_adr_2, 0, layer_idx, LV_DISPLAY_RENDER_MODE_DIRECT);
|
||||
}
|
||||
|
||||
lv_display_t * lv_st_ltdc_create_partial(void * render_buf_1, void * render_buf_2, uint32_t buf_size,
|
||||
uint32_t layer_idx)
|
||||
{
|
||||
return create(render_buf_1, render_buf_2, buf_size, layer_idx, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_display_t * create(void * buf1, void * buf2, uint32_t buf_size, uint32_t layer_idx,
|
||||
lv_display_render_mode_t mode)
|
||||
{
|
||||
LTDC_LayerCfgTypeDef * layer_cfg = &hltdc.LayerCfg[layer_idx];
|
||||
uint32_t layer_width = layer_cfg->ImageWidth;
|
||||
uint32_t layer_height = layer_cfg->ImageHeight;
|
||||
uint32_t layer_cf = layer_cfg->PixelFormat;
|
||||
lv_color_format_t cf = get_lv_cf_from_layer_cf(layer_cf);
|
||||
|
||||
lv_display_t * disp = lv_display_create(layer_width, layer_height);
|
||||
lv_display_set_color_format(disp, cf);
|
||||
lv_display_set_flush_cb(disp, flush_cb);
|
||||
lv_display_set_flush_wait_cb(disp, flush_wait_cb);
|
||||
lv_display_set_driver_data(disp, (void *)(uintptr_t)layer_idx);
|
||||
|
||||
if(mode == LV_DISPLAY_RENDER_MODE_DIRECT) {
|
||||
uint32_t cf_size = lv_color_format_get_size(cf);
|
||||
lv_display_set_buffers(disp, buf1, buf2, layer_width * layer_height * cf_size, LV_DISPLAY_RENDER_MODE_DIRECT);
|
||||
|
||||
if(buf1 != NULL && buf2 != NULL) {
|
||||
HAL_LTDC_RegisterCallback(&hltdc, HAL_LTDC_RELOAD_EVENT_CB_ID, reload_event_callback);
|
||||
SYNC_INIT(layer_idx);
|
||||
}
|
||||
}
|
||||
else {
|
||||
lv_display_set_buffers(disp, buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
|
||||
#if LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
hdma2d.XferCpltCallback = transfer_complete_callback;
|
||||
SYNC_INIT(layer_idx);
|
||||
#endif
|
||||
}
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
|
||||
{
|
||||
uint32_t layer_idx = (uint32_t)(uintptr_t)lv_display_get_driver_data(disp);
|
||||
g_data.disp_flushed_in_flush_cb[layer_idx] = false;
|
||||
|
||||
if(disp->render_mode == LV_DISPLAY_RENDER_MODE_DIRECT) {
|
||||
if(lv_display_is_double_buffered(disp) && lv_display_flush_is_last(disp)) {
|
||||
HAL_LTDC_SetAddress_NoReload(&hltdc, (uint32_t)px_map, layer_idx);
|
||||
g_data.layer_interrupt_is_owned[layer_idx] = true;
|
||||
HAL_LTDC_Reload(&hltdc, LTDC_RELOAD_VERTICAL_BLANKING);
|
||||
}
|
||||
else {
|
||||
g_data.disp_flushed_in_flush_cb[layer_idx] = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LTDC_LayerCfgTypeDef * layer_cfg = &hltdc.LayerCfg[layer_idx];
|
||||
|
||||
lv_color_format_t cf = lv_display_get_color_format(disp);
|
||||
int32_t disp_width = lv_display_get_horizontal_resolution(disp);
|
||||
|
||||
uint8_t * fb = (uint8_t *) layer_cfg->FBStartAdress;
|
||||
uint32_t px_size = lv_color_format_get_size(cf);
|
||||
uint32_t fb_stride = px_size * disp_width;
|
||||
uint8_t * first_pixel = fb + fb_stride * area->y1 + px_size * area->x1;
|
||||
|
||||
int32_t area_width = lv_area_get_width(area);
|
||||
int32_t area_height = lv_area_get_height(area);
|
||||
|
||||
#if LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
uint32_t dma2d_input_cf = get_dma2d_input_cf_from_lv_cf(cf);
|
||||
uint32_t dma2d_output_cf = get_dma2d_output_cf_from_layer_cf(layer_cfg->PixelFormat);
|
||||
|
||||
while(DMA2D->CR & DMA2D_CR_START);
|
||||
DMA2D->FGPFCCR = dma2d_input_cf;
|
||||
DMA2D->FGMAR = (uint32_t)px_map;
|
||||
DMA2D->FGOR = 0;
|
||||
DMA2D->OPFCCR = dma2d_output_cf;
|
||||
DMA2D->OMAR = (uint32_t)first_pixel;
|
||||
DMA2D->OOR = disp_width - area_width;
|
||||
DMA2D->NLR = (area_width << DMA2D_NLR_PL_Pos) | (area_height << DMA2D_NLR_NL_Pos);
|
||||
g_data.dma2d_interrupt_owner = layer_idx + 1;
|
||||
DMA2D->CR = DMA2D_CR_START | DMA2D_CR_TCIE | (0x1U << DMA2D_CR_MODE_Pos); /* memory-to-memory with PFC */
|
||||
#else
|
||||
uint32_t area_stride = px_size * area_width;
|
||||
uint8_t * fb_p = first_pixel;
|
||||
uint8_t * px_map_p = px_map;
|
||||
for(int i = 0; i < area_height; i++) {
|
||||
lv_memcpy(fb_p, px_map_p, area_stride);
|
||||
fb_p += fb_stride;
|
||||
px_map_p += area_stride;
|
||||
}
|
||||
g_data.disp_flushed_in_flush_cb[layer_idx] = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void flush_wait_cb(lv_display_t * disp)
|
||||
{
|
||||
uint32_t layer_idx = (uint32_t)(uintptr_t)lv_display_get_driver_data(disp);
|
||||
if(!g_data.disp_flushed_in_flush_cb[layer_idx]) {
|
||||
SYNC_WAIT(layer_idx);
|
||||
}
|
||||
}
|
||||
|
||||
static lv_color_format_t get_lv_cf_from_layer_cf(uint32_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LTDC_PIXEL_FORMAT_ARGB8888:
|
||||
return LV_COLOR_FORMAT_ARGB8888;
|
||||
case LTDC_PIXEL_FORMAT_RGB888:
|
||||
return LV_COLOR_FORMAT_RGB888;
|
||||
case LTDC_PIXEL_FORMAT_RGB565:
|
||||
return LV_COLOR_FORMAT_RGB565;
|
||||
case LTDC_PIXEL_FORMAT_L8:
|
||||
return LV_COLOR_FORMAT_L8;
|
||||
case LTDC_PIXEL_FORMAT_AL88:
|
||||
return LV_COLOR_FORMAT_AL88;
|
||||
default:
|
||||
LV_ASSERT_MSG(0, "the LTDC color format is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
static void reload_event_callback(LTDC_HandleTypeDef * hltdc)
|
||||
{
|
||||
uint32_t i;
|
||||
for(i = 0; i < MAX_LAYER; i++) {
|
||||
if(g_data.layer_interrupt_is_owned[i]) {
|
||||
g_data.layer_interrupt_is_owned[i] = false;
|
||||
SYNC_SIGNAL_ISR(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
static void transfer_complete_callback(DMA2D_HandleTypeDef * hdma2d)
|
||||
{
|
||||
DMA2D->IFCR = 0x3FU;
|
||||
uint32_t owner = g_data.dma2d_interrupt_owner;
|
||||
if(owner) {
|
||||
g_data.dma2d_interrupt_owner = 0;
|
||||
owner -= 1;
|
||||
SYNC_SIGNAL_ISR(owner);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t get_dma2d_output_cf_from_layer_cf(uint32_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LTDC_PIXEL_FORMAT_ARGB8888:
|
||||
return DMA2D_OUTPUT_ARGB8888;
|
||||
case LTDC_PIXEL_FORMAT_RGB888:
|
||||
return DMA2D_OUTPUT_RGB888;
|
||||
case LTDC_PIXEL_FORMAT_RGB565:
|
||||
return DMA2D_OUTPUT_RGB565;
|
||||
default:
|
||||
LV_ASSERT_MSG(0, "DMA2D cannot output to the LTDC color format");
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t get_dma2d_input_cf_from_lv_cf(uint32_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
return DMA2D_INPUT_ARGB8888;
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
return DMA2D_INPUT_RGB888;
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
return DMA2D_INPUT_RGB565;
|
||||
case LV_COLOR_FORMAT_L8:
|
||||
return DMA2D_INPUT_L8;
|
||||
case LV_COLOR_FORMAT_AL88:
|
||||
return DMA2D_INPUT_AL88;
|
||||
case LV_COLOR_FORMAT_A8:
|
||||
return DMA2D_INPUT_A8;
|
||||
default:
|
||||
LV_ASSERT_MSG(0, "the LVGL color format is not a DMA2D input color format");
|
||||
}
|
||||
}
|
||||
#endif /*LV_ST_LTDC_USE_DMA2D_FLUSH*/
|
||||
|
||||
#endif /*LV_USE_ST_LTDC*/
|
65
src/drivers/display/st_ltdc/lv_st_ltdc.h
Normal file
65
src/drivers/display/st_ltdc/lv_st_ltdc.h
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @file lv_st_ltdc.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_ST_LTDC_H
|
||||
#define LV_ST_LTDC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
#if LV_USE_ST_LTDC
|
||||
|
||||
#include "../../../display/lv_display.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a direct render mode display bound to a LTDC layer.
|
||||
* @param fb_adr_1 The LTDC layer's framebuffer memory address.
|
||||
* @param fb_adr_2 An additional framebuffer-sized buffer to use for double buffering, or `NULL`.
|
||||
* @param layer_idx The LTDC layer number to bind the display to. Typically 0 or 1.
|
||||
* @return The display.
|
||||
*/
|
||||
lv_display_t * lv_st_ltdc_create_direct(void * fb_adr_1, void * fb_adr_2, uint32_t layer_idx);
|
||||
|
||||
/**
|
||||
* Create a partial render mode display bound to a LTDC layer. The layer's framebuffer is flushed to internally.
|
||||
* Enable `LV_ST_LTDC_USE_DMA2D_FLUSH` for parallel flushing.
|
||||
* @param render_buf_1 A render buffer.
|
||||
* @param render_buf_2 An additional render buffer for double-buffering, or `NULL`.
|
||||
* @param buf_size The size of the buffer(s) in bytes.
|
||||
* @param layer_idx The LTDC layer number to bind the display to. Typically 0 or 1.
|
||||
* @return The display.
|
||||
*/
|
||||
lv_display_t * lv_st_ltdc_create_partial(void * render_buf_1, void * render_buf_2, uint32_t buf_size,
|
||||
uint32_t layer_idx);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_ST_LTDC*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_ST_LTDC_H*/
|
@ -32,6 +32,7 @@ extern "C" {
|
||||
#include "display/st7796/lv_st7796.h"
|
||||
|
||||
#include "display/renesas_glcdc/lv_renesas_glcdc.h"
|
||||
#include "display/st_ltdc/lv_st_ltdc.h"
|
||||
|
||||
#include "nuttx/lv_nuttx_entry.h"
|
||||
#include "nuttx/lv_nuttx_fbdev.h"
|
||||
|
@ -3746,6 +3746,25 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Driver for ST LTDC */
|
||||
#ifndef LV_USE_ST_LTDC
|
||||
#ifdef CONFIG_LV_USE_ST_LTDC
|
||||
#define LV_USE_ST_LTDC CONFIG_LV_USE_ST_LTDC
|
||||
#else
|
||||
#define LV_USE_ST_LTDC 0
|
||||
#endif
|
||||
#endif
|
||||
#if LV_USE_ST_LTDC
|
||||
/* Only used for partial. */
|
||||
#ifndef LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
#ifdef CONFIG_LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
#define LV_ST_LTDC_USE_DMA2D_FLUSH CONFIG_LV_ST_LTDC_USE_DMA2D_FLUSH
|
||||
#else
|
||||
#define LV_ST_LTDC_USE_DMA2D_FLUSH 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** LVGL Windows backend */
|
||||
#ifndef LV_USE_WINDOWS
|
||||
#ifdef CONFIG_LV_USE_WINDOWS
|
||||
|
Loading…
Reference in New Issue
Block a user