russhughes / st7789_mpy

Fast MicroPython driver for ST7789 display module written in C
Other
531 stars 107 forks source link
bitmap-font driver esp32 firmware ili9341 ili9342 m5stack-core m5stack-core2 micropython pyboard st7735 st7789 t-display t-dongle-s3 twatch-2020 wio-terminal

ST7789 Driver for MicroPython

This driver is based on devbis' st7789_mpy driver. I modified the original driver for one of my projects to add:

Included are 12 bitmap fonts derived from classic pc text mode fonts, 26 Hershey vector fonts and several example programs for different devices.

Display Configuration

Some displays may use a BGR color order or inverted colors. The cfg_helper.py program can be used to determine the color order, inversion_mode, colstart, and rowstart values needed for a display.

Color Modes

You can test for the correct color order needed by a display by filling it with the st7789.RED color and observing the actual color displayed.

colstart and rowstart

Some displays have a frame buffer memory larger than the physical display matrix. In these cases, the driver must be configured with the position of the first physical column and row pixels relative to the frame buffer. Each rotation setting of the display may require different colstart and rowstart values.

The driver automatically sets the colstart and rowstart values for common 135x240, 240x240, 170x320 and 240x320 displays. If the default values do not work for your display, these values can be overridden using the offsets method. The offsets method should be called after any rotation method calls.

128x128 st7735 cfg_helper.py example

inversion_mode(False)
color_order = st7789.BGR
for rotation 0 use offset(2, 1)
for rotation 1 use offset(1, 2)
for rotation 2 use offset(2, 3)
for rotation 3 use offset(3, 2)

128x160 st7735 cfg_helper.py example

inversion_mode(False)
color_order = st7789.RGB
for rotation 0 use offset(0, 0)
for rotation 1 use offset(0, 0)
for rotation 2 use offset(0, 0)
for rotation 3 use offset(0, 0)

Pre-compiled firmware files

The firmware directory contains pre-compiled firmware for various devices with the st7789 C driver and frozen python font files. See the README.md file in the fonts folder for more information on the font files.

MicroPython MicroPython v1.20.0 compiled with ESP IDF v4.4.4 using CMake

Directory File Device
GENERIC-7789 firmware.bin Generic ESP32 devices
GENERIC_SPIRAM-7789 firmware.bin Generic ESP32 devices with SPI Ram
GENERIC_C3 firmware.bin Generic ESP32-C3 devices
LOLIN_S2_MINI firmware.bin Wemos S2 mini
PYBV11 firmware.dfu Pyboard v1.1 (No PNG)
RP2 firmware.uf2 Raspberry Pi Pico RP2040
RP2W firmware.uf2 Raspberry Pi PicoW RP2040
T-DISPLAY firmware.bin LILYGO® TTGO T-Display
T-Watch-2020 firmware.bin LILYGO® T-Watch 2020
WIO_TERMINAL firmware.bin Seeed Wio Terminal

Additional Modules

Module Source
axp202c https://github.com/lewisxhe/AXP202X_Libraries
focaltouch https://gitlab.com/mooond/t-watch2020-esp32-with-micropython

Video Examples

Example Video
PYBV11 hello.py https://youtu.be/OtcERmad5ps
PYBV11 scroll.py https://youtu.be/ro13rvaLKAc
T-DISPLAY fonts.py https://youtu.be/2cnAhEucPD4
T-DISPLAY hello.py https://youtu.be/z41Du4GDMSY
T-DISPLAY scroll.py https://youtu.be/GQa-RzHLBak
T-DISPLAY roids.py https://youtu.be/JV5fPactSPU
TWATCH-2020 draw.py https://youtu.be/O_lDBnvH1Sw
TWATCH-2020 hello.py https://youtu.be/Bwq39tuMoY4
TWATCH-2020 bitmap.py https://youtu.be/DgYzgnAW2d8
TWATCH-2020 watch.py https://youtu.be/NItKb6umMc4

This is a work in progress.

Thanks go out to:

-- Russ

Overview

This is a driver for MicroPython to handle cheap displays based on the ST7789 chip. The driver is written in C. Firmware is provided for ESP32, ESP32 with SPIRAM, pyboard1.1, and Raspberry Pi Pico devices.

ST7789 display photo

Setup MicroPython Build Environment in Ubuntu 20.04.2

See the MicroPython README.md if you run into any build issues not directly related to the st7789 driver. The recommended MicroPython build instructions may have changed.

Update and upgrade Ubuntu using apt-get if you are using a new install of Ubuntu or the Windows Subsystem for Linux.

sudo apt-get -y update
sudo apt-get -y upgrade

Use apt-get to install the required build tools.

sudo apt-get -y install build-essential libffi-dev git pkg-config cmake virtualenv python3-pip python3-virtualenv

Install a compatible esp-idf SDK

The MicroPython README.md states: "The ESP-IDF changes quickly, and MicroPython only supports certain versions. Currently, MicroPython supports v4.0.2, v4.1.1, and v4.2 although other IDF v4 versions may also work." I have had good luck using IDF v4.4

Clone the esp-idf SDK repo -- this usually takes several minutes.

git clone -b v4.4 --recursive https://github.com/espressif/esp-idf.git
cd esp-idf/
git pull

If you already have a copy of the IDF, you can checkout a version compatible with MicroPython and update the submodules using:

$ cd esp-idf
$ git checkout v4.4
$ git submodule update --init --recursive

Install the esp-idf SDK.

./install.sh

Source the esp-idf export.sh script to set the required environment variables. You must source the file and not run it using ./export.sh. You will need to source this file before compiling MicroPython.

