mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-10 04:37:55 +08:00
feat(display): initial lovyan integration (#8630)
This commit is contained in:
@@ -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.
|
||||
You’ll 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``
|
||||
|
||||
@@ -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 */
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user