Skip to content

Commit

Permalink
Merge pull request #315 from PGNetHun/bugfix/display_drivers_20240111
Browse files Browse the repository at this point in the history
Update LVGL and display drivers
  • Loading branch information
PGNetHun authored Jan 12, 2024
2 parents 33e61b3 + 36704e4 commit bc4c8b4
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 70 deletions.
75 changes: 26 additions & 49 deletions driver/esp32/ili9XXX.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@
import lvgl as lv
import lv_utils
import micropython
import gc

from micropython import const

micropython.alloc_emergency_exception_buf(256)


# Constants
COLOR_MODE_RGB = const(0x00)
COLOR_MODE_BGR = const(0x08)
Expand All @@ -53,7 +51,7 @@
DISPLAY_TYPE_ST7789 = const(4)
DISPLAY_TYPE_ST7735 = const(5)

TRANSFER_BUFFER_LENGTH = const(16)
_TRANSFER_BUFFER_LENGTH = const(16)

class ili9XXX:

Expand All @@ -66,7 +64,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 @@ -100,24 +98,24 @@ def __init__(self,
self.half_duplex = half_duplex
self.display_type = display_type
self.color_format = color_format
self.pixel_size = lv.color_format_get_size(color_format)
self.swap_rgb565_bytes = swap_rgb565_bytes
self.rgb565_swap_func = lv.draw_sw_rgb565_swap if swap_rgb565_bytes else None

if not color_format:
raise RuntimeError("No color format is defined")
raise RuntimeError(f"No color format defined for display {self.display_name}")

# SPI

self.start_time_ptr = esp.C_Pointer()
self.end_time_ptr = esp.C_Pointer()
self.trans_result_ptr = esp.C_Pointer()
self.trans = esp.spi_transaction_t()
self.flush_acc_setup_cycles = 0
self.flush_acc_dma_cycles = 0

# Flush
self.pixel_size = lv.color_format_get_size(color_format)

# Monitor

self.monitor_acc_time = 0
self.monitor_acc_px = 0
self.monitor_count = 0
Expand All @@ -128,33 +126,20 @@ def __init__(self,

# Allocate display buffer(s)

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)
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")
self.buf_size = (self.width * self.height * self.pixel_size) // factor
self.buf1 = esp.heap_caps_malloc(self.buf_size, esp.MALLOC_CAP.DMA)
if not self.buf1:
free = esp.heap_caps_get_largest_free_block(esp.MALLOC_CAP.DMA)
raise RuntimeError(f"Not enough DMA-capable memory to allocate display buffer. Needed: {self.buf_size} bytes, largest free block: {free} bytes")
self.buf2 = esp.heap_caps_malloc(self.buf_size, esp.MALLOC_CAP.DMA) if double_buffer else None

# 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.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_buffers(self.buf1, self.buf2, self.buf_size, lv.DISPLAY_RENDER_MODE.PARTIAL)
self.disp_drv.set_flush_cb(esp.ili9xxx_flush if hybrid and hasattr(esp, 'ili9xxx_flush') else self.flush)
self.disp_drv.set_driver_data({
'dc': self.dc,
'spi': self.spi,
Expand All @@ -164,6 +149,8 @@ def __init__(self,
'start_y': self.start_y
})

# Initialize display

if self.initialize:
self.init()

Expand Down Expand Up @@ -227,7 +214,7 @@ def disp_spi_init(self):
ret = esp.spi_bus_initialize(self.spihost, buscfg, 1)
if ret != 0: raise RuntimeError("Failed initializing SPI bus")

self.trans_buffer = esp.heap_caps_malloc(TRANSFER_BUFFER_LENGTH, esp.MALLOC_CAP.DMA)
self.trans_buffer = esp.heap_caps_malloc(_TRANSFER_BUFFER_LENGTH, esp.MALLOC_CAP.DMA)
self.cmd_trans_data = self.trans_buffer.__dereference__(1)
self.word_trans_data = self.trans_buffer.__dereference__(4)

Expand All @@ -245,7 +232,6 @@ def disp_spi_init(self):
def post_isr(arg):
reported_transmitted = self.bytes_transmitted
if reported_transmitted > 0:
print('- Completed DMA of %d bytes (mem_free=0x%X)' % (reported_transmitted , gc.mem_free()))
self.bytes_transmitted -= reported_transmitted

# Called in ISR context!
Expand All @@ -270,14 +256,13 @@ def flush_isr(spi_transaction_ptr):

def deinit(self):

print('Deinitializing {}..'.format(self.display_name))

# Prevent callbacks to lvgl, which refer to the buffers we are about to delete

if lv_utils.event_loop.is_running():
self.event_loop.deinit()

self.disp.remove()
if self.disp_drv:
self.disp_drv.delete()

if self.spi:

Expand All @@ -299,18 +284,13 @@ def deinit(self):

# Free RAM

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

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.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.buf2:
esp.heap_caps_free(self.buf2)
self.buf2 = None

if self.trans_buffer:
esp.heap_caps_free(self.trans_buffer)
Expand Down Expand Up @@ -339,7 +319,7 @@ def send_cmd(self, cmd):

def send_data(self, data):
esp.gpio_set_level(self.dc, 1) # Data mode
if len(data) > TRANSFER_BUFFER_LENGTH: raise RuntimeError('Data too long, please use DMA!')
if len(data) > _TRANSFER_BUFFER_LENGTH: raise RuntimeError('Data too long, please use DMA!')
trans_data = self.trans_buffer.__dereference__(len(data))
trans_data[:] = data[:]
self.spi_send(trans_data)
Expand Down Expand Up @@ -391,12 +371,9 @@ async def _init(self, sleep_func):
if 'delay' in cmd:
await sleep_func(cmd['delay'])

print("{} initialization completed".format(self.display_name))

# Enable backlight

if self.backlight != -1:
print("Enable backlight")
esp.gpio_set_level(self.backlight, self.backlight_on)

def init(self):
Expand Down
4 changes: 2 additions & 2 deletions driver/generic/st77xx.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,10 +459,10 @@ def __init__(self,doublebuffer=True,factor=4):

# 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_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)
self.disp_drv.set_color_format(color_format)
self.disp_drv.set_flush_cb(self.disp_drv_flush_cb)

class St7735(St7735_hw,St77xx_lvgl):
def __init__(self,res,doublebuffer=True,factor=4,**kw):
Expand Down
11 changes: 2 additions & 9 deletions examples/example1.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,19 @@ def init_gui_stm32(self):

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

# 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)
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)
self.disp_drv.set_buffers(buf1, buf2, len(buf1), lv.DISPLAY_RENDER_MODE.PARTIAL)

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

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

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)
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.set_buffers(buf1, buf2, len(buf1), lv.DISPLAY_RENDER_MODE.PARTIAL)

