Standalone binary .mpy module for lvgl (so we can "just use it" in micropython)

This is turning into more work than I expected… do we “roll our own” (quick, works) or attempt to try and make whatever we do look and feel the same as other similar efforts (or even be marginally compatible with them) ? Shudder at the difficulty of working out what those other efforts might be, and which might be the “best”…

@kdschlosser does lvgl require a framebuffer?, and if so, how does it deal with buffers that are less than the size of the screen? Does it properly accommodate all writes etc that span multiple buffers? Does it properly understand hardware features, like scrolling, while logically keeping track of how its own buffers must reflect that?

Is there any “bare bones” Arduino (not micropython) lvgl demo that uses the most minimal possibly subset of lvgl that you know of, which I can build first and test, before attempting to port it into an lvgl.mpy file? Doing strace on the one that shipped with my LCD boards shows it including half the examples during the build… it’s easier to start from the basics and add all the other stuff after the start is working…

yes LVGL needs to have something to write to So there MUST be a buffer that is provided to LVGL. LVGL does not write to the display it simply calls a function passing the buffer to that function along with the rectangle in x, y coordinates on the screen that the buffer data should be written to. It is the users responsibility to get the data written to the display.

People want a plug and play solution and that doesn’t exist. in my opinion it is outside of the scope of what LVGL should me making. provide 2 maybe 3 different drivers to how for example purposes at most. I don’t believe it should be the responsibility of the LVGL developers to write hardware drivers for a display. That falls into the responsibility area of the display manufacturer. That is how it works with computers and that same way should also be done with MCU’s

as an example. You don’t see any display drivers in QT or wxWidgets do you? Those are both graphics frameworks just like LVGL is… Why is there a need to include any driver with LVGL at all??

If that was the way it worked then having a MPY file for LVGL would be a snap and could easily be done. Due to MicroPythons built in SPI a user is not going to be able get the benefits of using DMA and double buffering That is due to a design issue in MicroPython and not LVGL. The problem should be corrected in MicroPython, it is not the responsibility of LVGL to come up with some kind of a solution that ends up causing other issues like accessing other devices that might be on the same bus as the display.
That is all outside of the scope LVGL or any binding for LVGL.

LVGL should not be including any drivers with it.There are simply too many different combinations of display, display IC, communication busses and MCU’s to make it something that can be done easily. There is no commonality between all of them. they are all different in ways that would require special handling and special drivers would have to be written for each combination.

A bus driver needs to be written for the following

RGB ESP32
RGB STM32
RGB NXP
RGB RPI
RGB Micro:bit
RGB SAMD
RGB Renesas
RGB Qemu-ARM
RGB PowerPC
RGB PIC16bit
RGB NRF
RGB MIMXRT
RGB ESP8266
RGB CC3200
RGB ARM


MIPI ESP32
MIPI STM32
MIPI NXP
MIPI RPI
MIPI Micro:bit
MIPI SAMD
MIPI Renesas
MIPI Qemu-ARM
MIPI PowerPC
MIPI PIC16bit
MIPI NRF
MIPI MIMXRT
MIPI ESP8266
MIPI CC3200
MIPI ARM


SPI ESP32
SPI STM32
SPI NXP
SPI RPI
SPI Micro:bit
SPI SAMD
SPI Renesas
SPI Qemu-ARM
SPI PowerPC
SPI PIC16bit
SPI NRF
SPI MIMXRT
SPI ESP8266
SPI CC3200
SPI ARM


I8080 ESP32
I8080 STM32
I8080 NXP
I8080 RPI
I8080 Micro:bit
I8080 SAMD
I8080 Renesas
I8080 Qemu-ARM
I8080 PowerPC
I8080 PIC16bit
I8080 NRF
I8080 MIMXRT
I8080 ESP8266
I8080 CC3200
I8080 ARM


I6060 ESP32
I6060 STM32
I6060 NXP
I6060 RPI
I6060 Micro:bit
I6060 SAMD
I6060 Renesas
I6060 Qemu-ARM
I6060 PowerPC
I6060 PIC16bit
I6060 NRF
I6060 MIMXRT
I6060 ESP8266
I6060 CC3200
I6060 ARM


I2C ESP32
I2C STM32
I2C NXP
I2C RPI
I2C Micro:bit
I2C SAMD
I2C Renesas
I2C Qemu-ARM
I2C PowerPC
I2C PIC16bit
I2C NRF
I2C MIMXRT
I2C ESP8266
I2C CC3200
I2C ARM


I2S ESP32
I2S STM32
I2S NXP
I2S RPI
I2S Micro:bit
I2S SAMD
I2S Renesas
I2S Qemu-ARM
I2S PowerPC
I2S PIC16bit
I2S NRF
I2S MIMXRT
I2S ESP8266
I2S CC3200
I2S ARM

and then you would need to write drivers for the different display IC’s
Here are a few ICs (this is not all inclusive)

ASLIC
    AX6120: Mono LCD

Avant
    SAP1024B: Mono LCD
    SAP3305: Mono LCD
    SBN0064G: Mono LCD
    SBN1661G: Mono LCD
    SBN6400G: Mono LCD
    SCN0080G: Mono LCD
    SCN6400G: Mono LCD
    SDN0080G: Mono LCD
    SDN8000G: Mono LCD
    SDN8080G: Mono LCD
    SEN6A39: Mono LCD
    SEN6A40: Mono LCD

