Mit dem Display des T-QT arbeiten

Hier werden einzelne Projekte mit MicroPython vorgestellt
Antworten
Heinrichs
Beiträge: 185
Registriert: Do 21. Okt 2010, 18:31

Mit dem Display des T-QT arbeiten

Beitrag von Heinrichs » Di 24. Jan 2023, 10:39

An mehreren Stellen wird im Internet darauf hingewiesen, dass das auf dem T-QT befindliche Display einen Treiber (GC9107) besitzt, der kompatibel mit dem Treiber SST7789 des TTGO T-Display sein soll. Somit sollte das Display des T-QT mit der Firmware generic_s3_st7789_firmware.bin von Russ Hughes anzusteuern sein (vgl. meinen Beitrag Micropython-Firmware auf dem T-QT installieren). Die wichtigsten Informationen zur aktuellen Version (Stand 20.01.23) des in der Firmware integrierten ST7789-Treibers habe ich in der Anlage zum ST7789 zusammengefasst.

PinOut_klein.jpg
Abb. 1
PinOut_klein.jpg (31.34 KiB) 19314 mal betrachtet

Als Test-Programm diente der folgende Code. Dabei wurden die Parameter für die Pins entsprechend den Angaben der Abbildung 1 vorgenommen; für die übrigen Parameter habe ich diejenigen Werte benutzt, welche auch beim TTGO eingesetzt werden:

Code: Alles auswählen

# Display_Test_1

from machine import Pin, SPI, SoftSPI
import st7789
from time import sleep

spi = SPI(1, baudrate=20000000, polarity=1, sck=Pin(3), mosi=Pin(2)) 
display = st7789.ST7789(spi, 128, 128, reset=Pin(1, Pin.OUT), cs=Pin(5, Pin.OUT), dc=Pin(6, Pin.OUT), backlight=Pin(10, Pin.OUT), rotation=1)
display.init()
display.off() # Hintergrundbeleuchtung einschalten (vgl. http://www.forum.g-heinrichs.de/viewtopic.php?f=18&t=174)
display.fill(0) # löschen
sleep(2)
display.fill(7789.MAGENTA) # Display mit Magenta-Farbe füllen
sleep(2)
print('ENDE')
Nach dem Starten erreicht das Programm zwar das Ende ohne Fehlermeldung, aber es wird nicht mit der Magenta-Farbe gefüllt. Es ändert sich hier auch nichts, wenn wir statt des Id-Wertes 1 für das Hardware-SPI den Wert 2 einsetzen. Allerdings erkennt man bei genauem Hinschauen, dass die Hintergrundbeleuchtung eingeschaltet ist. Ein weiterer Test zeigt auch, dass diese Hintergrundbeleuchtung mit display.on() ausgeschaltet werden kann. Das passt zu den Feststellungen aus meinem Beitrag T-QT: Ein kleiner Bruder des TTGO T-Display.

Nun habe ich das Hardware-SPI durch ein Software-SPI ersetzt; die Instanziierung lautet in diesem Fall:

spi = SoftSPI(baudrate=800000, polarity=1, sck=Pin(3), mosi=Pin(2), miso=Pin(6)) # miso = dc

Und tatsächlich können wir mit diesem Programm eine Einfärbung des Displays feststellen; allerdings ist die angezeigte Farbe nicht MAGENTA!

Ein weiteres (kleineres) Problem zeigt sich, wenn wir den rotation-Parameter bei der Instanziierung von display verändern. Mit diesem Parameter können wir die Darstellung auf dem Display einstellen: Die Standard-Einstellung ist rotation=1; diese ist für den Fall geeignet, dass für den Betrachter der USB-Anschluss des T-QT-Moduls auf der linken Seite liegt. Für andere Blickrichtungen kann die Anzeige um 90° (rotation=2), 180° (rotation=3) oder 270° (rotation=4) rotiert werden. Bei den rotation-Werten 2 und 3 ist die Darstellung um 1 Pixel verschoben.


Zwei Dinge sind jetzt zu klären:

