From 5f97124e9d62a0e74698ebe9755f8fb91a60b004 Mon Sep 17 00:00:00 2001 From: pepepper Date: Mon, 17 Aug 2026 00:14:55 +0900 Subject: [PATCH] add sample program of lvgl over PEG for 5gen brain --- .gitmodules | 3 + x1/Makefile | 5 + x1/event_dumper/Makefile | 36 + x1/event_dumper/libbrain/Makefile | 23 + x1/event_dumper/libbrain/libbrain.h | 57 + x1/event_dumper/libbrain/sys.s | 39 + x1/event_dumper/linker.ld | 243 +++++ x1/event_dumper/lv_conf.h | 1526 +++++++++++++++++++++++++++ x1/event_dumper/lvgl | 1 + x1/event_dumper/main.c | 590 +++++++++++ x1/event_dumper/peg_const.h | 65 ++ x1/event_dumper/peg_func.h | 71 ++ x1/event_dumper/pseudo_peg_lib.h | 7 + 13 files changed, 2666 insertions(+) create mode 100644 .gitmodules create mode 100644 x1/event_dumper/Makefile create mode 100644 x1/event_dumper/libbrain/Makefile create mode 100644 x1/event_dumper/libbrain/libbrain.h create mode 100644 x1/event_dumper/libbrain/sys.s create mode 100644 x1/event_dumper/linker.ld create mode 100644 x1/event_dumper/lv_conf.h create mode 160000 x1/event_dumper/lvgl create mode 100644 x1/event_dumper/main.c create mode 100644 x1/event_dumper/peg_const.h create mode 100644 x1/event_dumper/peg_func.h create mode 100644 x1/event_dumper/pseudo_peg_lib.h diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..81337c6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "x1/event_dumper/lvgl"] + path = x1/event_dumper/lvgl + url = https://github.com/lvgl/lvgl diff --git a/x1/Makefile b/x1/Makefile index c09077c..43e81b0 100644 --- a/x1/Makefile +++ b/x1/Makefile @@ -46,6 +46,11 @@ injector/uboot.bin: @./extract.py -p injector/disable_mmu.elf injector/disable_mmu.bin @./extract.py -p injector/disable_mmu.elf injector/disable_mmu.bin @./injector/inject.py 0xed0000 0x700000 injector/disable_mmu.bin u-boot.bin injector/uboot.bin + +event_dumper/AppMain.bin: event_dumper/main.c + @$(CC) -nostdlib -static -fPIC -marm -march=armv7-a+fp -O0 event_dumper/main.c -o event_dumper/AppMain.elf -T event_dumper/linker.ld + @./extract.py -p event_dumper/AppMain.elf event_dumper/AppMain.bin + samplefb/AppMain.bin: @$(CC) -nostdlib -static -fPIC -marm -march=armv7-a+fp -O0 samplefb/main.c -o samplefb/AppMain.elf -T samplefb/linker.ld @./extract.py -p samplefb/AppMain.elf samplefb/AppMain.bin diff --git a/x1/event_dumper/Makefile b/x1/event_dumper/Makefile new file mode 100644 index 0000000..e1be16a --- /dev/null +++ b/x1/event_dumper/Makefile @@ -0,0 +1,36 @@ +include lvgl/lvgl.mk + +CROSS_COMPILE:=arm-none-eabi- +AS:=$(CROSS_COMPILE)as +CC:=$(CROSS_COMPILE)gcc +STRIP:=$(CROSS_COMPILE)strip +OBJCOPY:=$(CROSS_COMPILE)objcopy + +CFLAGS = -static -fno-pic -fno-pie -no-pie -marm -mcpu=cortex-a7 -O0 -I. -U__linux__ -fno-builtin-free +LDFLAGS = -nostdlib -marm -Llibbrain -lbrain -lgcc +LDFLAGS += -T linker.ld + +SRCS = main.c +SRCS += $(CSRCS) + +OBJS = $(SRCS:.c=.o) +OBJS := $(OBJS:.S=.o) + +TARGET = AppMain.bin +LIBBRAIN = libbrain/libbrain.a + +all: $(TARGET) + +%.o: %.S + $(CC) $(CFLAGS) -c $< -o $@ + +$(LIBBRAIN): + $(MAKE) -C libbrain + +$(TARGET): $(OBJS) $(LIBBRAIN) + @$(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) -o AppMain.elf + @$(OBJCOPY) -O binary AppMain.elf $(TARGET) + +clean: + rm -f $(OBJS) $(TARGET) AppMain.elf + $(MAKE) -C libbrain clean diff --git a/x1/event_dumper/libbrain/Makefile b/x1/event_dumper/libbrain/Makefile new file mode 100644 index 0000000..299e995 --- /dev/null +++ b/x1/event_dumper/libbrain/Makefile @@ -0,0 +1,23 @@ +CROSS_COMPILE := arm-linux-gnueabihf- +AS := $(CROSS_COMPILE)as +AR := $(CROSS_COMPILE)ar + +TARGET := libbrain.a +OBJS := sys.o + +ASFLAGS := -W +ARFLAGS := -crs + +.PHONY: +all: $(TARGET) + +.PHONY: +clean: + -rm -f $(TARGET) *.o + +%.o: %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(TARGET): $(OBJS) + $(AR) $(ARFLAGS) $@ $^ + diff --git a/x1/event_dumper/libbrain/libbrain.h b/x1/event_dumper/libbrain/libbrain.h new file mode 100644 index 0000000..04717c0 --- /dev/null +++ b/x1/event_dumper/libbrain/libbrain.h @@ -0,0 +1,57 @@ +#ifndef H_LIB_BRAIN_H +#define H_LIB_BRAIN_H + +typedef unsigned long size_t; +typedef void FILE; +typedef void* DIR; + +struct stat { + unsigned int flags; + unsigned int st_atim; + unsigned int st_mtim; + unsigned int st_ctim; + size_t st_size; +}; + +struct dirent { + unsigned int type; + size_t size; + size_t filename_length; + char filename[260]; +}; + +enum { + SEEK_SET = 0, + SEEK_CUR, + SEEK_END, +}; + +void *malloc(size_t size); +void *realloc(void* ptr, size_t size); +int free(void *ptr); +void *memcpy(void *dst, const void *src, size_t n); +void *memset(void *ptr, int ch, size_t n); +FILE *fopen(const char *filename, const char *mode); +int fclose(FILE *stream); +int ftell(FILE *stream); +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); +int fseek(FILE *stream, int offset, int whence); +int feof(FILE *stream); +int fflush(FILE *stream); +int fgetc(FILE *stream); +char *fgets(char *s, int n, FILE *stream); +int fputc(int ch, FILE *stream); +int fputs(const char *str, FILE *stream); +int ferror(FILE *stream); +int remove(const char *filepath); +int rename(const char *oldpath, const char *newpath); +int mkdir(const char *pathname); +int stat(const char *filepath, struct stat *buf); +int closedir(DIR *dirp); +struct dirent *readdir(DIR *dirp); +DIR *opendir(const char *pathname); + +int printf(const char *fmt,...); + +#endif diff --git a/x1/event_dumper/libbrain/sys.s b/x1/event_dumper/libbrain/sys.s new file mode 100644 index 0000000..3be20aa --- /dev/null +++ b/x1/event_dumper/libbrain/sys.s @@ -0,0 +1,39 @@ +.text +.align 4 + +.macro thunk name, addr +.global \name +.type \name, %function +\name: + ldr pc, [pc, #-4] + .word \addr +.endm + +thunk malloc, 0x600063c4 +thunk free, 0x600063c8 +thunk realloc, 0x600063d0 + +thunk fopen, 0x60006400 +thunk fclose, 0x60006404 +thunk ftell, 0x60006408 +thunk fread, 0x6000640c +thunk fwrite, 0x60006410 +thunk feof, 0x60006418 +thunk fflush, 0x6000641c +thunk fgetc, 0x60006420 +thunk fgets, 0x60006424 +thunk fputc, 0x60006428 +thunk fputs, 0x6000642c +thunk ferror, 0x60006430 +thunk remove, 0x60006434 +thunk rename, 0x60006438 +thunk mkdir, 0x6000643c +thunk stat, 0x60006444 + +thunk closedir, 0x6000644c +thunk readdir, 0x60006450 +thunk opendir, 0x60006454 + +thunk printf, 0x60092004 +thunk memset, 0x60092108 +thunk memcpy, 0x60092118 diff --git a/x1/event_dumper/linker.ld b/x1/event_dumper/linker.ld new file mode 100644 index 0000000..ac3cc75 --- /dev/null +++ b/x1/event_dumper/linker.ld @@ -0,0 +1,243 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", + "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(main) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x00010000)); . = SEGMENT_START("text-segment", 0x00010000) + SIZEOF_HEADERS; + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + PROVIDE_HIDDEN (__rel_iplt_start = .); + *(.rel.iplt) + PROVIDE_HIDDEN (__rel_iplt_end = .); + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .rel.plt : + { + *(.rel.plt) + } + .rela.plt : + { + *(.rela.plt) + } + .init : + { + KEEP (*(SORT_NONE(.init))) + } + .plt : { *(.plt) } + .iplt : { *(.iplt) } + .text 0x90000000: + { + *(.text.init) + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(SORT(.text.sorted.*)) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf.em. */ + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx) + } + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } + .ARM.exidx : + { + PROVIDE_HIDDEN (__exidx_start = .); + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + PROVIDE_HIDDEN (__exidx_end = .); + } + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : + { + PROVIDE_HIDDEN (__tdata_start = .); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + . = DATA_SEGMENT_RELRO_END (0, .); + .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } + .data : + { + PROVIDE (__data_start = .); + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + *(.data1) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we do not + pad the .data section. */ + . = ALIGN(. != 0 ? 32 / 8 : 1); + } + + . = ALIGN(32 / 8); + . = SEGMENT_START("ldata-segment", .); + . = ALIGN(32 / 8); + __end__ = .; + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1. */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions. */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2. */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2. */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions. */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3. */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF 5. */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} \ No newline at end of file diff --git a/x1/event_dumper/lv_conf.h b/x1/event_dumper/lv_conf.h new file mode 100644 index 0000000..9ef0f51 --- /dev/null +++ b/x1/event_dumper/lv_conf.h @@ -0,0 +1,1526 @@ +/** + * @file lv_conf.h + * Configuration file for v9.5.0 + */ + +/* + * Copy this file as `lv_conf.h` + * 1. simply next to `lvgl` folder + * 2. or to any other place and + * - define `LV_CONF_INCLUDE_SIMPLE`; + * - add the path as an include path. + */ + +/* clang-format off */ +#if 1 /* Set this to "1" to enable content */ + +#ifndef LV_CONF_H +#define LV_CONF_H + +/* If you need to include anything here, do it inside the `__ASSEMBLY__` guard */ +#if 0 && defined(__ASSEMBLY__) +#include "my_include.h" +#endif + +/*==================== + COLOR SETTINGS + *====================*/ + +/** Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888) */ +#define LV_COLOR_DEPTH 16 + +/*========================= + STDLIB WRAPPER SETTINGS + *=========================*/ + +/** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ +#define LV_USE_STDLIB_MALLOC LV_STDLIB_CUSTOM + +/** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ +#define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN + +/** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ +#define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN + +#define LV_STDINT_INCLUDE +#define LV_STDDEF_INCLUDE +#define LV_STDBOOL_INCLUDE +#define LV_INTTYPES_INCLUDE +#define LV_LIMITS_INCLUDE +#define LV_STDARG_INCLUDE + +#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN + /** Size of memory available for `lv_malloc()` in bytes (>= 2kB) */ + #define LV_MEM_SIZE (64 * 1024U) /**< [bytes] */ + + /** Size of the memory expand for `lv_malloc()` in bytes */ + #define LV_MEM_POOL_EXPAND_SIZE 0 + + /** Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too. */ + #define LV_MEM_ADR 0 /**< 0: unused*/ + /* Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc */ + #if LV_MEM_ADR == 0 + #undef LV_MEM_POOL_INCLUDE + #undef LV_MEM_POOL_ALLOC + #endif +#endif /*LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN*/ + +/*==================== + HAL SETTINGS + *====================*/ + +/** Default display refresh, input device read and animation step period. */ +#define LV_DEF_REFR_PERIOD 33 /**< [ms] */ + +/** Default Dots Per Inch. Used to initialize default sizes such as widgets sized, style paddings. + * (Not so important, you can adjust it to modify default sizes and spaces.) */ +#define LV_DPI_DEF 130 /**< [px/inch] */ + +/*================= + * OPERATING SYSTEM + *=================*/ +/** Select operating system to use. Possible options: + * - LV_OS_NONE + * - LV_OS_PTHREAD + * - LV_OS_FREERTOS + * - LV_OS_CMSIS_RTOS2 + * - LV_OS_RTTHREAD + * - LV_OS_WINDOWS + * - LV_OS_MQX + * - LV_OS_SDL2 + * - LV_OS_CUSTOM */ +#define LV_USE_OS LV_OS_NONE + +#if LV_USE_OS == LV_OS_CUSTOM + #define LV_OS_CUSTOM_INCLUDE +#endif +#if LV_USE_OS == LV_OS_FREERTOS + /* + * Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM + * than unblocking a task using an intermediary object such as a binary semaphore. + * RTOS task notifications can only be used when there is only one task that can be the recipient of the event. + */ + #define LV_USE_FREERTOS_TASK_NOTIFY 1 +#endif + +/*======================== + * RENDERING CONFIGURATION + *========================*/ + +/** Align stride of all layers and images to this bytes */ +#define LV_DRAW_BUF_STRIDE_ALIGN 1 + +/** Align start address of draw_buf addresses to this bytes*/ +#define LV_DRAW_BUF_ALIGN 4 + +/** Using matrix for transformations. + * Requirements: + * - `LV_USE_MATRIX = 1`. + * - Rendering engine needs to support 3x3 matrix transformations. */ +#define LV_DRAW_TRANSFORM_USE_MATRIX 0 + +/* If a widget has `style_opa < 255` (not `bg_opa`, `text_opa` etc) or not NORMAL blend mode + * it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks. + * "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers + * and can't be drawn in chunks. */ + +/** The target buffer size for simple layer chunks. */ +#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /**< [bytes]*/ + +/* Limit the max allocated memory for simple and transformed layers. + * It should be at least `LV_DRAW_LAYER_SIMPLE_BUF_SIZE` sized but if transformed layers are also used + * it should be enough to store the largest widget too (width x height x 4 area). + * Set it to 0 to have no limit. */ +#define LV_DRAW_LAYER_MAX_MEMORY 0 /**< No limit by default [bytes]*/ + +/** Stack size of drawing thread. + * NOTE: If FreeType or ThorVG is enabled, it is recommended to set it to 32KB or more. + */ +#define LV_DRAW_THREAD_STACK_SIZE (8 * 1024) /**< [bytes]*/ + +/** Thread priority of the drawing task. + * Higher values mean higher priority. + * Can use values from lv_thread_prio_t enum in lv_os.h: LV_THREAD_PRIO_LOWEST, + * LV_THREAD_PRIO_LOW, LV_THREAD_PRIO_MID, LV_THREAD_PRIO_HIGH, LV_THREAD_PRIO_HIGHEST + * Make sure the priority value aligns with the OS-specific priority levels. + * On systems with limited priority levels (e.g., FreeRTOS), a higher value can improve + * rendering performance but might cause other tasks to starve. */ +#define LV_DRAW_THREAD_PRIO LV_THREAD_PRIO_HIGH + +#define LV_USE_DRAW_SW 1 +#if LV_USE_DRAW_SW == 1 + /* + * Selectively disable color format support in order to reduce code size. + * NOTE: some features use certain color formats internally, e.g. + * - gradients use RGB888 + * - bitmaps with transparency may use ARGB8888 + */ + #define LV_DRAW_SW_SUPPORT_RGB565 1 + #define LV_DRAW_SW_SUPPORT_RGB565_SWAPPED 1 + #define LV_DRAW_SW_SUPPORT_RGB565A8 1 + #define LV_DRAW_SW_SUPPORT_RGB888 1 + #define LV_DRAW_SW_SUPPORT_XRGB8888 1 + #define LV_DRAW_SW_SUPPORT_ARGB8888 1 + #define LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED 1 + #define LV_DRAW_SW_SUPPORT_L8 1 + #define LV_DRAW_SW_SUPPORT_AL88 1 + #define LV_DRAW_SW_SUPPORT_A8 1 + #define LV_DRAW_SW_SUPPORT_I1 1 + + /* The threshold of the luminance to consider a pixel as + * active in indexed color format */ + #define LV_DRAW_SW_I1_LUM_THRESHOLD 127 + + /** Set number of draw units. + * - > 1 requires operating system to be enabled in `LV_USE_OS`. + * - > 1 means multiple threads will render the screen in parallel. */ + #define LV_DRAW_SW_DRAW_UNIT_CNT 1 + + /** Use Arm-2D to accelerate software (sw) rendering. */ + #define LV_USE_DRAW_ARM2D_SYNC 0 + + /** Enable native helium assembly to be compiled. */ + #define LV_USE_NATIVE_HELIUM_ASM 0 + + /** + * - 0: Use a simple renderer capable of drawing only simple rectangles with gradient, images, text, and straight lines only. + * - 1: Use a complex renderer capable of drawing rounded corners, shadow, skew lines, and arcs too. */ + #define LV_DRAW_SW_COMPLEX 1 + + #if LV_DRAW_SW_COMPLEX == 1 + /** Allow buffering some shadow calculation. + * LV_DRAW_SW_SHADOW_CACHE_SIZE is the maximum shadow size to buffer, where shadow size is + * `shadow_width + radius`. Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost. */ + #define LV_DRAW_SW_SHADOW_CACHE_SIZE 0 + + /** Set number of maximally-cached circle data. + * The circumference of 1/4 circle are saved for anti-aliasing. + * `radius * 4` bytes are used per circle (the most often used radiuses are saved). + * - 0: disables caching */ + #define LV_DRAW_SW_CIRCLE_CACHE_SIZE 4 + #endif + + #define LV_USE_DRAW_SW_ASM LV_DRAW_SW_ASM_NONE + + #if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM + #define LV_DRAW_SW_ASM_CUSTOM_INCLUDE "" + #endif + + /** Enable drawing complex gradients in software: linear at an angle, radial or conical */ + #define LV_USE_DRAW_SW_COMPLEX_GRADIENTS 0 + +#endif + +/*Use TSi's aka (Think Silicon) NemaGFX */ +#define LV_USE_NEMA_GFX 0 + +#if LV_USE_NEMA_GFX + /** Select which NemaGFX static library headers to use. Possible options: + * - LV_NEMA_LIB_NONE an alias of LV_NEMA_LIB_M33_REVC + * - LV_NEMA_LIB_M33_REVC + * - LV_NEMA_LIB_M33_NEMAPVG + * - LV_NEMA_LIB_M55 + * - LV_NEMA_LIB_M7 + * You must also take care to link the correct corresponding static library + * in libs/nema_gfx/lib/core/ + */ + #define LV_USE_NEMA_LIB LV_NEMA_LIB_NONE + + /** Select which NemaGFX HAL to use. Possible options: + * - LV_NEMA_HAL_CUSTOM + * - LV_NEMA_HAL_STM32 */ + #define LV_USE_NEMA_HAL LV_NEMA_HAL_CUSTOM + #if LV_USE_NEMA_HAL == LV_NEMA_HAL_STM32 + #define LV_NEMA_STM32_HAL_INCLUDE + + /** Set it to a value like __attribute__((section("Nemagfx_Memory_Pool_Buffer"))) + * and define the section in the linker script if you need the GPU memory to + * be, e.g. in a region where accesses will not be cached. + */ + #define LV_NEMA_STM32_HAL_ATTRIBUTE_POOL_MEM + #endif + + /*Enable Vector Graphics Operations. Available only if NemaVG library is present*/ + #define LV_USE_NEMA_VG 0 + #if LV_USE_NEMA_VG + /*Define application's resolution used for VG related buffer allocation */ + #define LV_NEMA_GFX_MAX_RESX 800 + #define LV_NEMA_GFX_MAX_RESY 600 + #endif +#endif + +/** Use NXP's PXP on iMX RTxxx platforms. */ +#define LV_USE_PXP 0 + +#if LV_USE_PXP + /** Use PXP for drawing.*/ + #define LV_USE_DRAW_PXP 1 + + /** Use PXP to rotate display.*/ + #define LV_USE_ROTATE_PXP 0 + + #if LV_USE_DRAW_PXP && LV_USE_OS + /** Use additional draw thread for PXP processing.*/ + #define LV_USE_PXP_DRAW_THREAD 1 + #endif + + /** Enable PXP asserts. */ + #define LV_USE_PXP_ASSERT 0 +#endif + +/** Use NXP's G2D on MPU platforms. */ +#define LV_USE_G2D 0 + +#if LV_USE_G2D + /** Use G2D for drawing. **/ + #define LV_USE_DRAW_G2D 1 + + /** Use G2D to rotate display. **/ + #define LV_USE_ROTATE_G2D 0 + + /** Maximum number of buffers that can be stored for G2D draw unit. + * Includes the frame buffers and assets. */ + #define LV_G2D_HASH_TABLE_SIZE 50 + + #if LV_USE_DRAW_G2D && LV_USE_OS + /** Use additional draw thread for G2D processing.*/ + #define LV_USE_G2D_DRAW_THREAD 1 + #endif + + /** Enable G2D asserts. */ + #define LV_USE_G2D_ASSERT 0 +#endif + +/** Use Renesas Dave2D on RA platforms. */ +#define LV_USE_DRAW_DAVE2D 0 + +/** Draw using cached SDL textures*/ +#define LV_USE_DRAW_SDL 0 + +/** Use VG-Lite GPU. */ +#define LV_USE_DRAW_VG_LITE 0 +#if LV_USE_DRAW_VG_LITE + /** Enable VG-Lite custom external 'gpu_init()' function */ + #define LV_VG_LITE_USE_GPU_INIT 0 + + /** Enable VG-Lite assert. */ + #define LV_VG_LITE_USE_ASSERT 0 + + /** VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */ + #define LV_VG_LITE_FLUSH_MAX_COUNT 8 + + /** Enable border to simulate shadow. + * NOTE: which usually improves performance, + * but does not guarantee the same rendering quality as the software. */ + #define LV_VG_LITE_USE_BOX_SHADOW 1 + + /** VG-Lite gradient maximum cache number. + * @note The memory usage of a single gradient image is 4K bytes. */ + #define LV_VG_LITE_GRAD_CACHE_CNT 32 + + /** VG-Lite stroke maximum cache number. */ + #define LV_VG_LITE_STROKE_CACHE_CNT 32 + + /** VG-Lite unaligned bitmap font maximum cache number. */ + #define LV_VG_LITE_BITMAP_FONT_CACHE_CNT 256 + + /** Remove VLC_OP_CLOSE path instruction (Workaround for NXP) **/ + #define LV_VG_LITE_DISABLE_VLC_OP_CLOSE 0 + + /** Disable blit rectangular offset to resolve certain hardware errors. */ + #define LV_VG_LITE_DISABLE_BLIT_RECT_OFFSET 0 + + /** Disable linear gradient extension for some older versions of drivers. */ + #define LV_VG_LITE_DISABLE_LINEAR_GRADIENT_EXT 0 + + /** Maximum path dump print length (in points) */ + #define LV_VG_LITE_PATH_DUMP_MAX_LEN 1000 + + /** Enable usage of the LVGL's built-in vg_lite driver */ + #define LV_USE_VG_LITE_DRIVER 0 + #if LV_USE_VG_LITE_DRIVER + /** Used to pick the correct GPU series folder valid options are gc255, gc355 and gc555*/ + #define LV_VG_LITE_HAL_GPU_SERIES gc255 + + /** Used to pick the correct GPU revision header it depends on the vendor */ + #define LV_VG_LITE_HAL_GPU_REVISION 0x40 + + /** Base memory address of the GPU IP it depends on SoC, + * default value is for NXP based devices */ + #define LV_VG_LITE_HAL_GPU_BASE_ADDRESS 0x40240000 + #endif /*LV_USE_VG_LITE_DRIVER*/ + + /** Use ThorVG (a software vector library) as VG-Lite driver to allow testing VGLite on PC + * Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ + #define LV_USE_VG_LITE_THORVG 0 + #if LV_USE_VG_LITE_THORVG + /** Enable LVGL's blend mode support */ + #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0 + + /** Enable YUV color format support */ + #define LV_VG_LITE_THORVG_YUV_SUPPORT 0 + + /** Enable Linear gradient extension support */ + #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0 + + /** Enable alignment on 16 pixels */ + #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 + + /** Buffer address alignment */ + #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN 64 + + /** Enable multi-thread render */ + #define LV_VG_LITE_THORVG_THREAD_RENDER 0 + #endif /*LV_USE_VG_LITE_THORVG*/ +#endif + +/** Accelerate blends, fills, etc. with STM32 DMA2D */ +#define LV_USE_DRAW_DMA2D 0 +#if LV_USE_DRAW_DMA2D + #define LV_DRAW_DMA2D_HAL_INCLUDE "stm32h7xx_hal.h" + + /* if enabled, the user is required to call `lv_draw_dma2d_transfer_complete_interrupt_handler` + * upon receiving the DMA2D global interrupt + */ + #define LV_USE_DRAW_DMA2D_INTERRUPT 0 +#endif + +/** Draw using cached OpenGLES textures. Requires LV_USE_OPENGLES */ +#define LV_USE_DRAW_OPENGLES 0 +#if LV_USE_DRAW_OPENGLES + #define LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT 64 +#endif + +/** Draw using espressif PPA accelerator */ +#define LV_USE_PPA 0 +#if LV_USE_PPA + #define LV_USE_PPA_IMG 0 + #define LV_PPA_BURST_LENGTH 128 +#endif + +/* Use EVE FT81X GPU. */ +#define LV_USE_DRAW_EVE 0 +#if LV_USE_DRAW_EVE + /* EVE_GEN value: 2, 3, or 4 */ + #define LV_DRAW_EVE_EVE_GENERATION 4 + + /* The maximum number of bytes to buffer before a single SPI transmission. + * Set it to 0 to disable write buffering. + */ + #define LV_DRAW_EVE_WRITE_BUFFER_SIZE 2048 +#endif + +/** Use NanoVG Renderer + * - Requires LV_USE_NANOVG, LV_USE_MATRIX. + */ +#define LV_USE_DRAW_NANOVG 0 +#if LV_USE_DRAW_NANOVG + /** Select OpenGL backend for NanoVG: + * - LV_NANOVG_BACKEND_GL2: OpenGL 2.0 + * - LV_NANOVG_BACKEND_GL3: OpenGL 3.0+ + * - LV_NANOVG_BACKEND_GLES2: OpenGL ES 2.0 + * - LV_NANOVG_BACKEND_GLES3: OpenGL ES 3.0+ + */ + #define LV_NANOVG_BACKEND LV_NANOVG_BACKEND_GLES2 + + /** Draw image texture cache count. */ + #define LV_NANOVG_IMAGE_CACHE_CNT 128 + + /** Draw letter texture cache count. */ + #define LV_NANOVG_LETTER_CACHE_CNT 512 +#endif + +/*======================= + * FEATURE CONFIGURATION + *=======================*/ + +/*------------- + * Logging + *-----------*/ + +/** Enable log module */ +#define LV_USE_LOG 0 +#if LV_USE_LOG + /** Set value to one of the following levels of logging detail: + * - LV_LOG_LEVEL_TRACE Log detailed information. + * - LV_LOG_LEVEL_INFO Log important events. + * - LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem. + * - LV_LOG_LEVEL_ERROR Log only critical issues, when system may fail. + * - LV_LOG_LEVEL_USER Log only custom log messages added by the user. + * - LV_LOG_LEVEL_NONE Do not log anything. */ + #define LV_LOG_LEVEL LV_LOG_LEVEL_WARN + + /** - 1: Print log with 'printf'; + * - 0: User needs to register a callback with `lv_log_register_print_cb()`. */ + #define LV_LOG_PRINTF 0 + + /** Set callback to print logs. + * E.g `my_print`. The prototype should be `void my_print(lv_log_level_t level, const char * buf)`. + * Can be overwritten by `lv_log_register_print_cb`. */ + //#define LV_LOG_PRINT_CB + + /** - 1: Enable printing timestamp; + * - 0: Disable printing timestamp. */ + #define LV_LOG_USE_TIMESTAMP 1 + + /** - 1: Print file and line number of the log; + * - 0: Do not print file and line number of the log. */ + #define LV_LOG_USE_FILE_LINE 1 + + /* Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs. */ + #define LV_LOG_TRACE_MEM 1 /**< Enable/disable trace logs in memory operations. */ + #define LV_LOG_TRACE_TIMER 1 /**< Enable/disable trace logs in timer operations. */ + #define LV_LOG_TRACE_INDEV 1 /**< Enable/disable trace logs in input device operations. */ + #define LV_LOG_TRACE_DISP_REFR 1 /**< Enable/disable trace logs in display re-draw operations. */ + #define LV_LOG_TRACE_EVENT 1 /**< Enable/disable trace logs in event dispatch logic. */ + #define LV_LOG_TRACE_OBJ_CREATE 1 /**< Enable/disable trace logs in object creation (core `obj` creation plus every widget). */ + #define LV_LOG_TRACE_LAYOUT 1 /**< Enable/disable trace logs in flex- and grid-layout operations. */ + #define LV_LOG_TRACE_ANIM 1 /**< Enable/disable trace logs in animation logic. */ + #define LV_LOG_TRACE_CACHE 1 /**< Enable/disable trace logs in cache operations. */ +#endif /*LV_USE_LOG*/ + +/*------------- + * Asserts + *-----------*/ + +/* Enable assertion failures if an operation fails or invalid data is found. + * If LV_USE_LOG is enabled, an error message will be printed on failure. */ +#define LV_USE_ASSERT_NULL 1 /**< Check if the parameter is NULL. (Very fast, recommended) */ +#define LV_USE_ASSERT_MALLOC 1 /**< Checks is the memory is successfully allocated or no. (Very fast, recommended) */ +#define LV_USE_ASSERT_STYLE 0 /**< Check if the styles are properly initialized. (Very fast, recommended) */ +#define LV_USE_ASSERT_MEM_INTEGRITY 0 /**< Check the integrity of `lv_mem` after critical operations. (Slow) */ +#define LV_USE_ASSERT_OBJ 0 /**< Check the object's type and existence (e.g. not deleted). (Slow) */ + +/** Add a custom handler when assert happens e.g. to restart MCU. */ +#define LV_ASSERT_HANDLER_INCLUDE +#define LV_ASSERT_HANDLER while(1); /**< Halt by default */ + +/*------------- + * Debug + *-----------*/ + +/** 1: Draw random colored rectangles over the redrawn areas. */ +#define LV_USE_REFR_DEBUG 0 + +/** 1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/ +#define LV_USE_LAYER_DEBUG 0 + +/** 1: Adds the following behaviors for debugging: + * - Draw overlays with different colors for each draw_unit's tasks. + * - Draw index number of draw unit on white background. + * - For layers, draws index number of draw unit on black background. */ +#define LV_USE_PARALLEL_DRAW_DEBUG 0 + +/*------------- + * Others + *-----------*/ + +#define LV_ENABLE_GLOBAL_CUSTOM 0 +#if LV_ENABLE_GLOBAL_CUSTOM + /** Header to include for custom 'lv_global' function" */ + #define LV_GLOBAL_CUSTOM_INCLUDE +#endif + +/** Default cache size in bytes. + * Used by image decoders such as `lv_lodepng` to keep the decoded image in memory. + * 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 memory will be + * released immediately after use. */ +#define LV_CACHE_DEF_SIZE 0 + +/** Default number of image header cache entries. The cache is used to store the headers of images + * The main logic is like `LV_CACHE_DEF_SIZE` but for image headers. */ +#define LV_IMAGE_HEADER_CACHE_DEF_CNT 0 + +/** Number of stops allowed per gradient. Increase this to allow more stops. + * This adds (sizeof(lv_color_t) + 1) bytes per additional stop. */ +#define LV_GRADIENT_MAX_STOPS 2 + +/** Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. + * - 0: round down, + * - 64: round up from x.75, + * - 128: round up from half, + * - 192: round up from x.25, + * - 254: round up */ +#define LV_COLOR_MIX_ROUND_OFS 0 + +/** Add 2 x 32-bit variables to each `lv_obj_t` to speed up getting style properties */ +#define LV_OBJ_STYLE_CACHE 0 + +/** Add `id` field to `lv_obj_t` */ +#define LV_USE_OBJ_ID 0 + +/** Enable support widget names*/ +#define LV_USE_OBJ_NAME 0 + +/** Automatically assign an ID when obj is created */ +#define LV_OBJ_ID_AUTO_ASSIGN LV_USE_OBJ_ID + +/** Use builtin obj ID handler functions: +* - lv_obj_assign_id: Called when a widget is created. Use a separate counter for each widget class as an ID. +* - lv_obj_id_compare: Compare the ID to decide if it matches with a requested value. +* - lv_obj_stringify_id: Return string-ified identifier, e.g. "button3". +* - lv_obj_free_id: Does nothing, as there is no memory allocation for the ID. +* When disabled these functions needs to be implemented by the user.*/ +#define LV_USE_OBJ_ID_BUILTIN 1 + +/** Use obj property set/get API. */ +#define LV_USE_OBJ_PROPERTY 0 + +/** Enable property name support. */ +#define LV_USE_OBJ_PROPERTY_NAME 1 + +/* Enable the multi-touch gesture recognition feature */ +/* Gesture recognition requires the use of floats */ +#define LV_USE_GESTURE_RECOGNITION 0 + +/*===================== + * COMPILER SETTINGS + *====================*/ + +/** For big endian systems set to 1 */ +#define LV_BIG_ENDIAN_SYSTEM 0 + +/** Define a custom attribute for `lv_tick_inc` function */ +#define LV_ATTRIBUTE_TICK_INC + +/** Define a custom attribute for `lv_timer_handler` function */ +#define LV_ATTRIBUTE_TIMER_HANDLER + +/** Define a custom attribute for `lv_display_flush_ready` function */ +#define LV_ATTRIBUTE_FLUSH_READY + +/** Align VG_LITE buffers on this number of bytes. + * @note vglite_src_buf_aligned() uses this value to validate alignment of passed buffer pointers. */ +#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1 + +/** Will be added where memory needs to be aligned (with -Os data might not be aligned to boundary by default). + * E.g. __attribute__((aligned(4)))*/ +#define LV_ATTRIBUTE_MEM_ALIGN + +/** Attribute to mark large constant arrays, for example for font bitmaps */ +#define LV_ATTRIBUTE_LARGE_CONST + +/** Compiler prefix for a large array declaration in RAM */ +#define LV_ATTRIBUTE_LARGE_RAM_ARRAY + +/** Place performance critical functions into a faster memory (e.g RAM) */ +#define LV_ATTRIBUTE_FAST_MEM + +/** Export integer constant to binding. This macro is used with constants in the form of LV_ that + * should also appear on LVGL binding API such as MicroPython. */ +#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /**< The default value just prevents GCC warning */ + +/** Prefix all global extern data with this */ +#define LV_ATTRIBUTE_EXTERN_DATA + +/** Use `float` as `lv_value_precise_t` */ +#define LV_USE_FLOAT 0 + +/** Enable matrix support + * - Requires `LV_USE_FLOAT = 1` */ +#define LV_USE_MATRIX 0 + +/** Include `lvgl_private.h` in `lvgl.h` to access internal data and functions by default */ +#ifndef LV_USE_PRIVATE_API + #define LV_USE_PRIVATE_API 0 +#endif + +/*================== + * FONT USAGE + *===================*/ + +/* Montserrat fonts with ASCII range and some symbols using bpp = 4 + * https://fonts.google.com/specimen/Montserrat */ +#define LV_FONT_MONTSERRAT_8 0 +#define LV_FONT_MONTSERRAT_10 0 +#define LV_FONT_MONTSERRAT_12 0 +#define LV_FONT_MONTSERRAT_14 1 +#define LV_FONT_MONTSERRAT_16 0 +#define LV_FONT_MONTSERRAT_18 0 +#define LV_FONT_MONTSERRAT_20 0 +#define LV_FONT_MONTSERRAT_22 0 +#define LV_FONT_MONTSERRAT_24 0 +#define LV_FONT_MONTSERRAT_26 0 +#define LV_FONT_MONTSERRAT_28 0 +#define LV_FONT_MONTSERRAT_30 0 +#define LV_FONT_MONTSERRAT_32 0 +#define LV_FONT_MONTSERRAT_34 0 +#define LV_FONT_MONTSERRAT_36 0 +#define LV_FONT_MONTSERRAT_38 0 +#define LV_FONT_MONTSERRAT_40 0 +#define LV_FONT_MONTSERRAT_42 0 +#define LV_FONT_MONTSERRAT_44 0 +#define LV_FONT_MONTSERRAT_46 0 +#define LV_FONT_MONTSERRAT_48 0 + +/* Demonstrate special features */ +#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /**< bpp = 3 */ +#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /**< Hebrew, Arabic, Persian letters and all their forms */ +#define LV_FONT_SOURCE_HAN_SANS_SC_14_CJK 0 /**< 1338 most common CJK radicals */ +#define LV_FONT_SOURCE_HAN_SANS_SC_16_CJK 0 /**< 1338 most common CJK radicals */ + +/** Pixel perfect monospaced fonts */ +#define LV_FONT_UNSCII_8 0 +#define LV_FONT_UNSCII_16 0 + +/** Optionally declare custom fonts here. + * + * You can use any of these fonts as the default font too and they will be available + * globally. Example: + * + * @code + * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2) + * @endcode + */ +#define LV_FONT_CUSTOM_DECLARE + +/** Always set a default font */ +#define LV_FONT_DEFAULT &lv_font_montserrat_14 + +/** Enable handling large font and/or fonts with a lot of characters. + * The limit depends on the font size, font face and bpp. + * A compiler error will be triggered if a font needs it. */ +#define LV_FONT_FMT_TXT_LARGE 0 + +/** Enables/disables support for compressed fonts. */ +#define LV_USE_FONT_COMPRESSED 0 + +/** Enable drawing placeholders when glyph dsc is not found. */ +#define LV_USE_FONT_PLACEHOLDER 1 + +/*================= + * TEXT SETTINGS + *=================*/ + +/** + * Select a character encoding for strings. + * Your IDE or editor should have the same character encoding. + * - LV_TXT_ENC_UTF8 + * - LV_TXT_ENC_ASCII + */ +#define LV_TXT_ENC LV_TXT_ENC_UTF8 + +/** While rendering text strings, break (wrap) text on these chars. */ +#define LV_TXT_BREAK_CHARS " ,.;:-_)]}" + +/** If a word is at least this long, will break wherever "prettiest". + * To disable, set to a value <= 0. */ +#define LV_TXT_LINE_BREAK_LONG_LEN 0 + +/** Minimum number of characters in a long word to put on a line before a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ +#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 + +/** Minimum number of characters in a long word to put on a line after a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ +#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 + +/** Support bidirectional text. Allows mixing Left-to-Right and Right-to-Left text. + * The direction will be processed according to the Unicode Bidirectional Algorithm: + * https://www.w3.org/International/articles/inline-bidi-markup/uba-basics */ +#define LV_USE_BIDI 0 +#if LV_USE_BIDI + /*Set the default direction. Supported values: + *`LV_BASE_DIR_LTR` Left-to-Right + *`LV_BASE_DIR_RTL` Right-to-Left + *`LV_BASE_DIR_AUTO` detect text base direction*/ + #define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO +#endif + +/** Enable Arabic/Persian processing + * In these languages characters should be replaced with another form based on their position in the text */ +#define LV_USE_ARABIC_PERSIAN_CHARS 0 + +/*The control character to use for signaling text recoloring*/ +#define LV_TXT_COLOR_CMD "#" + +/*================== + * WIDGETS + *================*/ +/* Documentation for widgets can be found here: https://docs.lvgl.io/master/widgets/index.html . */ + +/** 1: Causes these widgets to be given default values at creation time. + * - lv_buttonmatrix_t: Get default maps: {"Btn1", "Btn2", "Btn3", "\n", "Btn4", "Btn5", ""}, else map not set. + * - lv_checkbox_t : String label set to "Check box", else set to empty string. + * - lv_dropdown_t : Options set to "Option 1", "Option 2", "Option 3", else no values are set. + * - lv_roller_t : Options set to "Option 1", "Option 2", "Option 3", "Option 4", "Option 5", else no values are set. + * - lv_label_t : Text set to "Text", else empty string. + * - lv_arclabel_t : Text set to "Arced Text", else empty string. + * */ +#define LV_WIDGETS_HAS_DEFAULT_VALUE 1 + +#define LV_USE_ANIMIMG 1 + +#define LV_USE_ARC 1 + +#define LV_USE_ARCLABEL 1 + +#define LV_USE_BAR 1 + +#define LV_USE_BUTTON 1 + +#define LV_USE_BUTTONMATRIX 1 + +#define LV_USE_CALENDAR 1 +#if LV_USE_CALENDAR + #define LV_CALENDAR_WEEK_STARTS_MONDAY 0 + #if LV_CALENDAR_WEEK_STARTS_MONDAY + #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"} + #else + #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"} + #endif + + #define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} + #define LV_USE_CALENDAR_HEADER_ARROW 1 + #define LV_USE_CALENDAR_HEADER_DROPDOWN 1 + #define LV_USE_CALENDAR_CHINESE 0 +#endif /*LV_USE_CALENDAR*/ + +#define LV_USE_CANVAS 1 + +#define LV_USE_CHART 1 + +#define LV_USE_CHECKBOX 1 + +#define LV_USE_DROPDOWN 1 /**< Requires: lv_label */ + +#define LV_USE_IMAGE 1 /**< Requires: lv_label */ + +#define LV_USE_IMAGEBUTTON 1 + +#define LV_USE_KEYBOARD 1 + +#define LV_USE_LABEL 1 +#if LV_USE_LABEL + #define LV_LABEL_TEXT_SELECTION 1 /**< Enable selecting text of the label */ + #define LV_LABEL_LONG_TXT_HINT 1 /**< Store some extra info in labels to speed up drawing of very long text */ + #define LV_LABEL_WAIT_CHAR_COUNT 3 /**< The count of wait chart */ +#endif + +#define LV_USE_LED 1 + +#define LV_USE_LINE 1 + +#define LV_USE_LIST 1 + +#define LV_USE_LOTTIE 0 /**< Requires: lv_canvas, thorvg */ + +#define LV_USE_MENU 1 + +#define LV_USE_MSGBOX 1 + +#define LV_USE_ROLLER 1 /**< Requires: lv_label */ + +#define LV_USE_SCALE 1 + +#define LV_USE_SLIDER 1 /**< Requires: lv_bar */ + +#define LV_USE_SPAN 1 +#if LV_USE_SPAN + /** A line of text can contain this maximum number of span descriptors. */ + #define LV_SPAN_SNIPPET_STACK_SIZE 64 +#endif + +#define LV_USE_SPINBOX 1 + +#define LV_USE_SPINNER 1 + +#define LV_USE_SWITCH 1 + +#define LV_USE_TABLE 1 + +#define LV_USE_TABVIEW 1 + +#define LV_USE_TEXTAREA 1 /**< Requires: lv_label */ +#if LV_USE_TEXTAREA != 0 + #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /**< [ms] */ +#endif + +#define LV_USE_TILEVIEW 1 + +#define LV_USE_WIN 1 + +#define LV_USE_3DTEXTURE 0 + +/*================== + * THEMES + *==================*/ +/* Documentation for themes can be found here: https://docs.lvgl.io/master/common-widget-features/styles/styles.html#themes . */ + +/** A simple, impressive and very complete theme */ +#define LV_USE_THEME_DEFAULT 1 +#if LV_USE_THEME_DEFAULT + /** 0: Light mode; 1: Dark mode */ + #define LV_THEME_DEFAULT_DARK 0 + + /** 1: Enable grow on press */ + #define LV_THEME_DEFAULT_GROW 1 + + /** Default transition time in ms. */ + #define LV_THEME_DEFAULT_TRANSITION_TIME 80 +#endif /*LV_USE_THEME_DEFAULT*/ + +/** A very simple theme that is a good starting point for a custom theme */ +#define LV_USE_THEME_SIMPLE 1 + +/** A theme designed for monochrome displays */ +#define LV_USE_THEME_MONO 1 + +/*================== + * LAYOUTS + *==================*/ +/* Documentation for layouts can be found here: https://docs.lvgl.io/master/common-widget-features/layouts/index.html . */ + +/** A layout similar to Flexbox in CSS. */ +#define LV_USE_FLEX 1 + +/** A layout similar to Grid in CSS. */ +#define LV_USE_GRID 1 + +/*==================== + * 3RD PARTS LIBRARIES + *====================*/ +/* Documentation for libraries can be found here: https://docs.lvgl.io/master/libs/index.html . */ + +/* File system interfaces for common APIs */ + +/** Setting a default driver letter allows skipping the driver prefix in filepaths. + * Documentation about how to use the below driver-identifier letters can be found at + * https://docs.lvgl.io/master/main-modules/fs.html#lv-fs-identifier-letters . */ +#define LV_FS_DEFAULT_DRIVER_LETTER '\0' + +/** API for fopen, fread, etc. */ +#define LV_USE_FS_STDIO 0 +#if LV_USE_FS_STDIO + #define LV_FS_STDIO_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_STDIO_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #define LV_FS_STDIO_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ +#endif + +/** API for open, read, etc. */ +#define LV_USE_FS_POSIX 0 +#if LV_USE_FS_POSIX + #define LV_FS_POSIX_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_POSIX_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #define LV_FS_POSIX_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ +#endif + +/** API for CreateFile, ReadFile, etc. */ +#define LV_USE_FS_WIN32 0 +#if LV_USE_FS_WIN32 + #define LV_FS_WIN32_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_WIN32_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #define LV_FS_WIN32_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ +#endif + +/** API for FATFS (needs to be added separately). Uses f_open, f_read, etc. */ +#define LV_USE_FS_FATFS 0 +#if LV_USE_FS_FATFS + #define LV_FS_FATFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_FATFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #define LV_FS_FATFS_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ +#endif + +/** API for memory-mapped file access. */ +#define LV_USE_FS_MEMFS 0 +#if LV_USE_FS_MEMFS + #define LV_FS_MEMFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ +#endif + +/** API for LittleFs. */ +#define LV_USE_FS_LITTLEFS 0 +#if LV_USE_FS_LITTLEFS + #define LV_FS_LITTLEFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_LITTLEFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ +#endif + +/** API for Arduino LittleFs. */ +#define LV_USE_FS_ARDUINO_ESP_LITTLEFS 0 +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_ARDUINO_ESP_LITTLEFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ +#endif + +/** API for Arduino Sd. */ +#define LV_USE_FS_ARDUINO_SD 0 +#if LV_USE_FS_ARDUINO_SD + #define LV_FS_ARDUINO_SD_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_ARDUINO_SD_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ +#endif + +/** API for UEFI */ +#define LV_USE_FS_UEFI 0 +#if LV_USE_FS_UEFI + #define LV_FS_UEFI_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ +#endif + +#define LV_USE_FS_FROGFS 0 +#if LV_USE_FS_FROGFS + #define LV_FS_FROGFS_LETTER '\0' +#endif + +/** LODEPNG decoder library */ +#define LV_USE_LODEPNG 0 + +/** PNG decoder(libpng) library */ +#define LV_USE_LIBPNG 0 + +/** BMP decoder library */ +#define LV_USE_BMP 0 + +/** JPG + split JPG decoder library. + * Split JPG is a custom format optimized for embedded systems. */ +#define LV_USE_TJPGD 0 + +/** libjpeg-turbo decoder library. + * - Supports complete JPEG specifications and high-performance JPEG decoding. */ +#define LV_USE_LIBJPEG_TURBO 0 + +/** WebP decoder library */ +#define LV_USE_LIBWEBP 0 + +/** GIF decoder library */ +#define LV_USE_GIF 0 +#if LV_USE_GIF + /** GIF decoder accelerate */ + #define LV_GIF_CACHE_DECODE_DATA 0 +#endif + +/** GStreamer library */ +#define LV_USE_GSTREAMER 0 + +/** Decode bin images to RAM */ +#define LV_BIN_DECODER_RAM_LOAD 0 + +/** RLE decompress library */ +#define LV_USE_RLE 0 + +/** QR code library */ +#define LV_USE_QRCODE 0 + +/** Barcode code library */ +#define LV_USE_BARCODE 0 + +/** FreeType library */ +#define LV_USE_FREETYPE 0 +#if LV_USE_FREETYPE + /** Let FreeType use LVGL memory and file porting */ + #define LV_FREETYPE_USE_LVGL_PORT 0 + + /** Cache count of glyphs in FreeType, i.e. number of glyphs that can be cached. + * The higher the value, the more memory will be used. */ + #define LV_FREETYPE_CACHE_FT_GLYPH_CNT 256 +#endif + +/** Built-in TTF decoder */ +#define LV_USE_TINY_TTF 0 +#if LV_USE_TINY_TTF + /* Enable loading TTF data from files */ + #define LV_TINY_TTF_FILE_SUPPORT 0 + #define LV_TINY_TTF_CACHE_GLYPH_CNT 128 + #define LV_TINY_TTF_CACHE_KERNING_CNT 256 +#endif + +/** Rlottie library */ +#define LV_USE_RLOTTIE 0 + +/** Requires `LV_USE_3DTEXTURE = 1` */ +#define LV_USE_GLTF 0 + +/** Enable Vector Graphic APIs + * Requires `LV_USE_MATRIX = 1` + * and a rendering engine supporting vector graphics, e.g. + * (LV_USE_DRAW_SW and LV_USE_THORVG) or LV_USE_DRAW_VG_LITE or LV_USE_NEMA_VG. */ +#define LV_USE_VECTOR_GRAPHIC 0 + +/** Enable ThorVG (vector graphics library) from the src/libs folder. + * Requires LV_USE_VECTOR_GRAPHIC */ +#define LV_USE_THORVG_INTERNAL 0 + +/** Enable ThorVG by assuming that its installed and linked to the project + * Requires LV_USE_VECTOR_GRAPHIC */ +#define LV_USE_THORVG_EXTERNAL 0 + +/** Enable NanoVG (vector graphics library) */ +#define LV_USE_NANOVG 0 + +/** Use lvgl built-in LZ4 lib */ +#define LV_USE_LZ4_INTERNAL 0 + +/** Use external LZ4 library */ +#define LV_USE_LZ4_EXTERNAL 0 + +/*SVG library + * - Requires `LV_USE_VECTOR_GRAPHIC = 1` */ +#define LV_USE_SVG 0 +#define LV_USE_SVG_ANIMATION 0 +#define LV_USE_SVG_DEBUG 0 + +/** FFmpeg library for image decoding and playing videos. + * Supports all major image formats so do not enable other image decoder with it. */ +#define LV_USE_FFMPEG 0 +#if LV_USE_FFMPEG + /** Dump input information to stderr */ + #define LV_FFMPEG_DUMP_FORMAT 0 + /** Use lvgl file path in FFmpeg Player widget + * You won't be able to open URLs after enabling this feature. + * Note that FFmpeg image decoder will always use lvgl file system. */ + #define LV_FFMPEG_PLAYER_USE_LV_FS 0 +#endif + +/*================== + * OTHERS + *==================*/ +/* Documentation for several of the below items can be found here: https://docs.lvgl.io/master/auxiliary-modules/index.html . */ + +/** 1: Enable API to take snapshot for object */ +#define LV_USE_SNAPSHOT 0 + +/** 1: Enable system monitor component */ +#define LV_USE_SYSMON 0 +#if LV_USE_SYSMON + /** Get the idle percentage. E.g. uint32_t my_get_idle(void); */ + #define LV_SYSMON_GET_IDLE lv_os_get_idle_percent + /** 1: Enable usage of lv_os_get_proc_idle_percent.*/ + #define LV_SYSMON_PROC_IDLE_AVAILABLE 0 + #if LV_SYSMON_PROC_IDLE_AVAILABLE + /** Get the applications idle percentage. + * - Requires `LV_USE_OS == LV_OS_PTHREAD` */ + #define LV_SYSMON_GET_PROC_IDLE lv_os_get_proc_idle_percent + #endif + + /** 1: Show CPU usage and FPS count. + * - Requires `LV_USE_SYSMON = 1` */ + #define LV_USE_PERF_MONITOR 0 + #if LV_USE_PERF_MONITOR + #define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT + + /** 0: Displays performance data on the screen; 1: Prints performance data using log. */ + #define LV_USE_PERF_MONITOR_LOG_MODE 0 + #endif + + /** 1: Show used memory and memory fragmentation. + * - Requires `LV_USE_STDLIB_MALLOC = LV_STDLIB_BUILTIN` + * - Requires `LV_USE_SYSMON = 1`*/ + #define LV_USE_MEM_MONITOR 0 + #if LV_USE_MEM_MONITOR + #define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT + #endif +#endif /*LV_USE_SYSMON*/ + +/** 1: Enable runtime performance profiler */ +#define LV_USE_PROFILER 0 +#if LV_USE_PROFILER + /** 1: Enable the built-in profiler */ + #define LV_USE_PROFILER_BUILTIN 1 + #if LV_USE_PROFILER_BUILTIN + /** Default profiler trace buffer size */ + #define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /**< [bytes] */ + #define LV_PROFILER_BUILTIN_DEFAULT_ENABLE 1 + #define LV_USE_PROFILER_BUILTIN_POSIX 0 /**< Enable POSIX profiler port */ + #endif + + /** Header to include for profiler */ + #define LV_PROFILER_INCLUDE "lvgl/src/misc/lv_profiler_builtin.h" + + /** Profiler start point function */ + #define LV_PROFILER_BEGIN LV_PROFILER_BUILTIN_BEGIN + + /** Profiler end point function */ + #define LV_PROFILER_END LV_PROFILER_BUILTIN_END + + /** Profiler start point function with custom tag */ + #define LV_PROFILER_BEGIN_TAG LV_PROFILER_BUILTIN_BEGIN_TAG + + /** Profiler end point function with custom tag */ + #define LV_PROFILER_END_TAG LV_PROFILER_BUILTIN_END_TAG + + /*Enable layout profiler*/ + #define LV_PROFILER_LAYOUT 1 + + /*Enable disp refr profiler*/ + #define LV_PROFILER_REFR 1 + + /*Enable draw profiler*/ + #define LV_PROFILER_DRAW 1 + + /*Enable indev profiler*/ + #define LV_PROFILER_INDEV 1 + + /*Enable decoder profiler*/ + #define LV_PROFILER_DECODER 1 + + /*Enable font profiler*/ + #define LV_PROFILER_FONT 1 + + /*Enable fs profiler*/ + #define LV_PROFILER_FS 1 + + /*Enable style profiler*/ + #define LV_PROFILER_STYLE 0 + + /*Enable timer profiler*/ + #define LV_PROFILER_TIMER 1 + + /*Enable cache profiler*/ + #define LV_PROFILER_CACHE 1 + + /*Enable event profiler*/ + #define LV_PROFILER_EVENT 1 +#endif + +/** 1: Enable Monkey test */ +#define LV_USE_MONKEY 0 + +/** 1: Enable grid navigation */ +#define LV_USE_GRIDNAV 0 + +/** 1: Enable `lv_obj` fragment logic */ +#define LV_USE_FRAGMENT 0 + +/** 1: Support using images as font in label or span widgets */ +#define LV_USE_IMGFONT 0 + +/** 1: Enable an observer pattern implementation */ +#define LV_USE_OBSERVER 1 + +/** 1: Enable Pinyin input method + * - Requires: lv_keyboard */ +#define LV_USE_IME_PINYIN 0 +#if LV_USE_IME_PINYIN + /** 1: Use default thesaurus. + * @note If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesaurus. */ + #define LV_IME_PINYIN_USE_DEFAULT_DICT 1 + /** Set maximum number of candidate panels that can be displayed. + * @note This needs to be adjusted according to size of screen. */ + #define LV_IME_PINYIN_CAND_TEXT_NUM 6 + + /** Use 9-key input (k9). */ + #define LV_IME_PINYIN_USE_K9_MODE 1 + #if LV_IME_PINYIN_USE_K9_MODE == 1 + #define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3 + #endif /*LV_IME_PINYIN_USE_K9_MODE*/ +#endif + +/** 1: Enable file explorer. + * - Requires: lv_table */ +#define LV_USE_FILE_EXPLORER 0 +#if LV_USE_FILE_EXPLORER + /** Maximum length of path */ + #define LV_FILE_EXPLORER_PATH_MAX_LEN (128) + /** Quick access bar, 1:use, 0:do not use. + * - Requires: lv_list */ + #define LV_FILE_EXPLORER_QUICK_ACCESS 1 +#endif + +/** 1: Enable Font manager */ +#define LV_USE_FONT_MANAGER 0 +#if LV_USE_FONT_MANAGER + +/**Font manager name max length*/ +#define LV_FONT_MANAGER_NAME_MAX_LEN 32 + +#endif + +/** Enable emulated input devices, time emulation, and screenshot compares. */ +#define LV_USE_TEST 0 +#if LV_USE_TEST + +/** Enable `lv_test_screenshot_compare`. + * Requires lodepng and a few MB of extra RAM. */ +#define LV_USE_TEST_SCREENSHOT_COMPARE 0 + +#if LV_USE_TEST_SCREENSHOT_COMPARE + /** 1: Automatically create missing reference images*/ + #define LV_TEST_SCREENSHOT_CREATE_REFERENCE_IMAGE 1 +#endif /*LV_USE_TEST_SCREENSHOT_COMPARE*/ + +#endif /*LV_USE_TEST*/ + +/** 1: Enable text translation support */ +#define LV_USE_TRANSLATION 0 + +/*1: Enable color filter style*/ +#define LV_USE_COLOR_FILTER 0 + +/*================== + * DEVICES + *==================*/ + +/** Use SDL to open window on PC and handle mouse and keyboard. */ +#define LV_USE_SDL 0 +#if LV_USE_SDL + #define LV_SDL_INCLUDE_PATH + #define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /**< LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance */ + #define LV_SDL_BUF_COUNT 1 /**< 1 or 2 */ + #define LV_SDL_ACCELERATED 1 /**< 1: Use hardware acceleration*/ + #define LV_SDL_FULLSCREEN 0 /**< 1: Make the window full screen by default */ + #define LV_SDL_DIRECT_EXIT 1 /**< 1: Exit the application when all SDL windows are closed */ + #define LV_SDL_MOUSEWHEEL_MODE LV_SDL_MOUSEWHEEL_MODE_ENCODER /*LV_SDL_MOUSEWHEEL_MODE_ENCODER/CROWN*/ +#endif + +/** Use X11 to open window on Linux desktop and handle mouse and keyboard */ +#define LV_USE_X11 0 +#if LV_USE_X11 + #define LV_X11_DIRECT_EXIT 1 /**< Exit application when all X11 windows have been closed */ + #define LV_X11_DOUBLE_BUFFER 1 /**< Use double buffers for rendering */ + /* Select only 1 of the following render modes (LV_X11_RENDER_MODE_PARTIAL preferred!). */ + #define LV_X11_RENDER_MODE_PARTIAL 1 /**< Partial render mode (preferred) */ + #define LV_X11_RENDER_MODE_DIRECT 0 /**< Direct render mode */ + #define LV_X11_RENDER_MODE_FULL 0 /**< Full render mode */ +#endif + +/** Use Wayland to open a window and handle input on Linux or BSD desktops */ +#define LV_USE_WAYLAND 0 +#if LV_USE_WAYLAND + #define LV_WAYLAND_DIRECT_EXIT 1 /**< 1: Exit the application when all Wayland windows are closed */ +#endif + +/** Driver for /dev/fb */ +#define LV_USE_LINUX_FBDEV 0 +#if LV_USE_LINUX_FBDEV + #define LV_LINUX_FBDEV_BSD 0 + #define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL + #define LV_LINUX_FBDEV_BUFFER_COUNT 0 + #define LV_LINUX_FBDEV_BUFFER_SIZE 60 + #define LV_LINUX_FBDEV_MMAP 1 +#endif + +/** Use Nuttx to open window and handle touchscreen */ +#define LV_USE_NUTTX 0 + +#if LV_USE_NUTTX + #define LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP 0 + + /** Use independent image heap for default draw buffer */ + #define LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP 0 + + #define LV_USE_NUTTX_LIBUV 0 + + /** Use Nuttx custom init API to open window and handle touchscreen */ + #define LV_USE_NUTTX_CUSTOM_INIT 0 + + /** Driver for /dev/lcd */ + #define LV_USE_NUTTX_LCD 0 + #if LV_USE_NUTTX_LCD + #define LV_NUTTX_LCD_BUFFER_COUNT 0 + #define LV_NUTTX_LCD_BUFFER_SIZE 60 + #endif + + /** Driver for /dev/input */ + #define LV_USE_NUTTX_TOUCHSCREEN 0 + + /** Touchscreen cursor size in pixels(<=0: disable cursor) */ + #define LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE 0 + + /** Driver for /dev/mouse */ + #define LV_USE_NUTTX_MOUSE 0 + + /** Mouse movement step (pixels) */ + #define LV_USE_NUTTX_MOUSE_MOVE_STEP 1 + + /*NuttX trace file and its path*/ + #define LV_USE_NUTTX_TRACE_FILE 0 + #if LV_USE_NUTTX_TRACE_FILE + #define LV_NUTTX_TRACE_FILE_PATH "/data/lvgl-trace.log" + #endif + +#endif + +/** Driver for /dev/dri/card */ +#define LV_USE_LINUX_DRM 0 + +#if LV_USE_LINUX_DRM + + /* Use the MESA GBM library to allocate DMA buffers that can be + * shared across sub-systems and libraries using the Linux DMA-BUF API. + * The GBM library aims to provide a platform independent memory management system + * it supports the major GPU vendors - This option requires linking with libgbm */ + #define LV_USE_LINUX_DRM_GBM_BUFFERS 0 +#endif + +/** Interface for TFT_eSPI */ +#define LV_USE_TFT_ESPI 0 + +/** Interface for Lovyan_GFX */ +#define LV_USE_LOVYAN_GFX 0 + +#if LV_USE_LOVYAN_GFX + #define LV_LGFX_USER_INCLUDE "lv_lgfx_user.hpp" + +#endif /*LV_USE_LOVYAN_GFX*/ + +/** Driver for evdev input devices */ +#define LV_USE_EVDEV 0 + +/** Driver for libinput input devices */ +#define LV_USE_LIBINPUT 0 + +#if LV_USE_LIBINPUT + #define LV_LIBINPUT_BSD 0 + + /** Full keyboard support */ + #define LV_LIBINPUT_XKB 0 + #if LV_LIBINPUT_XKB + /** "setxkbmap -query" can help find the right values for your keyboard */ + #define LV_LIBINPUT_XKB_KEY_MAP { .rules = NULL, .model = "pc101", .layout = "us", .variant = NULL, .options = NULL } + #endif +#endif + +/* Drivers for LCD devices connected via SPI/parallel port */ +#define LV_USE_ST7735 0 +#define LV_USE_ST7789 0 +#define LV_USE_ST7796 0 +#define LV_USE_ILI9341 0 +#define LV_USE_FT81X 0 +#define LV_USE_NV3007 0 + +#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341 | LV_USE_NV3007) + #define LV_USE_GENERIC_MIPI 1 +#else + #define LV_USE_GENERIC_MIPI 0 +#endif + +/** Driver for Renesas GLCD */ +#define LV_USE_RENESAS_GLCDC 0 + +/** Driver for ST LTDC */ +#define LV_USE_ST_LTDC 0 +#if LV_USE_ST_LTDC + /* Only used for partial. */ + #define LV_ST_LTDC_USE_DMA2D_FLUSH 0 +#endif + +/** Driver for NXP ELCDIF */ +#define LV_USE_NXP_ELCDIF 0 + +/** LVGL Windows backend */ +#define LV_USE_WINDOWS 0 + +/** LVGL UEFI backend */ +#define LV_USE_UEFI 0 +#if LV_USE_UEFI + #define LV_USE_UEFI_INCLUDE "myefi.h" /**< Header that hides the actual framework (EDK2, gnu-efi, ...) */ + #define LV_UEFI_USE_MEMORY_SERVICES 0 /**< Use the memory functions from the boot services table */ +#endif + +/** Use a generic OpenGL driver that can be used to embed in other applications or used with GLFW/EGL + * - Requires LV_USE_MATRIX. + */ +#define LV_USE_OPENGLES 0 +#if LV_USE_OPENGLES + #define LV_USE_OPENGLES_DEBUG 1 /**< Enable or disable debug for opengles */ +#endif + +/** Use GLFW to open window on PC and handle mouse and keyboard. Requires*/ +#define LV_USE_GLFW 0 + + +/** QNX Screen display and input drivers */ +#define LV_USE_QNX 0 +#if LV_USE_QNX + #define LV_QNX_BUF_COUNT 1 /**< 1 or 2 */ +#endif + +/** Enable or disable for external data and destructor function */ +#define LV_USE_EXT_DATA 0 + +/*===================== +* BUILD OPTIONS +*======================*/ + +/** Enable examples to be built with the library. */ +#define LV_BUILD_EXAMPLES 0 + +/** Build the demos */ +#define LV_BUILD_DEMOS 0 + +/*=================== + * DEMO USAGE + ====================*/ + +#if LV_BUILD_DEMOS + /** Show some widgets. This might be required to increase `LV_MEM_SIZE`. */ + #define LV_USE_DEMO_WIDGETS 0 + + /** Demonstrate usage of encoder and keyboard. */ + #define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 + + /** Benchmark your system */ + #define LV_USE_DEMO_BENCHMARK 0 + + #if LV_USE_DEMO_BENCHMARK + /** Use fonts where bitmaps are aligned 16 byte and has Nx16 byte stride */ + #define LV_DEMO_BENCHMARK_ALIGNED_FONTS 0 + #endif + + /** Render test for each primitive. + * - Requires at least 480x272 display. */ + #define LV_USE_DEMO_RENDER 0 + + /** Stress test for LVGL */ + #define LV_USE_DEMO_STRESS 0 + + /** Music player demo */ + #define LV_USE_DEMO_MUSIC 0 + #if LV_USE_DEMO_MUSIC + #define LV_DEMO_MUSIC_SQUARE 0 + #define LV_DEMO_MUSIC_LANDSCAPE 0 + #define LV_DEMO_MUSIC_ROUND 0 + #define LV_DEMO_MUSIC_LARGE 0 + #define LV_DEMO_MUSIC_AUTO_PLAY 0 + #endif + + /** Vector graphic demo */ + #define LV_USE_DEMO_VECTOR_GRAPHIC 0 + + /** GLTF demo */ + #define LV_USE_DEMO_GLTF 0 + + /*--------------------------- + * Demos from lvgl/lv_demos + ---------------------------*/ + + /** Flex layout demo */ + #define LV_USE_DEMO_FLEX_LAYOUT 0 + + /** Smart-phone like multi-language demo */ + #define LV_USE_DEMO_MULTILANG 0 + + /*E-bike demo with Lottie animations (if LV_USE_LOTTIE is enabled)*/ + #define LV_USE_DEMO_EBIKE 0 + #if LV_USE_DEMO_EBIKE + #define LV_DEMO_EBIKE_PORTRAIT 0 /*0: for 480x270..480x320, 1: for 480x800..720x1280*/ + #endif + + /** High-resolution demo */ + #define LV_USE_DEMO_HIGH_RES 0 + + /* Smart watch demo */ + #define LV_USE_DEMO_SMARTWATCH 0 +#endif /* LV_BUILD_DEMOS */ + +/*--END OF LV_CONF_H--*/ + +#endif /*LV_CONF_H*/ + +#endif /*End of "Content enable"*/ diff --git a/x1/event_dumper/lvgl b/x1/event_dumper/lvgl new file mode 160000 index 0000000..85aa60d --- /dev/null +++ b/x1/event_dumper/lvgl @@ -0,0 +1 @@ +Subproject commit 85aa60d18b3d5e5588d7b247abf90198f07c8a63 diff --git a/x1/event_dumper/main.c b/x1/event_dumper/main.c new file mode 100644 index 0000000..c43b74a --- /dev/null +++ b/x1/event_dumper/main.c @@ -0,0 +1,590 @@ +/* =========================================================================== + * event_dumper — LVGL running as an app on top of the Brain's PEG kernel. + * + * Architecture (iter 26, confirmed on real hardware): + * - We register as a PegDecoratedWindow with Message override (slot 19). + * - Draw dispatch (slot 12) is never invoked for us by PEG's dirty-region + * walker, so we push our own shadow buffer to the screen ourselves + * via push_shadow_to_screen(), driven from Message and a 200ms LVGL + * timer. That guarantees updates without depending on PEG's Invalidate. + * ========================================================================= */ + +#include "lvgl/lvgl.h" +#include "pseudo_peg_lib.h" + +/* libc stubs supplied by libbrain (see libbrain/sys.s). Extern-declared + * instead of `#include "libbrain/libbrain.h"` because that header defines + * `typedef unsigned long size_t` which conflicts with LVGL's `unsigned int`. */ +extern void* malloc(unsigned int size); +extern void* realloc(void* ptr, unsigned int size); +extern int free(void* ptr); +extern void* memset(void* ptr, int ch, unsigned int n); + +static PegBitmap g_lvgl_pegbmp; + +typedef struct { + void* reserved; + char* exec_path; + void* pPresent; + void* reserved2; +} app_ctx; + +/* ===== State ===== */ +static void* g_window; +static int32_t g_fb_w = 480; +static int32_t g_fb_h = 640; + +/* Saved from app_ctx so app_exit() can hand it back to sh_ExitApp */ +static char* g_exec_path; + +/* Key code (PegMessage.Param) that triggers a clean exit. Adjust after + * seeing the `key param=0x??` value in the debug label for the physical + * button you want to use. */ +#define EXIT_KEY_SCAN 0x1B + +/* LVGL renders directly into g_shadow (we own it, freed in app_exit). + * push_shadow_to_screen() blits it onto the PEG screen. */ +static uint8_t* g_shadow; +static uint32_t g_shadow_bytes; + +static volatile uint32_t g_draw_calls; +static volatile uint32_t g_msg_calls; +static volatile uint16_t g_last_msg_type; +static volatile uint16_t g_last_msg_subtype; +static volatile int32_t g_last_msg_data; + +/* Ring buffer of recent wTypes so we can see the sequence of dispatches + * regardless of frequency. */ +#define WTYPE_HISTORY_LEN 12 +static volatile uint16_t g_wtype_history[WTYPE_HISTORY_LEN]; +static volatile uint8_t g_wtype_head; + +/* Count of each wType we've received (indexed by type; only first 64 kept + * to keep the array small). Higher types get bucketed into slot 63. */ +static volatile uint32_t g_wtype_counts[64]; + +/* ---- PEG tick-rate probe (see PEG_SetTimer call in main) ---- */ +#define PROBE_TIMER_ID 0x50EC +#define PROBE_TIMER_TICKS 50 /* per docs, ONE_SECOND is typically 50 */ +static volatile uint32_t g_probe_fires; +static volatile uint32_t g_probe_first_ms; +static volatile uint32_t g_probe_last_ms; +static volatile uint32_t g_probe_last_delta_ms; + +/* Captured base Message handler for delegation */ +static msg_fn_t g_base_msg; + +/* Forward decls (definitions live at the bottom of the file) */ +uint32_t tstmr_get_millis(void); +void my_sleep(uint32_t millis); + +/* LVGL indev shared state (produced by our_Message, consumed by read_cb) */ +static lv_indev_t* g_indev_pointer; +static lv_indev_t* g_indev_keypad; +static volatile int16_t g_touch_x; +static volatile int16_t g_touch_y; +static volatile lv_indev_state_t g_touch_state = LV_INDEV_STATE_REL; +static volatile uint32_t g_key_pending; + +/* Last-input snapshots for the debug label */ +static volatile int16_t g_last_touch_x = -1; +static volatile int16_t g_last_touch_y = -1; +static volatile uint8_t g_last_touch_state; /* 0=up, 1=down */ + +/* Snapshot of the last PM_KEY* PegMessage for the debug label. Param is + * the actual key code; ExtParams[0] holds Brain's state/modifier bits. */ +static volatile int32_t g_last_key_seen = 0; /* 0 = never seen */ +static volatile uint16_t g_last_key_type; /* PM_KEY / PM_KEY_DOWN */ +static volatile uint16_t g_last_key_param; +static volatile int32_t g_last_key_ext0; +static volatile int32_t g_last_key_ext1; +static volatile int16_t g_last_key_ptx; +static volatile int16_t g_last_key_pty; +static volatile lv_indev_state_t g_key_state = LV_INDEV_STATE_REL; + +/* Brain key code (in PegMessage.Param) → LVGL key constant. */ +static uint32_t peg_key_to_lvgl(int32_t k) { + switch (k) { + case 0x0D: return LV_KEY_ENTER; + case 0x1B: return LV_KEY_ESC; + case 0x08: return LV_KEY_BACKSPACE; + case 0x20: return ' '; + case 0x25E: return LV_KEY_LEFT; + case 0x25F: return LV_KEY_DOWN; + case 0x260: return LV_KEY_UP; + case 0x261: return LV_KEY_RIGHT; + case 0x265: return 0; /* SHIFT (sticky — sets modifier bit 0x40 in + * ExtParams[0] on the next real keypress) */ + default: return (uint32_t)k; + } +} + +static void indev_pointer_read(lv_indev_t* d, lv_indev_data_t* out) { + (void)d; + out->point.x = g_touch_x; + out->point.y = g_touch_y; + out->state = g_touch_state; +} +static void indev_keypad_read(lv_indev_t* d, lv_indev_data_t* out) { + (void)d; + out->key = g_key_pending; + out->state = g_key_state; + if (g_key_state == LV_INDEV_STATE_PR) + g_key_state = LV_INDEV_STATE_REL; +} + +/* Tear down PEG + LVGL, then jump back to the launcher. + * sh_ExitApp never returns on success. + * + * Order matters: + * 1. KillTimer — stop any future PM_TIMER dispatch to a soon-to-be-freed + * window. + * 2. PEG_Destroy — posts PM_DESTROY; PresMgr unlinks us from its window + * tree and runs the dtor (which free()s the window). Async, but PEG + * typically processes the queue before yielding to the shell. + * 3. lv_deinit — releases every LVGL-owned allocation (display, indevs, + * timers, screen widgets). Uses our free() → sys_free trampoline. + * 4. free(shadow) — LVGL v9's lv_display_set_buffers doesn't take + * ownership, so the caller (us) owns it. + * 5. sh_ExitApp — launcher takes over. + */ +static void app_exit(void) { + if (g_window) { + PEG_KillTimer(g_window, PROBE_TIMER_ID); + PEG_Destroy(g_window, g_window); + g_window = NULL; + } + lv_deinit(); + if (g_shadow) { + free(g_shadow); + g_shadow = NULL; + } + if (g_exec_path) sh_ExitApp(g_exec_path); // without this, screen goes mysterious green'ish window + /* Should not reach here. Fall through returns to caller; PEG scheduler + * takes over again which is at least survivable. */ +} + +/* Push our LVGL shadow through PEG's proper draw pipeline into PEG's + * internal shadow, then EndDraw's MemoryToScreen flushes to physical FB. + * Doing this synchronously means we don't depend on PEG's Draw dispatch + * (which never fires on us — the dirty walker skips windows that aren't + * registered as top-level focus targets via STATUS bit 0x40). */ +static void push_shadow_to_screen(void) { + if (!g_shadow || !g_window) + return; + + /* mReal is embedded in every PegThing at +0x0C */ + const struct PegRect* pRect = (const struct PegRect*)((char*)g_window + 0x0C); + PEG_WinBeginDraw(g_window, pRect); + + g_lvgl_pegbmp.bpp = 0x10; + g_lvgl_pegbmp.flags = 0x00; + g_lvgl_pegbmp.wWidth = (uint16_t)g_fb_w; + g_lvgl_pegbmp.wHeight = (uint16_t)g_fb_h; + g_lvgl_pegbmp.reserved = 0; + g_lvgl_pegbmp.refcount = 1; + g_lvgl_pegbmp.pData = g_shadow; + + void* scr = PEG_GetScreen(); + if (scr) { + void** vt = *(void***)scr; + ((scr_bitmap_fn)vt[SCR_VF_BITMAP])(scr, 0, &g_lvgl_pegbmp); + ((scr_enddraw_fn)vt[SCR_VF_ENDDRAW])(scr); + } +} + +/* Debug label refreshed by a periodic LVGL timer */ +static lv_obj_t* g_dbg_label; +static void refresh_cb(lv_timer_t* t) { + (void)t; + if (g_dbg_label) { + char buf[256]; + int n = 0; + n += lv_snprintf(buf + n, sizeof(buf) - n, + "drw=%u msg=%u\n", + (unsigned)g_draw_calls, (unsigned)g_msg_calls); + n += lv_snprintf(buf + n, sizeof(buf) - n, + "hist:"); + for (int i = 0; i < WTYPE_HISTORY_LEN && n < (int)sizeof(buf) - 8; i++) { + int idx = (g_wtype_head + i) % WTYPE_HISTORY_LEN; + n += lv_snprintf(buf + n, sizeof(buf) - n, " %u", + (unsigned)g_wtype_history[idx]); + } + n += lv_snprintf(buf + n, sizeof(buf) - n, "\n"); + static const uint8_t interesting[] = {4, 6, 8, 9, 10, 11, 17, 24, 25, 28, 30, 32, 33}; + for (unsigned i = 0; i < sizeof(interesting) && n < (int)sizeof(buf) - 16; i++) { + uint8_t k = interesting[i]; + if (g_wtype_counts[k]) { + n += lv_snprintf(buf + n, sizeof(buf) - n, " t%u=%u", + k, (unsigned)g_wtype_counts[k]); + } + } + /* Last touch — coordinates + state (DN/UP) */ + if (g_last_touch_x >= 0) { + n += lv_snprintf(buf + n, sizeof(buf) - n, + "\ntouch: (%d,%d) %s", + (int)g_last_touch_x, (int)g_last_touch_y, + g_last_touch_state ? "DN" : "UP"); + } + /* Last key event: param = key code, ext0 flags (0x800 press, + * 0xC00 held, 0x40 SHIFT-sticky active). */ + if (g_last_key_seen) { + n += lv_snprintf(buf + n, sizeof(buf) - n, + "\nkey t=%u param=0x%X ext0=0x%X ext1=0x%X" + "\n pt=(%d,%d)", + (unsigned)g_last_key_type, + (unsigned)g_last_key_param, + (unsigned)g_last_key_ext0, + (unsigned)g_last_key_ext1, + (int)g_last_key_ptx, (int)g_last_key_pty); + } + /* Tick-rate probe: show fires, last delta, and cumulative average. + * SetTimer requested PROBE_TIMER_TICKS ticks per fire; delta_ms + * lets us back-calculate ms per tick. */ + if (g_probe_fires > 0) { + uint32_t avg = (g_probe_last_ms - g_probe_first_ms) / + (g_probe_fires > 1 ? g_probe_fires - 1 : 1); + n += lv_snprintf(buf + n, sizeof(buf) - n, + "\ntimer fires=%u last=%ums avg=%ums (tick~%u.%02ums)", + (unsigned)g_probe_fires, + (unsigned)g_probe_last_delta_ms, + (unsigned)avg, + (unsigned)(avg / PROBE_TIMER_TICKS), + (unsigned)((avg * 100u / PROBE_TIMER_TICKS) % 100u)); + } + lv_label_set_text(g_dbg_label, buf); + } + push_shadow_to_screen(); +} + +/* Draw override (vtable slot 12). Not currently dispatched by PEG in our + * setup — kept as a reference implementation of the proper PEG draw + * pipeline in case a future subclass configuration triggers it. */ +static void our_Draw(void* self, const struct PegRect* invalid) { + g_draw_calls++; + + /* Probe (60x60 top-left, colour cycles) */ + if (g_shadow) { + uint16_t* px = (uint16_t*)g_shadow; + uint16_t c = (uint16_t)((g_draw_calls * 0x1111) | 0x0800); + if (g_draw_calls & 1) + c ^= 0xF800; + for (int y = 0; y < 60; y++) { + uint16_t* row = px + (uint32_t)y * g_fb_w; + for (int x = 0; x < 60; x++) + row[x] = c; + } + } + + lv_timer_handler(); + + /* Proper Draw pattern per PEG docs: + * BeginDraw(invalidRect) → base Draw / custom → EndDraw() */ + PEG_WinBeginDraw(self, invalid); + PEG_WinBaseDraw(self, invalid); + + /* Custom overlay: blit our LVGL shadow */ + if (g_shadow) { + g_lvgl_pegbmp.bpp = 0x10; + g_lvgl_pegbmp.flags = 0x00; + g_lvgl_pegbmp.wWidth = (uint16_t)g_fb_w; + g_lvgl_pegbmp.wHeight = (uint16_t)g_fb_h; + g_lvgl_pegbmp.reserved = 0; + g_lvgl_pegbmp.refcount = 1; + g_lvgl_pegbmp.pData = g_shadow; + + void* scr = PEG_GetScreen(); + if (scr) { + void** scr_vt = *(void***)scr; + ((scr_bitmap_fn)scr_vt[SCR_VF_BITMAP])(scr, 0, &g_lvgl_pegbmp); + } + } + + /* Matching EndDraw — Screen()->EndDraw() per PegThing::EndDraw inline */ + { + void* scr = PEG_GetScreen(); + if (scr) { + void** scr_vt = *(void***)scr; + ((scr_enddraw_fn)scr_vt[SCR_VF_ENDDRAW])(scr); + } + } + /* NO self-Invalidate — nesting BeginDraw/EndDraw inside our_Draw is + * balanced. Continuous updates need a separate Invalidate path. */ +} + +/* ===== Message override — dispatch input events into LVGL indev ========= */ +static int32_t our_Message(void* self, const struct PegMessage* msg) { + unsigned short t = msg->Type; + unsigned short param = msg->Param; + + g_msg_calls++; + g_last_msg_type = t; + g_last_msg_subtype = param; + g_last_msg_data = msg->ExtParams[0]; + + /* Ring buffer of wTypes we've seen */ + g_wtype_history[g_wtype_head] = t; + g_wtype_head = (uint8_t)((g_wtype_head + 1) % WTYPE_HISTORY_LEN); + g_wtype_counts[t < 64 ? t : 63]++; + + /* Small Message probe (top-right corner) — just for visual confirmation + * that Message dispatch is reaching us. Written into shadow only; + * push_shadow_to_screen below flushes it. */ + if (g_shadow) { + uint16_t* sh = (uint16_t*)g_shadow; + uint16_t c = (uint16_t)((g_msg_calls * 0x2108) | 0x0400); + int32_t x0 = g_fb_w - 60; + for (int y = 0; y < 60; y++) { + uint16_t* row = sh + (uint32_t)y * g_fb_w + x0; + for (int x = 0; x < 60; x++) + row[x] = c; + } + int32_t bar_len = (t > 63 ? 63 : t) * 4; + for (int y = 60; y < 70; y++) { + uint16_t* row = sh + (uint32_t)y * g_fb_w + x0; + for (int x = 0; x < bar_len; x++) + row[x] = 0xF800; + for (int x = bar_len; x < 60; x++) + row[x] = 0x0000; + } + } + + switch (t) { + /* Pointer / touch — position lives in the union's Point field */ + case PM_LBUTTONDOWN: + g_touch_x = (int16_t)msg->Point.x; + g_touch_y = (int16_t)msg->Point.y; + g_touch_state = LV_INDEV_STATE_PR; + g_last_touch_x = g_touch_x; + g_last_touch_y = g_touch_y; + g_last_touch_state = 1; + break; + case PM_LBUTTONUP: + g_touch_x = (int16_t)msg->Point.x; + g_touch_y = (int16_t)msg->Point.y; + g_touch_state = LV_INDEV_STATE_REL; + g_last_touch_x = g_touch_x; + g_last_touch_y = g_touch_y; + g_last_touch_state = 0; + break; + + /* Key input — Brain layout: + * Param = raw key code (e.g. 0x265 = SHIFT, 0x1B = ESC, ASCII) + * ExtParams[0]= state/modifier flags (0x800 = press, 0xC00 = held, + * bit 0x40 = SHIFT-sticky is active) + * ExtParams[1]= (unused) */ + case PM_KEY: + case PM_KEY_DOWN: { + int32_t code = (int32_t)param; + g_last_key_seen = 1; + g_last_key_type = t; + g_last_key_param = param; + g_last_key_ext0 = msg->ExtParams[0]; + g_last_key_ext1 = msg->ExtParams[1]; + g_last_key_ptx = (int16_t)msg->Point.x; + g_last_key_pty = (int16_t)msg->Point.y; + if (code == EXIT_KEY_SCAN) { + app_exit(); /* never returns on success */ + return 0; + } + uint32_t k = peg_key_to_lvgl(code); + if (k) { + g_key_pending = k; + g_key_state = LV_INDEV_STATE_PR; + } + break; + } + case PM_KEY_UP: + g_key_state = LV_INDEV_STATE_REL; + break; + + case PM_TIMER: { + uint32_t now = tstmr_get_millis(); + if (param == PROBE_TIMER_ID) { + if (g_probe_fires == 0) { + g_probe_first_ms = now; + g_probe_last_delta_ms = 0; + } else { + g_probe_last_delta_ms = now - g_probe_last_ms; + } + g_probe_last_ms = now; + g_probe_fires++; + } + break; + } + } + + /* Tick LVGL on every message (input drives widget state changes), + * then push the result to the physical screen through PEG's pipeline. */ + lv_timer_handler(); + push_shadow_to_screen(); + + /* Delegate to base so PEG's own bookkeeping runs. */ + return g_base_msg(self, msg); +} + +/* flush_cb: g_shadow IS the LVGL frame buffer, so nothing to copy. + * push_shadow_to_screen() takes care of moving it to the panel. */ +static void shadow_flush(lv_display_t* disp, const lv_area_t* area, uint8_t* px_buf) { + (void)area; + (void)px_buf; + lv_display_flush_ready(disp); +} + +/* Private vtable — what a C++ compiler would auto-generate for a subclass. + * PEG's PegDecoratedWindow uses a shared static vtable in ROM (0x600DAF88), + * so we copy it here, patch our overridden slots, and swap our window's + * vptr to this array. Heap allocation would work equally well; static is + * chosen for simpler debugging (fixed address). */ +static void* g_static_vt[80] __attribute__((aligned(16))); + +__attribute__((section(".text.init"))) void main(app_ctx* ctx) { + /* Save exec_path so app_exit() can pass it to sh_ExitApp later */ + if (ctx) g_exec_path = ctx->exec_path; + + /* --- Panel geometry --- */ + if (ctx && ctx->pPresent) { + short rect[4] = {0}; + PEG_ScreenRect(ctx->pPresent, rect); + int32_t w = rect[2] - rect[0] + 1; + int32_t h = rect[3] - rect[1] + 1; + if (w >= 64 && w <= 4096 && h >= 64 && h <= 4096) { + g_fb_w = w; + g_fb_h = h; + } + } + + /* --- Shadow buffer LVGL renders into --- */ + g_shadow_bytes = (uint32_t)g_fb_w * (uint32_t)g_fb_h * 2u; + g_shadow = (uint8_t*)lv_malloc(g_shadow_bytes); + + /* --- LVGL bring-up (rendering into shadow buffer) --- */ + lv_init(); + lv_tick_set_cb(tstmr_get_millis); + lv_display_t* display = lv_display_create(g_fb_w, g_fb_h); + lv_display_set_color_format(display, LV_COLOR_FORMAT_RGB565); + lv_display_set_buffers(display, g_shadow, NULL, g_shadow_bytes, + LV_DISPLAY_RENDER_MODE_FULL); + lv_display_set_flush_cb(display, shadow_flush); + + /* ---- LVGL widget setup ---- */ + lv_obj_t* scr = lv_screen_active(); + lv_obj_set_style_bg_color(scr, lv_color_hex(0x102040), 0); /* dark blue-grey */ + lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0); + + lv_obj_t* label = lv_label_create(scr); + lv_label_set_text_fmt(label, + "LVGL via PEG\n%ldx%ld RGB565", (long)g_fb_w, (long)g_fb_h); + lv_obj_set_style_text_color(label, lv_color_hex(0xFFFFFF), 0); + lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); + + /* A colourful rectangle so we see a solid block regardless of font */ + lv_obj_t* box = lv_obj_create(scr); + lv_obj_set_size(box, 200, 100); + lv_obj_align(box, LV_ALIGN_TOP_MID, 0, 20); + lv_obj_set_style_bg_color(box, lv_color_hex(0x00C000), 0); + lv_obj_set_style_border_width(box, 4, 0); + lv_obj_set_style_border_color(box, lv_color_hex(0xFF8000), 0); + + /* Debug label at bottom: msg counts, wType histogram, last touch/key, + * PEG-timer probe stats. */ + lv_obj_t* dbg = lv_label_create(scr); + lv_obj_set_style_text_color(dbg, lv_color_hex(0xFFFF00), 0); + lv_obj_set_style_bg_color(dbg, lv_color_hex(0x000000), 0); + lv_obj_set_style_bg_opa(dbg, LV_OPA_COVER, 0); + lv_obj_set_style_pad_all(dbg, 4, 0); + lv_obj_align(dbg, LV_ALIGN_BOTTOM_LEFT, 0, 0); + lv_label_set_text(dbg, "waiting..."); + g_dbg_label = dbg; + + /* Setup indev */ + g_indev_pointer = lv_indev_create(); + lv_indev_set_type(g_indev_pointer, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(g_indev_pointer, indev_pointer_read); + + g_indev_keypad = lv_indev_create(); + lv_indev_set_type(g_indev_keypad, LV_INDEV_TYPE_KEYPAD); + lv_indev_set_read_cb(g_indev_keypad, indev_keypad_read); + + /* Render into shadow a few times to complete initial paint */ + for (int i = 0; i < 5; i++) + lv_timer_handler(); + + /* Repeating LVGL timer: refresh debug label and push shadow → panel + * so widgets animate even when no input arrives. */ + lv_timer_create(refresh_cb, 200, NULL); + + /* --- Register as a real PEG window --- */ + if (ctx && ctx->pPresent) { + g_window = lv_malloc(0x108); + if (g_window) { + memset(g_window, 0, 0x108); + + /* Construct + place. AdjustClient recomputes mClient from + * mReal + frame thickness; harmless even though we bypass + * PEG's client-area drawing. */ + PEG_DecWindow_ctor(g_window, AF_ENABLED | FF_THIN); + PEG_RectSet((short*)((char*)g_window + 0x0C), + 0, 0, (short)(g_fb_w - 1), (short)(g_fb_h - 1)); + PEG_AdjustClient(g_window); + + /* Manual subclassing: copy the shared PegDecoratedWindow vtable, + * patch our overridden slots, and point our instance at it. + * (What a C++ compiler would do automatically for us.) */ + void** base_vt = *(void***)g_window; + for (int i = 0; i < 80; i++) + g_static_vt[i] = base_vt[i]; + g_base_msg = (msg_fn_t)base_vt[VFUNC_MESSAGE]; + g_static_vt[VFUNC_DRAW] = (void*)our_Draw; + g_static_vt[VFUNC_MESSAGE] = (void*)our_Message; + *(void**)g_window = g_static_vt; + + /* PegPresentationManager::Add(window, show=TRUE) */ + typedef void (*add_fn)(void*, void*, int); + void** pm_vt = *(void***)ctx->pPresent; + ((add_fn)pm_vt[3])(ctx->pPresent, g_window, 1); + + /* Route keyboard input to us without triggering the focus-event + * chain (bit 0x40 pathway) which needs additional setup. */ + PEG_SetCurrent(ctx->pPresent, g_window); + + /* Kick off the PEG-tick probe: one PM_TIMER per PROBE_TIMER_TICKS + * ticks, repeated. Handled in our_Message case PM_TIMER. */ + PEG_SetTimer(g_window, PROBE_TIMER_ID, + PROBE_TIMER_TICKS, PROBE_TIMER_TICKS); + } + } + + /* Return — cooperative scheduler, main-loop starves everything. */ + return; +} + +/* ===== LVGL alloc hooks + libc stubs ================================== */ +void* lv_malloc_core(size_t size) { + return malloc(size); +} +void* lv_realloc_core(void* p, size_t size) { + return realloc(p, size); +} +void lv_free_core(void* p) { + free(p); +} +void lv_mem_init(void) {} +void lv_mem_deinit(void) {} +lv_result_t lv_mem_test_core(void) { + return LV_RESULT_OK; +} +void lv_mem_monitor_core(lv_mem_monitor_t* m) { + (void)m; +} + +uint32_t tstmr_get_millis(void) { + uint32_t lo = *(volatile uint32_t*)0x410A3C00; + uint32_t hi = *(volatile uint32_t*)0x410A3C04; + return (uint32_t)(((((uint64_t)hi) << 32) | lo) / 1000); +} +void my_sleep(uint32_t millis) { + uint32_t start = tstmr_get_millis(); + while (tstmr_get_millis() - start < millis) { + } +} diff --git a/x1/event_dumper/peg_const.h b/x1/event_dumper/peg_const.h new file mode 100644 index 0000000..8179d28 --- /dev/null +++ b/x1/event_dumper/peg_const.h @@ -0,0 +1,65 @@ +#ifndef PEG_CONST_H +#define PEG_CONST_H + +/* PegThing frame-style values (from PEG API docs) */ +#define FF_NONE 0 +#define FF_THIN 1 +#define FF_RAISED 2 +#define FF_RECESSED 3 +#define FF_THICK 4 + +#define AF_ENABLED 0x10 + +/* ===== PegMessage.Type constants (Brain-specific numbering) ============= + * Values come from watching wTypes arrive in our_Message on real hardware. + * They do NOT match the generic PEG SDK numbering. Field usage per type: + * PM_KEY / PM_KEY_DOWN — Param = key code (0x265=SHIFT, 0x1B=ESC, ASCII, + * arrows 0x25E..0x261). ExtParams[0] = KFLAG_* / + * KMOD_* bits below. ExtParams[1] unused. + * PM_LBUTTONDOWN/UP — Point.x/y = touch coordinates. + * PM_TIMER — Param = timer Id passed to SetTimer. */ +#define PM_KEY 9 +#define PM_LBUTTONDOWN 10 +#define PM_LBUTTONUP 11 +#define PM_TIMER 32 +#define PM_KEY_DOWN 33 +#define PM_KEY_UP 34 /* tentative — needs confirmation */ + +/* Bits found in PegMessage.ExtParams[0] on key messages */ +#define KMOD_SHIFT 0x40 /* SHIFT-sticky is engaged for this event */ +#define KFLAG_PRESS 0x800 /* set on any key press */ +#define KFLAG_HELD 0xC00 /* set while a key is held down (repeat) */ + +struct PegPoint { + unsigned short x; + unsigned short y; +}; + +struct PegRect { + unsigned short Left; + unsigned short Top; + unsigned short Right; + unsigned short Bottom; +}; + +struct PegMessage { + void* pSource; + void* pTarget; + unsigned short Type; + unsigned short Param; + + union { + struct PegRect Rect; + struct PegPoint Point; + int ExtParams[2]; + void* pData; + int UserLong[2]; + unsigned int UserULONG[2]; + short UserShoft[4]; + unsigned short UserUShoft[4]; + unsigned char UserUByte[8]; + }; + void* pNext; +}; + +#endif // PEG_CONST_H \ No newline at end of file diff --git a/x1/event_dumper/peg_func.h b/x1/event_dumper/peg_func.h new file mode 100644 index 0000000..ba08f53 --- /dev/null +++ b/x1/event_dumper/peg_func.h @@ -0,0 +1,71 @@ +#ifndef PEG_FUNC_H +#define PEG_FUNC_H + +#include "peg_const.h" + +/* ===== Function-pointer typedefs ========================================= + * Since we can't run C++ static init (no ELF loader), method prototypes + * from the PEG SDK are re-declared here as function pointers, addressed + * directly at the fixed kernel export slots. */ + +typedef void* (*decwin_ctor_proc) (void* self, unsigned short style); +typedef void (*pegrect_set_proc) (short* rect, short x1, short y1, + short x2, short y2); +typedef void (*screen_rect_proc) (void* pm, short out_rect[4]); +typedef void (*adjust_client_proc) (void* self); +typedef void (*win_begin_draw_proc)(void* self, const struct PegRect* rect); +typedef void (*win_base_draw_proc) (void* self, const struct PegRect* rect); +typedef void* (*get_screen_proc) (void); +typedef void (*set_current_proc) (void* pm, void* target); +typedef void (*pt_settimer_proc) (void* pWho, unsigned int Id, + unsigned int Count, unsigned int Reset); +typedef void (*pt_killtimer_proc) (void* pWho, unsigned int Id); +typedef void (*pt_destroy_proc) (void* pSource, void* pTarget); +typedef void (*sh_exitapp_proc) (char* path); + +/* PegScreen vtable slots */ +typedef struct __attribute__((packed)) { + unsigned char bpp; + unsigned char flags; + unsigned short wWidth; + unsigned short wHeight; + unsigned short reserved; + unsigned int refcount; + unsigned char* pData; +} PegBitmap; +typedef void (*scr_bitmap_fn) (void* scr, int packed_xy, PegBitmap* bmp); +typedef void (*scr_enddraw_fn)(void* scr); + +/* Signature of every PegThing::Message override (vfunc[19]) */ +typedef int (*msg_fn_t)(void* self, const struct PegMessage* msg); + +/* ===== Kernel export addresses (x1ram, verified) ======================== + * Most PEG_* addresses in the 0x60004000-0x60006FFF range are jump-table + * trampolines (`ldr pc,[pc,#-4]; .word ADDR`); a few point straight at + * the implementation. sh_ExitApp lives in Brain's shell area, not PEG. */ + +#define PEG_DecWindow_ctor ((decwin_ctor_proc) 0x6000486c) /* ord 0x09 */ +#define PEG_RectSet ((pegrect_set_proc) 0x60004130) /* ord 0x23 */ +#define PEG_ScreenRect ((screen_rect_proc) 0x60005358) /* ord 0x0B */ +#define PEG_AdjustClient ((adjust_client_proc) 0x60004850) /* ord 0x07 */ +#define PEG_WinBeginDraw ((win_begin_draw_proc)0x60004590) /* → 6010D050 → screen.vfunc[3] */ +#define PEG_WinBaseDraw ((win_base_draw_proc) 0x6000602C) /* → 600478EC = PegWindow::Draw base */ +#define PEG_GetScreen ((get_screen_proc) 0x60004144) /* → 600B5520 */ +#define PEG_SetCurrent ((set_current_proc) 0x600313C8) /* PresMgr, routes key input */ +#define PEG_SetTimer ((pt_settimer_proc) 0x600470A0) /* PegThing wrapper — Count/Reset in PEG ticks */ +#define PEG_KillTimer ((pt_killtimer_proc) 0x600470D0) /* PegThing wrapper */ +#define PEG_Destroy ((pt_destroy_proc) 0x6002A3E4) /* posts PM_DESTROY to pTarget */ + +/* Brain shell function — hands control back to the launcher. + * NEVER RETURNS; call after cleaning up owned resources. */ +#define sh_ExitApp ((sh_exitapp_proc) 0x840E7A48) + +/* PegScreen vtable slots we call directly */ +#define SCR_VF_BITMAP 4 /* Bitmap blit — screen->vfunc[4](packed_xy, bmp) */ +#define SCR_VF_ENDDRAW 16 /* EndDraw — flushes MemoryToScreen when nesting=0 */ + +/* PegThing vtable slots we override */ +#define VFUNC_DRAW 12 +#define VFUNC_MESSAGE 19 + +#endif /* PEG_FUNC_H */ diff --git a/x1/event_dumper/pseudo_peg_lib.h b/x1/event_dumper/pseudo_peg_lib.h new file mode 100644 index 0000000..4c8c4c9 --- /dev/null +++ b/x1/event_dumper/pseudo_peg_lib.h @@ -0,0 +1,7 @@ +#ifndef PSEUDO_PEG_LIB_H +#define PSEUDO_PEG_LIB_H + +#include "peg_const.h" +#include "peg_func.h" + +#endif // PSEUDO_PEG_LIB_H \ No newline at end of file