# disp_drv.gpu_blend_cb = lcd.gpu_blend
# disp_drv.gpu_fill_cb = lcd.gpu_fill
Expand Down
2 changes: 1 addition & 1 deletion lvgl
Submodule lvgl updated 73 files
+2 −1 .github/workflows/ccpp.yml
+28 −18 Kconfig
+4 −0 demos/benchmark/lv_demo_benchmark.c
+1 −1 demos/multilang/lv_demo_multilang.c
+12 −0 demos/multilang/lv_demo_multilang.h
+5 −0 demos/music/lv_demo_music_main.h
+1 −0 demos/render/lv_demo_render.c
+4 −0 demos/render/lv_demo_render.h
+0 −4 demos/transform/lv_demo_transform.c
+12 −0 demos/transform/lv_demo_transform.h
+12 −0 demos/widgets/lv_demo_widgets.h
+3 −3 docs/overview/display.rst
+8 −0 docs/widgets/calendar.rst
+1 −1 examples/others/file_explorer/lv_example_file_explorer_2.c
+1 −1 examples/others/fragment/lv_example_fragment_2.c
+3 −3 examples/porting/lv_port_disp_template.c
+6 −0 lv_conf_template.h
+2 −2 scripts/LVGLImage.py
+4 −4 scripts/code-format.py
+34 −4 scripts/style_api_gen.py
+4 −4 src/core/lv_obj_pos.c
+1 −1 src/core/lv_obj_scroll.c
+6 −2 src/core/lv_obj_style_gen.c
+32 −20 src/core/lv_obj_style_gen.h
+3 −3 src/core/lv_obj_tree.c
+1 −1 src/core/lv_obj_tree.h
+2 −7 src/dev/display/drm/lv_linux_drm.c
+4 −5 src/dev/display/fb/lv_linux_fbdev.c
+1 −1 src/dev/evdev/lv_evdev.c
+3 −14 src/dev/nuttx/lv_nuttx_fbdev.c
+1 −2 src/dev/nuttx/lv_nuttx_lcd.c
+1 −1 src/dev/sdl/lv_sdl_keyboard.c
+1 −1 src/dev/sdl/lv_sdl_mouse.c
+1 −1 src/dev/sdl/lv_sdl_mousewheel.c
+45 −47 src/dev/sdl/lv_sdl_window.c
+2 −0 src/dev/sdl/lv_sdl_window.h
+1 −1 src/dev/vg_lite_tvg/vg_lite_matrix.c
+41 −41 src/dev/vg_lite_tvg/vg_lite_tvg.cpp
+3 −3 src/dev/x11/lv_x11_display.c
+44 −13 src/display/lv_display.c
+17 −17 src/display/lv_display.h
+2 −0 src/display/lv_display_private.h
+3 −0 src/draw/vg_lite/lv_draw_buf_vg_lite.c
+1 −1 src/draw/vg_lite/lv_draw_vg_lite_vector.c
+1 −0 src/draw/vg_lite/lv_vg_lite_utils.c
+2 −2 src/indev/lv_indev.c
+2 −2 src/indev/lv_indev.h
+4 −2 src/lv_api_map.h
+18 −0 src/lv_conf_internal.h
+4 −0 src/misc/lv_style.c
+5 −0 src/misc/lv_style_gen.c
+42 −30 src/misc/lv_style_gen.h
+68 −10 src/others/observer/lv_observer.c
+12 −0 src/others/observer/lv_observer.h
+1 −1 src/others/snapshot/lv_snapshot.c
+1 −1 src/themes/lv_theme.c
+1 −1 src/widgets/buttonmatrix/lv_buttonmatrix.c
+41 −2 src/widgets/calendar/lv_calendar_header_dropdown.c
+13 −0 src/widgets/calendar/lv_calendar_header_dropdown.h
+1 −1 src/widgets/canvas/lv_canvas.c
+3 −3 src/widgets/image/lv_image.c
+2 −0 src/widgets/imagebutton/lv_imagebutton.c
+4 −0 src/widgets/menu/lv_menu.h
+1 −1 src/widgets/msgbox/lv_msgbox.c
+1 −1 src/widgets/tabview/lv_tabview.c
+1 −1 src/widgets/win/lv_win.c
+7 −1 tests/CMakeLists.txt
+1 −0 tests/main.py
+ tests/ref_imgs/widgets/calendar_08.png
+19 −1 tests/src/lv_test_conf.h
+2 −4 tests/src/lv_test_init.c
+12 −0 tests/src/test_cases/widgets/test_calendar.c
+1 −1 tests/src/test_cases/widgets/test_win.c

0 comments on commit bc4c8b4

Please sign in to comment.