Chip Wealth
    CH1115: PMOLED

EM Microelectronics
    EM6126: Mono LCD
    V6118: Mono LCD

Elan
    EM65100: Mono Graphic LCD
    EM65168: Mono Graphic LCD
    EM65568: Mono Graphic LCD
    EPL43102: Mono Graphic LCD
    EPL65132: Mono Graphic LCD
    EPL09060: Mono LCD

Epson
    S1D10605: Mono LCD
    S1D15719: Mono LCD
    S1D15722: Mono LCD
    SED1330: Mono LCD
    SED1335: Mono LCD
    SED1520: Mono LCD
    SED1521: Mono LCD
    SED1530: Mono LCD
    SED1565: Mono LCD
    SED1566: Mono LCD
    SED1575: Mono LCD

Eureka Microelectronics
    EK7010: Mono LCD
    EK7011: Mono LCD

Fitipower
    ED73002A: TFT Display
    EK73002: TFT Display
    EK73215: TFT Display
    EK73217A: TFT Display
    EK79001: TFT Display
    EK79007: TFT Display
    EK79202: TFT Display
    EK9713: TFT Display
    EK9716B: TFT Display
    JD9852: TFT Display

Galaxy Core
    GC9A01A: TFT Display

Genitop
    GT20L16S1Y: Mono LCD
    GT21L16T1W: Mono LCD
    GT23L16U2W: Mono LCD
    GT23L24T3Y: Mono LCD

Goworld
    GW7707: Mono LCD

Himax
    HX8705: E-paper
    HX8218-C01: TFT Display
    HX8227-A: TFT Display
    HX8232-A: TFT Display
    HX8238-A: TFT Display
    HX8238-D: TFT Display
    HX8249: TFT Display
    HX8250: TFT Display
    HX8257: TFT Display
    HX8264: TFT Display
    HX8278-A-LT: TFT Display
    HX8282: TFT Display
    HX8288: TFT Display
    HX8312: TFT Display
    HX8345-A: TFT Display
    HX8347-A: TFT Display
    HX8352: TFT Display
    HX8353-E: TFT Display
    HX8357-B: TFT Display
    HX8363-A: TFT Display
    HX8369-A: TFT Display
    HX8394-F: TFT Display
    HX8399: TFT Display
    HX8615A: TFT Display
    HX8643-A: TFT Display
    HX8655-A: TFT Display
    HX8664: TFT Display
    HX8678: TFT Display
    HX8695: TFT Display
    HX8696-A: TFT Display
    HX8819: TFT Display
    HX8902-B: TFT Display

Hitachi
    HD44780: Mono Character LCD
    HD61202: Mono LCD
    HD61203: Mono LCD
    HD61830B: Mono LCD
    HD66100F: Mono LCD
    HD66712: Mono LCD
    HD66750: Mono LCD

Holtek
    HT1611C: Mono Digit LCD
    HT1613C: Mono Digit LCD
    HT1616C: Mono Digit LCD
    HT1620: Mono Digit LCD
    HT1621: Mono Digit LCD
    HT1622: Mono Digit LCD
    HT16220: Mono Digit LCD
    HT1623: Mono Digit LCD
    HT1625: Mono Digit LCD
    HT1626: Mono Digit LCD
    HT1647: Mono Digit LCD
    HT1647A: Mono Digit LCD
    HT1650: Mono Digit LCD
    HT1660: Mono Digit LCD

Ilitek
    ILI5480: TFT Display
    ILI5960: TFT Display
    ILI6122: TFT Display
    ILI6123: TFT Display
    ILI6126: TFT Display
    ILI6480: TFT Display
    ILI8961: TFT Display
    ILI9163C: TFT Display
    ILI9225G: TFT Display
    ILI9320: TFT Display
    ILI9325: TFT Display
    ILI9325C: TFT Display
    ILI9327: TFT Display
    ILI9328: TFT Display
    ILI9340: TFT Display
    ILI9341: TFT Display
    ILI9341V: TFT Display
    ILI9342: TFT Display
    ILI9481: TFT Display
    ILI9486: TFT Display
    ILI9488: TFT Display
    ILI9806E: TFT Display
    ILI9806H: TFT Display
    ILI9881C: TFT Display
    ILI6122: TFT Display
    ILI6123: TFT Display
    ILI6126: TFT Display

Integrated Solutions
    IST3004: Mono LCD
    IST3020: Mono LCD
    IST3040: Mono LCD
    IST3042: Mono LCD
    IST3088: Mono LCD
    IST3931: Mono LCD

LDT
    LD7134: OLED
    LD7138: OLED

LG
    DP4216: PMOLED
    LG4538: TFT Display

MPS
    MP1518: LED Driver
    MP3202: LED Driver

Microchip
    AY0438: Mono LCD

Minilogic Device
    ML1001: Mono LCD

NEC
    µPD7225: Mono LCD

NXP
    PCA8539: Mono LCD
    PCF8538: Mono LCD
    PCF8583: Mono LCD

Neotec
    NT7066U: Mono Character LCD
    NT7063B: Mono LCD
    NT7065B: Mono LCD
    NT7070B: Mono LCD
    NT7086: Mono LCD
    NT7107: Mono LCD
    NT7108: Mono LCD
    NT7108C: Mono LCD
    NT7450B: Mono LCD

