feat(display): initial lovyan integration (#8630)

This commit is contained in:
Felix Biego
2025-09-04 21:49:08 +03:00
committed by GitHub
parent 323204d314
commit a00fda00eb
8 changed files with 303 additions and 3 deletions
+8
View File
@@ -2075,6 +2075,14 @@ menu "LVGL configuration"
bool "Use TFT_eSPI driver"
default n
config LV_USE_LOVYAN_GFX
bool "Use LovyanGFX driver"
default n
config LV_LGFX_USER_INCLUDE
string "Header for LovyanGFX user configuration"
default "lv_lgfx_user.hpp"
depends on LV_USE_LOVYAN_GFX
config LV_USE_EVDEV
bool "Use evdev input driver"
default n
@@ -23,9 +23,29 @@ library folder.
Set up drivers
--------------
To get started it's recommended to use `TFT_eSPI <https://github.com/Bodmer/TFT_eSPI>`__ library as a TFT
driver to simplify testing. To make it work, setup ``TFT_eSPI``
according to your TFT display type via editing either:
To get started, the recommended option is to use the LovyanGFX
library as the TFT driver, since it makes testing much easier.
Youll need to create a display configuration file, such as ``my_display.hpp``
similar to the example in `LovyanGFX user_setting.ino <https://github.com/lovyan03/LovyanGFX/blob/master/examples/HowToUse/2_user_setting/2_user_setting.ino>`__
In the Arduino IDE, you can create a new tab and name it ``my_display.hpp`` and paste the content of your configuration file there.
If you prefer not to use LovyanGFX, you can integrate other graphics libraries as well by implementing a wrapper class in the same way LovyanGFX is handled;
`lv_lgfx_user.hpp <https://github.com/lvgl/lvgl/blob/master/src/drivers/display/lovyan_gfx/lv_lgfx_user.hpp>`__
provides a good example of this. Once your configuration file
is ready, update ``lv_conf.h`` to include it, for example:
.. code-block:: c
/* Interface for Lovyan_GFX */
#define LV_USE_LOVYAN_GFX 1
#if LV_USE_LOVYAN_GFX
#define LV_LGFX_USER_INCLUDE "my_display.hpp"
#endif /*LV_USE_LOVYAN_GFX*/
Alternatively, you can use `TFT_eSPI <https://github.com/Bodmer/TFT_eSPI>`__ library.
To make it work, set up ``TFT_eSPI`` according to your
TFT display type via editing either:
- ``User_Setup.h``
- or by selecting a configuration in the ``User_Setup_Select.h``
+8
View File
@@ -1314,6 +1314,14 @@
/** Interface for TFT_eSPI */
#define LV_USE_TFT_ESPI 0
/** Interface for Lovyan_GFX */
#define LV_USE_LOVYAN_GFX 0
#if LV_USE_LOVYAN_GFX
#define LV_LGFX_USER_INCLUDE "lv_lgfx_user.hpp"
#endif /*LV_USE_LOVYAN_GFX*/
/** Driver for evdev input devices */
#define LV_USE_EVDEV 0
@@ -0,0 +1,53 @@
#pragma once
#if LV_USE_LOVYAN_GFX
/**
* If using LovyanGFX create LGFX class that inherits from lgfx::LGFX_Device
* https://github.com/lovyan03/LovyanGFX/blob/master/examples/HowToUse/2_user_setting/2_user_setting.ino */
/**
* If using other display drivers that is not LovyanGFX
* Create an LGFX wrapper class that implements the functions used in lv_lovyan_gfx.cpp */
class LGFX
{
public:
LGFX(void) {}
bool init(void)
{
return true;
}
void initDMA(void) {}
void waitDMA(void) {}
void fillScreen(uint16_t color) {}
void setRotation(uint8_t rotation) {}
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data) {}
void pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data) {}
void startWrite(void) {}
uint32_t getStartCount(void)
{
return 0;
}
void endWrite(void) {}
void setBrightness(uint8_t brightness){}
void writePixel(int32_t x, int32_t y, const uint16_t color) {}
bool getTouch(uint16_t *x, uint16_t *y)
{
return false;
}
};
#endif
@@ -0,0 +1,145 @@
/**
* @file lv_lovyan_gfx.cpp
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_lovyan_gfx.h"
#if LV_USE_LOVYAN_GFX
#include LV_LGFX_USER_INCLUDE
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct {
LGFX * tft;
} lv_lovyan_gfx_t;
/**********************
* STATIC PROTOTYPES
**********************/
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
static void resolution_changed_event_cb(lv_event_t * e);
static void read_touch(lv_indev_t * indev_driver, lv_indev_data_t * data);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
lv_display_t * lv_lovyan_gfx_create(uint32_t hor_res, uint32_t ver_res, void * buf, uint32_t buf_size_bytes, bool touch)
{
lv_lovyan_gfx_t * dsc = (lv_lovyan_gfx_t *)lv_malloc_zeroed(sizeof(lv_lovyan_gfx_t));
LV_ASSERT_MALLOC(dsc);
if(dsc == NULL) return NULL;
lv_display_t * disp = lv_display_create(hor_res, ver_res);
if(disp == NULL) {
lv_free(dsc);
return NULL;
}
dsc->tft = new LGFX();
dsc->tft->init(); /* TFT init */
dsc->tft->initDMA();
dsc->tft->setRotation(0);
dsc->tft->setBrightness(255);
dsc->tft->startWrite();
dsc->tft->fillScreen(0x00000);
lv_display_set_driver_data(disp, (void *)dsc);
lv_display_set_flush_cb(disp, flush_cb);
lv_display_set_color_format(disp, LV_COLOR_FORMAT_RGB565_SWAPPED);
lv_display_add_event_cb(disp, resolution_changed_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL);
lv_display_set_buffers(disp, (void *)buf, NULL, buf_size_bytes, LV_DISPLAY_RENDER_MODE_PARTIAL);
if(touch) {
/* Register an input device when touch is enabled */
lv_indev_t * lv_input = lv_indev_create();
lv_indev_set_driver_data(lv_input, (void *)dsc);
lv_indev_set_type(lv_input, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(lv_input, read_touch);
}
return disp;
}
/**********************
* STATIC FUNCTIONS
**********************/
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
{
lv_lovyan_gfx_t * dsc = (lv_lovyan_gfx_t *)lv_display_get_driver_data(disp);
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
if(dsc->tft->getStartCount() == 0) {
dsc->tft->endWrite();
}
dsc->tft->pushImageDMA(area->x1, area->y1, w, h, (uint16_t *)px_map);
dsc->tft->waitDMA();
lv_display_flush_ready(disp);
}
static void resolution_changed_event_cb(lv_event_t * e)
{
lv_display_t * disp = (lv_display_t *)lv_event_get_target(e);
lv_lovyan_gfx_t * dsc = (lv_lovyan_gfx_t *)lv_display_get_driver_data(disp);
int32_t hor_res = lv_display_get_horizontal_resolution(disp);
int32_t ver_res = lv_display_get_vertical_resolution(disp);
lv_display_rotation_t rot = lv_display_get_rotation(disp);
/* handle rotation */
switch(rot) {
case LV_DISPLAY_ROTATION_0:
dsc->tft->setRotation(0); /* Portrait orientation */
break;
case LV_DISPLAY_ROTATION_90:
dsc->tft->setRotation(1); /* Landscape orientation */
break;
case LV_DISPLAY_ROTATION_180:
dsc->tft->setRotation(2); /* Portrait orientation, flipped */
break;
case LV_DISPLAY_ROTATION_270:
dsc->tft->setRotation(3); /* Landscape orientation, flipped */
break;
}
}
static void read_touch(lv_indev_t * indev_driver, lv_indev_data_t * data)
{
lv_lovyan_gfx_t * dsc = (lv_lovyan_gfx_t *)lv_indev_get_driver_data(indev_driver);
uint16_t x;
uint16_t y;
bool touched = dsc->tft->getTouch(&x, &y);
if(!touched) {
data->state = LV_INDEV_STATE_RELEASED;
}
else {
data->state = LV_INDEV_STATE_PRESSED;
/*Set the coordinates*/
data->point.x = x;
data->point.y = y;
}
}
#endif /*LV_USE_LOVYAN_GFX*/
@@ -0,0 +1,45 @@
/**
* @file lv_lovyan_gfx.h
*
*/
#ifndef LV_LOVYAN_GFX_H
#define LV_LOVYAN_GFX_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../../display/lv_display.h"
#include "../../../indev/lv_indev.h"
#if LV_USE_LOVYAN_GFX
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
lv_display_t * lv_lovyan_gfx_create(uint32_t hor_res, uint32_t ver_res, void * buf, uint32_t buf_size_bytes,
bool touch);
/**********************
* MACROS
**********************/
#endif /* LV_USE_LOVYAN_GFX */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LV_LOVYAN_GFX_H */
+1
View File
@@ -24,6 +24,7 @@ extern "C" {
#include "display/fb/lv_linux_fbdev.h"
#include "display/tft_espi/lv_tft_espi.h"
#include "display/lovyan_gfx/lv_lovyan_gfx.h"
#include "display/lcd/lv_lcd_generic_mipi.h"
#include "display/ili9341/lv_ili9341.h"
+20
View File
@@ -4219,6 +4219,26 @@
#endif
#endif
/** Interface for Lovyan_GFX */
#ifndef LV_USE_LOVYAN_GFX
#ifdef CONFIG_LV_USE_LOVYAN_GFX
#define LV_USE_LOVYAN_GFX CONFIG_LV_USE_LOVYAN_GFX
#else
#define LV_USE_LOVYAN_GFX 0
#endif
#endif
#if LV_USE_LOVYAN_GFX
#ifndef LV_LGFX_USER_INCLUDE
#ifdef CONFIG_LV_LGFX_USER_INCLUDE
#define LV_LGFX_USER_INCLUDE CONFIG_LV_LGFX_USER_INCLUDE
#else
#define LV_LGFX_USER_INCLUDE "lv_lgfx_user.hpp"
#endif
#endif
#endif /*LV_USE_LOVYAN_GFX*/
/** Driver for evdev input devices */
#ifndef LV_USE_EVDEV
#ifdef CONFIG_LV_USE_EVDEV