modules: lvgl: Move gluecode back to zephyr main repo
Moves back the module specific gluecode into the main repository Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
This commit is contained in:
parent
81650746f7
commit
2e2163c1bc
|
@ -3164,7 +3164,7 @@ West:
|
|||
- brgl
|
||||
- pdgendt
|
||||
files:
|
||||
- modules/Kconfig.lvgl
|
||||
- modules/lvgl/
|
||||
- tests/lib/gui/lvgl/
|
||||
labels:
|
||||
- manifest-lvgl
|
||||
|
|
|
@ -24,7 +24,7 @@ source "modules/Kconfig.esp32"
|
|||
source "modules/Kconfig.imx"
|
||||
source "modules/Kconfig.infineon"
|
||||
source "modules/Kconfig.libmetal"
|
||||
source "modules/Kconfig.lvgl"
|
||||
source "modules/lvgl/Kconfig"
|
||||
source "modules/Kconfig.mcux"
|
||||
source "modules/Kconfig.microchip"
|
||||
source "modules/Kconfig.nuvoton"
|
||||
|
@ -105,6 +105,9 @@ comment "THRIFT module not available."
|
|||
comment "Segger module not available."
|
||||
depends on !ZEPHYR_SEGGER_MODULE
|
||||
|
||||
comment "LVGL module not available."
|
||||
depends on !ZEPHYR_LVGL_MODULE
|
||||
|
||||
# This ensures that symbols are available in Kconfig for dependency checking
|
||||
# and referencing, while keeping the settings themselves unavailable when the
|
||||
# modules are not present in the workspace
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
# Copyright (c) 2022 Huawei Inc.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config LVGL
|
||||
bool "LVGL GUI library"
|
||||
help
|
||||
This option enables the LVGL GUI library.
|
||||
|
||||
if LVGL
|
||||
|
||||
config LV_DPI_DEF
|
||||
int
|
||||
|
||||
config LV_Z_BITS_PER_PIXEL
|
||||
int
|
||||
|
||||
config LV_Z_DOUBLE_VDB
|
||||
bool
|
||||
|
||||
config LV_Z_FULL_REFRESH
|
||||
bool
|
||||
|
||||
config LV_Z_VBD_CUSTOM_SECTION
|
||||
bool
|
||||
|
||||
config LV_Z_VDB_ALIGN
|
||||
int
|
||||
|
||||
config LV_Z_VDB_SIZE
|
||||
int
|
||||
|
||||
config LV_Z_POINTER_KSCAN
|
||||
bool
|
||||
|
||||
config LV_Z_POINTER_KSCAN_MSGQ_COUNT
|
||||
int
|
||||
default 10
|
||||
|
||||
config LV_Z_POINTER_KSCAN_SWAP_XY
|
||||
bool
|
||||
|
||||
config LV_Z_POINTER_KSCAN_INVERT_X
|
||||
bool
|
||||
|
||||
config LV_Z_POINTER_KSCAN_INVERT_Y
|
||||
bool
|
||||
|
||||
choice LV_COLOR_DEPTH
|
||||
default LV_COLOR_DEPTH_16
|
||||
prompt "Color depth (bits per pixel)"
|
||||
depends on LVGL
|
||||
|
||||
config LV_COLOR_DEPTH_32
|
||||
bool "32: ARGB8888"
|
||||
config LV_COLOR_DEPTH_16
|
||||
bool "16: RGB565"
|
||||
config LV_COLOR_DEPTH_8
|
||||
bool "8: RGB232"
|
||||
config LV_COLOR_DEPTH_1
|
||||
bool "1: monochrome"
|
||||
endchoice
|
||||
|
||||
config LV_COLOR_16_SWAP
|
||||
bool
|
||||
|
||||
endif
|
229
modules/lvgl/CMakeLists.txt
Normal file
229
modules/lvgl/CMakeLists.txt
Normal file
|
@ -0,0 +1,229 @@
|
|||
# Copyright (c) 2019 jan.van_winkel@dxplore.eu
|
||||
# Copyright (c) 2020 Teslabs Engineering S.L.
|
||||
# Copyright (c) 2023 Fabian Blatz <fabianblatz@gmail.com>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if(CONFIG_LVGL)
|
||||
|
||||
set(ZEPHYR_CURRENT_LIBRARY lvgl)
|
||||
set(LVGL_DIR ${ZEPHYR_LVGL_MODULE_DIR})
|
||||
|
||||
zephyr_interface_library_named(LVGL)
|
||||
zephyr_library()
|
||||
|
||||
zephyr_include_directories(${LVGL_DIR}/src/)
|
||||
zephyr_include_directories(.)
|
||||
|
||||
zephyr_compile_definitions(LV_CONF_INCLUDE_SIMPLE=1)
|
||||
zephyr_compile_definitions(LV_CONF_PATH=${CMAKE_CURRENT_SOURCE_DIR}/lv_conf.h)
|
||||
|
||||
zephyr_library_sources(
|
||||
${LVGL_DIR}/src/core/lv_disp.c
|
||||
${LVGL_DIR}/src/core/lv_event.c
|
||||
${LVGL_DIR}/src/core/lv_group.c
|
||||
${LVGL_DIR}/src/core/lv_indev.c
|
||||
${LVGL_DIR}/src/core/lv_indev_scroll.c
|
||||
${LVGL_DIR}/src/core/lv_obj.c
|
||||
${LVGL_DIR}/src/core/lv_obj_class.c
|
||||
${LVGL_DIR}/src/core/lv_obj_draw.c
|
||||
${LVGL_DIR}/src/core/lv_obj_pos.c
|
||||
${LVGL_DIR}/src/core/lv_obj_scroll.c
|
||||
${LVGL_DIR}/src/core/lv_obj_style.c
|
||||
${LVGL_DIR}/src/core/lv_obj_style_gen.c
|
||||
${LVGL_DIR}/src/core/lv_obj_tree.c
|
||||
${LVGL_DIR}/src/core/lv_refr.c
|
||||
${LVGL_DIR}/src/core/lv_theme.c
|
||||
|
||||
${LVGL_DIR}/src/draw/arm2d/lv_gpu_arm2d.c
|
||||
${LVGL_DIR}/src/draw/lv_draw.c
|
||||
${LVGL_DIR}/src/draw/lv_draw_arc.c
|
||||
${LVGL_DIR}/src/draw/lv_draw_img.c
|
||||
${LVGL_DIR}/src/draw/lv_draw_label.c
|
||||
${LVGL_DIR}/src/draw/lv_draw_layer.c
|
||||
${LVGL_DIR}/src/draw/lv_draw_line.c
|
||||
${LVGL_DIR}/src/draw/lv_draw_mask.c
|
||||
${LVGL_DIR}/src/draw/lv_draw_rect.c
|
||||
${LVGL_DIR}/src/draw/lv_draw_transform.c
|
||||
${LVGL_DIR}/src/draw/lv_draw_triangle.c
|
||||
${LVGL_DIR}/src/draw/lv_img_buf.c
|
||||
${LVGL_DIR}/src/draw/lv_img_cache.c
|
||||
${LVGL_DIR}/src/draw/lv_img_decoder.c
|
||||
${LVGL_DIR}/src/draw/nxp/pxp/lv_draw_pxp_blend.c
|
||||
${LVGL_DIR}/src/draw/nxp/pxp/lv_gpu_nxp_pxp.c
|
||||
${LVGL_DIR}/src/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.c
|
||||
${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_arc.c
|
||||
${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_blend.c
|
||||
${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_rect.c
|
||||
${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_arc.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_bg.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_composite.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_img.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_label.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_layer.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_line.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_mask.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_polygon.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_rect.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_stack_blur.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_texture_cache.c
|
||||
${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_utils.c
|
||||
${LVGL_DIR}/src/draw/stm32_dma2d/lv_gpu_stm32_dma2d.c
|
||||
${LVGL_DIR}/src/draw/sw/lv_draw_sw.c
|
||||
${LVGL_DIR}/src/draw/sw/lv_draw_sw_arc.c
|
||||
${LVGL_DIR}/src/draw/sw/lv_draw_sw_blend.c
|
||||
${LVGL_DIR}/src/draw/sw/lv_draw_sw_dither.c
|
||||
${LVGL_DIR}/src/draw/sw/lv_draw_sw_gradient.c
|
||||
${LVGL_DIR}/src/draw/sw/lv_draw_sw_img.c
|
||||
${LVGL_DIR}/src/draw/sw/lv_draw_sw_layer.c
|
||||
${LVGL_DIR}/src/draw/sw/lv_draw_sw_letter.c
|
||||
${LVGL_DIR}/src/draw/sw/lv_draw_sw_line.c
|
||||
${LVGL_DIR}/src/draw/sw/lv_draw_sw_polygon.c
|
||||
${LVGL_DIR}/src/draw/sw/lv_draw_sw_rect.c
|
||||
${LVGL_DIR}/src/draw/sw/lv_draw_sw_transform.c
|
||||
${LVGL_DIR}/src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.c
|
||||
|
||||
${LVGL_DIR}/src/extra/layouts/flex/lv_flex.c
|
||||
${LVGL_DIR}/src/extra/layouts/grid/lv_grid.c
|
||||
${LVGL_DIR}/src/extra/libs/bmp/lv_bmp.c
|
||||
${LVGL_DIR}/src/extra/libs/ffmpeg/lv_ffmpeg.c
|
||||
${LVGL_DIR}/src/extra/libs/freetype/lv_freetype.c
|
||||
${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_fatfs.c
|
||||
${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_posix.c
|
||||
${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_stdio.c
|
||||
${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_win32.c
|
||||
${LVGL_DIR}/src/extra/libs/gif/gifdec.c
|
||||
${LVGL_DIR}/src/extra/libs/gif/lv_gif.c
|
||||
${LVGL_DIR}/src/extra/libs/png/lodepng.c
|
||||
${LVGL_DIR}/src/extra/libs/png/lv_png.c
|
||||
${LVGL_DIR}/src/extra/libs/qrcode/lv_qrcode.c
|
||||
${LVGL_DIR}/src/extra/libs/qrcode/qrcodegen.c
|
||||
${LVGL_DIR}/src/extra/libs/rlottie/lv_rlottie.c
|
||||
${LVGL_DIR}/src/extra/libs/sjpg/lv_sjpg.c
|
||||
${LVGL_DIR}/src/extra/libs/sjpg/tjpgd.c
|
||||
${LVGL_DIR}/src/extra/lv_extra.c
|
||||
${LVGL_DIR}/src/extra/others/fragment/lv_fragment.c
|
||||
${LVGL_DIR}/src/extra/others/fragment/lv_fragment_manager.c
|
||||
${LVGL_DIR}/src/extra/others/gridnav/lv_gridnav.c
|
||||
${LVGL_DIR}/src/extra/others/ime/lv_ime_pinyin.c
|
||||
${LVGL_DIR}/src/extra/others/imgfont/lv_imgfont.c
|
||||
${LVGL_DIR}/src/extra/others/monkey/lv_monkey.c
|
||||
${LVGL_DIR}/src/extra/others/msg/lv_msg.c
|
||||
${LVGL_DIR}/src/extra/others/snapshot/lv_snapshot.c
|
||||
${LVGL_DIR}/src/extra/themes/basic/lv_theme_basic.c
|
||||
${LVGL_DIR}/src/extra/themes/default/lv_theme_default.c
|
||||
${LVGL_DIR}/src/extra/themes/mono/lv_theme_mono.c
|
||||
${LVGL_DIR}/src/extra/widgets/animimg/lv_animimg.c
|
||||
${LVGL_DIR}/src/extra/widgets/calendar/lv_calendar.c
|
||||
${LVGL_DIR}/src/extra/widgets/calendar/lv_calendar_header_arrow.c
|
||||
${LVGL_DIR}/src/extra/widgets/calendar/lv_calendar_header_dropdown.c
|
||||
${LVGL_DIR}/src/extra/widgets/chart/lv_chart.c
|
||||
${LVGL_DIR}/src/extra/widgets/colorwheel/lv_colorwheel.c
|
||||
${LVGL_DIR}/src/extra/widgets/imgbtn/lv_imgbtn.c
|
||||
${LVGL_DIR}/src/extra/widgets/keyboard/lv_keyboard.c
|
||||
${LVGL_DIR}/src/extra/widgets/led/lv_led.c
|
||||
${LVGL_DIR}/src/extra/widgets/list/lv_list.c
|
||||
${LVGL_DIR}/src/extra/widgets/menu/lv_menu.c
|
||||
${LVGL_DIR}/src/extra/widgets/meter/lv_meter.c
|
||||
${LVGL_DIR}/src/extra/widgets/msgbox/lv_msgbox.c
|
||||
${LVGL_DIR}/src/extra/widgets/span/lv_span.c
|
||||
${LVGL_DIR}/src/extra/widgets/spinbox/lv_spinbox.c
|
||||
${LVGL_DIR}/src/extra/widgets/spinner/lv_spinner.c
|
||||
${LVGL_DIR}/src/extra/widgets/tabview/lv_tabview.c
|
||||
${LVGL_DIR}/src/extra/widgets/tileview/lv_tileview.c
|
||||
${LVGL_DIR}/src/extra/widgets/win/lv_win.c
|
||||
|
||||
${LVGL_DIR}/src/font/lv_font.c
|
||||
${LVGL_DIR}/src/font/lv_font_dejavu_16_persian_hebrew.c
|
||||
${LVGL_DIR}/src/font/lv_font_fmt_txt.c
|
||||
${LVGL_DIR}/src/font/lv_font_loader.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_10.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_12.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_12_subpx.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_14.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_16.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_18.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_20.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_22.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_24.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_26.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_28.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_28_compressed.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_30.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_32.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_34.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_36.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_38.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_40.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_42.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_44.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_46.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_48.c
|
||||
${LVGL_DIR}/src/font/lv_font_montserrat_8.c
|
||||
${LVGL_DIR}/src/font/lv_font_simsun_16_cjk.c
|
||||
${LVGL_DIR}/src/font/lv_font_unscii_16.c
|
||||
${LVGL_DIR}/src/font/lv_font_unscii_8.c
|
||||
|
||||
${LVGL_DIR}/src/hal/lv_hal_disp.c
|
||||
${LVGL_DIR}/src/hal/lv_hal_indev.c
|
||||
${LVGL_DIR}/src/hal/lv_hal_tick.c
|
||||
|
||||
${LVGL_DIR}/src/misc/lv_anim.c
|
||||
${LVGL_DIR}/src/misc/lv_anim_timeline.c
|
||||
${LVGL_DIR}/src/misc/lv_area.c
|
||||
${LVGL_DIR}/src/misc/lv_async.c
|
||||
${LVGL_DIR}/src/misc/lv_bidi.c
|
||||
${LVGL_DIR}/src/misc/lv_color.c
|
||||
${LVGL_DIR}/src/misc/lv_fs.c
|
||||
${LVGL_DIR}/src/misc/lv_gc.c
|
||||
${LVGL_DIR}/src/misc/lv_ll.c
|
||||
${LVGL_DIR}/src/misc/lv_log.c
|
||||
${LVGL_DIR}/src/misc/lv_lru.c
|
||||
${LVGL_DIR}/src/misc/lv_math.c
|
||||
${LVGL_DIR}/src/misc/lv_mem.c
|
||||
${LVGL_DIR}/src/misc/lv_printf.c
|
||||
${LVGL_DIR}/src/misc/lv_style.c
|
||||
${LVGL_DIR}/src/misc/lv_style_gen.c
|
||||
${LVGL_DIR}/src/misc/lv_templ.c
|
||||
${LVGL_DIR}/src/misc/lv_timer.c
|
||||
${LVGL_DIR}/src/misc/lv_tlsf.c
|
||||
${LVGL_DIR}/src/misc/lv_txt.c
|
||||
${LVGL_DIR}/src/misc/lv_txt_ap.c
|
||||
${LVGL_DIR}/src/misc/lv_utils.c
|
||||
|
||||
${LVGL_DIR}/src/widgets/lv_arc.c
|
||||
${LVGL_DIR}/src/widgets/lv_bar.c
|
||||
${LVGL_DIR}/src/widgets/lv_btn.c
|
||||
${LVGL_DIR}/src/widgets/lv_btnmatrix.c
|
||||
${LVGL_DIR}/src/widgets/lv_canvas.c
|
||||
${LVGL_DIR}/src/widgets/lv_checkbox.c
|
||||
${LVGL_DIR}/src/widgets/lv_dropdown.c
|
||||
${LVGL_DIR}/src/widgets/lv_img.c
|
||||
${LVGL_DIR}/src/widgets/lv_label.c
|
||||
${LVGL_DIR}/src/widgets/lv_line.c
|
||||
${LVGL_DIR}/src/widgets/lv_objx_templ.c
|
||||
${LVGL_DIR}/src/widgets/lv_roller.c
|
||||
${LVGL_DIR}/src/widgets/lv_slider.c
|
||||
${LVGL_DIR}/src/widgets/lv_switch.c
|
||||
${LVGL_DIR}/src/widgets/lv_table.c
|
||||
${LVGL_DIR}/src/widgets/lv_textarea.c
|
||||
|
||||
lvgl.c
|
||||
lvgl_display.c
|
||||
lvgl_display_mono.c
|
||||
lvgl_display_16bit.c
|
||||
lvgl_display_24bit.c
|
||||
lvgl_display_32bit.c
|
||||
lvgl_display_mono.c
|
||||
)
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_LV_Z_USE_FILESYSTEM lvgl_fs.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_LV_Z_MEM_POOL_SYS_HEAP lvgl_mem.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_LV_Z_SHELL lvgl_shell.c)
|
||||
|
||||
zephyr_library_link_libraries(LVGL)
|
||||
target_link_libraries(LVGL INTERFACE zephyr_interface)
|
||||
|
||||
endif()
|
61
modules/lvgl/Kconfig
Normal file
61
modules/lvgl/Kconfig
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Copyright (c) 2023 Fabian Blatz <fabianblatz@gmail.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config ZEPHYR_LVGL_MODULE
|
||||
bool
|
||||
|
||||
config LVGL
|
||||
bool "LVGL support"
|
||||
help
|
||||
This option enables the LVGL graphics library.
|
||||
|
||||
if LVGL
|
||||
|
||||
config LV_USE_MONKEY
|
||||
bool
|
||||
|
||||
config LV_DPI_DEF
|
||||
int
|
||||
|
||||
config LV_CONF_SKIP
|
||||
bool
|
||||
default n
|
||||
|
||||
config APP_LINK_WITH_LVGL
|
||||
bool "Link 'app' with LVGL"
|
||||
default y
|
||||
help
|
||||
Add LVGL header files to the 'app' include path. It may be
|
||||
disabled if the include paths for LVGL are causing aliasing
|
||||
issues for 'app'.
|
||||
|
||||
config LV_Z_USE_FILESYSTEM
|
||||
bool "LVGL file system support"
|
||||
depends on FILE_SYSTEM
|
||||
default y if FILE_SYSTEM
|
||||
help
|
||||
Enable LittlevGL file system
|
||||
|
||||
choice LV_COLOR_DEPTH
|
||||
default LV_COLOR_DEPTH_16
|
||||
prompt "Color depth (bits per pixel)"
|
||||
|
||||
config LV_COLOR_DEPTH_32
|
||||
bool "32: ARGB8888"
|
||||
config LV_COLOR_DEPTH_16
|
||||
bool "16: RGB565"
|
||||
config LV_COLOR_DEPTH_8
|
||||
bool "8: RGB232"
|
||||
config LV_COLOR_DEPTH_1
|
||||
bool "1: monochrome"
|
||||
endchoice
|
||||
|
||||
config LV_COLOR_16_SWAP
|
||||
bool
|
||||
|
||||
rsource "Kconfig.memory"
|
||||
rsource "Kconfig.input"
|
||||
rsource "Kconfig.shell"
|
||||
|
||||
|
||||
endif
|
41
modules/lvgl/Kconfig.input
Normal file
41
modules/lvgl/Kconfig.input
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Copyright (c) 2018-2019 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
# Copyright (c) 2020 Teslabs Engineering S.L.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
menu "Input device settings"
|
||||
|
||||
config LV_Z_POINTER_KSCAN
|
||||
bool "Keyboard scan pointer input"
|
||||
depends on KSCAN
|
||||
help
|
||||
Enable keyboard scan pointer input
|
||||
|
||||
if LV_Z_POINTER_KSCAN
|
||||
|
||||
config LV_Z_POINTER_KSCAN_MSGQ_COUNT
|
||||
int "Keyboard scan message queue count maximum"
|
||||
default 10
|
||||
help
|
||||
Maximum number of items in the keyboard scan message queue.
|
||||
|
||||
config LV_Z_POINTER_KSCAN_SWAP_XY
|
||||
bool "Swap keyboard scan X,Y axes"
|
||||
help
|
||||
Swap keyboard scan X,Y axes. This option can be used to align keyboard
|
||||
scan coordinates with the display.
|
||||
|
||||
config LV_Z_POINTER_KSCAN_INVERT_X
|
||||
bool "Invert keyboard scan X axis"
|
||||
help
|
||||
Invert keyboard scan X axis. This option can be used to align keyboard
|
||||
scan coordinates with the display.
|
||||
|
||||
config LV_Z_POINTER_KSCAN_INVERT_Y
|
||||
bool "Invert keyboard scan Y axis"
|
||||
help
|
||||
Invert keyboard scan Y axis. This option can be used to align keyboard
|
||||
scan coordinates with the display.
|
||||
|
||||
endif # LV_Z_POINTER_KSCAN
|
||||
|
||||
endmenu
|
119
modules/lvgl/Kconfig.memory
Normal file
119
modules/lvgl/Kconfig.memory
Normal file
|
@ -0,0 +1,119 @@
|
|||
# Copyright (c) 2018-2019 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
# Copyright (c) 2020 Teslabs Engineering S.L.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
menu "Memory manager settings"
|
||||
|
||||
config LV_Z_BITS_PER_PIXEL
|
||||
int "Bits per pixel"
|
||||
default 32
|
||||
range 1 32
|
||||
depends on LV_Z_BUFFER_ALLOC_STATIC
|
||||
help
|
||||
Number of bits per pixel.
|
||||
|
||||
choice LV_Z_MEMORY_POOL
|
||||
prompt "Memory pool"
|
||||
default LV_Z_MEM_POOL_SYS_HEAP
|
||||
help
|
||||
Memory pool to use for lvgl allocated objects
|
||||
|
||||
config LV_Z_MEM_POOL_HEAP_LIB_C
|
||||
bool "C library Heap"
|
||||
depends on !MINIMAL_LIBC || (MINIMAL_LIBC_MALLOC_ARENA_SIZE != 0)
|
||||
help
|
||||
Use C library malloc and free to allocate objects on the C library heap
|
||||
|
||||
config LV_Z_MEM_POOL_SYS_HEAP
|
||||
bool "User space lvgl pool"
|
||||
help
|
||||
Use a dedicated memory pool from a private sys heap.
|
||||
|
||||
endchoice
|
||||
|
||||
if LV_Z_MEM_POOL_SYS_HEAP
|
||||
|
||||
config LV_Z_MEM_POOL_MIN_SIZE
|
||||
int "Minimum memory pool block size"
|
||||
default 16
|
||||
help
|
||||
Size of the smallest block in the memory pool in bytes
|
||||
|
||||
config LV_Z_MEM_POOL_MAX_SIZE
|
||||
int "Maximum memory pool block size"
|
||||
default 2048
|
||||
help
|
||||
Size of the largest block in the memory pool in bytes
|
||||
|
||||
config LV_Z_MEM_POOL_NUMBER_BLOCKS
|
||||
int "Number of max size blocks in memory pool"
|
||||
default 1
|
||||
help
|
||||
Number of maximum sized blocks in the memory pool.
|
||||
|
||||
endif
|
||||
|
||||
config LV_Z_VDB_SIZE
|
||||
int "Rendering buffer size"
|
||||
default 10
|
||||
range 1 100
|
||||
help
|
||||
Size of the buffer used for rendering screen content as a percentage
|
||||
of total display size.
|
||||
|
||||
config LV_Z_DOUBLE_VDB
|
||||
bool "Use two rendering buffers"
|
||||
help
|
||||
Use two buffers to render and flush data in parallel
|
||||
|
||||
config LV_Z_FULL_REFRESH
|
||||
bool "Force full refresh mode"
|
||||
help
|
||||
Force full refresh of display on update. When combined with
|
||||
LV_Z_VDB_SIZE, this setting can improve performance for display
|
||||
controllers that require a framebuffer to be present in system memory,
|
||||
since the controller can render the LVGL framebuffer directly
|
||||
|
||||
config LV_Z_VDB_ALIGN
|
||||
int "Rending buffer alignment"
|
||||
default 4
|
||||
depends on LV_Z_BUFFER_ALLOC_STATIC
|
||||
help
|
||||
Rendering buffer alignment. Depending on chosen color depth,
|
||||
buffer may be accessed as a uint8_t *, uint16_t *, or uint32_t *,
|
||||
so buffer must be aligned to prevent unaligned memory access
|
||||
|
||||
config LV_Z_VBD_CUSTOM_SECTION
|
||||
bool "Link rendering buffers to custom section"
|
||||
depends on LV_Z_BUFFER_ALLOC_STATIC
|
||||
help
|
||||
Place LVGL rendering buffers in custom section, with tag ".lvgl_buf".
|
||||
This can be used by custom linker scripts to relocate the LVGL
|
||||
rendering buffers to a custom location, such as tightly coupled or
|
||||
external memory.
|
||||
|
||||
choice LV_Z_RENDERING_BUFFER_ALLOCATION
|
||||
prompt "Rendering Buffer Allocation"
|
||||
default LV_Z_BUFFER_ALLOC_STATIC
|
||||
help
|
||||
Type of allocation that should be used for allocating rendering buffers
|
||||
|
||||
config LV_Z_BUFFER_ALLOC_STATIC
|
||||
bool "Static"
|
||||
help
|
||||
Rendering buffers are statically allocated based on the following
|
||||
configuration parameters:
|
||||
* Horizontal screen resolution
|
||||
* Vertical screen resolution
|
||||
* Rendering buffer size
|
||||
* Bytes per pixel
|
||||
|
||||
config LV_Z_BUFFER_ALLOC_DYNAMIC
|
||||
bool "Dynamic"
|
||||
help
|
||||
Rendering buffers are dynamically allocated based on the actual
|
||||
display parameters
|
||||
|
||||
endchoice
|
||||
|
||||
endmenu
|
19
modules/lvgl/Kconfig.shell
Normal file
19
modules/lvgl/Kconfig.shell
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Copyright (c) 2023 Fabian Blatz <fabianblatz@gmail.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config LV_Z_SHELL
|
||||
bool "LVGL Shell"
|
||||
depends on SHELL
|
||||
help
|
||||
Enable LVGL shell for testing.
|
||||
|
||||
if LV_Z_SHELL
|
||||
|
||||
config LV_Z_MAX_MONKEY_COUNT
|
||||
int "Maximum number of monkeys"
|
||||
default 4
|
||||
depends on LV_USE_MONKEY
|
||||
help
|
||||
Number of monkey instances that can exist in parallel
|
||||
|
||||
endif
|
50
modules/lvgl/lv_conf.h
Normal file
50
modules/lvgl/lv_conf.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
* Copyright (c) 2020 Teslabs Engineering S.L.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_MODULES_LVGL_LV_CONF_H_
|
||||
#define ZEPHYR_MODULES_LVGL_LV_CONF_H_
|
||||
|
||||
/* Memory manager settings */
|
||||
|
||||
#define LV_MEMCPY_MEMSET_STD 1
|
||||
|
||||
#if defined(CONFIG_LV_Z_MEM_POOL_HEAP_LIB_C)
|
||||
|
||||
#define LV_MEM_CUSTOM_INCLUDE "stdlib.h"
|
||||
#define LV_MEM_CUSTOM_ALLOC malloc
|
||||
#define LV_MEM_CUSTOM_REALLOC realloc
|
||||
#define LV_MEM_CUSTOM_FREE free
|
||||
|
||||
#else
|
||||
|
||||
#define LV_MEM_CUSTOM_INCLUDE "lvgl_mem.h"
|
||||
#define LV_MEM_CUSTOM_ALLOC lvgl_malloc
|
||||
#define LV_MEM_CUSTOM_REALLOC lvgl_realloc
|
||||
#define LV_MEM_CUSTOM_FREE lvgl_free
|
||||
|
||||
#endif
|
||||
|
||||
/* HAL settings */
|
||||
|
||||
#define LV_TICK_CUSTOM 1
|
||||
#define LV_TICK_CUSTOM_INCLUDE <zephyr/kernel.h>
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (k_uptime_get_32())
|
||||
|
||||
/* Misc settings */
|
||||
|
||||
#define LV_SPRINTF_CUSTOM 1
|
||||
#define LV_SPRINTF_INCLUDE "stdio.h"
|
||||
#define lv_snprintf snprintf
|
||||
#define lv_vsnprintf vsnprintf
|
||||
|
||||
/*
|
||||
* Needed because of a workaround for a GCC bug,
|
||||
* see https://github.com/lvgl/lvgl/issues/3078
|
||||
*/
|
||||
#define LV_CONF_SUPPRESS_DEFINE_CHECK 1
|
||||
|
||||
#endif /* ZEPHYR_MODULES_LVGL_LV_CONF_H_ */
|
385
modules/lvgl/lvgl.c
Normal file
385
modules/lvgl/lvgl.c
Normal file
|
@ -0,0 +1,385 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/init.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <lvgl.h>
|
||||
#include "lvgl_display.h"
|
||||
#ifdef CONFIG_LV_Z_USE_FILESYSTEM
|
||||
#include "lvgl_fs.h"
|
||||
#endif
|
||||
#ifdef CONFIG_LV_Z_POINTER_KSCAN
|
||||
#include <zephyr/drivers/kscan.h>
|
||||
#endif
|
||||
#include LV_MEM_CUSTOM_INCLUDE
|
||||
|
||||
#define LOG_LEVEL CONFIG_LV_LOG_LEVEL
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(lvgl);
|
||||
|
||||
static lv_disp_drv_t disp_drv;
|
||||
struct lvgl_disp_data disp_data = {
|
||||
.blanking_on = false,
|
||||
};
|
||||
#ifdef CONFIG_LV_Z_POINTER_KSCAN
|
||||
static lv_indev_drv_t indev_drv;
|
||||
#endif /* CONFIG_LV_Z_POINTER_KSCAN */
|
||||
|
||||
#define DISPLAY_NODE DT_CHOSEN(zephyr_display)
|
||||
#define KSCAN_NODE DT_CHOSEN(zephyr_keyboard_scan)
|
||||
|
||||
#ifdef CONFIG_LV_Z_BUFFER_ALLOC_STATIC
|
||||
|
||||
static lv_disp_draw_buf_t disp_buf;
|
||||
|
||||
#define DISPLAY_WIDTH DT_PROP(DISPLAY_NODE, width)
|
||||
#define DISPLAY_HEIGHT DT_PROP(DISPLAY_NODE, height)
|
||||
|
||||
#define BUFFER_SIZE \
|
||||
(CONFIG_LV_Z_BITS_PER_PIXEL * \
|
||||
((CONFIG_LV_Z_VDB_SIZE * DISPLAY_WIDTH * DISPLAY_HEIGHT) / 100) / 8)
|
||||
|
||||
#define NBR_PIXELS_IN_BUFFER (BUFFER_SIZE * 8 / CONFIG_LV_Z_BITS_PER_PIXEL)
|
||||
|
||||
/* NOTE: depending on chosen color depth buffer may be accessed using uint8_t *,
|
||||
* uint16_t * or uint32_t *, therefore buffer needs to be aligned accordingly to
|
||||
* prevent unaligned memory accesses.
|
||||
*/
|
||||
static uint8_t buf0[BUFFER_SIZE]
|
||||
#ifdef CONFIG_LV_Z_VBD_CUSTOM_SECTION
|
||||
Z_GENERIC_SECTION(.lvgl_buf)
|
||||
#endif
|
||||
__aligned(CONFIG_LV_Z_VDB_ALIGN);
|
||||
|
||||
#ifdef CONFIG_LV_Z_DOUBLE_VDB
|
||||
static uint8_t buf1[BUFFER_SIZE]
|
||||
#ifdef CONFIG_LV_Z_VBD_CUSTOM_SECTION
|
||||
Z_GENERIC_SECTION(.lvgl_buf)
|
||||
#endif
|
||||
__aligned(CONFIG_LV_Z_VDB_ALIGN);
|
||||
#endif /* CONFIG_LV_Z_DOUBLE_VDB */
|
||||
|
||||
#endif /* CONFIG_LV_Z_BUFFER_ALLOC_STATIC */
|
||||
|
||||
#if CONFIG_LV_LOG_LEVEL != 0
|
||||
/*
|
||||
* In LVGLv8 the signature of the logging callback has changes and it no longer
|
||||
* takes the log level as an integer argument. Instead, the log level is now
|
||||
* already part of the buffer passed to the logging callback. It's not optimal
|
||||
* but we need to live with it and parse the buffer manually to determine the
|
||||
* level and then truncate the string we actually pass to the logging framework.
|
||||
*/
|
||||
static void lvgl_log(const char *buf)
|
||||
{
|
||||
/*
|
||||
* This is ugly and should be done in a loop or something but as it
|
||||
* turned out, Z_LOG()'s first argument (that specifies the log level)
|
||||
* cannot be an l-value...
|
||||
*
|
||||
* We also assume lvgl is sane and always supplies the level string.
|
||||
*/
|
||||
switch (buf[1]) {
|
||||
case 'E':
|
||||
LOG_ERR("%s", buf + strlen("[Error] "));
|
||||
break;
|
||||
case 'W':
|
||||
LOG_WRN("%s", buf + strlen("Warn] "));
|
||||
break;
|
||||
case 'I':
|
||||
LOG_INF("%s", buf + strlen("[Info] "));
|
||||
break;
|
||||
case 'T':
|
||||
LOG_DBG("%s", buf + strlen("[Trace] "));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LV_Z_BUFFER_ALLOC_STATIC
|
||||
|
||||
static int lvgl_allocate_rendering_buffers(lv_disp_drv_t *disp_driver)
|
||||
{
|
||||
struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_driver->user_data;
|
||||
int err = 0;
|
||||
|
||||
if (data->cap.x_resolution <= DISPLAY_WIDTH) {
|
||||
disp_driver->hor_res = data->cap.x_resolution;
|
||||
} else {
|
||||
LOG_ERR("Horizontal resolution is larger than maximum");
|
||||
err = -ENOTSUP;
|
||||
}
|
||||
|
||||
if (data->cap.y_resolution <= DISPLAY_HEIGHT) {
|
||||
disp_driver->ver_res = data->cap.y_resolution;
|
||||
} else {
|
||||
LOG_ERR("Vertical resolution is larger than maximum");
|
||||
err = -ENOTSUP;
|
||||
}
|
||||
|
||||
disp_driver->draw_buf = &disp_buf;
|
||||
#ifdef CONFIG_LV_Z_DOUBLE_VDB
|
||||
lv_disp_draw_buf_init(disp_driver->draw_buf, &buf0, &buf1, NBR_PIXELS_IN_BUFFER);
|
||||
#else
|
||||
lv_disp_draw_buf_init(disp_driver->draw_buf, &buf0, NULL, NBR_PIXELS_IN_BUFFER);
|
||||
#endif /* CONFIG_LV_Z_DOUBLE_VDB */
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int lvgl_allocate_rendering_buffers(lv_disp_drv_t *disp_driver)
|
||||
{
|
||||
void *buf0 = NULL;
|
||||
void *buf1 = NULL;
|
||||
uint16_t buf_nbr_pixels;
|
||||
uint32_t buf_size;
|
||||
struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_driver->user_data;
|
||||
|
||||
disp_driver->hor_res = data->cap.x_resolution;
|
||||
disp_driver->ver_res = data->cap.y_resolution;
|
||||
|
||||
buf_nbr_pixels = (CONFIG_LV_Z_VDB_SIZE * disp_driver->hor_res * disp_driver->ver_res) / 100;
|
||||
/* one horizontal line is the minimum buffer requirement for lvgl */
|
||||
if (buf_nbr_pixels < disp_driver->hor_res) {
|
||||
buf_nbr_pixels = disp_driver->hor_res;
|
||||
}
|
||||
|
||||
switch (data->cap.current_pixel_format) {
|
||||
case PIXEL_FORMAT_ARGB_8888:
|
||||
buf_size = 4 * buf_nbr_pixels;
|
||||
break;
|
||||
case PIXEL_FORMAT_RGB_888:
|
||||
buf_size = 3 * buf_nbr_pixels;
|
||||
break;
|
||||
case PIXEL_FORMAT_RGB_565:
|
||||
buf_size = 2 * buf_nbr_pixels;
|
||||
break;
|
||||
case PIXEL_FORMAT_MONO01:
|
||||
case PIXEL_FORMAT_MONO10:
|
||||
buf_size = buf_nbr_pixels / 8;
|
||||
buf_size += (buf_nbr_pixels % 8) == 0 ? 0 : 1;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
buf0 = LV_MEM_CUSTOM_ALLOC(buf_size);
|
||||
if (buf0 == NULL) {
|
||||
LOG_ERR("Failed to allocate memory for rendering buffer");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LV_Z_DOUBLE_VDB
|
||||
buf1 = LV_MEM_CUSTOM_ALLOC(buf_size);
|
||||
if (buf1 == NULL) {
|
||||
LV_MEM_CUSTOM_FREE(buf0);
|
||||
LOG_ERR("Failed to allocate memory for rendering buffer");
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
disp_driver->draw_buf = LV_MEM_CUSTOM_ALLOC(sizeof(lv_disp_draw_buf_t));
|
||||
if (disp_driver->draw_buf == NULL) {
|
||||
LV_MEM_CUSTOM_FREE(buf0);
|
||||
LV_MEM_CUSTOM_FREE(buf1);
|
||||
LOG_ERR("Failed to allocate memory to store rendering buffers");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
lv_disp_draw_buf_init(disp_driver->draw_buf, buf0, buf1, buf_nbr_pixels);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_LV_Z_BUFFER_ALLOC_STATIC */
|
||||
|
||||
#ifdef CONFIG_LV_Z_POINTER_KSCAN
|
||||
K_MSGQ_DEFINE(kscan_msgq, sizeof(lv_indev_data_t), CONFIG_LV_Z_POINTER_KSCAN_MSGQ_COUNT, 4);
|
||||
|
||||
static void lvgl_pointer_kscan_callback(const struct device *dev, uint32_t row, uint32_t col,
|
||||
bool pressed)
|
||||
{
|
||||
lv_indev_data_t data = {
|
||||
.point.x = col,
|
||||
.point.y = row,
|
||||
.state = pressed ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL,
|
||||
};
|
||||
|
||||
if (k_msgq_put(&kscan_msgq, &data, K_NO_WAIT) != 0) {
|
||||
LOG_DBG("Could not put input data into queue");
|
||||
}
|
||||
}
|
||||
|
||||
static void lvgl_pointer_kscan_read(lv_indev_drv_t *drv, lv_indev_data_t *data)
|
||||
{
|
||||
lv_disp_t *disp;
|
||||
struct lvgl_disp_data *disp_data;
|
||||
struct display_capabilities *cap;
|
||||
lv_indev_data_t curr;
|
||||
|
||||
static lv_indev_data_t prev = {
|
||||
.point.x = 0,
|
||||
.point.y = 0,
|
||||
.state = LV_INDEV_STATE_REL,
|
||||
};
|
||||
|
||||
if (k_msgq_get(&kscan_msgq, &curr, K_NO_WAIT) != 0) {
|
||||
goto set_and_release;
|
||||
}
|
||||
|
||||
prev = curr;
|
||||
|
||||
disp = lv_disp_get_default();
|
||||
disp_data = disp->driver->user_data;
|
||||
cap = &disp_data->cap;
|
||||
|
||||
/* adjust kscan coordinates */
|
||||
if (IS_ENABLED(CONFIG_LV_Z_POINTER_KSCAN_SWAP_XY)) {
|
||||
lv_coord_t x;
|
||||
|
||||
x = prev.point.x;
|
||||
prev.point.x = prev.point.y;
|
||||
prev.point.y = x;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_LV_Z_POINTER_KSCAN_INVERT_X)) {
|
||||
if (cap->current_orientation == DISPLAY_ORIENTATION_NORMAL ||
|
||||
cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_180) {
|
||||
prev.point.x = cap->x_resolution - prev.point.x;
|
||||
} else {
|
||||
prev.point.x = cap->y_resolution - prev.point.x;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_LV_Z_POINTER_KSCAN_INVERT_Y)) {
|
||||
if (cap->current_orientation == DISPLAY_ORIENTATION_NORMAL ||
|
||||
cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_180) {
|
||||
prev.point.y = cap->y_resolution - prev.point.y;
|
||||
} else {
|
||||
prev.point.y = cap->x_resolution - prev.point.y;
|
||||
}
|
||||
}
|
||||
|
||||
/* rotate touch point to match display rotation */
|
||||
if (cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_90) {
|
||||
lv_coord_t x;
|
||||
|
||||
x = prev.point.x;
|
||||
prev.point.x = prev.point.y;
|
||||
prev.point.y = cap->y_resolution - x;
|
||||
} else if (cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_180) {
|
||||
prev.point.x = cap->x_resolution - prev.point.x;
|
||||
prev.point.y = cap->y_resolution - prev.point.y;
|
||||
} else if (cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_270) {
|
||||
lv_coord_t x;
|
||||
|
||||
x = prev.point.x;
|
||||
prev.point.x = cap->x_resolution - prev.point.y;
|
||||
prev.point.y = x;
|
||||
}
|
||||
|
||||
/* filter readings within display */
|
||||
if (prev.point.x <= 0) {
|
||||
prev.point.x = 0;
|
||||
} else if (prev.point.x >= cap->x_resolution) {
|
||||
prev.point.x = cap->x_resolution - 1;
|
||||
}
|
||||
|
||||
if (prev.point.y <= 0) {
|
||||
prev.point.y = 0;
|
||||
} else if (prev.point.y >= cap->y_resolution) {
|
||||
prev.point.y = cap->y_resolution - 1;
|
||||
}
|
||||
|
||||
set_and_release:
|
||||
*data = prev;
|
||||
|
||||
data->continue_reading = k_msgq_num_used_get(&kscan_msgq) > 0;
|
||||
}
|
||||
|
||||
static int lvgl_pointer_kscan_init(void)
|
||||
{
|
||||
const struct device *kscan_dev = DEVICE_DT_GET(KSCAN_NODE);
|
||||
|
||||
if (!device_is_ready(kscan_dev)) {
|
||||
LOG_ERR("Keyboard scan device not ready.");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (kscan_config(kscan_dev, lvgl_pointer_kscan_callback) < 0) {
|
||||
LOG_ERR("Could not configure keyboard scan device.");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = lvgl_pointer_kscan_read;
|
||||
|
||||
if (lv_indev_drv_register(&indev_drv) == NULL) {
|
||||
LOG_ERR("Failed to register input device.");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
kscan_enable_callback(kscan_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_LV_Z_POINTER_KSCAN */
|
||||
|
||||
static int lvgl_init(void)
|
||||
{
|
||||
|
||||
const struct device *display_dev = DEVICE_DT_GET(DISPLAY_NODE);
|
||||
|
||||
int err = 0;
|
||||
|
||||
if (!device_is_ready(display_dev)) {
|
||||
LOG_ERR("Display device not ready.");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#if CONFIG_LV_LOG_LEVEL != 0
|
||||
lv_log_register_print_cb(lvgl_log);
|
||||
#endif
|
||||
|
||||
lv_init();
|
||||
|
||||
#ifdef CONFIG_LV_Z_USE_FILESYSTEM
|
||||
lvgl_fs_init();
|
||||
#endif
|
||||
|
||||
disp_data.display_dev = display_dev;
|
||||
display_get_capabilities(display_dev, &disp_data.cap);
|
||||
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
disp_drv.user_data = (void *)&disp_data;
|
||||
|
||||
#ifdef CONFIG_LV_Z_FULL_REFRESH
|
||||
disp_drv.full_refresh = 1;
|
||||
#endif
|
||||
|
||||
err = lvgl_allocate_rendering_buffers(&disp_drv);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (set_lvgl_rendering_cb(&disp_drv) != 0) {
|
||||
LOG_ERR("Display not supported.");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (lv_disp_drv_register(&disp_drv) == NULL) {
|
||||
LOG_ERR("Failed to register display device.");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LV_Z_POINTER_KSCAN
|
||||
lvgl_pointer_kscan_init();
|
||||
#endif /* CONFIG_LV_Z_POINTER_KSCAN */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(lvgl_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
|
56
modules/lvgl/lvgl_display.c
Normal file
56
modules/lvgl/lvgl_display.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "lvgl_display.h"
|
||||
|
||||
int set_lvgl_rendering_cb(lv_disp_drv_t *disp_drv)
|
||||
{
|
||||
int err = 0;
|
||||
struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data;
|
||||
|
||||
switch (data->cap.current_pixel_format) {
|
||||
case PIXEL_FORMAT_ARGB_8888:
|
||||
disp_drv->flush_cb = lvgl_flush_cb_32bit;
|
||||
disp_drv->rounder_cb = NULL;
|
||||
#ifdef CONFIG_LV_COLOR_DEPTH_32
|
||||
disp_drv->set_px_cb = NULL;
|
||||
#else
|
||||
disp_drv->set_px_cb = lvgl_set_px_cb_32bit;
|
||||
#endif
|
||||
break;
|
||||
case PIXEL_FORMAT_RGB_888:
|
||||
disp_drv->flush_cb = lvgl_flush_cb_24bit;
|
||||
disp_drv->rounder_cb = NULL;
|
||||
disp_drv->set_px_cb = lvgl_set_px_cb_24bit;
|
||||
break;
|
||||
case PIXEL_FORMAT_RGB_565:
|
||||
case PIXEL_FORMAT_BGR_565:
|
||||
disp_drv->flush_cb = lvgl_flush_cb_16bit;
|
||||
disp_drv->rounder_cb = NULL;
|
||||
#ifdef CONFIG_LV_COLOR_DEPTH_16
|
||||
disp_drv->set_px_cb = NULL;
|
||||
#else
|
||||
disp_drv->set_px_cb = lvgl_set_px_cb_16bit;
|
||||
#endif
|
||||
break;
|
||||
case PIXEL_FORMAT_MONO01:
|
||||
case PIXEL_FORMAT_MONO10:
|
||||
disp_drv->flush_cb = lvgl_flush_cb_mono;
|
||||
disp_drv->rounder_cb = lvgl_rounder_cb_mono;
|
||||
disp_drv->set_px_cb = lvgl_set_px_cb_mono;
|
||||
break;
|
||||
default:
|
||||
disp_drv->flush_cb = NULL;
|
||||
disp_drv->rounder_cb = NULL;
|
||||
disp_drv->set_px_cb = NULL;
|
||||
err = -ENOTSUP;
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
45
modules/lvgl/lvgl_display.h
Normal file
45
modules/lvgl/lvgl_display.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_MODULES_LVGL_DISPLAY_H_
|
||||
#define ZEPHYR_MODULES_LVGL_DISPLAY_H_
|
||||
|
||||
#include <zephyr/drivers/display.h>
|
||||
#include <lvgl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct lvgl_disp_data {
|
||||
const struct device *display_dev;
|
||||
struct display_capabilities cap;
|
||||
bool blanking_on;
|
||||
};
|
||||
|
||||
void lvgl_flush_cb_mono(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
|
||||
void lvgl_flush_cb_16bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
|
||||
void lvgl_flush_cb_24bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
|
||||
void lvgl_flush_cb_32bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
|
||||
|
||||
void lvgl_set_px_cb_mono(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
void lvgl_set_px_cb_16bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
void lvgl_set_px_cb_24bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
void lvgl_set_px_cb_32bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
|
||||
void lvgl_rounder_cb_mono(lv_disp_drv_t *disp_drv, lv_area_t *area);
|
||||
|
||||
int set_lvgl_rendering_cb(lv_disp_drv_t *disp_drv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_MODULES_LVGL_DISPLAY_H_ */
|
34
modules/lvgl/lvgl_display_16bit.c
Normal file
34
modules/lvgl/lvgl_display_16bit.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <lvgl.h>
|
||||
#include "lvgl_display.h"
|
||||
|
||||
void lvgl_flush_cb_16bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data;
|
||||
uint16_t w = area->x2 - area->x1 + 1;
|
||||
uint16_t h = area->y2 - area->y1 + 1;
|
||||
struct display_buffer_descriptor desc;
|
||||
|
||||
desc.buf_size = w * 2U * h;
|
||||
desc.width = w;
|
||||
desc.pitch = w;
|
||||
desc.height = h;
|
||||
display_write(data->display_dev, area->x1, area->y1, &desc, (void *)color_p);
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_LV_COLOR_DEPTH_16
|
||||
void lvgl_set_px_cb_16bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
uint16_t *buf_xy = (uint16_t *)(buf + x * 2U + y * 2U * buf_w);
|
||||
*buf_xy = lv_color_to16(color);
|
||||
}
|
||||
#endif
|
48
modules/lvgl/lvgl_display_24bit.c
Normal file
48
modules/lvgl/lvgl_display_24bit.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <lvgl.h>
|
||||
#include "lvgl_display.h"
|
||||
|
||||
void lvgl_flush_cb_24bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data;
|
||||
uint16_t w = area->x2 - area->x1 + 1;
|
||||
uint16_t h = area->y2 - area->y1 + 1;
|
||||
struct display_buffer_descriptor desc;
|
||||
|
||||
desc.buf_size = w * 3U * h;
|
||||
desc.width = w;
|
||||
desc.pitch = w;
|
||||
desc.height = h;
|
||||
display_write(data->display_dev, area->x1, area->y1, &desc, (void *)color_p);
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
void lvgl_set_px_cb_24bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
uint8_t *buf_xy = buf + x * 3U + y * 3U * buf_w;
|
||||
lv_color32_t converted_color;
|
||||
|
||||
#ifdef CONFIG_LV_COLOR_DEPTH_32
|
||||
if (opa != LV_OPA_COVER) {
|
||||
lv_color_t mix_color;
|
||||
|
||||
mix_color.ch.red = *buf_xy;
|
||||
mix_color.ch.green = *(buf_xy + 1);
|
||||
mix_color.ch.blue = *(buf_xy + 2);
|
||||
color = lv_color_mix(color, mix_color, opa);
|
||||
}
|
||||
#endif
|
||||
|
||||
converted_color.full = lv_color_to32(color);
|
||||
*buf_xy = converted_color.ch.red;
|
||||
*(buf_xy + 1) = converted_color.ch.green;
|
||||
*(buf_xy + 2) = converted_color.ch.blue;
|
||||
}
|
41
modules/lvgl/lvgl_display_32bit.c
Normal file
41
modules/lvgl/lvgl_display_32bit.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <lvgl.h>
|
||||
#include "lvgl_display.h"
|
||||
|
||||
void lvgl_flush_cb_32bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data;
|
||||
uint16_t w = area->x2 - area->x1 + 1;
|
||||
uint16_t h = area->y2 - area->y1 + 1;
|
||||
struct display_buffer_descriptor desc;
|
||||
|
||||
desc.buf_size = w * 4U * h;
|
||||
desc.width = w;
|
||||
desc.pitch = w;
|
||||
desc.height = h;
|
||||
display_write(data->display_dev, area->x1, area->y1, &desc, (void *)color_p);
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_LV_COLOR_DEPTH_32
|
||||
void lvgl_set_px_cb_32bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
uint32_t *buf_xy = (uint32_t *)(buf + x * 4U + y * 4U * buf_w);
|
||||
|
||||
if (opa == LV_OPA_COVER) {
|
||||
/* Do not mix if not required */
|
||||
*buf_xy = lv_color_to32(color);
|
||||
} else {
|
||||
lv_color_t bg_color = *((lv_color_t *)buf_xy);
|
||||
*buf_xy = lv_color_to32(lv_color_mix(color, bg_color, opa));
|
||||
}
|
||||
}
|
||||
#endif
|
109
modules/lvgl/lvgl_display_mono.c
Normal file
109
modules/lvgl/lvgl_display_mono.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <lvgl.h>
|
||||
#include "lvgl_display.h"
|
||||
|
||||
void lvgl_flush_cb_mono(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
uint16_t w = area->x2 - area->x1 + 1;
|
||||
uint16_t h = area->y2 - area->y1 + 1;
|
||||
struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data;
|
||||
const struct device *display_dev = data->display_dev;
|
||||
struct display_buffer_descriptor desc;
|
||||
const bool is_epd = data->cap.screen_info & SCREEN_INFO_EPD;
|
||||
const bool is_last = lv_disp_flush_is_last(disp_drv);
|
||||
|
||||
if (is_epd && !data->blanking_on && !is_last) {
|
||||
/*
|
||||
* Turn on display blanking when using an EPD
|
||||
* display. This prevents updates and the associated
|
||||
* flicker if the screen is rendered in multiple
|
||||
* steps.
|
||||
*/
|
||||
display_blanking_on(display_dev);
|
||||
data->blanking_on = true;
|
||||
}
|
||||
|
||||
desc.buf_size = (w * h) / 8U;
|
||||
desc.width = w;
|
||||
desc.pitch = w;
|
||||
desc.height = h;
|
||||
display_write(display_dev, area->x1, area->y1, &desc, (void *)color_p);
|
||||
if (data->cap.screen_info & SCREEN_INFO_DOUBLE_BUFFER) {
|
||||
display_write(display_dev, area->x1, area->y1, &desc, (void *)color_p);
|
||||
}
|
||||
|
||||
if (is_epd && is_last && data->blanking_on) {
|
||||
/*
|
||||
* The entire screen has now been rendered. Update the
|
||||
* display by disabling blanking.
|
||||
*/
|
||||
display_blanking_off(display_dev);
|
||||
data->blanking_on = false;
|
||||
}
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
void lvgl_set_px_cb_mono(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x,
|
||||
lv_coord_t y, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data;
|
||||
uint8_t *buf_xy;
|
||||
uint8_t bit;
|
||||
|
||||
if (data->cap.screen_info & SCREEN_INFO_MONO_VTILED) {
|
||||
buf_xy = buf + x + y / 8 * buf_w;
|
||||
|
||||
if (data->cap.screen_info & SCREEN_INFO_MONO_MSB_FIRST) {
|
||||
bit = 7 - y % 8;
|
||||
} else {
|
||||
bit = y % 8;
|
||||
}
|
||||
} else {
|
||||
buf_xy = buf + x / 8 + y * buf_w / 8;
|
||||
|
||||
if (data->cap.screen_info & SCREEN_INFO_MONO_MSB_FIRST) {
|
||||
bit = 7 - x % 8;
|
||||
} else {
|
||||
bit = x % 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->cap.current_pixel_format == PIXEL_FORMAT_MONO10) {
|
||||
if (color.full == 0) {
|
||||
*buf_xy &= ~BIT(bit);
|
||||
} else {
|
||||
*buf_xy |= BIT(bit);
|
||||
}
|
||||
} else {
|
||||
if (color.full == 0) {
|
||||
*buf_xy |= BIT(bit);
|
||||
} else {
|
||||
*buf_xy &= ~BIT(bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lvgl_rounder_cb_mono(lv_disp_drv_t *disp_drv, lv_area_t *area)
|
||||
{
|
||||
struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data;
|
||||
|
||||
if (data->cap.screen_info & SCREEN_INFO_X_ALIGNMENT_WIDTH) {
|
||||
area->x1 = 0;
|
||||
area->x2 = data->cap.x_resolution - 1;
|
||||
} else {
|
||||
if (data->cap.screen_info & SCREEN_INFO_MONO_VTILED) {
|
||||
area->y1 &= ~0x7;
|
||||
area->y2 |= 0x7;
|
||||
} else {
|
||||
area->x1 &= ~0x7;
|
||||
area->x2 |= 0x7;
|
||||
}
|
||||
}
|
||||
}
|
226
modules/lvgl/lvgl_fs.c
Normal file
226
modules/lvgl/lvgl_fs.c
Normal file
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/fs/fs.h>
|
||||
#include <stdlib.h>
|
||||
#include "lvgl_fs.h"
|
||||
|
||||
static bool lvgl_fs_ready(struct _lv_fs_drv_t *drv)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static lv_fs_res_t errno_to_lv_fs_res(int err)
|
||||
{
|
||||
switch (err) {
|
||||
case 0:
|
||||
return LV_FS_RES_OK;
|
||||
case -EIO:
|
||||
/*Low level hardware error*/
|
||||
return LV_FS_RES_HW_ERR;
|
||||
case -EBADF:
|
||||
/*Error in the file system structure */
|
||||
return LV_FS_RES_FS_ERR;
|
||||
case -ENOENT:
|
||||
/*Driver, file or directory is not exists*/
|
||||
return LV_FS_RES_NOT_EX;
|
||||
case -EFBIG:
|
||||
/*Disk full*/
|
||||
return LV_FS_RES_FULL;
|
||||
case -EACCES:
|
||||
/*Access denied. Check 'fs_open' modes and write protect*/
|
||||
return LV_FS_RES_DENIED;
|
||||
case -EBUSY:
|
||||
/*The file system now can't handle it, try later*/
|
||||
return LV_FS_RES_BUSY;
|
||||
case -ENOMEM:
|
||||
/*Not enough memory for an internal operation*/
|
||||
return LV_FS_RES_OUT_OF_MEM;
|
||||
case -EINVAL:
|
||||
/*Invalid parameter among arguments*/
|
||||
return LV_FS_RES_INV_PARAM;
|
||||
default:
|
||||
return LV_FS_RES_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void *lvgl_fs_open(struct _lv_fs_drv_t *drv, const char *path, lv_fs_mode_t mode)
|
||||
{
|
||||
int err;
|
||||
int zmode = FS_O_CREATE;
|
||||
void *file;
|
||||
|
||||
/* LVGL is passing absolute paths without the root slash add it back
|
||||
* by decrementing the path pointer.
|
||||
*/
|
||||
path--;
|
||||
|
||||
zmode |= (mode & LV_FS_MODE_WR) ? FS_O_WRITE : 0;
|
||||
zmode |= (mode & LV_FS_MODE_RD) ? FS_O_READ : 0;
|
||||
|
||||
file = malloc(sizeof(struct fs_file_t));
|
||||
if (!file) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fs_file_t_init((struct fs_file_t *)file);
|
||||
|
||||
err = fs_open((struct fs_file_t *)file, path, zmode);
|
||||
if (err) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
static lv_fs_res_t lvgl_fs_close(struct _lv_fs_drv_t *drv, void *file)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = fs_close((struct fs_file_t *)file);
|
||||
return errno_to_lv_fs_res(err);
|
||||
}
|
||||
|
||||
static lv_fs_res_t lvgl_fs_read(struct _lv_fs_drv_t *drv, void *file, void *buf, uint32_t btr,
|
||||
uint32_t *br)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = fs_read((struct fs_file_t *)file, buf, btr);
|
||||
if (err > 0) {
|
||||
if (br != NULL) {
|
||||
*br = err;
|
||||
}
|
||||
err = 0;
|
||||
} else if (br != NULL) {
|
||||
*br = 0U;
|
||||
}
|
||||
return errno_to_lv_fs_res(err);
|
||||
}
|
||||
|
||||
static lv_fs_res_t lvgl_fs_write(struct _lv_fs_drv_t *drv, void *file, const void *buf,
|
||||
uint32_t btw, uint32_t *bw)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = fs_write((struct fs_file_t *)file, buf, btw);
|
||||
if (err == btw) {
|
||||
if (bw != NULL) {
|
||||
*bw = btw;
|
||||
}
|
||||
err = 0;
|
||||
} else if (err < 0) {
|
||||
if (bw != NULL) {
|
||||
*bw = 0U;
|
||||
}
|
||||
} else {
|
||||
if (bw != NULL) {
|
||||
*bw = err;
|
||||
}
|
||||
err = -EFBIG;
|
||||
}
|
||||
return errno_to_lv_fs_res(err);
|
||||
}
|
||||
|
||||
static lv_fs_res_t lvgl_fs_seek(struct _lv_fs_drv_t *drv, void *file, uint32_t pos,
|
||||
lv_fs_whence_t whence)
|
||||
{
|
||||
int err, fs_whence;
|
||||
|
||||
switch (whence) {
|
||||
case LV_FS_SEEK_END:
|
||||
fs_whence = FS_SEEK_END;
|
||||
break;
|
||||
case LV_FS_SEEK_CUR:
|
||||
fs_whence = FS_SEEK_CUR;
|
||||
break;
|
||||
case LV_FS_SEEK_SET:
|
||||
default:
|
||||
fs_whence = FS_SEEK_SET;
|
||||
break;
|
||||
}
|
||||
|
||||
err = fs_seek((struct fs_file_t *)file, pos, fs_whence);
|
||||
return errno_to_lv_fs_res(err);
|
||||
}
|
||||
|
||||
static lv_fs_res_t lvgl_fs_tell(struct _lv_fs_drv_t *drv, void *file, uint32_t *pos_p)
|
||||
{
|
||||
*pos_p = fs_tell((struct fs_file_t *)file);
|
||||
return LV_FS_RES_OK;
|
||||
}
|
||||
|
||||
static void *lvgl_fs_dir_open(struct _lv_fs_drv_t *drv, const char *path)
|
||||
{
|
||||
void *dir;
|
||||
int err;
|
||||
|
||||
/* LVGL is passing absolute paths without the root slash add it back
|
||||
* by decrementing the path pointer.
|
||||
*/
|
||||
path--;
|
||||
|
||||
dir = malloc(sizeof(struct fs_dir_t));
|
||||
if (!dir) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fs_dir_t_init((struct fs_dir_t *)dir);
|
||||
err = fs_opendir((struct fs_dir_t *)dir, path);
|
||||
if (err) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
static lv_fs_res_t lvgl_fs_dir_read(struct _lv_fs_drv_t *drv, void *dir, char *fn)
|
||||
{
|
||||
/* LVGL expects a string as return parameter but the format of the
|
||||
* string is not documented.
|
||||
*/
|
||||
return LV_FS_RES_NOT_IMP;
|
||||
}
|
||||
|
||||
static lv_fs_res_t lvgl_fs_dir_close(struct _lv_fs_drv_t *drv, void *dir)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = fs_closedir((struct fs_dir_t *)dir);
|
||||
free(dir);
|
||||
return errno_to_lv_fs_res(err);
|
||||
}
|
||||
|
||||
static lv_fs_drv_t fs_drv;
|
||||
|
||||
void lvgl_fs_init(void)
|
||||
{
|
||||
lv_fs_drv_init(&fs_drv);
|
||||
|
||||
/* LVGL uses letter based mount points, just pass the root slash as a
|
||||
* letter. Note that LVGL will remove the drive letter, or in this case
|
||||
* the root slash, from the path passed via the FS callbacks.
|
||||
* Zephyr FS API assumes this slash is present so we will need to add
|
||||
* it back.
|
||||
*/
|
||||
fs_drv.letter = '/';
|
||||
fs_drv.ready_cb = lvgl_fs_ready;
|
||||
|
||||
fs_drv.open_cb = lvgl_fs_open;
|
||||
fs_drv.close_cb = lvgl_fs_close;
|
||||
fs_drv.read_cb = lvgl_fs_read;
|
||||
fs_drv.write_cb = lvgl_fs_write;
|
||||
fs_drv.seek_cb = lvgl_fs_seek;
|
||||
fs_drv.tell_cb = lvgl_fs_tell;
|
||||
|
||||
fs_drv.dir_open_cb = lvgl_fs_dir_open;
|
||||
fs_drv.dir_read_cb = lvgl_fs_dir_read;
|
||||
fs_drv.dir_close_cb = lvgl_fs_dir_close;
|
||||
|
||||
lv_fs_drv_register(&fs_drv);
|
||||
}
|
20
modules/lvgl/lvgl_fs.h
Normal file
20
modules/lvgl/lvgl_fs.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_MODULES_LVGL_FS_H_
|
||||
#define ZEPHYR_MODULES_LVGL_FS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void lvgl_fs_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_MODULES_LVGL_FS_H_ */
|
67
modules/lvgl/lvgl_mem.c
Normal file
67
modules/lvgl/lvgl_mem.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
* Copyright (c) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "lvgl_mem.h"
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/init.h>
|
||||
#include <zephyr/sys/sys_heap.h>
|
||||
|
||||
#define HEAP_BYTES (CONFIG_LV_Z_MEM_POOL_MAX_SIZE * CONFIG_LV_Z_MEM_POOL_NUMBER_BLOCKS)
|
||||
|
||||
static char lvgl_heap_mem[HEAP_BYTES] __aligned(8);
|
||||
static struct sys_heap lvgl_heap;
|
||||
static struct k_spinlock lvgl_heap_lock;
|
||||
|
||||
void *lvgl_malloc(size_t size)
|
||||
{
|
||||
k_spinlock_key_t key;
|
||||
void *ret;
|
||||
|
||||
key = k_spin_lock(&lvgl_heap_lock);
|
||||
ret = sys_heap_alloc(&lvgl_heap, size);
|
||||
k_spin_unlock(&lvgl_heap_lock, key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *lvgl_realloc(void *ptr, size_t size)
|
||||
{
|
||||
k_spinlock_key_t key;
|
||||
void *ret;
|
||||
|
||||
key = k_spin_lock(&lvgl_heap_lock);
|
||||
ret = sys_heap_realloc(&lvgl_heap, ptr, size);
|
||||
k_spin_unlock(&lvgl_heap_lock, key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void lvgl_free(void *ptr)
|
||||
{
|
||||
k_spinlock_key_t key;
|
||||
|
||||
key = k_spin_lock(&lvgl_heap_lock);
|
||||
sys_heap_free(&lvgl_heap, ptr);
|
||||
k_spin_unlock(&lvgl_heap_lock, key);
|
||||
}
|
||||
|
||||
void lvgl_print_heap_info(bool dump_chunks)
|
||||
{
|
||||
k_spinlock_key_t key;
|
||||
|
||||
key = k_spin_lock(&lvgl_heap_lock);
|
||||
sys_heap_print_info(&lvgl_heap, dump_chunks);
|
||||
k_spin_unlock(&lvgl_heap_lock, key);
|
||||
}
|
||||
|
||||
static int lvgl_heap_init(void)
|
||||
{
|
||||
sys_heap_init(&lvgl_heap, &lvgl_heap_mem[0], HEAP_BYTES);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(lvgl_heap_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
29
modules/lvgl/lvgl_mem.h
Normal file
29
modules/lvgl/lvgl_mem.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_MODULES_LVGL_MEM_H_
|
||||
#define ZEPHYR_MODULES_LVGL_MEM_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void *lvgl_malloc(size_t size);
|
||||
|
||||
void *lvgl_realloc(void *ptr, size_t size);
|
||||
|
||||
void lvgl_free(void *ptr);
|
||||
|
||||
void lvgl_print_heap_info(bool dump_chunks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_MODULES_LVGL_MEM_H_ */
|
204
modules/lvgl/lvgl_shell.c
Normal file
204
modules/lvgl/lvgl_shell.c
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Fabian Blatz <fabianblatz@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/shell/shell.h>
|
||||
#include <lvgl.h>
|
||||
#include <autoconf.h>
|
||||
|
||||
#ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP
|
||||
#include "lvgl_mem.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LV_USE_MONKEY
|
||||
static lv_monkey_t *lvgl_monkeys[CONFIG_LV_Z_MAX_MONKEY_COUNT];
|
||||
|
||||
static const char *lvgl_monkey_indev_as_string(lv_monkey_t *monkey)
|
||||
{
|
||||
lv_indev_t *input_device;
|
||||
|
||||
input_device = lv_monkey_get_indev(monkey);
|
||||
if (!input_device || !input_device->driver) {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
switch (input_device->driver->type) {
|
||||
case LV_INDEV_TYPE_POINTER:
|
||||
return "pointer";
|
||||
case LV_INDEV_TYPE_KEYPAD:
|
||||
return "keypad";
|
||||
case LV_INDEV_TYPE_BUTTON:
|
||||
return "button";
|
||||
case LV_INDEV_TYPE_ENCODER:
|
||||
return "encoder";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static int lvgl_monkey_indev_from_string(const char *str, lv_indev_type_t *input_device)
|
||||
{
|
||||
if (strcmp(str, "pointer") == 0) {
|
||||
*input_device = LV_INDEV_TYPE_POINTER;
|
||||
} else if (strcmp(str, "keypad") == 0) {
|
||||
*input_device = LV_INDEV_TYPE_KEYPAD;
|
||||
} else if (strcmp(str, "button") == 0) {
|
||||
*input_device = LV_INDEV_TYPE_BUTTON;
|
||||
} else if (strcmp(str, "encoder") == 0) {
|
||||
*input_device = LV_INDEV_TYPE_ENCODER;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dump_monkey_info(const struct shell *sh)
|
||||
{
|
||||
shell_print(sh, "id device active");
|
||||
for (size_t i = 0; i < CONFIG_LV_Z_MAX_MONKEY_COUNT; i++) {
|
||||
if (lvgl_monkeys[i] != NULL) {
|
||||
shell_print(sh, "%-4u %-9s %-3s", i,
|
||||
lvgl_monkey_indev_as_string(lvgl_monkeys[i]),
|
||||
lv_monkey_get_enable(lvgl_monkeys[i]) ? "yes" : "no");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int cmd_lvgl_monkey(const struct shell *sh, size_t argc, char *argv[])
|
||||
{
|
||||
ARG_UNUSED(argc);
|
||||
ARG_UNUSED(argv);
|
||||
|
||||
dump_monkey_info(sh);
|
||||
shell_print(sh, "");
|
||||
shell_help(sh);
|
||||
|
||||
return SHELL_CMD_HELP_PRINTED;
|
||||
}
|
||||
|
||||
static int cmd_lvgl_monkey_create(const struct shell *sh, size_t argc, char *argv[])
|
||||
{
|
||||
bool created_monkey = false;
|
||||
lv_monkey_config_t default_config;
|
||||
|
||||
lv_monkey_config_init(&default_config);
|
||||
|
||||
if (argc == 2) {
|
||||
if (lvgl_monkey_indev_from_string(argv[1], &default_config.type) < 0) {
|
||||
shell_error(sh, "Invalid monkey input device %s", argv[1]);
|
||||
shell_help(sh);
|
||||
return SHELL_CMD_HELP_PRINTED;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < CONFIG_LV_Z_MAX_MONKEY_COUNT; i++) {
|
||||
if (lvgl_monkeys[i] == NULL) {
|
||||
lvgl_monkeys[i] = lv_monkey_create(&default_config);
|
||||
lv_monkey_set_enable(lvgl_monkeys[i], true);
|
||||
created_monkey = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!created_monkey) {
|
||||
shell_error(sh, "Error creating monkey instance");
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
dump_monkey_info(sh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_lvgl_monkey_set(const struct shell *sh, size_t argc, char *argv[])
|
||||
{
|
||||
int index;
|
||||
|
||||
index = atoi(argv[1]);
|
||||
if (index < 0 || index >= CONFIG_LV_Z_MAX_MONKEY_COUNT || lvgl_monkeys[index] == NULL) {
|
||||
shell_error(sh, "Invalid monkey index");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if (strcmp(argv[2], "active") == 0) {
|
||||
lv_monkey_set_enable(lvgl_monkeys[index], true);
|
||||
} else if (strcmp(argv[2], "inactive") == 0) {
|
||||
lv_monkey_set_enable(lvgl_monkeys[index], false);
|
||||
} else {
|
||||
shell_error(sh, "Invalid monkey state %s", argv[2]);
|
||||
shell_help(sh);
|
||||
return SHELL_CMD_HELP_PRINTED;
|
||||
}
|
||||
|
||||
dump_monkey_info(sh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_LV_USE_MONKEY */
|
||||
|
||||
static int cmd_lvgl_stats(const struct shell *sh, size_t argc, char *argv[])
|
||||
{
|
||||
ARG_UNUSED(argc);
|
||||
ARG_UNUSED(argv);
|
||||
|
||||
shell_help(sh);
|
||||
return SHELL_CMD_HELP_PRINTED;
|
||||
}
|
||||
|
||||
static int cmd_lvgl_stats_memory(const struct shell *sh, size_t argc, char *argv[])
|
||||
{
|
||||
#ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP
|
||||
bool dump_chunks = false;
|
||||
|
||||
if (argc == 2) {
|
||||
if (strcmp(argv[1], "-c") == 0) {
|
||||
dump_chunks = true;
|
||||
} else {
|
||||
shell_error(sh, "unsupported option %s", argv[1]);
|
||||
shell_help(sh);
|
||||
return SHELL_CMD_HELP_PRINTED;
|
||||
}
|
||||
}
|
||||
|
||||
lvgl_print_heap_info(dump_chunks);
|
||||
return 0;
|
||||
#else
|
||||
ARG_UNUSED(argc);
|
||||
ARG_UNUSED(argv);
|
||||
shell_error(sh, "Set CONFIG_LV_Z_MEM_POOL_SYS_HEAP to enable memory statistics support.");
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(lvgl_cmd_stats,
|
||||
SHELL_CMD_ARG(memory, NULL,
|
||||
"Show LVGL memory statistics\n"
|
||||
"Usage: lvgl stats memory [-c]\n"
|
||||
"-c dump chunk information",
|
||||
cmd_lvgl_stats_memory, 1, 1),
|
||||
SHELL_SUBCMD_SET_END);
|
||||
|
||||
#ifdef CONFIG_LV_USE_MONKEY
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(
|
||||
lvgl_cmd_monkey,
|
||||
SHELL_CMD_ARG(create, NULL,
|
||||
"Create a new monkey instance (default: pointer)\n"
|
||||
"Usage: lvgl monkey create [pointer|keypad|button|encoder]",
|
||||
cmd_lvgl_monkey_create, 1, 1),
|
||||
SHELL_CMD_ARG(set, NULL,
|
||||
"Activate/deactive a monkey instance\n"
|
||||
"Usage: lvgl monkey set <index> <active|inactive>\n",
|
||||
cmd_lvgl_monkey_set, 3, 0),
|
||||
SHELL_SUBCMD_SET_END);
|
||||
#endif /* CONFIG_LV_USE_MONKEY */
|
||||
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(
|
||||
lvgl_cmds, SHELL_CMD(stats, &lvgl_cmd_stats, "Show LVGL statistics", cmd_lvgl_stats),
|
||||
#ifdef CONFIG_LV_USE_MONKEY
|
||||
SHELL_CMD(monkey, &lvgl_cmd_monkey, "LVGL monkey testing", cmd_lvgl_monkey),
|
||||
#endif /* CONFIG_LV_USE_MONKEY */
|
||||
SHELL_SUBCMD_SET_END);
|
||||
|
||||
SHELL_CMD_REGISTER(lvgl, &lvgl_cmds, "LVGL shell commands", NULL);
|
2
west.yml
2
west.yml
|
@ -270,7 +270,7 @@ manifest:
|
|||
revision: ce57712f3e426bbbb13acaec97b45369f716f43a
|
||||
path: modules/lib/loramac-node
|
||||
- name: lvgl
|
||||
revision: 5da257f782a8f9c6e265bdc60ebc2a93fdee24de
|
||||
revision: 8a6a2d1d29d17d1e4bdc94c243c146a39d635fdd
|
||||
path: modules/lib/gui/lvgl
|
||||
- name: lz4
|
||||
revision: 8e303c264fc21c2116dc612658003a22e933124d
|
||||
|
|
Loading…
Reference in a new issue