Skip to content

Commit

Permalink
Update to LVGL9.1 (lvgl#64)
Browse files Browse the repository at this point in the history
* Update PlatformIO demo to LVGL9.1

* Update ci.yml

Trying to fix a 
```
Run actions/setup-python@v1
Error: Version 3.x with arch x64 not found
```
failure on MacOS

* Add a build script that automatically tries to adjust SDL2 include and library paths. Fixes compilation failure on MacOS 14
  • Loading branch information
zmeiresearch authored May 13, 2024
1 parent b68b2d8 commit 172aa55
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 92 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: CI
on:
push:
pull_request:
workflow_dispatch:
schedule:
- cron: '0 0 * * 3'

Expand Down Expand Up @@ -61,7 +62,7 @@ jobs:
HOMEBREW_NO_AUTO_UPDATE=1 brew install sdl2
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
- uses: actions/setup-python@v5

- name: Install PlatformIO
run: |
Expand Down
74 changes: 28 additions & 46 deletions hal/sdl2/app_hal.c
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
#include <unistd.h>
#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/
#include <SDL2/SDL.h>
#include "display/monitor.h"
#include "indev/mouse.h"
#include "indev/mousewheel.h"
#include "indev/keyboard.h"
#include "sdl/sdl.h"
#include "drivers/sdl/lv_sdl_mouse.h"
#include "drivers/sdl/lv_sdl_mousewheel.h"
#include "drivers/sdl/lv_sdl_keyboard.h"


/**
* A task to measure the elapsed time for LittlevGL
* @param data unused
* @return never return
*/
static int tick_thread(void * data)
{
(void)data;

while(1) {
SDL_Delay(5); /*Sleep for 5 millisecond*/
lv_tick_inc(5); /*Tell LittelvGL that 5 milliseconds were elapsed*/
}

return 0;
static lv_display_t *lvDisplay;
static lv_indev_t *lvMouse;
static lv_indev_t *lvMouseWheel;
static lv_indev_t *lvKeyboard;


#if LV_USE_LOG != 0
static void lv_log_print_g_cb(lv_log_level_t level, const char * buf)
{
LV_UNUSED(level);
LV_UNUSED(buf);
}
#endif


void hal_setup(void)
Expand All @@ -34,43 +31,28 @@ void hal_setup(void)
setenv("DBUS_FATAL_WARNINGS", "0", 1);
#endif

#if LV_USE_LOG != 0
lv_log_register_print_cb(lv_log_print_g_cb);
#endif

/* Add a display
* Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/

static lv_disp_draw_buf_t disp_buf;
static lv_color_t buf[SDL_HOR_RES * 10]; /*Declare a buffer for 10 lines*/
lv_disp_draw_buf_init(&disp_buf, buf, NULL, SDL_HOR_RES * 10); /*Initialize the display buffer*/

static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
disp_drv.flush_cb = sdl_display_flush; /*Used when `LV_VDB_SIZE != 0` in lv_conf.h (buffered drawing)*/
disp_drv.draw_buf = &disp_buf;
disp_drv.hor_res = SDL_HOR_RES;
disp_drv.ver_res = SDL_VER_RES;
//disp_drv.disp_fill = monitor_fill; /*Used when `LV_VDB_SIZE == 0` in lv_conf.h (unbuffered drawing)*/
//disp_drv.disp_map = monitor_map; /*Used when `LV_VDB_SIZE == 0` in lv_conf.h (unbuffered drawing)*/
lv_disp_drv_register(&disp_drv);

/* Add the mouse as input device
* Use the 'mouse' driver which reads the PC's mouse*/
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Basic initialization*/
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = sdl_mouse_read; /*This function will be called periodically (by the library) to get the mouse position and state*/
lv_indev_drv_register(&indev_drv);

sdl_init();

/* Tick init.
* You have to call 'lv_tick_inc()' in periodically to inform LittelvGL about how much time were elapsed
* Create an SDL thread to do this*/
SDL_CreateThread(tick_thread, "tick", NULL);
lvDisplay = lv_sdl_window_create(SDL_HOR_RES, SDL_VER_RES);
lvMouse = lv_sdl_mouse_create();
lvMouseWheel = lv_sdl_mousewheel_create();
lvKeyboard = lv_sdl_keyboard_create();
}

void hal_loop(void)
{
Uint32 lastTick = SDL_GetTicks();
while(1) {
SDL_Delay(5);
lv_task_handler();
Uint32 current = SDL_GetTicks();
lv_tick_inc(current - lastTick); // Update the tick timer. Tick is new for LVGL 9
lastTick = current;
lv_timer_handler(); // Update the UI-
}
}
74 changes: 48 additions & 26 deletions hal/stm32f429_disco/tft.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <string.h>

#include "tft.h"
#include <lvgl.h>
#include "stm32f4xx.h"
#include "stm32f429i_discovery_lcd.h"
#include "ili9341.h"
Expand All @@ -19,6 +20,8 @@

#define SDRAM_BANK_ADDR ((uint32_t)0xD0000000)

#define LV_BUFFER_SIZE (TFT_HOR_RES * TFT_VER_RES / 8 * (LV_COLOR_DEPTH / 8))

#define DMA_STREAM DMA2_Stream0
#define DMA_CHANNEL DMA_CHANNEL_0
#define DMA_STREAM_IRQ DMA2_Stream0_IRQn
Expand All @@ -32,7 +35,7 @@
* STATIC PROTOTYPES
**********************/

static void tft_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p);
static void tft_flush(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);

