Freitag, 4. Dezember 2015

ILI9341 2,2" TFT - Display am Cubietruck


Vor ein paar Wochen habe ich mit bei AliExpress ein 2,2" TFT Display für meinen Cubietruck bestellt. Der Display-Controller auf bzw. hinter dem Display ist ein ILI9341. Leider gab es in der Lieferung des Displays und auch auf der Webseite des Shops keine
weiteren Informationen zu dem Produkt.

Ich bin während meiner Recherche auf diverse Seiten und Youtube-Videos gestoßen, bei denen entweder nur von Problemen berichtet wurde, unvollständig verschiedene Einrichtungsmöglichkeiten dargestellt, oder einfach nur simpel das Ergebnis - ein Display in Aktion - gezeigt wurde.

Um es kurz zu fassen... Das Display kann im Linux-System als Framebuffer-Device eingerichtet werden. Der Zugriff auf das Display geschieht mittels SPI-Bus. Auch ich werde an dieser Stelle nicht auf alle Details eingehen, aber zumindest die Punkte versuchen abzudecken die mir persönlich bei der Einrichtung gefehlt haben.

Das Display verfügt über 9 Pins, davon werden zwei für die Spannungsversorgung verwendet, vier für den SPI-Bus (MISO, MOSI, SCK und CS) und die restlichen drei werden für die Steuerung der LED-Beleuchtung, eine RESET-Leitung und eine Register-Select-Leitung verwendet.

Diese Pins müssen an einen passenden Pinheader des Cubietruck angeschlossen werden.
Im folgenden Bild habe ich dies für meine Hardware eingezeichnet.





Damit ist es das jedoch nicht gewesen, denn der Cubietruck weiß noch nichts davon das an den definierten Pins ein Display angeschlossen ist. Dies teilt man dem Kernel des Cubietrucks über eine Datei im /boot - Verzeichnis mit. Die Datei heißt script.bin. Um in diese die Konfiguration für das Display einzutragen muss man diese zunächst von ihrem Binären Format in ein menschen-lesbares Format umwandeln. Dies geschieht mittels einem normalerweise vorinstalliertem Tool - bin2fex.

root@cubietruck:/boot# bin2fex script.bin script.fex

Öffnen man nun die Datei mit einem Editor seiner Wahl sollte man nach den folgenden beiden Inhalten suchen und diese entsprechend den Beispielen unten anpassen.

Suchen nach spi2_para und die folgenden Anpassungen durchführen.
 

[spi2_para]
spi_used = 1
spi_cs_bitmap = 1
spi_cs0 = port:PC19<3>
spi_cs1 = port:PB13<2>
spi_sclk = port:PC20<3>
spi_mosi = port:PC21<3>
spi_miso = port:PC22<3>


Damit ist nun der SPI-Bus zum Display deklariert, es fehlen noch die übrigen Pins.

Suchen nach gpio_para und ebenfalls die folgenden Anpassungen durchführen.

[gpio_para]
gpio_used = 1
gpio_num = SET THE NUMBER OF DEFINED GPIO PINS
...
gpio_pin_3 = port:PB03<0><0>
gpio_pin_4 = port:PB04<0><0>
gpio_pin_5 = port:PB02<0><0>
...


Um das Display mit dem Cubietruck zu verbinden habe ich mir eine kleine Adapter-Platine erstellt (siehe Bild), diese kann man bei OSHPark.com ansehen und bestellen.




Achtung es kann sein das bereits gpio_pins deklariert sind, diese sollte man nicht anfassen sondern ggfls. die Nummerierung der neuen Pins anpassen. Zudem muss die Anzahl der zu verwendenden Pins im Kopf des Blocks korrigiert werden.

Wurden alle Änderungen durchgeführt muss die Fex-Datei wieder in sein binäres Pendant
umgewandelt werden. Dies geschieht mit dem Tool fex2bin.

root@cubietruck:/boot# bin2fex script.fex script.bin

Damit ist nun der Kernel und die Cubietruck-Hardware - nach einem Reboot - bereit auf das Display zuzugreifen.

Nun muss das Kernel-Modul geladen werden. Es handelt sich dabei um das fb_ili9341 von GitHub welches nun auch Bestandteil der Linux-Kernels ist.

root@cubietruck:/boot# modprobe fbtft dma=1
root@cubietruck:/boot# modprobe fbtft_device custom name=fb_ili9341 buswidth=8 \

                                                       gpios=reset:4,led:5,dc:3 busnum=2 rotate=270 bgr=1 \
                                                       mode=0 speed=64000000 txbuflen=64 fps=25 debug=1