New Japan Radio
    NJU6406B: Mono LCD
    NJU6407C: Mono LCD
    NJU6415: Mono LCD
    NJU6416: Mono LCD
    NJU6417C: Mono LCD
    NJU6420B: Mono LCD
    NJU6423B: Mono LCD
    NJU6424: Mono LCD
    NJU6426: Mono LCD
    NJU6445: Mono LCD
    NJU6446: Mono LCD
    NJU6450A: Mono LCD
    NJU6451A: Mono LCD
    NJU6515: Mono LCD
    NJU6539: Mono LCD
    NJU6679: Mono LCD
    NJU6452A: Mono LCD
    NJU6453A: Mono LCD
    NJU6466: Mono LCD
    NJU6467: Mono LCD
    NJU6468: Mono LCD
    NJU6469: Mono LCD
    NJU6470: Mono LCD
    NJU6538: Mono LCD
    NJU6624A-B: Mono LCD
    NJU6624C: Mono LCD
    NJU6625: Mono LCD
    NJU665: Mono LCD
    NJU6677: Mono LCD
    NJU6678V: Mono LCD
    NJU6680: Mono LCD
    NJU6818: Mono LCD

NewVision
    NV3035C: TFT Display
    NV3052C: TFT Display

Novatek
    NT3881D: Mono LCD
    NT3882: Mono LCD
    NT7502: Mono LCD
    NT7506: Mono LCD
    NT7508: Mono LCD
    NT7532: Mono LCD
    NT7534: Mono LCD
    NT7538: Mono LCD
    NT75451: Mono LCD
    NT7553E: Mono LCD
    NT7603: Mono LCD
    NT7605: Mono LCD
    NT7606: Mono LCD
    NT7607: Mono LCD
    NT7701: Mono LCD
    NT7702: Mono LCD
    NT7703: Mono LCD
    NT7704: Mono LCD
    NT7705: Mono LCD
    NT35510: TFT Display
    NT35532: TFT Display
    NT39016: TFT Display
    NT39103: TFT Display
    NT39207: TFT Display
    NT39212F: TFT Display
    NT39411: TFT Display
    NT39419: TFT Display
    NT51007D: TFT Display
    NT52001: TFT Display

OKI
    ML9044A-xxA-xxB: Mono LCD

Orient Display
    AC780S: Mono LCD

Orise Tech
    SPLC063B1: Mono LCD
    SPLC100B1: Mono LCD
    SPLC780D1: Mono LCD
    SPLC782A1: Mono LCD
    SPLC783A1: Mono LCD
    OTA5180A: TFT Display
    OTA5182A: TFT Display
    OTA7001A: TFT Display
    OTA7159A: TFT Display
    OTD9160A: TFT Display
    OTD9960: TFT Display
    OTM2201A: TFT Display
    OTM3225A: TFT Display
    OTM3225C: TFT Display
    OTM4001A: TFT Display
    SPFD5408B: TFT Display
    SPFD5420A: TFT Display

Phillips NXP
    PCF2100: Mono LCD
    PCF2113x: Mono LCD
    PCF2116: Mono LCD
    PCF2119x: Mono LCD
    PCF2119x-2: Mono LCD
    PCF8531: Mono LCD
    PCF8533: Mono LCD
    PCF8548: Mono LCD
    PCF8566: Mono LCD
    PCF8574: Mono LCD
    PCF8577C: Mono LCD
    PCF8578: Mono LCD
    PCF8579: Mono LCD
    PCF8812: Mono LCD

Princeton Technology
    PT6520: Mono LCD
    PT6574: Mono LCD
    PT6880: PMOLED
    PT6800: PMOLED

Raio Technology
    RA6963: Mono LCD
    RA8802-8820: Mono LCD
    RA8803-8822: Mono LCD
    RA8806: Mono LCD
    RA8808: Mono LCD
    RA8815: Mono LCD
    RA8816: Mono LCD
    RA8825: Mono LCD
    RA8835-RA88335A: Mono LCD
    RA8863: Mono LCD
    RA8900: Mono LCD
    RA8906: Mono LCD
    RA8911: Mono LCD
    RA8917: Mono LCD
    RA8875: TFT Display

Raydium Semiconductor
    RM67162: OLED
    RM68090: TFT Display

Renesas
    R61509V: TFT Display
    R61516: TFT Display

RockWorks
    RW1026: Mono LCD
    RW1033: Mono LCD
    RW1060: Mono LCD
    RW1062: Mono LCD
    RW1063: Mono LCD
    RW1067: Mono LCD
    RW1067C-0B: Mono LCD
    RW1067C-0C: Mono LCD
    RW1067C-0D: Mono LCD
    RW1068: Mono LCD
    RW1073-0A: Mono LCD
    RW1073-0B: Mono LCD
    RW1092: Mono LCD

ST
    STE2002: Mono LCD