/**********************
* STATIC VARIABLES
Expand All @@ -55,18 +58,22 @@ static void DMA_TransferComplete(DMA_HandleTypeDef *han);
static void DMA_TransferError(DMA_HandleTypeDef *han);

DMA_HandleTypeDef DmaHandle;
static lv_disp_drv_t disp_drv;
static lv_display_t * lvDisplay;

static uint8_t lvBuffer[LV_BUFFER_SIZE];
static int32_t x1_flush;
static int32_t y1_flush;
static int32_t x2_flush;
static int32_t y2_fill;
static int32_t y_fill_act;
static const lv_color_t *buf_to_flush;
static const uint8_t *buf_to_flush;

/**********************
* MACROS
**********************/



/**********************
* GLOBAL FUNCTIONS
**********************/
Expand All @@ -75,32 +82,47 @@ static const lv_color_t *buf_to_flush;
*/
void tft_init(void)
{
static lv_color_t disp_buf1[TFT_HOR_RES * 40];
static lv_disp_draw_buf_t buf;
lv_disp_draw_buf_init(&buf, disp_buf1, NULL, TFT_HOR_RES * 40);

lv_disp_drv_init(&disp_drv);

BSP_LCD_Init();
BSP_LCD_LayerDefaultInit(0, (uint32_t)my_fb);
HAL_LTDC_SetPixelFormat(&LtdcHandler, LTDC_PIXEL_FORMAT_RGB565, 0);
DMA_Config();
disp_drv.draw_buf = &buf;
disp_drv.flush_cb = tft_flush;
disp_drv.hor_res = TFT_HOR_RES;
disp_drv.ver_res = TFT_VER_RES;
#if TFT_USE_GPU != 0
DMA2D_Config();
disp_drv.gpu_blend_cb = gpu_mem_blend;
disp_drv.gpu_fill_cb = gpu_mem_fill;
#endif
lv_disp_drv_register(&disp_drv);
#if LV_USE_LOG != 0
lv_log_register_print_cb(lv_log_print_g_cb);
#endif

lvDisplay = lv_display_create(TFT_HOR_RES, TFT_VER_RES);
if (lvDisplay)
{
BSP_LCD_Init();
BSP_LCD_LayerDefaultInit(0, (uint32_t)my_fb);
HAL_LTDC_SetPixelFormat(&LtdcHandler, LTDC_PIXEL_FORMAT_RGB565, 0);
DMA_Config();

lv_display_set_color_format(lvDisplay, LV_COLOR_FORMAT_RGB565);
lv_display_set_flush_cb(lvDisplay, tft_flush);
lv_display_set_buffers(lvDisplay, lvBuffer, NULL, LV_BUFFER_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL);

#if TFT_USE_GPU != 0
DMA2D_Config();
disp_drv.gpu_blend_cb = gpu_mem_blend;
disp_drv.gpu_fill_cb = gpu_mem_fill;
#endif
}
}

/**********************
* STATIC FUNCTIONS
**********************/

/**
* LVGL Log print callback
* @param level log message level
* @param buf string to print
*/
#if LV_USE_LOG != 0
static void lv_log_print_g_cb(lv_log_level_t level, const char * buf)
{
LV_UNUSED(level);
LV_UNUSED(buf);
}
#endif