source export.sh
cd ..

Clone the MicroPython repo.

git clone https://github.com/micropython/micropython.git

Clone the st7789 driver repo.

git clone https://github.com/russhughes/st7789_mpy.git

Update the git submodules and compile the MicroPython cross-compiler

cd micropython/
git submodule update --init
cd mpy-cross/
make
cd ..
cd ports/esp32

Copy any .py files you want to include in the firmware as frozen python modules to the modules subdirectory in ports/esp32. Be aware there is a limit to the flash space available. You will know you have exceeded this limit if you receive an error message saying the code won't fit in the partition or if your firmware continuously reboots with an error.

For example:

cp ../../../st7789_mpy/fonts/bitmap/vga1_16x16.py modules
cp ../../../st7789_mpy/fonts/truetype/NotoSans_32.py modules
cp ../../../st7789_mpy/fonts/vector/scripts.py modules

Build the MicroPython firmware with the driver and frozen .py files in the modules directory. If you did not add any .py files to the modules directory, you can leave out the FROZEN_MANIFEST and FROZEN_MPY_DIR settings.

make USER_C_MODULES=../../../../st7789_mpy/st7789/micropython.cmake FROZEN_MANIFEST="" FROZEN_MPY_DIR=$UPYDIR/modules

Erase and flash the firmware to your device. Set PORT= to the ESP32's usb serial port. I could not get the USB serial port to work under the Windows Subsystem (WSL2) for Linux. If you have the same issue, you can copy the firmware.bin file and use the Windows esptool.py to flash your device.

make USER_C_MODULES=../../../../st7789_mpy/st7789/micropython.cmake PORT=/dev/ttyUSB0 erase
make USER_C_MODULES=../../../../st7789_mpy/st7789/micropython.cmake PORT=/dev/ttyUSB0 deploy

The firmware.bin file will be in the build-GENERIC directory. To flash using the python esptool.py utility. Use pip3 to install the esptool if it's not already installed.

pip3 install esptool

Set PORT= to the ESP32's USB serial port

esptool.py --port COM3 erase_flash
esptool.py --chip esp32 --port COM3 write_flash -z 0x1000 firmware.bin

CMake building instructions for MicroPython 1.14 and later

for ESP32:

$ cd micropython/ports/esp32

And then compile the module with specified USER_C_MODULES dir.

$ make USER_C_MODULES=../../../../st7789_mpy/st7789/micropython.cmake

for Raspberry Pi PICO:

$ cd micropython/ports/rp2

And then compile the module with specified USER_C_MODULES dir.

$ make USER_C_MODULES=../../../st7789_mpy/st7789/micropython.cmake

Working examples

This module was tested on ESP32, STM32 based pyboard v1.1, and the Raspberry Pi Pico. You have to provide an SPI object and the pin to use for the `dc' input of the screen.

# ESP32 Example
# To use baudrates above 26.6MHz you must use my firmware or modify the micropython
# source code to increase the SPI baudrate limit by adding SPI_DEVICE_NO_DUMMY to the
# .flag member of the spi_device_interface_config_t struct in the machine_hw_spi_init_internal.c
# file.  Not doing so will cause the ESP32 to crash if you use a baudrate that is too high.

import machine
import st7789
spi = machine.SPI(2, baudrate=40000000, polarity=1, sck=machine.Pin(18), mosi=machine.Pin(23))
display = st7789.ST7789(spi, 240, 240, reset=machine.Pin(4, machine.Pin.OUT), dc=machine.Pin(2, machine.Pin.OUT))
display.init()

Methods

The module exposes predefined colors: BLACK, BLUE, RED, GREEN, CYAN, MAGENTA, YELLOW, and WHITE

Scrolling

The st7789 display controller contains a 240 by 320-pixel frame buffer used to store the pixels for the display. For scrolling, the frame buffer consists of three separate areas; The (tfa) top fixed area, the (height) scrolling area, and the (bfa) bottom fixed area. The tfa is the upper portion of the frame buffer in pixels not to scroll. The height is the center portion of the frame buffer in pixels to scroll. The bfa is the lower portion of the frame buffer in pixels not to scroll. These values control the ability to scroll the entire or a part of the display.

For displays that are 320 pixels high, setting the tfa to 0, height to 320, and bfa to 0 will allow scrolling of the entire display. You can set the tfa and bfa to a non-zero value to scroll a portion of the display. tfa + height + bfa = should equal 320, otherwise the scrolling mode is undefined.

Displays less than 320 pixels high, the tfa, height, and bfa will need to be adjusted to compensate for the smaller LCD panel. The actual values will vary depending on the configuration of the LCD panel. For example, scrolling the entire 135x240 TTGO T-Display requires a tfa value of 40, height value of 240, and bfa value of 40 (40+240+40=320) because the T-Display LCD shows 240 rows starting at the 40th row of the frame buffer, leaving the last 40 rows of the frame buffer undisplayed.

Other displays like the Waveshare Pico LCD 1.3 inch 240x240 display require the tfa set to 0, height set to 240, and bfa set to 80 (0+240+80=320) to scroll the entire display. The Pico LCD 1.3 shows 240 rows starting at the 0th row of the frame buffer, leaving the last 80 rows of the frame buffer undisplayed.

The vscsad method sets the (VSSA) Vertical Scroll Start Address. The VSSA sets the line in the frame buffer that will be the first line after the tfa.

The ST7789 datasheet warns:

The value of the vertical scrolling start address is absolute (with reference to the frame memory),
it must not enter the fixed area (defined by Vertical Scrolling Definition, otherwise undesirable
image will be displayed on the panel.

Helper functions