lvgl / lv_binding_micropython

LVGL binding for MicroPython
MIT License
237 stars 156 forks source link

RPi Pico port compilation #174

Closed eudoxos closed 2 years ago

eudoxos commented 2 years ago

(proper solution: put conditionals around ESPIDF stuff)

Part of https://github.com/lvgl/lv_micropython/pull/42

amirgon commented 2 years ago

Hi @eudoxos! Thank you and @jgpeiro for this contribution!

  1. Please use conditionals (as you mentioned) around ESP32 stuff otherwise you would break the ESP32 port.
  2. I think it would make sense to add at least one RPi Pico display driver. Probably also some input device driver.
    Which display are you using?
eudoxos commented 2 years ago
  1. Please use conditionals (as you mentioned) around ESP32 stuff otherwise you would break the ESP32 port.

Done.

  1. I think it would make sense to add at least one RPi Pico display driver. Probably also some input device driver. Which display are you using?

I don't have any functional display yet... I was hoping to test with a ssd1306 oled with python-only driver, then I have a HX8357 (PiTFT) lying around and would eventually like to use ST7735-based TFT. I don't know much what is involved TBH.

amirgon commented 2 years ago

Merged!

Thank you for this contribution.

Did you make some progress with the display driver? I think it's important to provide at least one as a working example.

eudoxos commented 2 years ago

Did you make some progress with the display driver? I think it's important to provide at least one as a working example.