Samsung
    KS0031: Mono LCD
    KS0032: Mono LCD
    KS0035: Mono LCD
    KS0070B: Mono LCD
    KS0105: Mono LCD
    KS0106: Mono LCD
    KS0107: Mono LCD
    KS0713: Mono LCD
    S6A0031: Mono LCD
    S6A0032: Mono LCD
    S6A0063B: Mono LCD
    S6A0065: Mono LCD
    S6A0069: Mono LCD
    S6A0070: Mono LCD
    S6A0071: Mono LCD
    S6A0072: Mono LCD
    S6A0073: Mono LCD
    S6A0074: Mono LCD
    S6A0078: Mono LCD
    S6A0079: Mono LCD
    S6A0090: Mono LCD
    S6A0092: Mono LCD
    S6A0093: Mono LCD
    S6A0094: Mono LCD
    S6A2067: Mono LCD
    S6A2068: Mono LCD
    S6B0086: Mono LCD
    S6B0107: Mono LCD
    S6B0108: Mono LCD
    S6B0708: Mono LCD
    S6B0715: Mono LCD
    S6B0716: Mono LCD
    S6B0717: Mono LCD
    S6B0718: Mono LCD
    S6B0719: Mono LCD
    S6B0723: Mono LCD
    S6B0724: Mono LCD
    S6B0741: Mono LCD
    S6B0755: Mono LCD
    S6B0759: Mono LCD
    S6B0794: Mono LCD
    S6B0796: Mono LCD
    S6B1713: Mono LCD
    S6B2104: Mono LCD

Sanyo
    LC7940: Mono LCD
    LC7942ND: Mono LCD
    LC7981: Mono LCD
    LC7982A: Mono LCD
    LC7985: Mono LCD
    LC9401D: Mono LCD
    LC9430D: Mono LCD

Semico
    CS1520: Mono LCD

Sharp
    LH155BA: Mono LCD

Sino Wealth
    SH1101A: Mono LCD
    SH1107: PMOLED
    SH1108: PMOLED
    SH1106: PMOLED
    SH1122: PMOLED

Sitronix
    ST7045: FS LCD
    ST7049: FS LCD
    ST2101C: Mono LCD
    ST7571: Mono LCD
    ST7588T: Mono LCD
    ST7591: Mono LCD
    ST7598: Mono LCD
    ST8016T: Mono LCD
    ST8024S: Mono LCD
    ST7025: Mono LCD
    ST7026: Mono LCD
    ST7032: Mono LCD
    ST7033: Mono LCD
    ST7036: Mono LCD
    ST7038: Mono LCD
    ST7063C: Mono LCD
    ST7065C: Mono LCD
    ST7066U: Mono LCD
    ST7070: Mono LCD
    ST7076: Mono LCD
    ST7093: Mono LCD
    ST7522: Mono LCD
    ST75256: Mono LCD
    ST7526: Mono LCD
    ST7528: Mono LCD
    ST7529: Mono LCD
    ST7533: Mono LCD
    ST7539: Mono LCD
    ST7541: Mono LCD
    ST7545T: Mono LCD
    ST7546T: Mono LCD
    ST7548T: Mono LCD
    ST7549T: Mono LCD
    ST7556: Mono LCD
    ST7558: Mono LCD
    ST7565P: Mono LCD
    ST7565R: Mono LCD
    ST7565S: Mono LCD
    ST7565V: Mono LCD
    ST7567: Mono LCD
    ST7567A: Mono LCD
    ST7568: Mono LCD
    ST7579: Mono LCD
    ST7580: Mono LCD
    ST7585: Mono LCD
    ST7586: Mono LCD
    ST7920: Mono LCD
    ST7921: Mono LCD
    ST8008: Mono LCD
    ST8009: Mono LCD
    ST8011: Mono LCD
    ST8012: Mono LCD
    ST8016: Mono LCD
    ST8016S: Mono LCD
    ST8024: Mono LCD
    ST8024T: Mono LCD
    SC7283: TFT Display
    ST7735R: TFT Display
    ST7781: TFT Display
    ST7262: TFT Display
    ST7272A: TFT Display
    ST7282: TFT Display
    ST7282T2: TFT Display
    ST7301: TFT Display
    ST7701: TFT Display
    ST7715: TFT Display
    ST7735: TFT Display
    ST7735S: TFT Display
    ST7773: TFT Display
    ST7775R: TFT Display
    ST7789V: TFT Display
    ST7789VI: TFT Display
    ST7789S: TFT Display
    ST7796S: TFT Display

Solomon
    SSD1603: Bistable LCD
    SSD1615: Bistable LCD
    SSD1621: Bistable LCD
    SSD1623: Bistable LCD
    SSD1677: E-paper
    SSD1680: E-paper
    SSD1681: E-paper
    SSD1683: Mono LCD
    SSD1805: Mono LCD
    SSD1808: Mono LCD
    SSD1815B: Mono LCD
    SSD1829: Mono LCD
    SSD1839: Mono LCD
    SSD1848: Mono LCD
    SSD1851: Mono LCD
    SSD1852: Mono LCD
    SSD1854: Mono LCD
    SPD0301: PMOLED
    SSD1303: PMOLED
    SSD1305: PMOLED
    SSD1306: PMOLED
    SSD1307: PMOLED
    SSD1308: PMOLED
    SSD1309: PMOLED
    SSD1315: PMOLED
    SSD1316: PMOLED
    SSD1317: PMOLED
    SSD1320: PMOLED
    SSD1322: PMOLED
    SSD1325: PMOLED
    SSD1326: PMOLED
    SSD1327: PMOLED
    SSD1331: PMOLED
    SSD1332: PMOLED
    SSD1339: PMOLED
    SSD1351: PMOLED
    SSD1362: PMOLED
    SSD7317: PMOLED
    SSD1289: TFT Display
    SSD1298: TFT Display
    SSD2118: TFT Display
    SSD2119: TFT Display