Zunächst wird DMA aktiviert und daraufhin das Kernel-Modul mit einer Standard-Konfiguration geladen. Wichtig hierbei ist das der Parameter gpios die korrekten Pin-Nummern angegeben werden. Der LED-Pin kann bei Bedarf auch weggelassen werden.
Möchte man Problemen auf den Grund gehen kann man beispielsweise den Parameter debug auf den Wert 7 setzen, um die Detailtiefe der Debug-Ausgaben im Syslog drastisch zu erhöhen. Die Bildwiederholrate reduziert sich bei höheren Debug-Leveln jedoch sehr stark. So dauert es beispielsweise auf meinem System um die 35 Sekunden um ein Bild auf dem Display anzeigen zu lassen, wenn die Option debug auf den Wert 7 eingestellt ist.

Ist das Modul korrekt geladen wird unter /dev ein neues Framebuffer-Device eingefügt. Die LED-Beleuchtung wird nach dem erfolgreichen Ladevorgang ebenfalls eingeschaltet, sofern man den LED-Pin im gpios-Parameter angegeben hat. 

Der Parameter rotate gibt in Grad an wie das Display ausgerichtet sein soll. Mit der Option busnum wird angegeben welcher SPI-Port für die Kommunikation mit dem Display verwendet werden soll.
Im Beispiel oben ist der Wert 2 angegeben, dies liegt daran das oben in der Konfiguration der GPIO-Ports für die Hardware SPI2 konfiguriert wurde.

Der Wert 64 bei dem Parameter txbuflen gibt an wie groß der Byte-Buffer zur Datenübertragung an das Display verwendet werden soll. 
ACHTUNG, hier darf der Wert 64 nicht überschritten werden, da die Kommunikation sonst nicht funktioniert. Zumindest nicht mit meiner Hardware - diese hat dedoch auch geneu 0 kB DMA-Buffer zur Verfügung.

Ein Forums-Thread zu dem Problem existiert bereits.

Um zu testen ob das Display korrekt arbeitet kann man z.B. mit dem Tool fbi ein Bild darauf anzeigen.

root@cubietruck:/boot# fbi -d /dev/fb2 -T 1 -noverbose -a

Interessanterweise funktioniert das korrekte Laden des Kernel-Moduls per /etc/modules.conf - Datei nicht. Zumindest nicht auf meinem Armbian Linux. Ich habe die oben stehenden Aufrufe von modprobe in die /etc/rc.local eingetragen.

Möchte man nun noch ein Terminal auf das Display binden kann man das mit der folgenden Zeile einrichten. Auch diese habe ich in die rc.local eingetragen.

root@cubietruck:/boot# con2fbmap 1 2

Damit wird tty1 auf das Framebuffer-Device /dev/fb2 gebunden. !!!ACHTUNG nachdem das Kernel-Modul geladen wurde muss einige Zeit gewartet werden bis con2fbmap aufgerufen werden darf, da das Laden des Moduls einige Zeit im Hintergrund benötigt bis das Laden abgeschlossen ist!!!

Das Ergebnis wird dann in etwa wie auf dem folgenden Bild aussehen.




Wenn jemand mit hier einen Tipp hat wie oder was man verbessern könnte, dann bitte gerne einen Kommentar auf diesen Beitrag hinterlassen. Diese werden aber nicht direkt hier im Blog freigegeben. Ich werde diese dann bei Gelegenheit durch gehen und entsprechend manuell freigeben.

Ich hoffe das dieser kurze Artikel anderen weiter helfen wird und das Mysterium um das ILI9341 - Display etwas deklassiert. Im Nachhinein muss ich jedoch auch sagen das es deutlich einfacher gewesen ist alles einzurichten und das es auch dieses mal deutlich einfcher hätte sein können wenn die bereits vorhandenen Dokumentationsbeispiele detailierter und etwas mehr über den "Tellerrand" beschrieben worden wären.

Die Größte Hilfe bei der Einrichtung bot mit ein in russischer Sprache geschriebener Kommentar zu einem Youtube-Video welches das Display in Aktion zeigt. Dank dem Google-Translator war die sprachliche Hürde an dieser Stelle zu meistern.


UpConverter fixed

Vor einiger Zeit berichtete ich darüber das mein Versuch einen UpConverter für mein rad1o zu bauen leider fehlgeschlagen ist. Es lag an der...