Skip to content

Commit

Permalink
Merge pull request #314 from PGNetHun/bugfix/display_drivers_20240110
Browse files Browse the repository at this point in the history
Update LVGL and display drivers
  • Loading branch information
PGNetHun authored Jan 11, 2024
2 parents 5cea992 + 9054126 commit 33e61b3
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 64 deletions.
84 changes: 38 additions & 46 deletions driver/esp32/ili9XXX.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,6 @@
# color convert). Pure MicroPython is only supported for ili9341 and
# gc9a01 displays!
#
#
# Display configurations:
#
# ili9341:
# -
#
# ili9488:
# - SPI frequency: 40 MHz
# This means cca 9fps of full screen
# redraw. to increase FPS, you can use 80MHz SPI - easily add parameter
# mhz=80 in initialization of driver.
#
# ili9488g (gCore):
# - SPI frequency: 80 MHz
#
# gc9a01:
# - SPI frequency: 60 MHz, as that is the maximum the tested display
# would support despite the datasheet suggesting that higher freqs would be
# supported
#
# st7789:
# -
#
##############################################################################

import espidf as esp
Expand Down Expand Up @@ -89,7 +66,7 @@ def __init__(self,
invert=False, double_buffer=True, half_duplex=True, display_type=0, asynchronous=False, initialize=True,
color_format=lv.COLOR_FORMAT.RGB565, swap_rgb565_bytes=False
):

# Initializations