Sunplus
    SPL61A: Mono LCD
    SPLC086A: Mono LCD
    SPLC100A1: Mono LCD
    SPLC100A2: Mono LCD
    SPLC501C: Mono LCD
    SPLC502A: Mono LCD
    SPLC780A: Mono LCD
    SPLC780C: Mono LCD
    SPLC780D: Mono LCD
    SPLC783A: Mono LCD

Teralane Semiconductor
    TLS8201: Mono LCD

Tomato
    TL0324: Mono LCD

Toshiba
    T6A39: Mono LCD
    T6A40: Mono LCD

Ultrachip
    UC1601: Mono LCD
    UC1601s: Mono LCD
    UC1607: Mono LCD
    UC1608: Mono LCD
    UC1610: Mono LCD
    UC1611: Mono LCD
    UC1611S: Mono LCD
    UC1616: Mono LCD
    UC1617: Mono LCD
    UC1617s: Mono LCD
    UC1617w: Mono LCD
    UC1618: Mono LCD
    UC1628: Mono LCD
    UC1638: Mono LCD
    UC1682s: Mono LCD
    UC1701: Mono LCD
    UC1701x: Mono LCD
    UCi6963: Mono LCD
    UCi7066: Mono LCD

Wuxi I-CORE
    AIP31065: Mono LCD
    AIP31066: Mono LCD
    AIP31068L: Mono LCD
    AiP31565: Mono LCD

and then while we are there because LVGL would be promising a plug and play solution drivers for these touch IC’s would also need to be availabe (again not an all inclusive list)

Atmel
    mXT1066T2: Capacitive Touch
    mXT224E: Capacitive Touch
    mXT225T: Capacitive Touch
    mXT336T: Capacitive Touch
    mXT640T: Capacitive Touch

Burr Brown Products
    ADS7846: Capacitive Touch
    TSC2003: Resistive Touch
    TSC2007: Resistive Touch
    TSC2046: Resistive Touch

Elan
    eKT2101: Capacitive Touch

FocalTech
    FT5306: Capacitive Touch
    FT5336: Capacitive Touch
    FT5436: Capacitive Touch
    FT5x06: Capacitive Touch
    FT5x16: Capacitive Touch
    FT5x26: Capacitive Touch
    FT5x46: Capacitive Touch
    FT6336G: Capacitive Touch
    FT7311: Capacitive Touch
    FT7401: Capacitive Touch
    FT7511: Capacitive Touch
    FT7611: Capacitive Touch

Goodix
    GT5663: Capacitive Touch
    GT911: Capacitive Touch
    GT9271: Capacitive Touch
    GT968: Capacitive Touch

Ilitek
    ILI2511: Capacitive Touch

Microchip
    AR1100: Resistive Touch

Sitronix
    ST1624: Capacitive Touch
    ST1633: Capacitive Touch
    ST1633i: Capacitive Touch

I am only wanting to show the sheer scope of adding display drivers to LVGL. It’s an absoutly massive project to tackle. You can’t use libraries like tft_espi because they are specific to compiling using the Arduino IDE. There is really nothing that is made that is not attached to some kind of a build system that covers a large portion of the displays and touch controllers listed above.

From the previous message it sounds like lvgl needs either 1 or 2 buffers that are “screen size /10” and it handles all the paging of the buffer(s), pushing it to the display driver as needed.

Micropython has consistent i2c and spi apis across pretty much every port, so if we can make the display drivers work with that it’ll make compatibility far easier. However as noted they are both currently blocking for read/write operations, for use with a display they would need to also support non-blocking / background use. As an aside, non blocking use of these has been discussed as part of working towards asyncio interfaces to these peripherals, but work on that architecture hasn’t really been started yet.

I honestly think starting with getting both lvgl core and individual display drivers working as a user C module first will be easiest - then for any board that ships with a screen the board definition can include lvgl and the matching driver configured and compiled in.

The dynamic C modules that can be compiled and copied around are neat, but a bit harder to control and configure really. While users can copy them on with various tools, or manufacturers can make a "pre-baked filesystem that includes it… these are non standard things really. Having it just compiled into the firmware that matches that board is a fast more standard way to manage it.

Also, dynamic C modules do indeed take up quite a bit more ram, needing to be loaded from a filesystem. Of note, on any chip without hardware float support, assuming lvgl uses float (?) the dynamic C modules actually need their own copy of the soft float libraries compiled in, which ends up consuming something like an extra 20KB. If the driver.mpy also needs to use float at all, it’ll need it’s own copy too…

SPI cannot be used across all ports. NONE of them deal with DMA memory.
I2C is the same thing

MicroPython has no code in it to handle anything display related. ESP-IDF has some built in stuff for displays. I don’t think any of the other MCU brands SDK’s have anything to handle displays. Or if they do it is not to handle all of the different display bus types used in small format displays.

Oh I did also want to mention that MicroPython on an ESP32 has limited the amount of data that can be transmitted using SPI to 4096 bytes. more than that amount of data can be written to SPI if it is configured properly to do it which it is not. buffer sizes larger than 4096 bytes is almost a requirement when using a display.

I mean the public API for spi and i2c is consistent currently, and could ideally be extended in a consistent way for background (ie dma) transfers. Sure, any inconsistencies like length limits would need to be cleaned up in the process.

The stm port actually does use dma for hardware spi on most if not all chips, but blocks the running thread while waiting for it to finish.

The blocking is also done in ESP32 and there is a hard limit set on the maximum size transfer. If the maximum size is set when the driver is first initialized instead of being left at zero then the limit would be whatever has been set.