/**
* Flush a color buffer
* @param x1 left coordinate of the rectangle
Expand All @@ -109,7 +131,7 @@ void tft_init(void)
* @param y2 bottom coordinate of the rectangle
* @param color_p pointer to an array of colors
*/
static void tft_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p)
static void tft_flush(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
{
/*Return if the area is out the screen*/
if (area->x2 < 0)
Expand All @@ -132,7 +154,7 @@ static void tft_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *col
x2_flush = act_x2;
y2_fill = act_y2;
y_fill_act = act_y1;
buf_to_flush = color_p;
buf_to_flush = px_map;

/*##-7- Start the DMA transfer using the interrupt mode #*/
/* Configure the source, destination and buffer size DMA fields and Start DMA Stream transfer */
Expand Down Expand Up @@ -197,7 +219,7 @@ static void DMA_TransferComplete(DMA_HandleTypeDef *han)

if (y_fill_act > y2_fill)
{
lv_disp_flush_ready(&disp_drv);
lv_disp_flush_ready(lvDisplay);
}
else
{
Expand Down
12 changes: 5 additions & 7 deletions hal/stm32f429_disco/touchpad.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
/**********************
* STATIC PROTOTYPES
**********************/
static void touchpad_read(lv_indev_drv_t * drv, lv_indev_data_t *data);
static void touchpad_read(lv_indev_t * drv, lv_indev_data_t *data);
static bool touchpad_get_xy(int16_t *x, int16_t *y);

/**********************
Expand All @@ -47,11 +47,9 @@ void touchpad_init(void)
stmpe811_Init(TS_I2C_ADDRESS);
stmpe811_TS_Start(TS_I2C_ADDRESS);

lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.read_cb = touchpad_read;
indev_drv.type = LV_INDEV_TYPE_POINTER;
lv_indev_drv_register(&indev_drv);
lv_indev_t * indev_drv = lv_indev_create();
lv_indev_set_read_cb(indev_drv, touchpad_read);
lv_indev_set_type(indev_drv, LV_INDEV_TYPE_POINTER);
}

/**********************
Expand All @@ -65,7 +63,7 @@ void touchpad_init(void)
* @param y put the y coordinate here
* @return true: the device is pressed, false: released
*/
static void touchpad_read(lv_indev_drv_t * drv, lv_indev_data_t *data)
static void touchpad_read(lv_indev_t * dev, lv_indev_data_t *data)
{
static int16_t last_x = 0;
static int16_t last_y = 0;
Expand Down
18 changes: 6 additions & 12 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ build_flags =
; Add more defines below to overide lvgl:/src/lv_conf_simple.h
lib_deps =
; Use direct URL, because package registry is unstable
;lvgl@~7.11.0
lvgl=https://github.com/lvgl/lvgl/archive/refs/tags/v8.2.0.zip
[email protected]
lib_archive = false


[env:emulator_64bits]
platform = native@^1.1.3
extra_scripts = support/sdl2_build_extra.py
extra_scripts =
pre:support/sdl2_paths.py ; Tries to find SDL2 include and lib paths on your system - specifically for MacOS w/ Homebrew
post:support/sdl2_build_extra.py
build_flags =
${env.build_flags}
; -D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO
Expand All @@ -40,25 +41,18 @@ build_flags =
; SDL drivers options
-D LV_LVGL_H_INCLUDE_SIMPLE
-D LV_DRV_NO_CONF
-D USE_SDL
-D LV_USE_SDL
-D SDL_HOR_RES=480
-D SDL_VER_RES=320
-D SDL_ZOOM=1
-D SDL_INCLUDE_PATH="\"SDL2/SDL.h\""
-D LV_SDL_INCLUDE_PATH="\"SDL2/SDL.h\""

; LVGL memory options, setup for the demo to run properly
-D LV_MEM_CUSTOM=1
-D LV_MEM_SIZE="(128U * 1024U)"

; SDL2 includes, uncomment the next two lines on MAC OS if you intalled sdl via homebrew
; !find /opt/homebrew/Cellar/sdl2 -name "include" | sed "s/^/-I /"
; !find /opt/homebrew/Cellar/sdl2 -name "libSDL2.a" | xargs dirname | sed "s/^/-L /"

lib_deps =
${env.lib_deps}
; Use direct URL, because package registry is unstable
;lv_drivers@~7.9.0
lv_drivers=https://github.com/lvgl/lv_drivers/archive/refs/tags/v8.2.0.zip
build_src_filter =
+<*>
+<../hal/sdl2>
Expand Down
27 changes: 27 additions & 0 deletions support/sdl2_paths.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Import("env")
import sys
import os
import glob

if sys.platform.startswith("darwin"):
#sdl_include_path = !find /opt/homebrew/Cellar/sdl2 -name "include" | sed "s/^/-I /"
sdl_include = glob.glob("/opt/homebrew/Cellar/sdl2/*/include", recursive=True)
if sdl_include:
print(f"Found Homebrew SDL include path: {sdl_include[0]}")
env.Append(
CPPPATH=sdl_include[0]
)
sdl_lib = glob.glob("/opt/homebrew/Cellar/sdl2/**/libSDL2.a", recursive=True)
if sdl_lib:
print(f"Found Homebrew SDL lib path: {sdl_lib[0]}")
env.Append(
LIBPATH=os.path.dirname(sdl_lib[0])
)


#breakpoint()

#print('NewENV=====================================')
#print(env.Dump())
#print('DefaultENV=====================================')
#print(DefaultEnvironment().Dump())

0 comments on commit 172aa55

Please sign in to comment.