I purchased an off brand ST7789 1.3" Display a few months ago and recently decided it was time to try it out.
I did not realize it at the time but there isn't a consistent pinout between display boards. As it turns out the board I purchased did not pin out the chip-select (CS) line.
The ST7789 display driver will function without a CS line, however you need to configure the SPI mode (idle state, edge polarity) to communicate with the display. In most cases, I suppose that would be easy enough to change the display driver.
Now I wanted to make use of this display with a PI Pico and Micropython. Pimoroni provide a Micropython release with a small number additional libraries on top of MicroPython : https://github.com/pimoroni/pimoroni-pico (unlike CircuitPython which is significantly different from MicroPython).
I was trying to get their example code for one of their displays: https://shop.pimoroni.com/products/1-3-spi-colour-lcd-240x240-breakout to function with my off brand display. Unfortunately, I could not find a way to change the SPI operating mode of the display driver unless I wanted to compile their distribution from source (which I didn't want to do), the SPI initialization was all buried in C code.
An intsructables author provided a wonderful guide to breaking out the chip-select line: https://www.instructables.com/Adding-CS-Pin-to-13-LCD/ Many thanks. In the process of modify my display I learned a few things the hard way:
- Rotated R1 90' to bypass the NPN switch
- Tossed R2 away and used this as the CS pad
- Be carful with getting the display too hot. The adhesive that held the display in place virtually no longer exists now
- Be carful cleaning! Or don't clean at all. I ended up relocating the flux residue with isopropyl from the PCB to inside the display housing and its now a little merky
After the display modifications the display came to life!
I have never used one of these displays before, but I have to say I am impressed. I was able to get 35 FPS out of a 240x240 display running over SPI.
I still don't know what the best way to add graphics to the PICO is. The image I showed in the video was created with ffmpeg outputting a raw video frame:
ffmpeg -vcodec png -i img.png -vcodec rawvideo -f rawvideo -pix_fmt rgb565 img.raw
Of this random image cropped down to 240x240:
Loading the image from flash was very slow.
Update: Image Loading Speed
The framebuffer for the ST7789 is stored big-endian so when I was loading the Image I had endian swap in python which was really slow. I can endian swap the raw image file format using dd:
dd conv=swab if=img.raw of=img2.raw
Now loading the image is now significantly faster:
t1 = time.ticks_us() with open('img2.raw', 'rb') as f: for j in range(0,240,24): display_buffer[480*j:(480*(j+24))] = f.read(240*48) display.update() # only update display once now, remove those tabs! print((time.ticks_us() - t1)/1000)
Which now runs in 232 ms 85 ms and appears more as a transition animation versus terribly slow code.
Update: Overclocking in MicroPython
One can adjust the system clock frequency in MicroPython by issuing the following command:
machine.freq(190_000_000) # set system clock in Hz
When MicroPython alters the system clock frequency, it also reconfigures the peripheral clock source from clk_sys to the external crystal oscillator.
So, if you want to maintain a high-speed SPI clock frequency, you need to set the clock mux back to clk_sys yourself by:
mem32[0x40008000+0x48] = 0x800
With the Pico running at 190 MHz I achieved the following:
Rainbow Spinner: 53 FPS
FFT Demo: 16 FPS
Image Load + Draw: 56 ms (49ms letting the garbage collector run before the load)
Of course, there are no guarantees this will always work for every Pico and or display.