The reason why it is done the way that MicroPython has done it is to keep the API exactly the same across all MCU’s. This is what causes problems for LVGL and writing drivers because now the drivers have to be specifically written for the MCU it is being used with. Can’t use the SPI that is built into MicroPython to handle it.

In order to build LVGL for MicroPython portions of the SDK for the board have to be exposed to the MicroPython interpreter and in order to do that LVGL needs to be compiled as part of the firmware. For some of the ports where LVGL doesn’t need to have access to the MCU SDK LVGL is able to be compiled as a user C module but with the ESP32 this is not able to be done. To build LVGL into MicroPython without the ability to do it via the user C module the makefiles have to be changed. It make it more integrated then a standalone thing. Then when something happens like what is seen between version 20.0 and 21.0 of MicroPython where the build system has a gross change made it to things get really mucked up. No matter what I have tried I am not able to get the build system to pass the compiler flags used to build MicroPython to the compiler when LVGL gets compiled. I have tried and tried and I have not had any success.

It would be a lot better and easier of LVGL could be compiled as a user c module. It would make the entire build system for LVGL self contained. There would be no need to modify any of MicroPythons build system

I got most of the way to having user C module integration finished here: Integration as external c module with unmodified micropython. by andrewleech · Pull Request #242 · lvgl/lv_binding_micropython · GitHub but that needs rebasing for newer micropython, and I didn’t get esp working… cmake was fighting me. I got cmake sorted for rp2 though so it should have been close for esp.

I’m sure the buffer size stuff for esp can be fixed from a micropython side, I can only assume it’s just been built the way it is for simplicity and hasn’t had any strong reason / request to change it yet.

If we don’t fix the spi/i2c drivers in micropython so they can be used for lvgl, we’re left with lvgl having to build brand new drivers for all platforms which is way too much duplicated work! I have a strong personal hatred of reinventing the wheel, I’d much prefer to reuse as much as possible and build up from there.

I’m sure a simple extension to the existing micropython spi/i2c APIs can be figured out that would make it suitable!

Ruins the entire point of trying to make things modular, and brings a pile of other downsides (cannot ever use 2 displays, any updates/changes to either lvgl or hardware drivers require everything to be sync’d and rebuilt …)

“standard” is totally broken - we need to get away from that legacy thinking. The hardware ecosystem is simply to vast to expect everyone with one “thing” to be building new firmware’s for every other kind of device they wish to support. That concept is just bonkers.

folks who make displays can build one LCD driver and another touch driver for the dozen or so MCU’s they wish to support.

lvgl just builds one lvgl.mpy for the dozen or so MCU’s they wish to support.

MCU makers build just the one micropython firmware for their MCU

that’s minimal effort for everyone involved.

The alterative is every one of the above building everything for everyone else - that’s [ a dozen cubed, all squared, multiplied by the number of vendors out there] builds for everyone, with none of that mess ever supporting 2 displays…

Blocking for DMA sounds like a old-wives-tale? Whatever made someone think that’s necessary, was probably something else besides what they thought it was?

I’ve not tried it, but I’m pretty sure “C” can use the uPy SPI/I2C/etc structures (probably they need to be passed in as parameters of course) to get at and use those devices when it needs to (I seem to recall reading something about that in the doco someplace).

I do remember it mention that the output machine language is position-independent, so there’s a fair chance that both lvgl.mpy and the display.mpy drivers will survive for many consecutive uPy releases and work unchanged.

@andrewleech

I did see you work on getting LVGL to compile as a user C module. While this still ends up getting built into the firmware it doesn’t require the extensive modification to the MicroPython build system in order to work. It is a better solution than what is currently taking place but it in it’s current form it doesn’t support the ESP32 which is possibly the most used MCU with MicroPython and LVGL. It is a must that it will work with this MCU. I have come across the same problem that has already been posted about a duplicate main file. Not sure how to work around this. The MicroPython build system is a rats nest and hard to understand what is actually happening and in what order it is happening in.

Copies of the SPI and I2C drivers can be made and adjusted to remove any blocking and allow DMA transfers to work properly. I do not know if those would be able to be compiled as user C modules or not that all depends on the MicroPython build system and it exposing the relative SDK to the user C module.

If we are able to compile the bus drivers as user C modules which would expose the portions of the SDK’s then drivers for the actual displays can be written in Python code easy enough. Any manipulation of the frame buffer data that needs to be done can also be done in Python code using the viper code emitter so the code would execute at close to the same speed as C code. I am able to handle that kind of stuff. I can also modify the gen_mpy file so it will take care of writing the C code to handle the different types of busses that are available in the different SDK’s. What I am not proficient in is the build system If someone is able to get LVGL to build (without any drivers for the time being) for all MCU’s that MicroPython supports I can make the needed changes to gen_mpy to get it up to snuff to expose what is needed for the different busses. From there the drivers would be pretty easy to write.

The current way the drivers work is a driver handles both the display and also the bus aspects. They need to be separated. The display driver should be written so that it can be used with any bus. The line should be drawn at providing the display driver framework and providing the busses. it would be up to a display manufacturer or the user to write the code for the display they are using. we can provide 3 maybe 4 of the most popular ones but that is where the line should be drawn. otherwise it becomes to much to handle from a maintenance aspect.

CPython and MicroPython alike are a runtime language so a user should be able to select what display they want to use without having to recompile. Simply upload the py file that is for their display and that’s it. This would keep the size of the firmware from getting bloated and it stops the user from having to recompile MicroPython should they want to change the display they are using.

