Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update PlatformIO demo to LVGL9.1 #64

Merged
merged 4 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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())
Loading