Das angehängte Programm 'main.c' zeigt die Ansteuerung eines
WQVGA-TFT-Displays mit 480x270 und 64 Farben/Pixel. Es wurde mit einer
IAR-Kickstart Version für ARM auf einem STM32F4-Discovery-Board
entwickelt.
Als Display dient ein ET0430G0DH6. Die Anschlußbelegung findet sich
hier:
http://www.mino-elektronik.de/TFT-direct-drive/TFT-direct-drive.htm#tft-b
Es soll kein "digitaler Bilderrahmen" neu erfunden, sondern gezeigt
werden, wie mit wenig Aufwand und höchster Schreibgeschwindigkeit eine
einfache Bedieneinheit beim STM32F4 implementiert werden kann. Die
gezeigten Routinen können erheblich (>Faktor 2) optimiert werden. Um die
Übersichtlichkeit nicht zu vermindern, ist auch die Abfrage des
touch-screen entfallen.
Für eigene Anwendungen muß sichergestellt sein, dass der Prozessor
initialisiert ist und mit 168MHz läuft. Da bis auf ca. 1kB der
zusammenhängende Speicher von 128kB belegt ist, sollte für den Stack und
weitere Variablen das 64kB große CCM verwendet werden. Wenn nur ein
QVGA-TFT verwendet wird, bleibt erheblich mehr RAM frei.
Die Ausgabe zum Display erfolgt freilaufend ohne Timer über das
FSMC-Interface, was mit der einfachen Beschaltung für weitere Verwendung
blockiert ist. Mit ein bißchen Logik und einem 74VHC573 Latch, können
per FSMC-Bus auch weitere Speicherbausteine (o.ä.) ext. angeschlossen
werden.
Mit der angehängten .hex-Datei kann man ohne großen Aufwand und ohne TFT
die Beine vom µC wackeln lassen. Vsync (PD11) und Hsync (PD12) zeigen
das Timing.
Viel Erfolg!
Im Prinzip müßte jedes 4,3" Display verwendbar sein; unter Umständen muß
das Timing für Vsync und Hsync angepaßt werden.
Meine Quelle für TFTs ist Glyn. Der Einzelpreis liegt derzeit bei
ca. 35 € netto. Die EDT-Serie dort hat einheitliche 40-pol.
Steckverbinder, weshalb QVGA und WQVGA einfach auszutauschen sind.
Sicherlich gibt es hier auch Profis, die Dir genau sagen können, dass
und wo in China alles nur max. die Hälfte kostet :-)
@m.n. Tolle Info!!!
Seit einiger Zeit überlege ich mir, ob es Sinn macht einen einfachen
Applikations-Kontroller für TFT zu entwickeln.
Hintergrund:
Zur Zeit arbeite ich noch mit S65-Displays
Beitrag "The Siemens S65 132x176, 65536 color display with AVR"
Der Vorteil des Display ist die einfache Ansteuerung über SPI, d.h. die
Hardwareanforderungen sind sehr gering bzw. das Layouten sehr einfach.
Mir ist klar, dass bei höherer Auflösung die Bildaufbauzeiten extrem
ansteigen.
Die Idee bzw. Lösung: Applications-Controller-TFT (ACTFT):
Der Controller besitzt im einfachten Fall zwei Schnittstellen
1. eine serielle für die Applikation (SPI, I²C, RS232, CAN ...)
2. eine parallele für das Display (8Bit, 16bit, 24bit)
Der ACTFT (z.B. ein STM32FXXXX) arbeit als Interpreter, der einfache
Grafik Kommandos entgegennimmt (Init, SetPixel, ReadPixel, DrawLine,
DrawCircle, DrawBitmap, Fill, etc.)
oder sogar komplexe Kommandos ausführen kann (Menu, CheckBox, Animate,
GUI...)
Natürlich können die Befehle auch von einer PC-Simmulation ausgeführt
werden (einfache Simulation, Entwicklung und Design)
Ich denke, damit lassen sich alle Anwendungsfälle, die nicht extrem
zeitkritisch sind erfüllen.
Die Kommandos sind Hardware (TFT) unabhängig und somit universell
einsetzbar.
Einzig der ACTFT sollte die gängigen TFT-Ansteuerungen implementiert
haben.
Frage:
Gibt es so was als preiswerte Lösung bereits (davon gehe ich aus)?
Hat jemand interesse an so einem Projekt?
Wenn du mit 50 MHz oder so (weiss nicht mehr wo die Obergrenze war) in
das s65 Display schiebst ist der Bildaufbau au h recht flott. Ein
eigener Controller für größere displays? Dann lieber gleich einen
Controller nehmen der displayinterface und m besten noch dram Interface
hat. Dann ist man zwar schnell beim embedded PC, aber das wäre die
professionelle lösung.
m.n. schrieb:> Es soll kein "digitaler Bilderrahmen" neu erfunden werden,
Damit wollte ich ausdrücken, dass es mir nicht um die
Eierlegendewollmilchsau geht, die langsam bunte Bilder zeichnet. Dafür
reichen Papier und Buntstifte.
Es geht auch nicht darum, einen 'embedded PC' nachzuempfinden.
Mir geht es darum, an einen leistungsfähigen µC mit hinreichend RAM ein
TFT-Display sozusagen als 'Abfallprodukt' anzuschließen, wobei weder
Kosten noch Leistungseinbußen entstehen. Ein Beispiel hatte ich neulich
gezeigt: Beitrag "reziproker Frequenzzähler mit STM32F4Discovery"
Alternativ erlaubt der STM32F4 (wie auch RX610,RX62 +++) den Aufbau
kompletter Steuerungen mit Schrittmotoren, Inkremenetaldekodern, ADCs,
DACS, ... usw..
Das TFT ist dabei Mittel zum Zweck und nicht Selbstzweck!
@artjomka
Danke für deinen Beitrag. Eigentlich geht es mir es nicht um die
"Bildaufbaugeschwindigkeit" sondern um eine einheitliche Schnittstelle
und darum, dass nicht jedesmal die Firmware wegen "Bildschirmroutinen"
umgeschrieben werden muss.
Beispiel:
Ich habe eine Hardware und als Anzeige dient mir das Display XYZ,
welches über SPI angebunden wird.
Bei einem Displaywechsel möchte ich meine bestehende Hardware nicht
ändern (z.B. parallel anstatt SPI). Auch möchte ich meine Firmware nicht
anpassen müssen (z.B. anderer TFT-Controller).
All dies soll der ACTFT übernehmen.
Also:
Fall 1: Das Display XYZ ist abgekündigt (zB. S65)
Fall 2: Möchte ein anderes Display verwenden z.B. höhere Auflösung
Der Gedanke mit dem DMA und FSMC vom STM32F4 schwirrte mir auch vor
kurzen durch den Kopf.
Stört es beim STM32F4-Discovery nicht, daß FSMC_NWE auf der
USB-Overcurrent-LED liegt ?
Gruß Dennis
Dennis Heynlein schrieb:> Stört es beim STM32F4-Discovery nicht, daß FSMC_NWE auf der> USB-Overcurrent-LED liegt ?
Eigentlich nicht! Dennoch hatte ich schon vor langer Zeit R50 durch auf
3k3 erhöht, um "Interessenskonflikten" vorzubeugen; OverCurrent kann bei
mir allerdings nicht auftreten.
Im Betrieb glimmt daher LED8 nur und LED4 (A17), LED5 (D0) und LED6 (D1)
leuchten schön hell.
m.n. schrieb:> Dennis Heynlein schrieb:>> Stört es beim STM32F4-Discovery nicht, daß FSMC_NWE auf der>> USB-Overcurrent-LED liegt ?>> Eigentlich nicht! Dennoch hatte ich schon vor langer Zeit R50 durch auf> 3k3 erhöht, um "Interessenskonflikten" vorzubeugen; OverCurrent kann bei> mir allerdings nicht auftreten.> Im Betrieb glimmt daher LED8 nur und LED4 (A17), LED5 (D0) und LED6 (D1)> leuchten schön hell.
Okay :) gute Idee.
Ich habe mir das WaveShare TFT besorgt und bin angenehm überrascht.
Helligkeit und Blickwinkel finde ich für den Preis gut.
Ein Problem gibt es allerdings mit dem Timing. Die Datenübernahme
erfolgt laut Datenblatt (findet man unter
http://www.wvshare.com/column/LCD_Module.htm) mit der negativen DCLK
Flanke (siehe Seite P64 des HX8257-A Datasheets). Dieses Timing bekomme
ich mit dem FSMC eines STM32F4 nicht hin. Trotzdem kommt am Display mit
folgenden Einstellungen und angepasster Interuptroutine etwas ganz
ansehnliches raus:
#define THP 41 // Hsync pulse width
#define THB 2 // Hsync back porch
#define THF 2 // Hsync front porch
#define TVP 10 // Vsync pulse width
#define TVB 2 // Vsync back porch
#define TVF 2 // Vsync front porch
#define X_START_POS (THP+THB) // x-werte ab 43
#define Y_START_POS (TVP+TVB) // Zeilen ab 12
#define MAX_X (SIZE_X-1)
#define MAX_Y (SIZE_Y-1)
#define H_LINE_LEN (X_START_POS+SIZE_X+THF) // gesamte Zeile
#define V_LEN (Y_START_POS+SIZE_Y+TVF)
extern "C" void DMA2_Stream0_IRQHandler(void)
{
__enable_irq();
DMA2->LIFCR = 0xfd; //alle int-flags loeschen
if(line_cnt >= V_LEN)
{
line_cnt = 0;
line_adr = (uint32_t)&FrameBuf;
}
if(line_cnt < TVP)
DMA2_Stream0->M0AR = (uint32_t)(TFT_ADR + HSYNC_ADR_MASKE - THP);
else
DMA2_Stream0->M0AR = (uint32_t)(TFT_ADR + HSYNC_ADR_MASKE +
VSYNC_ADR_MASKE - THP);
if(line_cnt < Y_START_POS || line_cnt >=V_LEN-TVF)
{
DMA2_Stream0->CR = 0x490; // 8bit-modus Adressmodus PINC=0 , MINC =
1
DMA2_Stream0->PAR = (uint32_t)&black_pixel;
}
else
{
DMA2_Stream0->CR = 0x690; // 8bit-modus Adressmodus PINC =1 , MINC
= 1
DMA2_Stream0->PAR = ((uint32_t)line_adr)-(X_START_POS-1);
line_adr += SIZE_X;
}
DMA2_Stream0->NDTR = H_LINE_LEN;
line_cnt++;
DMA2_Stream0->CR |= 0x1;
}
Solange das Display kalt ist, scheint es Probleme mit der Datenübernahme
zu geben (Pixel flimmern).
Den Touch habe ich noch nicht untersucht.
Kennt jemand einen Workaround?
Peter Hegel schrieb:> Dieses Timing bekomme> ich mit dem FSMC eines STM32F4 nicht hin.
Das ist auch garnicht notwendig. Wichtig sind die Zeiten tds und tdh
(Seite P.67, tdf im Diagramm ist ein Druckfehler) in Bezug auf CLK, die
jeweils minimal 10ns betragen. Das Timing der neg. Flanke des /WR
Signals kann man recht gut per FSMC einstellen.
> Kennt jemand einen Workaround?
Wofür?
M. N. schrieb:> Das Timing der neg. Flanke des /WR> Signals kann man recht gut per FSMC einstellen.
Es ist alles genau anders herum! Ich habe noch einmal nachgesehen und
festgestellt, dass mein Display die pos. Flanke von /WR zur
Datenübernahme erwartet. Damit habe ich ein völlig entspanntes Timing
und Du die Niete gezogen.
Du könntest das Signal invertieren oder um 15-20ns verzögern, um die tds
einzuhalten. Aber Du weißt sicherlich selber, was zu tun ist.
Dass der FSMC flexibel einstellbar ist, darf man wohl nicht wörtlich
nehmen.
Ich habe es mit den Möglichkeiten der Renesas RX verwechselt, wo man den
Schreibimpuls nach Belieben positionieren kann.
Vielen Dank für die Infos.
Einen Inverter oder Verzögerung werde ich später einmal ausprobieren.
Jetzt bin ich erst einmal froh, dass das Display zuckt. Ich reiche die
Ergebnisse nach.
Die Seite P.67 habe ich übersehen (dachte gehört zum SPI Timing).
Da taucht aber schon die nächste Frage auf. Funktioniert denn das
Einhalten von tvhs zwischen den fallenden Flanken von VSYNC und HSYNC?
Gehen die nicht gleichzeitig Low wenn line_cnt == 0 ist:
DMA2_Stream0->M0AR = (uint32_t)(TFT_ADR + HSYNC_ADR_MASKE - THP);
Außerdem haben bei mir die ersten zwei Zeilen beim Display gefehlt. Ich
habe deinen Code etwas modifiziert, um alle 272 Zeilen zu bekommen.
Den Vertical Front Porch habe ich auch etwas anders implementiert:
if(line_cnt < Y_START_POS || line_cnt >= V_LEN-TVF)
...BlackPixel
Die Adressleitungen A16/A17 habe ich auf A20/A21 verschoben, um kurze
Verbindungen vom Discovery Stecker P2 zum TFT Stecker zu ermöglichen.
Auf jeden Fall hat mir deine Implementierung eine Menge Arbeit gespart.
Danke!
Peter Hegel schrieb:> Außerdem haben bei mir die ersten zwei Zeilen beim Display gefehlt. Ich> habe deinen Code etwas modifiziert, um alle 272 Zeilen zu bekommen.
Das habe ich gemerkt! :-)
Die zwei Zeilen hatte ich nicht aktiviert, um etwas mehr 'normales' RAM
zu erhalten. Wenn man das RAM sorgsam verwendet und auch CCM benutzt,
kann man auch die volle Zeilenzahl nutzen.
Peter Hegel schrieb:> Da taucht aber schon die nächste Frage auf. Funktioniert denn das> Einhalten von tvhs zwischen den fallenden Flanken von VSYNC und HSYNC?> Gehen die nicht gleichzeitig Low wenn line_cnt == 0 ist:> DMA2_Stream0->M0AR = (uint32_t)(TFT_ADR + HSYNC_ADR_MASKE - THP);
Meine Routinen kommen ursprünglich von einem QVGA-TFT. Da gibt es tvhs
und tvhh überhaupt nicht. Bei der Umstellung auf WQVGA hat sich
keinerlei Instabilität gezeigt. In einigen Punkten scheinen mir die
Datenblätter auch etwas 'erfinderisch' zu sein.
Vsync kann man auch steuern, indem man keine Adressleitung, sondern den
selben IO-Pin als Portbit setzt und löscht.
> Den Vertical Front Porch habe ich auch etwas anders implementiert:> if(line_cnt < Y_START_POS || line_cnt >= V_LEN-TVF)> ...BlackPixel
Die "Front Porches" (ist hoffentlich der Plural) haben sich im Laufe der
Zeit als völlig unnötig gezeigt; daher habe ich sie auch gnadenlos
weggelassen. Das dafür Zeiten angegeben sind liegt wohl an der
Kompatibilität zu Videosignalen, deren Timing auf Röhrenmonitore
Rücksicht nehmen mußte.
Wenn man die "Porches" verwendet und hierfür auch noch Platz im RAM hat,
kann man damit Zeichen auch außerhalb des sichtbaren Bereiches beginnen
oder enden lassen, was beispielsweise bei Laufschrift gut wirkt, wenn
links und rechts Teilbuchstaben angezeigt werden, bis die letzte Spalte
links verschwunden oder rechts aufgetaucht ist.
Vertikal kann man das Bild weich nach oben laufen lassen (soft-scroll).
Das sind aber alles Feinheiten, die vermutlich die meisten Leute
garnicht brauchen.
Hallo.
Gibt es Demohardware mit 800x480-Display, der ich mit 60fps
Graubilddaten übergeben kann und die das ohne Framebuffer direkt
anzeigt?
. Parallel
. zB. 6Bit Daten
. Die zwei VSYNC/HSYNC Bits kann ich bei Bedarf mitliefern
Beispielsweise auf Basis des hier vorgeschlagenen Quellcodes?
Bei den Controllern SSDxxxx der Ebay-China-Boards lese ich "Framebuffer"
oder "13fps" aber kein vsync/hsync auf der Pinheader-Belegung. Oder
können die 60fps ohne Buffer?
Grüße
Lars
Lars R. schrieb:> Gibt es Demohardware mit 800x480-Display, der ich mit 60fps> Graubilddaten übergeben kann und die das ohne Framebuffer direkt> anzeigt?> . Parallel> . zB. 6Bit Daten
Bestimmt nicht!
800x480 mit 256 bzw. 64 Graustufen brauchen einen Bildspeicher von
384kB. Der ..407 hat maximal 128K intern zur Verfügung; auch ein ..427
mit 192K würde nicht reichen.
Bei reiner sw-Darstellung würden 48kB reichen, die dann über SPI1
ausgegeben werden könnten.
Lars R. schrieb:> aber kein vsync/hsync auf der Pinheader-Belegung
Die arbeiten vermutlich im DE-Modus.
@m.n.:
Es hätte ja sein können, Du hast etwas.
Deine Homepage habe ich angeschaut. Bei Glyn sieht es auf den ersten
Blick so aus, dass es auch 800x480-Displays gibt, die zu den von Dir
verwendeten WQVGA kompatibel sind. KOMPLETTES Zwischenspeichern habe ich
nicht verlangt. Daten kommen vom FPGA.
Lars R. schrieb:> Bei Glyn sieht es auf den ersten> Blick so aus, dass es auch 800x480-Displays gibt, die zu den von Dir> verwendeten WQVGA kompatibel sind.
Die Steckverbinder (40-pol. FFC) sind gleich beschaltet. Die Datenrate
variiert natürlich mit den diversen Auflösungen.
> KOMPLETTES Zwischenspeichern habe ich> nicht verlangt. Daten kommen vom FPGA.
Da verstehe ich nicht so richtig, was Du eigentlich vor hast.
Bilddaten mit dem FPGA ausgeben. Pixel für Pixel. Zeile für Zeile.
Per Handshake oder in definierten Zyklen. Über 1.27mm oder 2.54mm.
Was ich umgehen möchte:
LCD-Kabel <-> PCB, Backlight, LCD, Timing, Init, Power.
Mit dem Display will ich mich eigentlich nicht beschäftigen. Auf der
Suche im Netz habe ich auch Andere gefunden, die einfach nur etwas
ausgeben wollen, aber nicht nur mit 5Hz SPI.
Wenn es dann auch eine Lösung jenseits der China-PCB-Displays wäre, bei
der man davon ausgehen kann, dass sie bei eventuellem Bedarf auch in ein
paar Monaten noch verfügbar ist...
Tolles Projekt.
Was passiert denn, wenn die Framerate zu niedrig wird? Flackert oder
flimmert das Display dann?
Und was ist, wenn die CPU in das externe SRAM schreibt während ein
DMA-Transfer zum TFT läuft? Dann müsste der Round-Robin Scheduler ja
dafür sorgen, dass lediglich die Geschwindigkeit des DMA-Transfers
vorübergehend etwas absinkt?
Steffen Koepf schrieb:> Was passiert denn, wenn die Framerate zu niedrig wird? Flackert oder> flimmert das Display dann?
Was ist denn der Unterschied zwischen Flackern und Flimmern?
Durch die Trägheit des TFTs kann die Bildwiederholrate (framerate) bis
ca. 30Hz gesenkt werden, sofern man direkt drauf sieht. Bei statischer
Anzeige von Grafiken/Texten ist das in Ordnung.
Bei schneller Ausgabe neuer Bildinhalte, wird die Ausgabe unruhig; eine
Laufschrift beispielsweise ist sehr ruckelig.
> Und was ist, wenn die CPU in das externe SRAM schreibt während ein> DMA-Transfer zum TFT läuft?
Das ist alles problemlos, da ein TFT kein exaktes Taktsignal bei der
Bildausgabe benötigt.
Der DMA-Controller besorgt sich die notwendigen Zugriffe. Wie
geschrieben, sollten die TFT-Datenleitungen mit einem xx573 entkoppelt
werden, oder DCLK besser dekodiert werden anstatt nur das /WR-Signal
direkt zu nutzen.