A example of how it would work from the user aspect.

from micropython import const
import display_bus
import st7796
import lvgl as lv

_WIDTH = const(480)
_HEIGHT = const(320)

_PWR_PIN = const(27)
_BKL_PIN = const(25)
_CS_PIN = const(23)
_DC_PIN = const(22)
_WR_PIN = const(21)
_DATA0_PIN = const(5)
_DATA1_PIN = const(6)
_DATA2_PIN = const(7)
_DATA3_PIN = const(8)
_DATA4_PIN = const(9)
_DATA5_PIN = const(10)
_DATA6_PIN = const(11)
_DATA7_PIN = const(12)

buf_size = int((_WIDTH * _HEIGHT) / 10) * lv.color_t.__SIZE__()

bus = display_bus.I8080Bus(
        max_transfer_bytes=buf_size,
        dc_gpio_num=_DC_PIN,
        wr_gpio_num=_WR_PIN, 
        data0_gpio_num=_DATA0_PIN,
        data1_gpio_num=_DATA1_PIN, 
        data2_gpio_num=_DATA2_PIN,
        data3_gpio_num=_DATA3_PIN, 
        data4_gpio_num=_DATA4_PIN, 
        data5_gpio_num=_DATA5_PIN, 
        data6_gpio_num=_DATA6_PIN, 
        data7_gpio_num=_DATA7_PIN, 
)


display = st7796.ST7796(
    buf_size=buf_size,
    mem_type=st7796.MEM_TYPE_DMA,
    pwr_gpio_num=_PWR_PIN,
    bkl_gpio_num=_BKL_PIN,
    orientation=st7796.LANDSCAPE,
    width=_WIDTH,
    height=_HEIGHT,
    bpp=st7796.BPP_16,
    colormode=st7796.RGB,
    bus=bus
)

so now if I wanted to change the display keeping the same type of bus all that would need to be done is an upload of the new display driver source and change the import along with the the appropriate module and class names used from the old driver.

The display driver should not care how the data is being sent. It should only care about what data is being sent. matching function/method names used across the board for all of the different bus types is what would allow this to work. If a bus doesn’t support a specific feature then it simply does nothing the same thing with the display drivers. The API names used for the display drivers should be a constant across all displays the same thing for the data bus drivers.

Respectfully, I disagree, for this reason:-

The correct way “from the user aspect” would be this:-

import hardware;
import display;
import touch;
... user code comes here

the most important thing to keep in mind is that under normal circumstances at all, they would never need to change their source code when they change their hardware.

or to be perfectly blunt: users should NEVER have to concern themselves with anything to do with pins, or the chip names of their display, and so on. They can if they want, but they should never have to.

The reason that would work, is because the user finds the st7796.mpy driver from wherever (which will usually never be a step they have to take, because it will ship with their board in future), and copies it onto their board with the name “display.mpy”, same for whatever touch driver is in use, and they also find the “esp31-d1-mini-hardware.mpy” file for their board, and copy that on as well with the name “hardware.mpy”.

  • the hardware.mpy defines all the board-implementation details required (pins, spi speeds, etc).
  • the display.mpy uses hardware.mpy in order to do its magic. Users with more than 1 display simply ensure that the hardware.mpy file correctly exposes the type and pins for each.
  • and touch.mpy is the input interface, again working from hardware.mpy exports

hardware can also expose other simple functions itself too, like led_builtin(led_on) or led_builtin(color_yellow) or beep(hertz2600) or camera_flash(onfor100ms) etc etc, as well as expose metainfo like hardware.numdisplays() and hardware.displayname(display1) and the pins etc to make those cross-platform and easy to work with as well. for example…

from sound import mp3

so whoever wrote the mp3 decoder inside the sound.mpy driver can ship it to anyone, and it “just works” everywhere, because everyone else’s hardware.mpy lets sound.mpy know how to make the sound.

Long story short: there’s no point doing any of this at all, if it’s not done properly with experienced empathy for those who need these tools in future.

The user is the developer not the consumer. The user is the person that is using the LVGL library to render the graphics. The consumer is the person that buys the device.

so when I say user I am talking about the person that is writing the code to run on the device.

The order of imports is irrelevant as well. It doesn’t matter what order things get imported.

The stuff you are mentioning about led colors and sounds has nothing to do with LVGL. This is not about making something that is a drop it on and go. basic functionality to get something to be displayed that’s it. the user (developer) would need to add whatever it is they want and how they want it.

Using MPY files for display drivers has zero benefit. in fact it only has downsides. it cannot be used at runtime, meaning it has to be compiled first it offers nothing in the way of speed because the buffer being written to the display would already be handled in C code. The only thing the display driver is responsible for is setting up LVGL to work with the display and to send the initialization commands to the display. other then that it really isn’t going to do a whole lot. the heavy lifting is going to be done by the bus driver which would be compiled as mpy files. Those need to have the speed of C code and also need to be able to access portions of an MCU’s SDK. The bus drivers allow the user to select the type of data connection to a display independently many display driver IC’s support 8, 9 or 16 bit I8080 and SPI so a choice can be made based on pin availability.

it seems like you are focused on MCU’s that come with displays already attached to them. what about MCU’s that don’t have a display attached and one is to be added? Maybe there are several different ones that can be added…

Perhaps it’s a good idea to find a time where we can talk about this on a videocall? Feels like it might be more efficient…