Not yet, though now I have the hardware (ST7735 and ST7789). There are (many) drivers for ST7735 (this one looks the most suitable: https://github.com/szampardi/st77xx_mpy) and @jgpeiro made pure-python driver for ST7789 w/ DMA (+ Xpt2046 touch) which is floating around the forum.

The place for drivers is https://github.com/lvgl/lv_drivers, as I understand, plus uPy drivers in https://github.com/lvgl/lv_binding_micropython/tree/master/driver? Is everything platform-specific? Are C drivers preferred to uPy drivers for performance, or does @micropython.viper or @micropython.native mostly do the job? Sorry for all the questions, maybe I just overlooked some docs on that.

amirgon commented 2 years ago

The place for drivers is https://github.com/lvgl/lv_drivers, as I understand, plus uPy drivers in https://github.com/lvgl/lv_binding_micropython/tree/master/driver?

LVGL C drivers and Micropython drivers (either C or Python) are separate and independent from each other.
The main reason is configuration:

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.

Is everything platform-specific?

Not necessarily.
For example, ft6x36 touch driver is generic and can be used on different platforms.
If you can create a platform independent driver with good enough performance - that's preferable.

Are C drivers preferred to uPy drivers for performance, or does @micropython.viper or @micropython.native mostly do the job?

It's a good question. The answer is different for each driver, I guess. For example, the ESP32 ili9XXX family of drivers support two modes - Pure Python and Hybrid. The hybrid implements the critical parts in C (the flush function) and the non-critical parts in Python (initialization for instance). The pure Python mode is significantly inferior to the hybrid mode in this case.

Regarding @micropython.viper and @micropython.native, these are useful when you need to process arrays of data for some filter or conversion and you want to do that in Python. We use it to handle different color modes with PNG for example, but they are less useful for working with SPI, I2C, configuring DMA etc.

So in general - it would be best to create Pure Python platform-agnostic drivers, but in reality to achieve performance we sometimes have to revert to platform specific code and write at least parts of the driver in C.

Sorry for all the questions, maybe I just overlooked some docs on that.

You didn't overlook, these things are poorly documented if at all.
Please feel free to ask!

eudoxos commented 2 years ago

There is something being cooked up (with the help of @jgpeiro) for Xpt2046 touchschreen and ST7789 LCD https://github.com/eudoxos/pico-st7789-driver-lvgl .

I just saw Adafruit's displayio, and (while I have reservations about Adafruit forking micropython without giving back upstream much (or is upstream just not interested?)), and that looks like the proper (=scalable, not that every arch needs its own rewrite of drivers) approach. Unlike micropython's framebuffer, they use blitting (not sure about DMA) like what LVGL needs. And they have bunch of drivers ready (those are in python).

Would integration of displayio be too much for thismicropython fork? Or are you active upstream to discuss that?

amirgon commented 2 years ago

There is something being cooked up (with the help of @jgpeiro) for Xpt2046 touchschreen and ST7789 LCD

Great!

Would integration of displayio be too much for thismicropython fork? Or are you active upstream to discuss that?

Anyone can open an issue or PR on upstream Micropython, or discuss in their forums. They are very friendly, you can try that of you want.

Regarding Afafruit, that's a commercial company, when they make open source code they make it only for their own devices. So I'm not sure how compatible it's with other platforms.
Their decision to fork Micropython, make many changes and maintain their own fork separately makes it hard to integrate code between their fork and ours.
Also, their focus is different. They don't care too much about performance and consider Circuitpython as a learning tool and not as a real development platform. For example, they don't make an effort to code the critical parts in C. So in that sense, their libraries are less attractive for us.

I suspect that displayio is heavily dependent on Circuitpython specific libraries, and does not stand by itself.

Do you see a way to integrate displayio without integrating many other Circuitpython libraries?

embeddedt commented 2 years ago

while I have reservations about Adafruit forking micropython without giving back upstream much (or is upstream just not interested?)

Upstream has been slow to accept changes in the past, and in my humble opinion, still is, relative to the popularity/size of the project. @amirgon's relatively straightforward PR for accelerating QSTR searches (which is necessary for the bindings to perform reasonably) has not been re-reviewed since February despite the requested changes being addressed.

I have gotten an inkling from various sources online, my own observations, etc. that they may be suffering from a lack of people to move the project forward rapidly. Until recently, it was often a better choice to use the master branch than an actual release, because releases were made so infrequently and they have a good CI testing system in place. In recent months there have been more frequent releases so this may be an issue of the past.

Of course, it could also be that the consistent stability is a result of a slower development pace.

They don't care too much about performance and consider Circuitpython as a learning tool and not as a real development platform.

I'm not 100% sure about this. They do seem to have made some useful changes to MicroPython core that wouldn't apply specifically to their hardware, such as introducing a generational heap, which can help reduce fragmentation issues. I recall seeing that that change as well was offered to upstream in the past and didn't really move forward, however, I cannot find the PR now. (I last looked at these changes a year or two ago.)

As far as I know, upstream Micropython is also not structured in a way that external libraries can be added by a user easily, which is the main reason for our fork to exist in the first place. I think that in the long-term, the hope is that https://github.com/lvgl/lv_binding_micropython will be a self-contained module that can be added to any MicroPython tree in order to add LVGL to a project.

amirgon commented 2 years ago

They don't care too much about performance and consider Circuitpython as a learning tool and not as a real development platform.

I'm not 100% sure about this.

They specifically say that "CircuitPython is focused on beginners, education, and getting folks started super fast.". They also recommend using Micropython for "Advanced APIs such as interrupts and threading" for exmaple.
I also think that their drivers are implemented in Python, also the critical parts. So it's great for learning but performance suffers.

Anyway, they have a CircuitPython emulation layer called Blinka that allows running CircuitPython libraries above either Micropython or Python, and displayio is also supported by Blinka. I'm not sure how well it works, but maybe worth exploring.

such as introducing a generational heap, which can help reduce fragmentation issues. I recall seeing that that change as well was offered to upstream in the past and didn't really move forward, however, I cannot find the PR now.

This? https://github.com/micropython/micropython/issues/3586 Looks like there are pros and cons to this change. It slows down performance but decrease fragmentation. It's also not always clear how to tag allocations as short/long.

As far as I know, upstream Micropython is also not structured in a way that external libraries can be added by a user easily, which is the main reason for our fork to exist in the first place.

They do support user-modules and we can improve the bindings to take advantage of it (on esp32, stm32 and unix ports) RPi already uses it.
But it's true that even with user modules we still need to change the Micropython code to integrate gc, for CI and for a few other things.

I think that in the long-term, the hope is that https://github.com/lvgl/lv_binding_micropython will be a self-contained module that can be added to any MicroPython tree in order to add LVGL to a project.

Ideally yes, but in reality it might be too limiting.
But we try to make only minimal changes and follow Micropython upstream very closely.

eudoxos commented 2 years ago

Thank you (both @amirgon and @embeddedt) for sharing your experience!

They specifically say that "CircuitPython is focused on beginners, education, and getting folks started super fast.". They also recommend using Micropython for "Advanced APIs such as interrupts and threading" for exmaple. I also think that their drivers are implemented in Python, also the critical parts. So it's great for learning but performance suffers.

I did not test, but specifically displayio is in C and ST7789 driver just defines the init sequence, similar to ST7735r.

Anyway, they have a CircuitPython emulation layer called Blinka that allows running CircuitPython libraries above either Micropython or Python, and displayio is also supported by Blinka. I'm not sure how well it works, but maybe worth exploring.

It looks like pyre-python re-implementation of their *io modules. It might be helpful to for jump-starting with unsupported hardware. Might try.