diff --git a/README.md b/README.md index 55c4d7fcd..313d56ccf 100644 --- a/README.md +++ b/README.md @@ -5,32 +5,32 @@ --- This repo is a submodule of [lv_micropython](https://github.com/lvgl/lv_micropython). -Please fork [lv_micropython](https://github.com/lvgl/lv_micropython) for a quick start with LVGL Micropython Bindings. +Please fork [lv_micropython](https://github.com/lvgl/lv_micropython) for a quick start with LVGL MicroPython Bindings. --- See also [Micropython + LittlevGL](https://blog.lvgl.io/2019-02-20/micropython-bindings) blog post. (LittlevGL is the previous name of LVGL.) -For advanced features, see [Pure Micropython Display Driver](https://blog.lvgl.io/2019-08-05/micropython-pure-display-driver) blog post. +For advanced features, see [Pure MicroPython Display Driver](https://blog.lvgl.io/2019-08-05/micropython-pure-display-driver) blog post. For questions and discussions - please use the forum: https://forum.lvgl.io/c/micropython -## Micropython +## MicroPython -Micropython Binding for LVGL provides an automatically generated Micropython module with classes and functions that allow the user access much of the LVGL library. +MicroPython Binding for LVGL provides an automatically generated MicroPython module with classes and functions that allow the user access much of the LVGL library. The module is generated automatically by the script [`gen_mpy.py`](https://github.com/lvgl/lv_binding_micropython/blob/master/gen/gen_mpy.py). -This script reads, preprocesses and parses LVGL header files, and generates a C file `lv_mpy.c` which defines the Micropython module (API) for accessing LVGL from Micropython. +This script reads, preprocesses and parses LVGL header files, and generates a C file `lv_mpy.c` which defines the MicroPython module (API) for accessing LVGL from MicroPython. Micopython's build script (Makefile or CMake) should run `gen_mpy.py` automatically to generate and compile `lv_mpy.c`. -- If you would like to see an example of how a generated `lv_mpy.c` looks like, have a look at [`lv_mpy_example.c`](https://raw.githubusercontent.com/lvgl/lv_binding_micropython/master/gen/lv_mpy_example.c). Note that its only exported (non static) symbol is `mp_module_lvgl` which should be registered in Micropython as a module. -- lv_binding_micropython is usually used as a git submodule of [lv_micropython](https://github.com/lvgl/lv_micropython) which builds Micropython + LVGL + lvgl-bindings, but can also be used on other forks of Micropython. +- If you would like to see an example of how a generated `lv_mpy.c` looks like, have a look at [`lv_mpy_example.c`](https://raw.githubusercontent.com/lvgl/lv_binding_micropython/master/gen/lv_mpy_example.c). Note that its only exported (non static) symbol is `mp_module_lvgl` which should be registered in MicroPython as a module. +- lv_binding_micropython is usually used as a git submodule of [lv_micropython](https://github.com/lvgl/lv_micropython) which builds MicroPython + LVGL + lvgl-bindings, but can also be used on other forks of MicroPython. It's worth noting that the Mircopython Bindings module (`lv_mpy.c`) is dependent on LVGL configuration. LVGL is configured by `lv_conf.h` where different objects and features could be enabled or disabled. LVGL bindings are generated only for the enabled objects and features. Changing `lv_conf.h` requires re running `gen_mpy.py`, therefore it's useful to run it automatically in the build script, as done by lv_micropython. ### Memory Management -When LVGL is built as a Micropython library, it is configured to allocate memory using Micropython memory allocation functions and take advantage of Micropython *Garbage Collection* ("gc"). +When LVGL is built as a MicroPython library, it is configured to allocate memory using MicroPython memory allocation functions and take advantage of MicroPython *Garbage Collection* ("gc"). This means that structs allocated for LVGL use don't need to be deallocated explicitly, gc takes care of that. -For this to work correctly, LVGL is configured to use gc and to use Micropython's memory allocation functions, and also register all LVGL "root" global variables to Micropython's gc. +For this to work correctly, LVGL is configured to use gc and to use MicroPython's memory allocation functions, and also register all LVGL "root" global variables to MicroPython's gc. From the user's perspective, structs can be created and will be collected by gc when they are no longer referenced. However, LVGL screen objects (`lv.obj` with no parent) are automatically assigned to default display, therefore not collected by gc even when no longer explicitly referenced. @@ -40,13 +40,13 @@ Make sure you keep a reference to your display driver and input driver to preven ### Concurrency -This implementation of Micropython Bindings to LVGL assumes that Micropython and LVGL are running **on a single thread** and **on the same thread** (or alternatively, running without multithreading at all). +This implementation of MicroPython Bindings to LVGL assumes that MicroPython and LVGL are running **on a single thread** and **on the same thread** (or alternatively, running without multithreading at all). No synchronization means (locks, mutexes) are taken. However, asynchronous calls to LVGL still take place periodically for screen refresh and other LVGL tasks such as animation. -This is achieved by using the internal Micropython scheduler (that must be enabled), by calling `mp_sched_schedule`. +This is achieved by using the internal MicroPython scheduler (that must be enabled), by calling `mp_sched_schedule`. `mp_sched_schedule` is called when screen needs to be refreshed. LVGL expects the function `lv_task_handler` to be called periodically (see [lvgl/README.md#porting](https://github.com/lvgl/lvgl/blob/6718decbb7b561b68e450203b83dff60ce3d802c/README.md#porting)). This is usually handled in the display device driver. -Here is [an example](https://github.com/lvgl/lv_binding_micropython/blob/77b0c9f2678b6fbd0950fbf27380052246841082/driver/SDL/modSDL.c#L23) of calling `lv_task_handler` with `mp_sched_schedule` for refreshing LVGL. [`mp_lv_task_handler`](https://github.com/lvgl/lv_binding_micropython/blob/77b0c9f2678b6fbd0950fbf27380052246841082/driver/SDL/modSDL.c#L7) is scheduled to run on the same thread Micropython is running, and it calls both `lv_task_handler` for LVGL task handling and `monitor_sdl_refr_core` for refreshing the display and handling mouse events. +Here is [an example](https://github.com/lvgl/lv_binding_micropython/blob/77b0c9f2678b6fbd0950fbf27380052246841082/driver/SDL/modSDL.c#L23) of calling `lv_task_handler` with `mp_sched_schedule` for refreshing LVGL. [`mp_lv_task_handler`](https://github.com/lvgl/lv_binding_micropython/blob/77b0c9f2678b6fbd0950fbf27380052246841082/driver/SDL/modSDL.c#L7) is scheduled to run on the same thread MicroPython is running, and it calls both `lv_task_handler` for LVGL task handling and `monitor_sdl_refr_core` for refreshing the display and handling mouse events. With REPL (interactive console), when waiting for the user input, asynchronous events can also happen. In [this example](https://github.com/lvgl/lv_mpy/blob/bc635700e4186f39763e5edee73660fbe1a27cd4/ports/unix/unix_mphal.c#L176) we just call `mp_handle_pending` periodically when waiting for a keypress. `mp_handle_pending` takes care of dispatching asynchronous events registered with `mp_sched_schedule`. @@ -73,11 +73,11 @@ All lvgl globals (functions, enums, types) are available under lvgl module. For ### Callbacks In C a callback is a function pointer. -In Micropython we would also need to register a *Micropython callable object* for each callback. -Therefore in the Micropython binding we need to register both a function pointer and a Micropython object for every callback. +In MicroPython we would also need to register a *MicroPython callable object* for each callback. +Therefore in the MicroPython binding we need to register both a function pointer and a MicroPython object for every callback. -Therefore we defined a **callback convention** that expects lvgl headers to be defined in a certain way. Callbacks that are declared according to the convention would allow the binding to register a Micropython object next to the function pointer when registering a callback, and access that object when the callback is called. -The Micropython callable object is automatically saved in a `user_data` variable which is provided when registering or calling the callback. +Therefore we defined a **callback convention** that expects lvgl headers to be defined in a certain way. Callbacks that are declared according to the convention would allow the binding to register a MicroPython object next to the function pointer when registering a callback, and access that object when the callback is called. +The MicroPython callable object is automatically saved in a `user_data` variable which is provided when registering or calling the callback. The callback convention assumes the following: - There's a struct that contains a field called `void * user_data`. @@ -94,7 +94,7 @@ In this case, the user should provide either `None` or a dict as the `user_data` The callback will receive a Blob which can be casted to the dict in the last argument. (See `async_call` example below) -As long as the convention above is followed, the lvgl Micropython binding script would automatically set and use `user_data` when callbacks are set and used. +As long as the convention above is followed, the lvgl MicroPython binding script would automatically set and use `user_data` when callbacks are set and used. From the user perspective, any python callable object (such as python regular function, class function, lambda etc.) can be user as an lvgl callbacks. For example: ```python @@ -108,21 +108,21 @@ lv.anim_set_exec_cb(anim, obj, obj.set_y) lvgl callbacks that do not follow the Callback Convention cannot be used with micropython callable objects. A discussion related to adjusting lvgl callbacks to the convention: https://github.com/lvgl/lvgl/issues/1036 -The `user_data` field **must not be used directly by the user**, since it is used internally to hold pointers to Micropython objects. +The `user_data` field **must not be used directly by the user**, since it is used internally to hold pointers to MicroPython objects. ### Display and Input Drivers LVGL can be configured to use different displays and different input devices. More information is available on [LVGL documentation](https://docs.lvgl.io/master/porting/display.html). Registering a driver is essentially calling a registration function (for example `disp_drv_register`) and passing a function pointer as a parameter (actually a struct that contains function pointers). The function pointer is used to access the actual display / input device. -When implementing a display or input LVGL driver with Micropython, there are 3 option: +When implementing a display or input LVGL driver with MicroPython, there are 3 option: - Implement a Pure Python driver. It the easiest way to implement a driver, but may perform poorly - Implement a Pure C driver. - Implemnent a Hybrid driver where the critical parts (such as the `flush` function) are in C, and the non-critical part (such as initializing the display) are implemented in Python. An example of Pure/Hybrid driver is the [ili9XXX.py](https://github.com/lvgl/lv_binding_micropython/blob/master/driver/esp32/ili9XXX.py). -The driver registration should eventually be performed in the Micropython script, either in the driver code itself in case of the pure/hybrid driver or in user code in case of C driver (for example, in the case of the SDL driver). Registering the driver on Python and not in C is important to make it easy for the user to select and replace drivers without building the project and changing C files. +The driver registration should eventually be performed in the MicroPython script, either in the driver code itself in case of the pure/hybrid driver or in user code in case of C driver (for example, in the case of the SDL driver). Registering the driver on Python and not in C is important to make it easy for the user to select and replace drivers without building the project and changing C files. When creating a display or input LVGL driver, make sure you let the user **configure all parameters on runtime**, such as SPI pins, frequency, etc. Eventually the user would want to build the firmware once and use the same driver in different configuration without re-building the C project. @@ -175,23 +175,23 @@ Currently supported drivers for Micropyton are Driver code is under `/driver` directory. -Drivers can also be implemented in pure Micropython, by providing callbacks (`disp_drv.flush_cb`, `indev_drv.read_cb` etc.) +Drivers can also be implemented in pure MicroPython, by providing callbacks (`disp_drv.flush_cb`, `indev_drv.read_cb` etc.) Currently the supported ILI9341, FT6X36 and XPT2046 are pure micropython drivers. ### Where are the drivers? -LVGL C drivers and Micropython drivers (either C or Python) are **separate and independent** from each other. +LVGL C drivers and MicroPython drivers (either C or Python) are **separate and independent** from each other. The main reason is configuration: - The C driver is usually configured with C macros (which pins it uses, frequency, etc.) Any configuration change requires rebuilding the firmware but that's understandable since any change in the application requires rebuilding the firmware anyway. -- In Micropython the driver is built once with Micropython firmware (if it's a C driver) or not built at all (if it's pure Python driver). On runtime the user initializes the driver and configures it. If the user switches SPI pins or some other configuration, there is no need to rebuild the firmware, just change the Python script and initialize the driver differently **on runtime**. +- In MicroPython the driver is built once with MicroPython firmware (if it's a C driver) or not built at all (if it's pure Python driver). On runtime the user initializes the driver and configures it. If the user switches SPI pins or some other configuration, there is no need to rebuild the firmware, just change the Python script and initialize the driver differently **on runtime**. -So the location for Micropython drivers is https://github.com/lvgl/lv_binding_micropython/tree/master/driver and is unrelated to https://github.com/lvgl/lv_drivers. +So the location for MicroPython drivers is https://github.com/lvgl/lv_binding_micropython/tree/master/driver and is unrelated to https://github.com/lvgl/lv_drivers. ### The Event Loop LVGL requires an Event Loop to re-draw the screen, handle user input etc. -The default Event Loop is implement in [lv_utils.py](https://github.com/lvgl/lv_binding_micropython/blob/master/lib/lv_utils.py) which uses Micropython Timer to schedule calls to LVGL. +The default Event Loop is implement in [lv_utils.py](https://github.com/lvgl/lv_binding_micropython/blob/master/lib/lv_utils.py) which uses MicroPython Timer to schedule calls to LVGL. It also supports running the Event Loop in [uasyncio](https://docs.micropython.org/en/latest/library/uasyncio.html) if needed. Some drivers start the event loop automatically if it doesn't already run. To configure the event loop for these drivers, just initialize the event loop before registering the driver. LVGL native drivers, such as the SDL driver, do not start the event loop. You must start the event loop explicitly otherwise screen will not refresh. @@ -203,15 +203,15 @@ event_loop = event_loop() ``` and you can configure it by providing parameters, see lv_utils.py for more details. -### Adding Micropython Bindings to a project +### Adding MicroPython Bindings to a project -An example project of "Micropython + lvgl + Bindings" is [`lv_mpy`](https://github.com/lvgl/lv_mpy). -Here is a procedure for adding lvgl to an existing Micropython project. (The examples in this list are taken from [`lv_mpy`](https://github.com/lvgl/lv_mpy)): +An example project of "MicroPython + lvgl + Bindings" is [`lv_mpy`](https://github.com/lvgl/lv_mpy). +Here is a procedure for adding lvgl to an existing MicroPython project. (The examples in this list are taken from [`lv_mpy`](https://github.com/lvgl/lv_mpy)): - Add [`lv_bindings`](https://github.com/lvgl/lv_binding_micropython) as a sub-module under `lib`. - Add `lv_conf.h` in `lib` - Edit the Makefile to run `gen_mpy.py` and build its product automatically. Here is [an example](https://github.com/lvgl/lv_micropython/blob/2940838bf6d4999050efecb29a4152ab5796d5b3/py/py.mk#L22-L38). -- Register lvgl module and display/input drivers in Micropython as a builtin module. [An example](https://github.com/lvgl/lv_micropython/blob/2940838bf6d4999050efecb29a4152ab5796d5b3/ports/unix/mpconfigport.h#L230). +- Register lvgl module and display/input drivers in MicroPython as a builtin module. [An example](https://github.com/lvgl/lv_micropython/blob/2940838bf6d4999050efecb29a4152ab5796d5b3/ports/unix/mpconfigport.h#L230). - Add lvgl roots to gc roots. [An example](https://github.com/lvgl/lv_micropython/blob/2940838bf6d4999050efecb29a4152ab5796d5b3/ports/unix/mpconfigport.h#L317-L318). - ~Configure lvgl to use *Garbage Collection* by setting several `LV_MEM_CUSTOM_*` and `LV_GC_*` macros [example](https://github.com/lvgl/lv_mpy/blob/bc635700e4186f39763e5edee73660fbe1a27cd4/lib/lv_conf.h#L28)~ lv_conf.h was moved to lv_binding_micropython git module. - Make sure you configure partitions correctly in `partitions.csv` and leave enough room for the LVGL module. @@ -252,11 +252,11 @@ python gen_mpy.py -MD lv_mpy_example.json -M lvgl -MP lv -I../../berkeley-db-1.x ### Binding other C libraries -The lvgl binding script can be used to bind other C libraries to Micropython. +The lvgl binding script can be used to bind other C libraries to MicroPython. I used it with [lodepng](https://github.com/lvandeve/lodepng) and with parts of ESP-IDF. For more details please read [this blog post](https://blog.lvgl.io/2019-08-05/micropython-pure-display-driver). -## Micropython Bindings Usage +## MicroPython Bindings Usage A simple example: [`advanced_demo.py`](https://github.com/lvgl/lv_binding_micropython/blob/master/gen/examples/advanced_demo.py). More examples can be found under `/examples` folder. @@ -279,7 +279,7 @@ mouse = lv.sdl_mouse_create() keyboard = lv.sdl_keyboard_create() keyboard.set_group(self.group) ``` -In this example, LVGL native SDL display and input drivers are registered on a unix port of Micropython. +In this example, LVGL native SDL display and input drivers are registered on a unix port of MicroPython. Here is an alternative example for ESP32 ILI9341 + XPT2046 drivers: diff --git a/driver/esp32/espidf.c b/driver/esp32/espidf.c index 18215c9ba..f548783fa 100644 --- a/driver/esp32/espidf.c +++ b/driver/esp32/espidf.c @@ -9,6 +9,7 @@ #include "freertos/task.h" #include "esp_system.h" #include "soc/cpu.h" +#include "lvgl/src/draw/sw/lv_draw_sw.h" // ESP IDF has some functions that are declared but not implemented. @@ -232,6 +233,11 @@ void ili9xxx_flush(void *_disp_drv, const void *_area, void *_color_p) size_t size = (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1); uint8_t color_size = 2; + bool swap_rgb565_bytes = mp_obj_get_int(mp_obj_dict_get(driver_data, MP_OBJ_NEW_QSTR(MP_QSTR_swap_rgb565_bytes))); + if ( swap_rgb565_bytes == true ) { + lv_draw_sw_rgb565_swap(color_p, size); + } + if ( dt == DISPLAY_TYPE_ILI9488 ) { color_size = 3; /*Convert ARGB to RGB is required (cut off A-byte)*/ diff --git a/driver/esp32/ili9XXX.py b/driver/esp32/ili9XXX.py index 084117466..80eb6bd3e 100644 --- a/driver/esp32/ili9XXX.py +++ b/driver/esp32/ili9XXX.py @@ -1,5 +1,6 @@ ############################################################################## -# Pure/Hybrid micropython lvgl display driver for ili9341 and ili9488 on ESP32 +# Pure/Hybrid micropython lvgl display driver for +# ili9341, ili9488, ili9488g, gc9a01, st7789 on ESP32 # # For ili9341 display: # @@ -64,6 +65,8 @@ import micropython import gc +from micropython import const + micropython.alloc_emergency_exception_buf(256) # gc.threshold(0x10000) # leave enough room for SPI master TX DMA buffers @@ -94,9 +97,10 @@ DISPLAY_TYPE_ST7789 = const(4) DISPLAY_TYPE_ST7735 = const(5) +_TRANS_BUFFER_LEN = const(16) + class ili9XXX: - TRANS_BUFFER_LEN = const(16) display_name = 'ili9XXX' init_cmds = [ ] @@ -107,7 +111,7 @@ def __init__(self, miso=5, mosi=18, clk=19, cs=13, dc=12, rst=4, power=14, backlight=15, backlight_on=0, power_on=0, spihost=esp.HSPI_HOST, spimode=0, mhz=40, factor=4, hybrid=True, width=240, height=320, start_x=0, start_y=0, invert=False, double_buffer=True, half_duplex=True, display_type=0, asynchronous=False, initialize=True, - color_format=None + color_format=None, swap_rgb565_bytes=False ): # Initializations @@ -140,6 +144,7 @@ def __init__(self, self.hybrid = hybrid self.half_duplex = half_duplex self.display_type = display_type + self.swap_rgb565_bytes = swap_rgb565_bytes self.buf_size = (self.width * self.height * lv.COLOR_DEPTH // 8) // factor @@ -167,6 +172,7 @@ def __init__(self, 'dc': self.dc, 'spi': self.spi, 'dt': self.display_type, + 'swap_rgb565_bytes': self.swap_rgb565_bytes, 'start_x': self.start_x, 'start_y': self.start_y}) @@ -238,7 +244,7 @@ def disp_spi_init(self): ret = esp.spi_bus_initialize(self.spihost, buscfg, 1) if ret != 0: raise RuntimeError("Failed initializing SPI bus") - self.trans_buffer = esp.heap_caps_malloc(TRANS_BUFFER_LEN, esp.MALLOC_CAP.DMA) + self.trans_buffer = esp.heap_caps_malloc(_TRANS_BUFFER_LEN, esp.MALLOC_CAP.DMA) self.cmd_trans_data = self.trans_buffer.__dereference__(1) self.word_trans_data = self.trans_buffer.__dereference__(4) @@ -353,7 +359,7 @@ def send_cmd(self, cmd): def send_data(self, data): esp.gpio_set_level(self.dc, 1) # Data mode - if len(data) > TRANS_BUFFER_LEN: raise RuntimeError('Data too long, please use DMA!') + if len(data) > _TRANS_BUFFER_LEN: raise RuntimeError('Data too long, please use DMA!') trans_data = self.trans_buffer.__dereference__(len(data)) trans_data[:] = data[:] self.spi_send(trans_data) @@ -442,6 +448,7 @@ def power_down(self): end_time_ptr = esp.C_Pointer() flush_acc_setup_cycles = 0 flush_acc_dma_cycles = 0 + _rgb565_swap = lv.draw_sw_rgb565_swap def flush(self, disp_drv, area, color_p): @@ -482,7 +489,10 @@ def flush(self, disp_drv, area, color_p): self.send_cmd(0x2C) size = (x2 - x1 + 1) * (y2 - y1 + 1) - data_view = color_p.__dereference__(size * lv.color_t.__SIZE__) + data_view = color_p.__dereference__(size * lv.COLOR_DEPTH // 8) + + if self.swap_rgb565_bytes: + self._rgb565_swap(data_view, size) esp.get_ccount(self.end_time_ptr) if self.end_time_ptr.int_val > self.start_time_ptr.int_val: @@ -542,12 +552,12 @@ def __init__(self, miso=5, mosi=18, clk=19, cs=13, dc=12, rst=4, power=14, backlight=15, backlight_on=0, power_on=0, spihost=esp.HSPI_HOST, spimode=0, mhz=40, factor=4, hybrid=True, width=240, height=320, start_x=0, start_y=0, colormode=COLOR_MODE_BGR, rot=PORTRAIT, invert=False, double_buffer=True, half_duplex=True, - asynchronous=False, initialize=True, color_format=lv.COLOR_FORMAT.NATIVE_REVERSED + asynchronous=False, initialize=True, color_format=lv.COLOR_FORMAT.NATIVE, swap_rgb565_bytes=True ): # Make sure Micropython was built such that color won't require processing before DMA - if lv.color_t.__SIZE__ != 2: + if lv.COLOR_DEPTH != 16: raise RuntimeError('ili9341 micropython driver requires defining LV_COLOR_DEPTH=16') self.display_name = 'ILI9341' @@ -586,7 +596,7 @@ def __init__(self, backlight_on=backlight_on, power_on=power_on, spihost=spihost, spimode=spimode, mhz=mhz, factor=factor, hybrid=hybrid, width=width, height=height, start_x=start_x, start_y=start_y, invert=invert, double_buffer=double_buffer, half_duplex=half_duplex, display_type=DISPLAY_TYPE_ILI9341, asynchronous=asynchronous, initialize=initialize, - color_format=color_format) + color_format=color_format, swap_rgb565_bytes=swap_rgb565_bytes) class ili9488(ili9XXX): @@ -597,7 +607,7 @@ def __init__(self, color_format=None, display_type=DISPLAY_TYPE_ILI9488, p16=False ): - if (lv.color_t.__SIZE__ != 4) and not p16: + if (lv.COLOR_DEPTH != 32) and not p16: raise RuntimeError('ili9488 micropython driver requires defining LV_COLOR_DEPTH=32') if not hybrid: raise RuntimeError('ili9488 micropython driver do not support non-hybrid driver') @@ -638,7 +648,8 @@ def __init__(self, super().__init__(miso=miso, mosi=mosi, clk=clk, cs=cs, dc=dc, rst=rst, power=power, backlight=backlight, backlight_on=backlight_on, power_on=power_on, spihost=spihost, spimode=spimode, mhz=mhz, factor=factor, hybrid=hybrid, width=width, height=height, invert=invert, double_buffer=double_buffer, half_duplex=half_duplex, - display_type=display_type, asynchronous=asynchronous, initialize=initialize, color_format=color_format) + display_type=display_type, asynchronous=asynchronous, initialize=initialize, + color_format=color_format) class ili9488g(ili9488): @@ -648,13 +659,13 @@ def __init__(self, rot=PORTRAIT, invert=False, double_buffer=True, half_duplex=True, asynchronous=False, initialize=True ): - if lv.color_t.__SIZE__ == 4: + if lv.COLOR_DEPTH == 32: colormode=COLOR_MODE_RGB color_format=None display_type=DISPLAY_TYPE_ILI9488 # 24-bit pixel handling p16=False - if lv.color_t.__SIZE__ == 2: + if lv.COLOR_DEPTH == 16: colormode=COLOR_MODE_BGR color_format=lv.COLOR_FORMAT.NATIVE_REVERSE display_type=DISPLAY_TYPE_ILI9341 # Force use of 16-bit pixel handling @@ -674,10 +685,10 @@ def __init__(self, miso=5, mosi=18, clk=19, cs=13, dc=12, rst=4, power=14, backlight=15, backlight_on=0, power_on=0, spihost=esp.HSPI_HOST, spimode=0, mhz=60, factor=4, hybrid=True, width=240, height=240, colormode=COLOR_MODE_RGB, rot=PORTRAIT, invert=False, double_buffer=True, half_duplex=True, asynchronous=False, initialize=True, - color_format=None + color_format=None, swap_rgb565_bytes=True ): - if lv.color_t.__SIZE__ != 2: + if lv.COLOR_DEPTH != 16: raise RuntimeError('gc9a01 micropython driver requires defining LV_COLOR_DEPTH=16') # This is included as the color mode appears to be reversed from the @@ -749,7 +760,8 @@ def __init__(self, super().__init__(miso=miso, mosi=mosi, clk=clk, cs=cs, dc=dc, rst=rst, power=power, backlight=backlight, backlight_on=backlight_on, power_on=power_on, spihost=spihost, spimode=spimode, mhz=mhz, factor=factor, hybrid=hybrid, width=width, height=height, invert=invert, double_buffer=double_buffer, half_duplex=half_duplex, - display_type=DISPLAY_TYPE_GC9A01, asynchronous=asynchronous, initialize=initialize, color_format=color_format) + display_type=DISPLAY_TYPE_GC9A01, asynchronous=asynchronous, initialize=initialize, color_format=color_format, + swap_rgb565_bytes=swap_rgb565_bytes) class st7789(ili9XXX): @@ -762,11 +774,11 @@ def __init__(self, miso=-1, mosi=19, clk=18, cs=5, dc=16, rst=23, power=-1, backlight=4, backlight_on=1, power_on=0, spihost=esp.HSPI_HOST, spimode=0, mhz=40, factor=4, hybrid=True, width=320, height=240, start_x=0, start_y=0, colormode=COLOR_MODE_BGR, rot=PORTRAIT, invert=True, double_buffer=True, half_duplex=True, - asynchronous=False, initialize=True, color_format=lv.COLOR_FORMAT.NATIVE_REVERSED): + asynchronous=False, initialize=True, color_format=lv.COLOR_FORMAT.NATIVE, swap_rgb565_bytes=True): # Make sure Micropython was built such that color won't require processing before DMA - if lv.color_t.__SIZE__ != 2: + if lv.COLOR_DEPTH != 16: raise RuntimeError('st7789 micropython driver requires defining LV_COLOR_DEPTH=16') self.display_name = 'ST7789' @@ -801,7 +813,7 @@ def __init__(self, backlight_on=backlight_on, power_on=power_on, spihost=spihost, spimode=spimode, mhz=mhz, factor=factor, hybrid=hybrid, width=width, height=height, start_x=start_x, start_y=start_y, invert=invert, double_buffer=double_buffer, half_duplex=half_duplex, display_type=DISPLAY_TYPE_ST7789, asynchronous=asynchronous, - initialize=initialize, color_format=color_format) + initialize=initialize, color_format=color_format, swap_rgb565_bytes=swap_rgb565_bytes) class st7735(ili9XXX): @@ -814,11 +826,11 @@ def __init__(self, miso=-1, mosi=19, clk=18, cs=13, dc=12, rst=4, power=-1, backlight=15, backlight_on=1, power_on=0, spihost=esp.HSPI_HOST, spimode=0, mhz=40, factor=4, hybrid=True, width=128, height=160, start_x=0, start_y=0, colormode=COLOR_MODE_RGB, rot=PORTRAIT, invert=False, double_buffer=True, half_duplex=True, - asynchronous=False, initialize=True, color_format=lv.COLOR_FORMAT.NATIVE_REVERSED): + asynchronous=False, initialize=True, color_format=lv.COLOR_FORMAT.NATIVE, swap_rgb565_bytes=True): # Make sure Micropython was built such that color won't require processing before DMA - if lv.color_t.__SIZE__ != 2: + if lv.COLOR_DEPTH != 16: raise RuntimeError('st7735 micropython driver requires defining LV_COLOR_DEPTH=16') self.display_name = 'ST7735' @@ -857,4 +869,4 @@ def __init__(self, backlight_on=backlight_on, power_on=power_on, spihost=spihost, spimode=spimode, mhz=mhz, factor=factor, hybrid=hybrid, width=width, height=height, start_x=start_x, start_y=start_y, invert=invert, double_buffer=double_buffer, half_duplex=half_duplex, display_type=DISPLAY_TYPE_ST7735, asynchronous=asynchronous, - initialize=initialize, color_format=color_format) + initialize=initialize, color_format=color_format, swap_rgb565_bytes=swap_rgb565_bytes) diff --git a/driver/generic/st77xx.py b/driver/generic/st77xx.py index e875775af..1aba6e8a3 100644 --- a/driver/generic/st77xx.py +++ b/driver/generic/st77xx.py @@ -441,13 +441,14 @@ def disp_drv_flush_cb(self,disp_drv,area,color): # blit in background self.blit(area.x1,area.y1,w:=(area.x2-area.x1+1),h:=(area.y2-area.y1+1),color.__dereference__(2*w*h),is_blocking=False) self.disp_drv.flush_ready() + def __init__(self,doublebuffer=True,factor=4): import lvgl as lv import lv_utils if lv.COLOR_DEPTH!=16: raise RuntimeError(f'LVGL *must* be compiled with LV_COLOR_DEPTH=16 (currently LV_COLOR_DEPTH={lv.COLOR_DEPTH}.') - bufSize=(self.width*self.height*lv.color_t.__SIZE__)//factor + bufSize=(self.width * self.height * lv.COLOR_DEPTH // 8) // factor if not lv.is_initialized(): lv.init() # create event loop if not yet present @@ -457,7 +458,7 @@ def __init__(self,doublebuffer=True,factor=4): self.disp_drv = lv.disp_create(self.width, self.height) self.disp_drv.set_flush_cb(self.disp_drv_flush_cb) self.disp_drv.set_draw_buffers(bytearray(bufSize), bytearray(bufSize) if doublebuffer else None, bufSize, lv.DISP_RENDER_MODE.PARTIAL) - self.disp_drv.set_color_format(lv.COLOR_FORMAT.NATIVE if self.bgr else lv.COLOR_FORMAT.NATIVE_REVERSED) + self.disp_drv.set_color_format(lv.COLOR_FORMAT.NATIVE) class St7735(St7735_hw,St77xx_lvgl): def __init__(self,res,doublebuffer=True,factor=4,**kw): diff --git a/examples/advanced_demo.py b/examples/advanced_demo.py index 68d982864..62a3586d9 100644 --- a/examples/advanced_demo.py +++ b/examples/advanced_demo.py @@ -358,8 +358,8 @@ def init_gui_stm32(self): lcd.init(w=hres, h=vres) self.disp_drv = lv.display_create(hres, vres) self.disp_drv.set_flush_cb(lcd.flush) - buf1_1 = bytearray(hres * 50 * lv.color_t.__SIZE__) - buf1_2 = bytearray(hres * 50 * lv.color_t.__SIZE__) + buf1_1 = bytearray(hres * 50 * lv.COLOR_DEPTH // 8) + buf1_2 = bytearray(hres * 50 * lv.COLOR_DEPTH // 8) self.disp_drv.set_draw_buffers(buf1_1, buf1_2, len(buf1_1), lv.DISPLAY_RENDER_MODE.PARTIAL) # Register touch sensor diff --git a/examples/example1.py b/examples/example1.py index 094906e12..768266814 100644 --- a/examples/example1.py +++ b/examples/example1.py @@ -13,7 +13,7 @@ class driver: def init_gui_SDL(self): self.event_loop = lv_utils.event_loop() self.disp_drv = lv.sdl_window_create(480, 320) - self.indev_drv = lv.sdl_mouse_create(); + self.indev_drv = lv.sdl_mouse_create() def init_gui_esp32(self): diff --git a/examples/example3.py b/examples/example3.py index 1485949cc..22a21b4f4 100644 --- a/examples/example3.py +++ b/examples/example3.py @@ -15,8 +15,8 @@ lcd.init(w=hres, h=vres) disp_drv = lv.disp_create(hres, vres) disp_drv.set_flush_cb(lcd.flush) - buf1_1 = bytearray(hres * 10 * lv.color_t.__SIZE__) - buf1_2 = bytearray(hres * 10 * lv.color_t.__SIZE__) + buf1_1 = bytearray(hres * 10 * lv.COLOR_DEPTH // 8) + buf1_2 = bytearray(hres * 10 * lv.COLOR_DEPTH // 8) disp_drv.set_draw_buffers(buf1_1, buf1_2, len(buf1_1), lv.DISP_RENDER_MODE.PARTIAL) # disp_drv.gpu_blend_cb = lcd.gpu_blend diff --git a/gen/gen_mpy.py b/gen/gen_mpy.py index a8cd78fe8..7240e4650 100644 --- a/gen/gen_mpy.py +++ b/gen/gen_mpy.py @@ -2113,7 +2113,7 @@ def get_arg_name(arg): if isinstance(arg, c_ast.PtrDecl) or isinstance(arg, c_ast.FuncDecl): return get_arg_name(arg.type) if hasattr(arg, 'declname'): return arg.declname - if hasattr(arg, 'name'): return name + if hasattr(arg, 'name'): return arg.name return 'unnamed_arg' # print("// Typedefs: " + ", ".join(get_arg_name(t) for t in typedefs)) diff --git a/lv_conf.h b/lv_conf.h index 446cdb92f..25da64608 100644 --- a/lv_conf.h +++ b/lv_conf.h @@ -17,12 +17,9 @@ #ifndef LV_CONF_H #define LV_CONF_H -#include - /*======================= * Development version! * ======================*/ - #define LV_USE_DEV_VERSION 1 /*==================== @@ -30,9 +27,7 @@ *====================*/ /*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ -#ifndef LV_COLOR_DEPTH - #define LV_COLOR_DEPTH 32 -#endif +#define LV_COLOR_DEPTH 16 /*========================= STDLIB WRAPPER SETTINGS @@ -42,6 +37,7 @@ * - 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_MICROPYTHON @@ -65,11 +61,6 @@ #endif #endif /*LV_USE_MALLOC == LV_STDLIB_BUILTIN*/ - -#if LV_USE_STDLIB_SPRINTF == LV_STDLIB_BUILTIN - #define LV_SPRINTF_USE_FLOAT 0 -#endif /*LV_USE_STDLIB_SPRINTF == LV_STDLIB_BUILTIN*/ - /*==================== HAL SETTINGS *====================*/ @@ -91,9 +82,6 @@ /*Align the start address of draw_buf addresses to this bytes*/ #define LV_DRAW_BUF_ALIGN 4 -/* Max. memory to be used for layers */ -#define LV_LAYER_MAX_MEMORY_USAGE 150 /*[kB]*/ - #define LV_USE_DRAW_SW 1 #if LV_USE_DRAW_SW == 1 /* Set the number of draw unit. @@ -125,14 +113,40 @@ * 0: to disable 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 #endif +/* Use Arm-2D on Cortex-M based devices. Please only enable it for Helium Powered devices for now */ +#define LV_USE_DRAW_ARM2D 0 + /* Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ #define LV_USE_DRAW_VGLITE 0 /* Use NXP's PXP on iMX RTxxx platforms. */ #define LV_USE_DRAW_PXP 0 +/* 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 +/* Enbale 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 +#endif + /*================= * OPERATING SYSTEM *=================*/ @@ -141,6 +155,8 @@ * - LV_OS_PTHREAD * - LV_OS_FREERTOS * - LV_OS_CMSIS_RTOS2 + * - LV_OS_RTTHREAD + * - LV_OS_WINDOWS * - LV_OS_CUSTOM */ #define LV_USE_OS LV_OS_NONE @@ -157,8 +173,7 @@ *-----------*/ /*Enable the log module*/ -#define LV_USE_LOG 0 - +#define LV_USE_LOG 1 #if LV_USE_LOG /*How important log should be added: @@ -172,12 +187,16 @@ /*1: Print the log with 'printf'; *0: User need to register a callback with `lv_log_register_print_cb()`*/ - #define LV_LOG_PRINTF 1 + #define LV_LOG_PRINTF 0 /*1: Enable print timestamp; *0: Disable print 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 #define LV_LOG_TRACE_TIMER 1 @@ -187,7 +206,6 @@ #define LV_LOG_TRACE_OBJ_CREATE 1 #define LV_LOG_TRACE_LAYOUT 1 #define LV_LOG_TRACE_ANIM 1 - #define LV_LOG_TRACE_MSG 1 #define LV_LOG_TRACE_CACHE 1 #endif /*LV_USE_LOG*/ @@ -254,8 +272,7 @@ #define LV_DISPLAY_ROT_MAX_BUF (10*1024) /*Garbage Collector settings - *Used if lvgl is bound to higher level language and the memory is managed by that language*/ - + *Used if LVGL is bound to higher level language and the memory is managed by that language*/ extern void mp_lv_init_gc(); #define LV_GC_INIT() mp_lv_init_gc() @@ -267,30 +284,33 @@ extern void mp_lv_init_gc(); /*Default cache size in bytes. *Used by image decoders such as `lv_lodepng` to keep the decoded image in the memory. - *Data larger than the size of the cache also can be allocated but - *will be dropped immediately after usage.*/ + *If size is not set to 0, the decoder will fail to decode when the cache is full. + *If size is 0, the cache function is not enabled and the decoded mem will be released immediately after use.*/ #ifdef MICROPY_CACHE_SIZE - #define LV_CACHE_DEF_SIZE MICROPY_CACHE_SIZE + #define LV_CACHE_DEF_SIZE MICROPY_CACHE_SIZE #else - #define LV_CACHE_DEF_SIZE 0 + #define LV_CACHE_DEF_SIZE 0 #endif /*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 +#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 +#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 1 +#define LV_OBJ_STYLE_CACHE 1 /* Add `id` field to `lv_obj_t` */ -#define LV_USE_OBJ_ID 0 +#define LV_USE_OBJ_ID 0 /* Use lvgl builtin method for obj ID */ -#define LV_USE_OBJ_ID_BUILTIN 0 +#define LV_USE_OBJ_ID_BUILTIN 0 + +/*Use obj property set/get API*/ +#define LV_USE_OBJ_PROPERTY 0 /*===================== * COMPILER SETTINGS @@ -328,8 +348,11 @@ extern void mp_lv_init_gc(); *should also appear on LVGL binding API such as Micropython.*/ #define LV_EXPORT_CONST_INT(int_value) enum {ENUM_##int_value = int_value} -/*Extend the default -32k..32k coordinate range to -4M..4M by using int32_t for coordinates instead of int16_t*/ -#define LV_USE_LARGE_COORD 0 +/*Prefix all global extern data with this*/ +#define LV_ATTRIBUTE_EXTERN_DATA + +/* Use `float` as `lv_value_precise_t` */ +#define LV_USE_FLOAT 0 /*================== * FONT USAGE @@ -480,6 +503,7 @@ extern void mp_lv_init_gc(); #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 texts*/ + #define LV_LABEL_WAIT_CHAR_COUNT 3 /*The count of wait chart*/ #endif #define LV_USE_LED 1 @@ -568,7 +592,7 @@ extern void mp_lv_init_gc(); /*API for fopen, fread, etc*/ #define LV_USE_FS_STDIO 0 #if LV_USE_FS_STDIO - #define LV_FS_STDIO_LETTER 'A' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_STDIO_LETTER 'A' /*Set an upper cased letter on which the drive will accessible (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 @@ -609,7 +633,7 @@ extern void mp_lv_init_gc(); #define LV_USE_LIBPNG 0 /*BMP decoder library*/ -#define LV_USE_BMP 1 +#define LV_USE_BMP 0 /* JPG + split JPG decoder library. * Split JPG is a custom format optimized for embedded systems. */ @@ -621,6 +645,16 @@ extern void mp_lv_init_gc(); /*GIF decoder library*/ #define LV_USE_GIF 1 +#if LV_USE_GIF +/*GIF decoder accelerate*/ +#define LV_GIF_CACHE_DECODE_DATA 0 +#endif + +/*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 1 @@ -634,33 +668,27 @@ extern void mp_lv_init_gc(); #else #define LV_USE_FREETYPE 0 #endif - #if LV_USE_FREETYPE - /*Memory used by FreeType to cache characters [bytes]*/ - #define LV_FREETYPE_CACHE_SIZE (64 * 1024) + /*Memory used by FreeType to cache characters in kilobytes*/ + #define LV_FREETYPE_CACHE_SIZE 768 /*Let FreeType to use LVGL memory and file porting*/ #define LV_FREETYPE_USE_LVGL_PORT 0 - /* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */ - /* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */ - /* if font size >= 256, must be configured as image cache */ - #define LV_FREETYPE_SBIT_CACHE 0 - /* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */ /* (0:use system defaults) */ - #define LV_FREETYPE_CACHE_FT_FACES 4 - #define LV_FREETYPE_CACHE_FT_SIZES 4 + #define LV_FREETYPE_CACHE_FT_FACES 8 + #define LV_FREETYPE_CACHE_FT_SIZES 8 + #define LV_FREETYPE_CACHE_FT_GLYPH_CNT 256 #endif /* Built-in TTF decoder */ #ifndef LV_USE_TINY_TTF - #define LV_USE_TINY_TTF 1 + #define LV_USE_TINY_TTF 0 #endif - #if LV_USE_TINY_TTF /* Enable loading TTF data from files */ - #define LV_TINY_TTF_FILE_SUPPORT 1 + #define LV_TINY_TTF_FILE_SUPPORT 0 #endif /*Rlottie library*/ @@ -669,15 +697,32 @@ extern void mp_lv_init_gc(); #else #define LV_USE_RLOTTIE 0 #endif + +/*Enable Vector Graphic APIs*/ +#define LV_USE_VECTOR_GRAPHIC 0 + +/* Enable ThorVG (vector graphics library) from the src/libs folder */ +#define LV_USE_THORVG_INTERNAL 0 + +/* Enable ThorVG by assuming that its installed and linked to the project */ +#define LV_USE_THORVG_EXTERNAL 0 + +/*Enable LZ4 compress/decompress lib*/ +#define LV_USE_LZ4 0 + +/*Use lvgl built-in LZ4 lib*/ +#define LV_USE_LZ4_INTERNAL 0 + +/*Use external LZ4 library*/ +#define LV_USE_LZ4_EXTERNAL 0 + /*FFmpeg library for image decoding and playing videos *Supports all major image formats so do not enable other image decoder with it*/ - #ifdef MICROPY_FFMPEG #define LV_USE_FFMPEG MICROPY_FFMPEG #else #define LV_USE_FFMPEG 0 #endif - #if LV_USE_FFMPEG /*Dump input information to stderr*/ #define LV_FFMPEG_DUMP_FORMAT 0 @@ -691,7 +736,7 @@ extern void mp_lv_init_gc(); #define LV_USE_SNAPSHOT 1 /*1: Enable system monitor component*/ -#define LV_USE_SYSMON 0 +#define LV_USE_SYSMON (LV_USE_MEM_MONITOR | LV_USE_PERF_MONITOR) /*1: Enable the runtime performance profiler*/ #define LV_USE_PROFILER 0 @@ -707,10 +752,16 @@ extern void mp_lv_init_gc(); #define LV_PROFILER_INCLUDE "lvgl/src/misc/lv_profiler_builtin.h" /*Profiler start point function*/ - #define LV_PROFILER_BEGIN LV_PROFILER_BUILTIN_BEGIN + #define LV_PROFILER_BEGIN LV_PROFILER_BUILTIN_BEGIN /*Profiler end point function*/ - #define LV_PROFILER_END LV_PROFILER_BUILTIN_END + #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 #endif /*1: Enable Monkey test*/ @@ -750,7 +801,7 @@ extern void mp_lv_init_gc(); #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 /*LV_IME_PINYIN_USE_K9_MODE*/ #endif /*1: Enable file explorer*/ @@ -769,19 +820,28 @@ extern void mp_lv_init_gc(); *==================*/ /*Use SDL to open window on PC and handle mouse and keyboard*/ - #ifdef MICROPY_SDL #define LV_USE_SDL MICROPY_SDL #else #define LV_USE_SDL 0 #endif - #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_BUF_COUNT 1 /*1 or 2*/ #define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/ - #define LV_SDL_DIRECT_EXIT 0 /*1: Exit the application when all SDL windows are closed*/ + #define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/ +#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 the application when all X11 windows have been closed*/ + #define LV_X11_DOUBLE_BUFFER 1 /*Use double buffers for endering*/ + /*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 /*Driver for /dev/fb*/ @@ -790,7 +850,6 @@ extern void mp_lv_init_gc(); #else #define LV_USE_LINUX_FBDEV 0 #endif - #if LV_USE_LINUX_FBDEV #define LV_LINUX_FBDEV_BSD 0 #define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL @@ -798,13 +857,24 @@ extern void mp_lv_init_gc(); #define LV_LINUX_FBDEV_BUFFER_SIZE 60 #endif -#define LV_USE_NUTTX_FBDEV 0 +/*Use Nuttx to open window and handle touchscreen*/ +#define LV_USE_NUTTX 0 +#if LV_USE_NUTTX + #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 -/*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/dri/card*/ @@ -813,15 +883,15 @@ extern void mp_lv_init_gc(); /*Interface for TFT_eSPI*/ #define LV_USE_TFT_ESPI 0 -/*Driver for /dev/input*/ -#define LV_USE_NUTTX_TOUCHSCREEN 0 +/*Driver for evdev input devices*/ +#define LV_USE_EVDEV 0 /*================== * EXAMPLES *==================*/ /*Enable the examples to be built with the library*/ -#define LV_BUILD_EXAMPLES 0 +#define LV_BUILD_EXAMPLES 1 /*=================== * DEMO USAGE @@ -838,10 +908,9 @@ extern void mp_lv_init_gc(); /*Benchmark your system*/ #define LV_USE_DEMO_BENCHMARK 0 -#if LV_USE_DEMO_BENCHMARK - /*Use RGB565A8 images with 16 bit color depth instead of ARGB8565*/ - #define LV_DEMO_BENCHMARK_RGB565A8 0 -#endif + +/*Render test for each primitives. Requires at least 480x272 display*/ +#define LV_USE_DEMO_RENDER 0 /*Stress test for LVGL*/ #define LV_USE_DEMO_STRESS 0 @@ -867,6 +936,9 @@ extern void mp_lv_init_gc(); /*Demonstrate scroll settings*/ #define LV_USE_DEMO_SCROLL 0 + +/*Vector graphic demo*/ +#define LV_USE_DEMO_VECTOR_GRAPHIC 0 /*--END OF LV_CONF_H--*/ #endif /*LV_CONF_H*/ diff --git a/lvgl b/lvgl index b172c64a8..a9960c621 160000 --- a/lvgl +++ b/lvgl @@ -1 +1 @@ -Subproject commit b172c64a8c8d7189f66c1ed5afae19c9a8fbef39 +Subproject commit a9960c6216ac001c3c2384bed26c41c3c86c626e