I tend to agree that - while we all may want LVGL/MicroPython integration - we have slightly different perspectives of the architecture and implementation. We’re also clearly more familiar with our own projects and a call may make it easier to explain the rational from the other side.

I’m happy to set up and host such a call if folks think it would be useful. FWIW Andrew and I are in Melbourne which is in AEDT.

I’m in Noosa, so AEST :slight_smile:

If you solder-your-own display, you’d make your own hardware.py to define the pins etc, go find (or write) the LCD driver (e.g.ili934x.py) and copy that onto your board, renaming it to “display.py” or “display.mpy”.

Your application (e.g. main.py) does not change in any way.

Yeah - I’m at a loss trying to understand your perspective? I can’t think of any use case where anyone would want a solution different to my proposal? What are you guys working on?

In my situation - I’m equipping my landcruiser which is set up for off-road touring, with a range of accessories (external floodlights, temperature sensors, ODBCII sender, GPS, LTE, Lithium battery monitors, TPMS, cameras, etc etc) which are all controlled by ESP32’s using espnow, BLE, and local wifi. The control and outputs for these things are ESP32 touchscreens (on my dash, and inside my tent, and in the back cooking area at least), and also via phone.

I’ve just ordered “one each” of every different sized display+esp32 combo I could find on aliexpress, in addition to the 3x 2.4" ones I already have. Almost every one of them uses different screen driver ICs and different touch driver systems. It’s a total dogs-breakfast shitstorm of cheap Chinese suppliers using whatever cheap boards they can to make product. You know - “real life”. If you’ve been around for more than a few years, you already know that there’s no time in the future where you will be able to keep getting the same screens. Everything changes, and rapidly. Thus, in my mind, there’s no place in the world for hardcoded or “baked in” LCD drivers in any firmware at all - it just makes zero sense, and the same goes for applications written to run on MCU’s: nobody in their right mind wants to build something awesome, but have to release 1000 different builds of it for people to use, based on their MCU+screen+pin decisions. Sorting out the hardware should NEVER be the responsibility of either application authors, nor Micropython itself, nor LVGL either. Hence the need for sanity in the declaration of hardware, and the distribution of drivers that use it.

Hope that sheds light on stuff? I’ve written MCU drivers for loads of different hardware over the last decade or so (and, before that, PC/Windows/Linux as well - my first-ever was a DAT tape-backup driver in about 1988!)… but that said - I do live in my own bubble. I don’t know what others have tried (if anything) to sanitize this mess to-date: all I know is that right now, it’s an unsustainable wreck that needs fixing.

p.s. My setup so-far is awesome-enough that I’m tinkering with the idea of running a crowdsupply campaign on it. Having absolute control of everything without having to run wires (other than power) is totally brilliant for cars, and would be amazing for loads of other uses as well. I’m thinking of calling it “GuPy” (for General-purpose Micropython") and shipping whatever minimal-set of hardware boards would be needed to support the majority of user screen needs, and most sensible list of sensors - like EGT sender, general purpose temps (winch body/cables/etc), CAN-Bus info, BLE transceiver for TPMS/UHF/ODBC/Audio/etc, FET switches for lights etc, engine immobilizer, GPS, GSM SMS/Data, datalogging, customisable display screens with dimming, app, cameras, radar, switches, level sensors (e.g. water), load cells, solar control, power current + voltage sensors and loggers, smart-switches (light sensors for night time auto-illumination), , data chart display to shows changes over time, alarms, fingerprint, keyswitch, mini solar, vibration charger, rf spectrum reader, shock sensor, voice recognition, speakers, water detector for airbox, temp+humid for fridge, alarms, radar, motion, reedsw, 9-axis thingo, gyro, magnetometer, innertia, 4g, lora, lidar, proximity sensor (car height), geiger, and anything else folks might want…

Colorado USA, -7UTC. I don’t sleep but 2-4 hours a day so I am game for some kind of a voice chat thing. Not really that big into the video calls tho.

I try to stand away from my person projects when working on something like this. That list I posted of display driver IC’s. There is like 500 of them in that list and that’s not all of them. I don’t think that @kisvegabor would want to maintain a large number of drivers. That being said… what if some order can be put to the chaos of driver ICs by creating a database that standardizes the different vocabulary used and stores the appropriate commands and responses if any. Something that could be added to by users with comments that can also be made by users should there be something out of sorts. Maybe a click counter for the number of people that had success using the information contained in it.

It would be a pretty simple thing to make, web based and it would for the most part maintain itself. It could also be a good tool for a user wanting to locate a Driver IC that meets their needs. so a search for specific options.

It would take some time to build the database initially but I think that it would provide a nice way for a user to get the information they need. Again user = developer not end user. Have it generate code for C and also for Python at the click of a button.

good idea or not so good idea?

I just want to add two things:

  1. I absolutely agree to have a video call :slight_smile: It will be much easier to discuss it. For me Monday is my long working day to have meetings with people from US. What abut next Monday 5pm CEST?
  2. By drivers I mean only the display and input device controller drivers and not SPI, I2C, etc. As the controller drivers are platform independent, LVGL will remain platform independent too. The user just need to add some callbacks to use the platform’s SPI/I2C/etc. In the end I think, 10 display controller and 5 touch controllers will cover most of the needs and these should not use too much flash. At least compared to e.g. the LVGL-MicroPython binding. Of course it should be possible to add new drivers by vendors or anyone.