devbis / st7789py_mpy

Slow micropython driver for 240x240 ST7789 display without CS pin from Ali Express, written in MicroPython
MIT License
85 stars 32 forks source link

This driver is not slow #7

Open antirez opened 9 months ago

antirez commented 9 months ago

Hello, thank you for writing this driver. Initially I used it with MicroPython SoftSPI, and performances where terrible. I did some profiling and found that it was the SoftSPI implementation itself that is so show, but at least with the ESP32-S3, if we switch to the hardware SPI, it goes from 1100 ticks to fill the screen to... 53! Basically more or less the performance of the C driver if I understand correctly.

Now the trick is that sometimes you can use the SPI() constructor and still use the SoftSPI() thing (and get a deprecation message). This depends on the first parameter, that must be a number, the hardware SPI identifier basically. To really use the hardware SPI, you need to do something like that when constructing the object:

    # Our display does not have a MISO pin, but the MicroPython
    # SPI implementation does not allow to avoid specifying one, so
    # we use just a not used pin in the device.
    spi = SPI(1, baudrate=40000000, polarity=1, sck=18, mosi=13, miso=37)
    display = st7789.ST7789(
        spi, 240, 240,
        reset=False,
        dc=Pin(38, Pin.OUT),
        cs=Pin(12, Pin.OUT),
    )
    display.init()

Note that the S3 seems able to use any pin for hardware SPI! I don't think that before ESP32-S3 it was like that, but I'm not sure.

I hope this helps! And I believe it would be cool to document this in the project README file. Others may benefit from this information.

foopod commented 9 months ago

Hey there @antirez! I have been experimenting with this and finding that the hardware SPI is indeed much faster than SoftSPI, but still nowhere near the speed I am getting with C performance.

I am using a ESP32-S3FN8 if that makes a difference, do you have any examples I could try out to see if I can repeat your findings?

Thanks!

antirez commented 9 months ago

Hello @foopod, yeah, that's a bit odd since one could expect that SPI is ... I/O bound. But actually because of the back and forth to set CS, init data transfer and so forth, it becomes a lot slower. Now mainly the thing is a tradeoff between memory and speed in Python, for this application: if you allocate a MicroPython Framebuffer, and then just draw there and blit it in a .show() method, you can get very good performances from the MicroPython driver. However when you can't afford so much memory, you have to revert to try to make SPI as fast as possible. And that's what I did here:

https://github.com/antirez/ST77xx-pure-MP

However my driver will soon also support the framebuffer (it was there, I later removed it because my project was super low-memory, then I have a new project with an ESP32, and I want the other mode available as well). I believe I'll implement this stuff in the next days.

Cheers

foopod commented 9 months ago

Brilliant! That makes a lot of sense. I have been using s3lcd to get the best performance under MicroPython for st7789. And this uses a framebuffer, but it would be great to have a pure python driver that can be used under a generic MicroPython firmware.

I will be following closely.

antirez commented 9 months ago

Thank you, @foopod. I just updated the driver to optionally use the framebuffer as well (and even mixing the two backends). Cheers.