if not lv.is_initialized():
Expand Down Expand Up @@ -126,6 +103,9 @@ def __init__(self,
self.swap_rgb565_bytes = swap_rgb565_bytes
self.rgb565_swap_func = lv.draw_sw_rgb565_swap if swap_rgb565_bytes else None

This comment has been minimized.

Copy link
@kdschlosser

kdschlosser Jan 11, 2024

Contributor

why? this wastes over 120 bytes of memory to do. The code is not going to execute any faster by doing this. I fail to see the purpose of it.


if not color_format:
raise RuntimeError("No color format is defined")

# SPI
self.start_time_ptr = esp.C_Pointer()
self.end_time_ptr = esp.C_Pointer()
Expand All @@ -143,28 +123,38 @@ def __init__(self,
self.monitor_count = 0
self.cycles_in_ms = esp.esp_clk_cpu_freq() // 1000

self.buf_size = (self.width * self.height * self.pixel_size) // factor

if invert:
self.init_cmds.append({'cmd': 0x21})

# Register display driver

self.buf1 = esp.heap_caps_malloc(self.buf_size, esp.MALLOC_CAP.DMA)
self.buf2 = esp.heap_caps_malloc(self.buf_size, esp.MALLOC_CAP.DMA) if double_buffer else None
# Allocate display buffer(s)

if self.buf1 and self.buf2:
print("Double buffer")
elif self.buf1:
print("Single buffer")
else:
buf_size = (self.width * self.height * self.pixel_size) // factor
self.buf_size = buf_size
self.draw_buf1 = lv.draw_buf_t()
self.draw_buf2 = None

buf1 = esp.heap_caps_malloc(buf_size, esp.MALLOC_CAP.DMA)

This comment has been minimized.

Copy link
@kdschlosser

kdschlosser Jan 11, 2024

Contributor

Allocating the buffer in DMA memory if double buffer is not being used is pointless to do.. It is also very limiting and has the potential to cause allocation failure.

Take the ESP32 as an example. there is only 328k of DMA memory available. in Fact after loading MicroPython and LVGL I was able to just barely fit 2 30K buffers into DMA space yet there was more than enough RAM available of I didn't use DMA memory. double buffering without DMA memory is not going to help at all either.

if not buf1:
raise RuntimeError("Not enough DMA-able memory to allocate display buffer")

if self.draw_buf1.init(width, height // factor, color_format, 0, buf1, buf_size) != lv.RESULT.OK:
raise RuntimeError("Draw buffer 1 initialization failed")

if double_buffer:
buf2 = esp.heap_caps_malloc(buf_size, esp.MALLOC_CAP.DMA)
if buf2:
self.draw_buf2 = lv.draw_buf_t()
if self.draw_buf2.init(width, height // factor, color_format, 0, buf2, buf_size) != lv.RESULT.OK:
raise RuntimeError("Draw buffer 2 initialization failed")

# Register display driver

self.disp_spi_init()
self.disp_drv = lv.display_create(self.width, self.height)
self.disp_drv.set_flush_cb(esp.ili9xxx_flush if hybrid and hasattr(esp, 'ili9xxx_flush') else self.flush)
self.disp_drv.set_draw_buffers(self.buf1, self.buf2, self.buf_size, lv.DISPLAY_RENDER_MODE.PARTIAL)

self.disp_drv.set_draw_buffers(self.draw_buf1, self.draw_buf2)
self.disp_drv.set_render_mode(lv.DISPLAY_RENDER_MODE.PARTIAL)
self.disp_drv.set_color_format(color_format)
self.disp_drv.set_driver_data({
'dc': self.dc,
'spi': self.spi,
Expand All @@ -174,9 +164,6 @@ def __init__(self,
'start_y': self.start_y
})

if color_format:
self.disp_drv.set_color_format(color_format)

if self.initialize:
self.init()

Expand Down Expand Up @@ -312,13 +299,18 @@ def deinit(self):

# Free RAM

if self.buf1:
esp.heap_caps_free(self.buf1)
self.buf1 = None
if self.draw_buf1:

esp.heap_caps_free(self.draw_buf1.unaligned_data)
self.draw_buf1.unaligned_data = None
lv.draw_buf_destroy(self.draw_buf1)
self.draw_buf1 = None

if self.buf2:
esp.heap_caps_free(self.buf2)
self.buf2 = None
if self.draw_buf2:
esp.heap_caps_free(self.draw_buf2.unaligned_data)
self.draw_buf2.unaligned_data = None
lv.draw_buf_destroy(self.draw_buf2)
self.draw_buf2 = None

if self.trans_buffer:
esp.heap_caps_free(self.trans_buffer)
Expand Down
9 changes: 7 additions & 2 deletions driver/generic/st77xx.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,16 +447,21 @@ def __init__(self,doublebuffer=True,factor=4):
import lv_utils

color_format = lv.COLOR_FORMAT.RGB565
bufSize=(self.width * self.height * lv.color_format_get_size(color_format)) // factor

if not lv.is_initialized(): lv.init()

# create event loop if not yet present
if not lv_utils.event_loop.is_running(): self.event_loop=lv_utils.event_loop()

# create display buffer(s)
draw_buf1 = lv.draw_buf_create(self.width, self.height // factor, color_format, 0)
draw_buf2 = lv.draw_buf_create(self.width, self.height // factor, color_format, 0) if doublebuffer else None

# attach all to self to avoid objects' refcount dropping to zero when the scope is exited
self.disp_drv = lv.disp_create(self.width, self.height)
self.disp_drv.set_flush_cb(self.disp_drv_flush_cb)
self.disp_drv.set_draw_buffers(bytearray(bufSize), bytearray(bufSize) if doublebuffer else None, bufSize, lv.DISP_RENDER_MODE.PARTIAL)
self.disp_drv.set_draw_buffers(draw_buf1, draw_buf2)
self.disp_drv.set_render_mode(lv.DISPLAY_RENDER_MODE.PARTIAL)
self.disp_drv.set_color_format(color_format)

class St7735(St7735_hw,St77xx_lvgl):
Expand Down
10 changes: 6 additions & 4 deletions examples/advanced_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,13 +357,15 @@ def init_gui_stm32(self):
# Register display driver
self.event_loop = event_loop()
lcd.init(w=hres, h=vres)

draw_buf1 = lv.draw_buf_create(hres, 50, color_format, 0)
draw_buf2 = lv.draw_buf_create(hres, 50, color_format, 0)

self.disp_drv = lv.display_create(hres, vres)
self.disp_drv.set_flush_cb(lcd.flush)
self.disp_drv.set_color_format(color_format)
buf_size = hres * 50 * lv.color_format_get_size(color_format)
buf1_1 = bytearray(buf_size)
buf1_2 = bytearray(buf_size)
self.disp_drv.set_draw_buffers(buf1_1, buf1_2, len(buf1_1), lv.DISPLAY_RENDER_MODE.PARTIAL)
self.disp_drv.set_draw_buffers(draw_buf1, draw_buf2)
self.disp_drv.set_render_mode(lv.DISPLAY_RENDER_MODE.PARTIAL)

# Register touch sensor
self.indev_drv = lv.indev_create()
Expand Down
17 changes: 14 additions & 3 deletions examples/example1.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,26 @@ def init_gui_stm32(self):

hres = 480
vres = 272
color_format = lv.COLOR_FORMAT.XRGB8888

# Register display driver
event_loop = lv_utils.event_loop()
lcd.init(w=hres, h=vres)

buf1 = lcd.framebuffer(1)
buf2 = lcd.framebuffer(2)
draw_buf1 = lv.draw_buf_t()
draw_buf2 = lv.draw_buf_t()
if draw_buf1.init(hres, vres, color_format, 0, buf1, len(buf1)) != lv.RESULT.OK:
raise RuntimeError("Draw buffer 1 initialization failed")
if draw_buf2.init(hres, vres, color_format, 0, buf2, len(buf2)) != lv.RESULT.OK:
raise RuntimeError("Draw buffer 2 initialization failed")

self.disp_drv = lv.disp_create(hres, vres)
self.disp_drv.set_flush_cb(lcd.flush)
buf1_1 = lcd.framebuffer(1)
buf1_2 = lcd.framebuffer(2)
self.disp_drv.set_draw_buffers(buf1_1, buf1_2, len(buf1_1), lv.DISP_RENDER_MODE.PARTIAL)
self.disp_drv.set_color_format(color_format)
self.disp_drv.set_draw_buffers(draw_buf1, draw_buf2)
self.disp_drv.set_render_mode(lv.DISPLAY_RENDER_MODE.PARTIAL)

# disp_drv.gpu_blend_cb = lcd.gpu_blend
# disp_drv.gpu_fill_cb = lcd.gpu_fill
Expand Down
19 changes: 14 additions & 5 deletions examples/example3.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,26 @@

hres = 480
vres = 272
color_format = lv.COLOR_FORMAT.ARGB8888
color_format = lv.COLOR_FORMAT.XRGB8888

lv.init()
event_loop = lv_utils.event_loop()
lcd.init(w=hres, h=vres)

buf1 = lcd.framebuffer(1)
buf2 = lcd.framebuffer(2)
draw_buf1 = lv.draw_buf_t()
draw_buf2 = lv.draw_buf_t()
if draw_buf1.init(hres, vres, color_format, 0, buf1, len(buf1)) != lv.RESULT.OK:
raise RuntimeError("Draw buffer 1 initialization failed")
if draw_buf2.init(hres, vres, color_format, 0, buf2, len(buf2)) != lv.RESULT.OK:
raise RuntimeError("Draw buffer 2 initialization failed")

disp_drv = lv.disp_create(hres, vres)
disp_drv.set_flush_cb(lcd.flush)
buf_size = hres * 10 * lv.color_format_get_size(color_format)
buf1_1 = bytearray(buf_size)
buf1_2 = bytearray(buf_size)
disp_drv.set_draw_buffers(buf1_1, buf1_2, len(buf1_1), lv.DISP_RENDER_MODE.PARTIAL)
disp_drv.set_color_format(color_format)
disp_drv.set_draw_buffers(draw_buf1, draw_buf2)
disp_drv.set_render_mode(lv.DISPLAY_RENDER_MODE.PARTIAL)

# disp_drv.gpu_blend_cb = lcd.gpu_blend
# disp_drv.gpu_fill_cb = lcd.gpu_fill
Expand Down
8 changes: 5 additions & 3 deletions lv_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@

/* Enable VG-Lite assert. */
#define LV_VG_LITE_USE_ASSERT 0

/* Simulate VG-Lite hardware using ThorVG */
#define LV_USE_VG_LITE_THORVG 0

#endif

/*=================
Expand Down Expand Up @@ -287,7 +291,7 @@ extern void mp_lv_init_gc();
*If size is not set to 0, the decoder will fail to decode when the cache is full.
*If size is 0, the cache function is not enabled and the decoded mem will be released immediately after use.*/
#ifdef MICROPY_CACHE_SIZE
#define LV_CACHE_DEF_SIZE MICROPY_CACHE_SIZE
#define LV_CACHE_DEF_SIZE MICROPY_CACHE_SIZE
#else
#define LV_CACHE_DEF_SIZE 0
#endif
Expand Down Expand Up @@ -514,8 +518,6 @@ extern void mp_lv_init_gc();

#define LV_USE_MENU 1

#define LV_USE_METER 1

#define LV_USE_MSGBOX 1

#define LV_USE_ROLLER 1 /*Requires: lv_label*/
Expand Down
2 changes: 1 addition & 1 deletion lvgl
Submodule lvgl updated 85 files
+0 −6 .devcontainer/__lv_conf.h__
+14 −5 CMakeLists.txt
+15 −26 Kconfig
+5 −3 docs/CHANGELOG.rst
+1 −1 env_support/cmake/custom.cmake
+0 −6 env_support/cmsis-pack/lv_conf_cmsis.h
+4 −6 lv_conf_template.h
+1 −0 scripts/code-format.cfg
+1 −1 src/core/lv_global.h
+2 −0 src/core/lv_obj_pos.c
+14 −8 src/core/lv_refr.c
+7 −2 src/dev/display/drm/lv_linux_drm.c
+5 −4 src/dev/display/fb/lv_linux_fbdev.c
+7 −7 src/dev/display/tft_espi/lv_tft_espi.cpp
+14 −3 src/dev/nuttx/lv_nuttx_fbdev.c
+1 −0 src/dev/nuttx/lv_nuttx_lcd.c
+47 −39 src/dev/sdl/lv_sdl_window.c
+1,319 −0 src/dev/vg_lite_tvg/vg_lite.h
+147 −0 src/dev/vg_lite_tvg/vg_lite_matrix.c
+2,471 −0 src/dev/vg_lite_tvg/vg_lite_tvg.cpp
+20 −16 src/display/lv_display.c
+14 −3 src/display/lv_display.h
+2 −2 src/display/lv_display_private.h
+13 −12 src/draw/lv_draw.c
+6 −1 src/draw/lv_draw.h
+5 −0 src/draw/lv_draw_buf.c
+8 −0 src/draw/lv_draw_image.c
+30 −19 src/draw/lv_draw_label.c
+3 −4 src/draw/lv_draw_label.h
+5 −0 src/draw/lv_draw_rect.c
+1 −17 src/draw/lv_image_buf.h
+7 −3 src/draw/nxp/vglite/lv_draw_vglite_label.c
+2 −5 src/draw/renesas/dave2d/lv_draw_dave2d.c
+103 −16 src/draw/renesas/dave2d/lv_draw_dave2d_image.c
+6 −5 src/draw/renesas/dave2d/lv_draw_dave2d_label.c
+1 −1 src/draw/renesas/dave2d/lv_draw_dave2d_utils.c
+0 −1 src/draw/sw/blend/lv_draw_sw_blend.c
+2 −1 src/draw/sw/lv_draw_sw_arc.c
+5 −3 src/draw/sw/lv_draw_sw_letter.c
+28 −1 src/draw/sw/lv_draw_sw_mask_rect.c
+4 −4 src/draw/vg_lite/lv_draw_vg_lite_arc.c
+4 −10 src/draw/vg_lite/lv_draw_vg_lite_label.c
+5 −5 src/draw/vg_lite/lv_draw_vg_lite_line.c
+5 −0 src/draw/vg_lite/lv_draw_vg_lite_type.h
+2 −2 src/draw/vg_lite/lv_vg_lite_decoder.c
+2 −2 src/draw/vg_lite/lv_vg_lite_math.h
+1 −1 src/draw/vg_lite/lv_vg_lite_path.c
+5 −5 src/draw/vg_lite/lv_vg_lite_utils.c
+4 −0 src/draw/vg_lite/lv_vg_lite_utils.h
+4 −3 src/font/lv_font.c
+9 −8 src/font/lv_font.h
+6 −5 src/font/lv_font_fmt_txt.c
+5 −5 src/font/lv_font_fmt_txt.h
+63 −39 src/libs/freetype/lv_freetype.c
+21 −18 src/libs/freetype/lv_freetype_glyph.c
+19 −31 src/libs/freetype/lv_freetype_image.c
+27 −34 src/libs/freetype/lv_freetype_outline.c
+7 −9 src/libs/freetype/lv_freetype_private.h
+0 −2 src/libs/thorvg/tvgInitializer.cpp
+1 −2 src/libs/thorvg/tvgSwMemPool.cpp
+2 −2 src/libs/thorvg/tvgSwRasterTexmap.h
+4 −0 src/libs/thorvg/tvgSwRenderer.cpp
+2 −131 src/libs/thorvg/tvgTaskScheduler.cpp
+0 −18 src/libs/thorvg/tvgTaskScheduler.h
+19 −19 src/libs/tiny_ttf/lv_tiny_ttf.c
+1 −2 src/lv_api_map.h
+10 −22 src/lv_conf_internal.h
+1 −1 src/misc/lv_color.h
+6 −7 src/others/imgfont/lv_imgfont.c
+0 −30 src/themes/default/lv_theme_default.c
+0 −6 src/themes/mono/lv_theme_mono.c
+0 −6 src/themes/simple/lv_theme_simple.c
+98 −24 src/widgets/bar/lv_bar.c
+1 −1 tests/CMakeLists.txt
+3 −8 tests/micropy_test/micropy.py
+ tests/ref_imgs/widgets/bar_corner_1.png
+ tests/ref_imgs/widgets/bar_corner_2.png
+ tests/ref_imgs/widgets/bar_corner_3.png
+ tests/ref_imgs/widgets/bar_corner_4.png
+ tests/ref_imgs/widgets/bar_corner_5.png
+ tests/ref_imgs/widgets/bar_corner_6.png
+0 −1 tests/src/lv_test_conf_minimal.h
+4 −2 tests/src/lv_test_init.c
+355 −353 tests/src/test_cases/libs/test_freetype.c
+82 −1 tests/src/test_cases/widgets/test_bar.c

0 comments on commit 33e61b3

Please sign in to comment.