1. Warum wird hier eine falsche Farbe angezeigt?
2. Warum funktioniert das Hardware-SPI nicht?
3. Wie können wir das Problem mit den rotation-Werten lösen?



1. Das Farbenproblem

Kümmern wir uns zunächst um die Farben! Tests mit anderen Farben zeigen, dass auch andere Farben nicht korrekt angezeigt werden. Die Farbe Grün (st7789.GREEN) wird hingegen richtig dargestellt. Außerdem stellen wir fest, dass Rot und Blau vertauscht angezeigt werden. Offensichtlich arbeitet der Display-Treiber GC9107 nicht mit einem RGB565-Format, sondern mit einem BGR565-Format (vgl. auch https://www.forum.g-heinrichs.de/viewto ... f=18&t=141). Eine solche Vertauschung von Rot- und Blauanteil können wir mit unserem st7789-Treiber bewirken, indem wir bei der Instanziierung von display den zusätzlichen Parameter

color_order=st7789.BGR

einfügen. Die Instanziierung von display sieht dann so aus:

display = st7789.ST7789(spi, 128, 128, reset=Pin(1, Pin.OUT), cs=Pin(5, Pin.OUT), dc=Pin(6, Pin.OUT), backlight=Pin(10, Pin.OUT), rotation=1, color_order=st7789.BGR)

Nun werden die Farben korrekt dargestellt. Das folgende Test-Programm Display_Test_2.py zeigt nun diese korrekte Darstellung der Farben. In diesem Programm wird auch beispielhaft die Anzeige von geometrischen Formen und Texten gezeigt.

Code: Alles auswählen

# Display_Test_2
# Durch Auskommentieren können Sie zwischen dem Hardware- und dem Software-SPI auswählen

from machine import Pin, SPI, SoftSPI
import st7789
import vga1_16x16 as font
from time import sleep

# spi = SPI(1, baudrate=20000000, sck=Pin(3), mosi=Pin(2), miso=Pin(6))
spi = SoftSPI(baudrate=800_000, polarity=1, sck=Pin(3), mosi=Pin(2), miso=Pin(6)) # miso = dc
display = st7789.ST7789(spi, 128, 128, reset=Pin(1, Pin.OUT), cs=Pin(5, Pin.OUT), dc=Pin(6, Pin.OUT), backlight=Pin(10, Pin.OUT), rotation=1, color_order=st7789.BGR)
display.init()
display.off() # Hintergrundbeleuchtung einschalten (vgl. http://www.forum.g-heinrichs.de/viewtopic.php?f=18&t=174)
display.fill(0) # löschen

# einige Farben anzeigen lassen
farben = [['weiß', st7789.WHITE],
          ['blau', st7789.BLUE],
          ['schwarz', st7789.BLACK],
          ['gelb', st7789.YELLOW],
          ['magenta', st7789.MAGENTA],
          ['rot', st7789.RED]]

for f in farben:
    print('Farbwert für ', f[0], ' ist ',  f[1])
    display.fill(f[1])
    sleep(1)
    
sleep(2)

# Kreise
for i in range(100):
    f = st7789.BLUE * i // 100
    display.fill_circle(64, 64, i, f)

# Text
display.text(font, 'ENDE', 35, 55)

print('ENDE')

Leider ist das Software-SPI recht langsam. Deswegen kümmern wir uns nun noch einmal um das Hardware-SPI.


2. Das Problem mit dem Hardware-SPI

Zunächst habe ich überprüft, ob durch das Hardware-SPI überhaupt Signale an das Display gesendet werden. Dazu habe ich die Signale sck und mosi auf Pins umgeleitet, die für Anschlusskabel zugängig sind. Die Signale habe ich dann mit einem Logik-Analysator angeschaut. Abb. 2 zeigt einen Screenshot; die Signale sehen auf den ersten Blick ganz ordentlich aus, insbesondere waren die Bits in der erwarteten Reihenfolge (MSB zuerst) gesendet worden. Die Ergebnisse waren für Id=1 und Id=2 gleich.

HW_SPI_Signal.jpg
Abb. 2
HW_SPI_Signal.jpg (18.81 KiB) 19312 mal betrachtet

SPI-Protokolle können sich noch in den Parametern "Clock Polarity" (CPOL) und "Clock Phase" (CPHA) unterscheiden (vgl. Abb. 3 links); Details dazu finden Sie hier. Diese können bei der Instanziierung angegeben werden (vgl. https://docs.micropython.org/en/latest/ ... e.SPI.html). Ein Blick in das Datenblatt des GC9107 zeigt, dass das Clock-Signal im Ruhezustand 0 sein soll und die Datenbits bei einer aufsteigenden Flanke von sck/SCL gelesen werden (vgl. Abb. 3 rechts).

polarity_phase_GC9107.jpg
Abb. 3
polarity_phase_GC9107.jpg (215.41 KiB) 19311 mal betrachtet

Das entspricht den Parameterwerten CPOL = 0 und CPHA = 0; da dies die Standardwerte sind, lassen wir jetzt den beim TTGO bislang benutzten Eintrag "polarity=1" bei der Instanziierung von spi einfach weg:

spi = SPI(1, baudrate=20000000, sck=Pin(3), mosi=Pin(2), miso=Pin(6))

Bei dieser Einstellung werden die einzelnen mosi-Bits bei einer steigenden Flanke des Takt-Signals sck übernommen. Damit funktioniert nun auch das Display des T-QT mit dem Hardware-SPI!

Prüfen Sie es selbst nach: Ändern Sie die Auskommentierung bei dem Programm Display_Test_2.py, und das Display wird jetzt korrekt mit den verschiedenen Farben ausgefüllt - und das wesentlich schneller als bei dem Software-SPI.

Merkwürdig ist nur, dass das Software-SPI trotz des falschen polarity-Parameters funktioniert hat.


3. Das Problem mit dem rotation-Parameter

Wie bereits erwähnt, müssen wir nur für die Fälle rotation=2 und rotation=3 aktiv werden. Dazu benutzen wir die Methode offset von unserem display-Objekt. Diese Methode dient dazu, die x- und y-Koordinaten an die interne Verarbeitung bei den verschiedenen Displays anzupassen. In unserem Fall führt der Befehl

display.offset(258, 258)

zum Ziel. Dies können Sie mit dem folgenden Programm austesten. Wer mag, kann zum Vergleich einmal die beiden Korrekturzeilen auskommentieren.

Code: Alles auswählen

# display_rotation_test.py

from machine import Pin, SPI
import st7789
import vga1_16x16 as font
from time import sleep

spi = SPI(1, baudrate=20_000_000, sck=Pin(3), mosi=Pin(2))
display = st7789.ST7789(spi, 128, 128, reset=Pin(1, Pin.OUT), cs=Pin(5, Pin.OUT), dc=Pin(6, Pin.OUT), backlight=Pin(10, Pin.OUT), rotation=1, color_order=st7789.BGR)

# rotation-Werte 1 und 4 arbeiten korrekt.
# Bei den rotation-Werten 2 und 3 ist die Anzeige um 1 Pixel verschoben, in diesem Fall Korrektur mit display.offset(258, 258), s. u.

display.init()
display.fill(0)
display.off() # umgekehrte Logik gegenüber TTGO!

# jetzt in einer Schleife alle rotation-Modi durchlaufen:
while True:
  for i in range(4):
    r = i + 1
    display.rotation(r)
    # die folgenden beiden Zeilen auskommentieren -> keine Korrektur!
    if (r == 2) or (r == 3):
        display.offset(258, 258)
    display.fill(0)
    display.rect(0, 0, 127, 127, st7789.RED)
    display.text(font, 'Test ' + str(r), 10, 20)
    sleep(2)

.
Dateianhänge
Fast_Micropython_Driver_For_ST7789_By_RussHughes.pdf
(647.27 KiB) 1702-mal heruntergeladen
GC_9107_Data_Sheet_V1_2_5897aaab18.pdf
(2.52 MiB) 1716-mal heruntergeladen

Antworten