Forum: Projekte & Code FT800 / FT810 Library


von Rudolph R. (rudolph)



Lesenswert?

Ich bin dabei, eine eigene Library für FT800 und FT810 zu schreiben.
Warum? Weil ich wissen wollte, wie man die Chips benutzt.
Und weil ich gerne in Zukunft mehr mit denen machen würde.

Ich habe als Hardware derzeit zum testen:

VM800B35A-PL 3,5" 320x240 FT800 von FTDI
FT810CB_HY50HD 5" 800x480 FT810 von HAOYU

Bestellt habe ich auch noch ein FT800CB-HY50B von HAOYU, aber das wird 
sich wohl noch vier Wochen hin ziehen, China eben...

An beide TFTs habe ich eine kleine Platine von mir dran gebastelt mit 
einem AT90CAN128 von Atmel, dazu noch jeweils ein Netzteil-Platinchen.
Versorgung und Signal-Pegel ist für beide TFT jeweils 5V.

Der SPI ist auf 8 MHz eingestellt, mehr geht mit den AVR nicht.
Wenn man das an einem schnelleren Controller verwendet ist zu beachten, 
dass der SPI beim Aufruf der ft800_init() noch langsamer als 11 MHz 
eingestellt sein muss, danach darf der dann bis 30MHz laufen.

Ja, das sind Test-Aufbauten.
Und ja, das grüne Ding ist eine Brot-Dose, mies aber preiswert.
Und ebenfalls ja, die GUI hat keinen Sinn, das ist nur zum Spielen.

Die "Library" besteht im Moment aus diesen Teilen:
FT800.h Contains FT80x/FT81x API definitions
FT800_commands.c Contains Functions for using the FT8xx
FT800_commands.h Contains FT800 Function Prototypes
FT800_config.h  configuration information for some TFTs and some 
pre-defined colors

Die FT800_commands.c aus den beiden angehängten Projekten unterscheiden 
sich nur dadurch, dass in dem FT810CB_HY50HD Projekt die Zeile 
auskommentiert ist mit der in der ft800_init() die Anzeige um 90° 
gedreht wird.

In der FT800_config.h wird das TFT das man benutzen möchte eingestellt, 
sowie zwischen FT800 und FT810 umgestellt.

Das Projekt für den FT810 funktioniert zwar, von dem was der FT810 
zusätzlich kann ist bisher aber nur ft800_cmd_setbase() implementiert.

Eine wichtige Einschränkung ist, dass ft800_cmd_inflate() und 
ft800_cmd_loadimage() nicht mit Bilder über 4080 Bytes Länge klar 
kommen.
Das liegt daran, dass die Bilder über den FIFO vom Kommando Co-Prozessor 
in den FT8xx geschoben werden und dieser hat eben nur 4k.
Das kann man auch weniger stumpf programmmieren und den FIFO mehrmals 
füllen, für den FT800 war mir das nur nicht wichtig genug und mit dem 
FT810 entfällt das unter Verwendung von cmd_mediafifo().

Es war jetzt aber kein Problem Icons mit 100x100 Pixel als .jpg in unter 
4k zu packen.


Über die ersten 60 Zeilen der FT800_commands.c wird die Hardware vom 
Rest gelöst, darüber müsste sich das an so ziemlich alles anpassen 
lassen, mehr oder weniger sinnvoll. :-)

Mein beiden Test-Projekte implementieren einen einfachen Scheduler mit 4 
"Tasks" die 250µs laufen dürfen und einmal pro ms aufgerufen werden.

Die Funktion ft800_loop() setzt da jetzt drauf auf, dass sie mit einem 
Abstand von 1ms aufgerufen wird.
Mit der Zähler-Variablen "delay" hangelt die sich von einem Aufruf zum 
nächsten.
Zuerst werden Touch-Events ausgewertet.
Dann in Folge Schritt für Schritt die Display-Liste zusammen gebaut und 
schliesslich abgeschlossen und ausgeführt - 40 Mal pro Sekunde.

Der Ansatz soll dafür sorgen, dass der Controller beim Übertragen der 
Kommandos für die Liste weiter ansprechbar bleibt.
Das funktioniert soweit ganz gut, nur haben die Controller nicht 
wirklich was anderes zu tun in den Test-Aufbauten.
Und ehrlich gesagt habe ich auch nicht mehr nachgemessen, ob sich alle 
Teile von ft800_loop() an das 250µs Limit halten.

Das wars was mir "spontan" dazu einfällt, ansonsten möchte ich nur 
anmerken, dass ich das nicht als abgeschlossen betrachte.

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

Ein winziges Update für FT800_commands.c und FT800_commands.h:

2.1
- removed the REG_ROTATE line from ft800_init()
- simplified ft800_busy() slightly
- implemented ft800_cmd_mediafifo(), ft800_cmd_setrotate(), 
ft800_cmd_setbitmap() (FT81x)

Damit benutze ich jetzt für beide Projekte exakt die gleichen Dateien.
Die REG_ROTATE Zeile habe ich im FT800 Spielplatz in die main() 
geworfen.

Und yeah, das FT800CB-HY50B ist verschickt, nur noch 3 1/2 Wochen... :-)

von Holger S. (223rem)


Lesenswert?

Hallo Rudolph,

besten Dank für Deine Vorarbeit.
Mein FT810CB-HY50HD ist auch seit gestern auf dem Weg ;-)
Werde demnächst mal ein Platinchen für FT812/FT813 stricken.

Gruß Holger...

von Rudolph R. (rudolph)


Lesenswert?

Ich habe noch den Plan im Hinterkopf, ein Board für den FT811 zu bauen.
Nur ist das nicht ganz so witzig, da überhaupt TFTs für zu finden.
Bringt ja irgendwie nichts, wenn man das an nichts anschliessen kann.

Ich habe zum Beispiel neidisch auf das neue 7" RaspberryPi TFT geschielt 
bis ich dann in einem Forens-Beitrag gelesen habe, dass das Ding keine 
quadratischen Pixel hat.
Da habe ich dann die Suche nach weiteren Infos dazu aufgegeben.
Dafür finde ich das Teil dann auch zu teuer.

VM800B50 werde ich dann auch noch in die Finger bekommen.

Das FT810CB_HY50HD hat mir auf jeden Fall zu viele Pixel für die Fläche.
Mein Plan ist das FT800CB-HY50B mit der FT810 Platine aufzurüsten, ich 
könnte dann auch mal versuchen den FT800 durch einen FT810 zu ersetzen.

Mal schauen, wäre ja nett, wenn sich langsam noch mehr Anbieter finden 
würden.

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

Noch ein kleines Update.
Ich stand am Donnerstag spontan vor der Aufgabe, das auf einem Arduino 
mini pro zum Laufen zu bringen, also als Arduino-Code und nicht direkt.

Das lief dann doch nicht ganz so, wie ich mir das überlegt hatte.
In der FT800_commands.c was ändern zu müssen kann eigentlich nicht das 
Ziel sein.
Ausserdem hatte ich die Bedienung des PowerDown Pins nicht abstrahiert 
und musste das entsprechend in der ft800_init() direkt ändern.

Also gibt es jetzt noch eine FT800_config.c in welche die Funktionen zur 
Abstrahierung der Hardware ausgelagert sind.

Es sollte jetzt nur noch notwendig sein, die FT800_config.h und/oder 
FT800_config.c an die Ziel-Hardware anzupassen.

Jetzt muss ich mal schauen, dass ich das wieder in Richtung Arduino 
geschubst bekomme, dann werfe ich die erweiterte FT800_config.c und 
FT800_config.h noch mal hier als Beispiel ab.

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

Arbeit, wie schnell die Zeit vergeht, wenn man Spass hat. :-)

Vor ein paar Tagen ist das FT800CB-HY50B aus China angekommen.

Das habe ich an den Controller der Brotdose angeschlossen, das 
Spielplatz_90CAN_FT800 Projekt aufgemacht, in der FT800_config.h das 
FT_VM800B50A als Display ausgewählt weil dieses ja auch 5" 480x272 hat, 
compiliert, eingespielt, läuft. :-)

Dann habe ich die komplett identische Platine von dem FT810CB_HY50HD mit 
dem FT810 auf das TFT gebaut, in der FT800_config.h das #define 
FT_81X_ENABLE aktiviert, compiliert, eingespielt, läuft.

Nächste Woche oder so will ich mal versuchen den FT800 von der anderen 
Platine auszulöten und durch einen FT810 zu ersetzen.
Probiert habe ich sowas allerdings noch nicht, QFN vermeide ich eher.

Dann habe ich mir gestern mal etwas mehr Mühe gebeben mit dem Gehäuse.
Und die Brotdose weg geworfen.

Was mir ja gut gefällt ist die niedrigere Auflösung bei 5", weniger 
prickelnd ist allerdings der schwache Betrachtungswinkel und resistiv 
ist es ja auch immer noch.
Beim Fotografieren fiel auch auf, dass das kräftig reflektiert.
Die Schutzfolie ist auch noch drauf, viel Effekt hatte die beim 5" 
800x480 aber nicht.

Weil mir aber vor allem die Lieferzeiten aus China auf den Keks gehen 
und die TFTs die FTDI verwendet etwas hochwertiger wirken, habe ich mich 
dran gemacht eine Erweiterungs-Platine für die VM800B zu bauen.
Die Doppel-Reihige Buchsenleiste dient dazu, auf die richtige Bauhöhe zu 
kommen damit die Platine auf der anderen Seite mit einem Dom verschraubt 
werden kann, das soll dann für das VM800B35 und das VM800B50 passen.
Auf der Platine habe ich einen 90CAN mit CAN und LIN, einen 600mA 
Schaltregler für das TFT und einen LDO für den µC.
Das Ziel ist eine Prototypische Anzeige-Einheit für Fahrzeuge.

von e-d (Gast)


Lesenswert?

FT800 aus deutschen Landen:
http://www.watterott.com/de/Gameduino-2

(basiert auf FT800 Display+Audio+Touch Controller von FTDI);

von Rudolph R. (rudolph)


Lesenswert?

e-d schrieb:
> FT800 aus deutschen Landen:

Naja, OpenSource von SeedStudio in USA produziert und von Watterott 
importiert.
Das hätte sicher auch eine andere Qualität wenn das ein Produkt von 
Watterott wäre.

Edit, ach ja, das Gameduino2 hat ja auch "nur" 4,3", damit ist die 
Pixel-Dichte auch höher als bei dem 3,5" oder 5" -> möchte ich nicht.

> http://www.watterott.com/de/Gameduino-2

Da nehme ich lieber das hier:
http://de.farnell.com/ftdi/vm800b50a-pl/entw-modul-ft800-eve-mit-5-anzeige/dp/2355184

Das kann man wenigstens direkt in ein Gehäuse einbauen.

Unter dem Aspekt sind die von Haoyu eben auch schick, die sind inklusive 
Einbau-Rahmen:
http://www.hotmcu.com/5-graphical-lcd-touchscreen-480x272-spi-ft800-p-124.html?cPath=6_16&zenid=j1ejj530jj088epnvoratp0843

Man muss die nur leider bisher direkt in China ordern, wenn es die zum 
Beispiel bei Watterott geben würde, das hätte was.

Leider ist die Auswahl an Modulen mit FT811 sehr dünn, Haoyu hat zwar 
eines, aber 5" mit 800x480 will ich inzwischen nicht mehr haben.
Ich würde das ja gerne mal mit Kapazitiv-Touch sehen.

: Bearbeitet durch User
von Rudolph R. (rudolph)



Lesenswert?

Ein kleines Update, diesmal mit den Support-Funktionen für Arduino.
Zu viel Arbeit, zu wenig Zeit zum Spielen...

Ein Beispiel-Projekt für den Arduino muss ich auch gerade schuldig 
bleiben, ich mache zwar was mit einem miniPro, das kann ich hier aber 
nicht veröffentlichen.

Spielplatz_90CAN_FT810_HY50B.zip - wie weiter oben auch, ein komplettes 
Beispiel-Projekt für den AT90CAN128

Test_M644_FT810.zip - das ganze mal schnell und ungestet für den 
ATMega644 umgesetzt weil ich per Mail gefragt wurde, wie man das macht.
Die für das Beispiel relevanten Unterschiede zwischen 90CAN128 und M644 
sind allerdings so klein, dass das quasi das gleiche Projekt ist.
In der FT800_config.c musste ich noch das pgm_read_byte_far() durch 
pgm_read_byte() ersetzen, der M644 hat ja "nur" 64k Flash.

Und dann erlaube ich mir mal, die Dateien die in der 90CAN...zip drin 
sind mal direkt mit anzuhängen, zum schnelleren durchklicken.
Das ist ja auch alles nicht so gross.

FT800.h FT800_commands.c FT800_commands.h FT800_config.c FT800_config.h

Was macht man jetzt damit?

Also erstmal einfach ein neues Projekt erstellen und die Dateien ins 
Verzeichnis werfen, dann im Projekt hinzufügen.

In der FT800_config.h stellt man ein, ob man einen FT80x oder FT81x 
benutzen möchte, wählt aus welchen Satz TFT-Einstellungen man benutzen 
möchte (oder erstellt einen neuen Satz), wählt die Plattform aus, im 
Moment AVR8 oder Arduino.

Für die jeweilige Plattform gibt es dann noch spezifische Includes für 
den Zugriff auf den SPI und Delay, sowie Defines für Chip-Select und 
Power-Down des FT800.

In der FT800_config.c stehen die Plattform-spezifischen Funktionen drin 
zum Setzen/Löschen von Chip-Select und Power-Down, zum Übertragen von 8 
Bit per SPI und zum Auslesen von Daten aus dem FLASH.

In der eigenen main.c braucht man jetzt:
#include "FT800.h"
#include "FT800_commands.h"

Mit ersterem bekommt man Definitionen für die ganzen Register und 
Optionen im FT8xx - siehe auch die User-Manuals.
Mit der FT800_commands.h bekommt man Zugriff auf die Funktionen mit 
denen die FT8xx angesprochen werden.

In der main() braucht man dann einen Aufruf von ft800_init(), damit wird 
der Chip erstmal grundsätzlich auf das angeschlossene TFT eingestellt.
Die ft800_init() ist auch der Teil der das Delay() benötigt, und zwar 
für den Power-Down-Reset.
Mit 6 und 21 ms, dazu noch schlapp 5 ms für den AVR Reset, dazu noch 
einige ms um die Bildaten an das TFT zu schicken - das Teil liefert in 
unter 50 ms nach dem Einschalten ein Bild und ist voll funktional, 
darüber staunen meine Kollegen auch immer, Einschalten, läuft.

Als nächstes kann man dann noch ausserhalb der Hauptschleife Bild-Daten 
in den FT8xx schreiben und kann entweder die Touch-Kalibrierung 
ausführen oder aber die REG_TOUCH_TRANSFORM_n Register mit vorher 
aufgezeichneten Werten beschreiben.

Meine Hauptschleife ist ein einfacher "Scheduler" mit vier "Tasks" die 
jeweils 250µs laufen dürfen und einmal pro ms aufgerufen werden.
Im Beispiel habe ich im ersten "Task" meine ft800_loop() eingehängt.

Die ft800_loop() schreibt nun die Anweisungs-Listen für den 
Kommando-Co-Prozessor über dessen 4k FIFO.
Da ich den SPI mit 8 MHz laufen lassen dauert es mindestens 1µs ein 
einzelnes Byte zu übertragen.
Mit Chip-Select und Bits-schubsen sind das vielleicht 200 Bytes die der 
Task innerhalb der zulässigen 250µs schafft.
Da andererseits die Daten gar nicht so schnell im FT8xx landen dürfen 
wie die über den SPI verschickt werden könnten, wird das schicken der 
Liste über das switch(delay) in insgesamt 25 Häppchen unterteilt.
Die Display-Liste wird also alle 25 ms einmal komplettiert, 40 Mal pro 
Sekunde.
Slot 0 nutze ich dabei noch für die Auswertung des Touch-Screens, Slot 
1...3 sind frei um dem FT8xx noch mehr Zeit für die Abarbeitung der 
vorherigen Liste zu geben.
In Slot 4...16 werden die verschiedenen Objekte die zu sehen sind 
definiert und mit Slot 24 wird schliesslich die Liste abgeschlossen und 
der FT8xx zur Abarbeitung aufgefordert.

Ich "reserviere" somit zwar quasi 25% der Rechenzeit eines AVR, die 
werden in den allermeisten Slots aber nicht mal genutzt und einige Slots 
sind auch noch komplett frei. Da geht noch einiges mehr und das für die 
Anzeige auf einem TFT bis zu 800x600 mit 40 Bildern pro Sekunde.
Wenn ich auf dem TFT ein Objekt anklicke, dann gibt es quasi sofort eine 
Reaktion, die Verzögerung sind ja nur maximal 25 ms.
Und für alles drum herum sind 75% Rechenzeit frei.

Ein anderer Ansatz wäre jetzt noch die Daten in einem Puffer zu sammeln 
und diesen alle 25 ms per DMA an den FT8xx zu schicken.
Aber weder hat der 90CAN128 DMA, noch würde ich das SRAM dafür opfern 
wollen.

Mit dem Arduino habe ich das praktisch genau so umgesetzt, nur ist dort 
meine Hauptschleife die loop() und braucht in dem Projekt länger als 1 
ms für einen Umlauf, damit konnte ich die ft800_loop() aber quasi 
identisch übernehmen.

Wichtig für den Arduino ist nur, die FT800_commands.c in 
FT800_commands.cpp und die FT800_config.c in FT800_config.cpp 
umzubenennen.
Sonst stellt sich die SPI-Lib, bzw. deren Include zickig an.
Die FT800_commands.c benutzt dabei nicht mal SPI, includiert aber 
FT800_config.h welche SPI.h includiert...

von Rudolph (Gast)


Angehängte Dateien:

Lesenswert?

Ein winziges Update resultierend aus meinem aktuellen Projekt für das 
ich einen Arduino benutzen soll.

In der FT800.h ist nur was auskommentiert was mit der Arduino IDE 
kollidiert, so aber auch nicht wirklich benutzt wird.
Da ist noch zu viel zu dicht an den Definitionen von FTDI.

In der FT800_config.h muss die Plattform nicht länger eingestellt 
werden, es gibt grundsätzlich eine automatische Unterscheidung von 
Arduino und nicht Arduino.
Und wenn es nicht Arduino ist wird noch auf GNUC/AVR getestet.

Entsprechend ist das in der FT800_config.c auch umgestellt.

Also nichts bewegendes, das ganze ist zumindest für mich auch schon sehr 
gut benutzbar, aber ich dachte mir gerade so, dass ich nach drei Wochen 
auch mal wieder was posten könnte. :-)

von Werner (Gast)


Lesenswert?

Hallo Rudolph,
ich habe deine SW mal auf einem MEGA64 getestet, läuft problemlos - 
Kompliment!
Eine Frage: Wie hast du die Bilder generiert? Welches Format ist das?

Werner

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

Schön wenn noch jemand Spass an der Geschichte hat, auch wenn ich das 
gerade etwas schleifen lassen muss.
Mein erstes richtiges Projekt war jetzt mit einem VM800B50A, also FTDIs 
5" mit FT800.
Gebraucht habe ich für das Projekt irgendwie nur ein kleines Sub-Set an 
Features, der Kollege wollte mehr oder weniger nur ein Text-Display 
haben, so in richtig nett gemacht. :-)

Wenn man als einfach-so-benutzbar nur 2x16 oder gar mal 4x20 LCDs kennt, 
ist so ein TFT schon sehr fett.
Vor allem kostet das mit dem FT8xx wirklich wenig Resourcen.

Die Bilder in der Daddeldu-Spielplatz Anwendung sind einfach nur .jpg, 
irgendwoher aus dem Netz gezogen, bearbeitet auf die gewünschte 
Auflösung, auf unter 4k gespeichert weil die Library ja nur maximal 4k 
laden kann (noch) und anschliessend mit Hex Workshop geladen und als 
C-Source exportiert. Geladen in den Speicher vom FT800 mit 
ft800_cmd_loadimage().
Ich habe das mal eben mit einem Foto durchgezogen das ich gemacht habe.

Für monochrome Symbole hat sich herausgestellt, dass das mit 
ft800_cmd_inflate() bessere Ergebnisse gibt.
Schön sauber in .png bearbeitet und am Ende dann mit dem Image-Convert 
Tool von FTDI auf "L8" konvertiert hat ein Symbol dann zum Beispiel mit 
100x80 Pixeln 1077 Bytes als .png und 936 Bytes im komprimierten FT800 
Format.
Wenn ich das gleiche Bild als .jpg mit 80% speichere bläht sich die 
Datei auf 1933 Bytes auf und bekommt Kompressions-Artefakte.

von Werner (Gast)


Lesenswert?

Hallo Rudolph,

danke für die Info, das mit dem Hex Workshop war der richtige Hinweis!
Ich möchte jpg verwenden, da es später auch für andere möglich sein soll 
die Bilder zu ersetzen. Gespeichert werden die Bilder dann auf einer 
SD-Karte.

Werner

von Rudolph (Gast)



Lesenswert?

Ich habe vor ein paar Tagen was neues zum Spielen bekommen.
Und zwar ein RVT70UQFNWC00 von Riverdi.

Dieses TFT hat 7" mit 800x480 Pixel Auflösung und einen FT813 verbaut.
Endlich mal eines mit kapazitiv touch.
Die Pixel sind auch annähernd quadratisch.

Ein wichtiger Unterschied zu den FTDI TFTs ist, dass Riverdi keinen 
Quarz verbaut hat, damit blieb dann spontan die Software in den ersten 
Zeilen der Initialisierung hängen.

Das TFT kommt auch "nackt", zum Lieferumfang gehört weder ein 
Folienkabel, noch ein Breakout-Board dazu mit Gegenstecker.
Riverdi hat passende Breakout-Boards, oder man schnitzt sich was. :-)

Einen ersten schnellen Test-Aufbau habe ich in ein Pult-Gehäuse von 
Hammond gemacht, das ich zusätzlich dafür beschafft hatte.


Das TFT hat keine Pegel-Wandler oder Spannungsregler für die Logik und 
benötigt eine 3,3V Versorgung sowie die Signale mit 3,3V.

Zusätzlich wird noch eine Spannung bis 7V benötigt für die 
Hintergrund-Beleuchtung, die 21 LEDs werden über einen verbauten Regler 
angesteuert.

Das blaue Platinchen im Bild ist ein 5V/600mA StepDown Wandler, die 
größere Platine daneben eigentlich eine 8-Kanal AD-Wandler Platine die 
ich für die Pegel-Wandler umgebastelt habe, zusätzlich sitzt da auch 
noch ein 3,3V LDO drauf.
Und unten dran hängt noch die Platine mit dem 90CAN128 die im ersten 
Post schon mal zu sehen ist.

Ist zwar hässlich und das Folien-Kabel etwas sehr lang, dennoch gehen da 
anstandslos die Daten mit 8 MHz über den SPI.

Das sieht so echt schick aus, die Oberfläche ist eine glatte 
Glas-Scheibe.
Zum Einbau wird das Teil mit doppelseitigem Klebeband ins Gehäuse 
geklebt, so richtig überzeugt mich das nicht, so mechanisch, sieht aber 
erstmal gut aus.
Für einen ordentlichen Einbau würde ich einen Absatz in das Gehäuse 
fräsen damit die ca. 1,5 mm dicke Scheibe bündig abschliesst.

Das reflektiert auch ziemlich stark, wenn das aus ist kann man das 
problemlos als Spiegel benutzen.
Stand der Technik und so.

Wichtig ist auch der Betrachtungswinkel.
Schräg von oben ist der Winkel bei dem man noch was erkennen kann größer 
als von unten, links/rechts soll der nach Datenblatt gleich sein.
Wenn man das etwa an einem Prüfstand verbaut ist es von Vorteil, wenn 
man da von schräg oben drauf schaut oder es eben mechanisch umdreht und 
die Anzeige dreht wenn man normalerweise von schräg unten drauf sieht.

von Rade P. (rade_p)


Lesenswert?

Great work,works like a charm using Winavr and atmega328p.Thank you 
Rudolph.But I encounter one small problem that I could not resolve on 
Connect Eve 4,3 bought from Mikroe.com.When printing more then 237 
points
ft800_cmd_point(1, 110, 1);
display freeze,do not start.Any solution or information about this 
problem?

von Rudolph R. (rudolph)


Lesenswert?

Well, short answer, every ft800_cmd_point() uses 16 bytes on the 
co-prozessor FIFO, that are 3792 bytes for 237 ft800_cmd_point().
With the start/end sequence and probably some colors this is more than 
the 4k the FIFO is in size.

It is possible though to squeeze in some more since ft800_cmd_point() is 
not a direct command for the FT8xx, more like a meta-command that I put 
together to make things simpler.
1
void ft800_cmd_point(int16_t x0, int16_t y0, uint16_t size)
2
{
3
  uint32_t calc;
4
5
  ft800_start_cmd((DL_BEGIN | FT_POINTS));
6
7
  calc = POINT_SIZE(size*16);
8
  spi_transmit((uint8_t)(calc));
9
  spi_transmit((uint8_t)(calc >> 8));
10
  spi_transmit((uint8_t)(calc >> 16));
11
  spi_transmit((uint8_t)(calc >> 24));
12
13
  calc = VERTEX2F(x0 * 16, y0 * 16);
14
  spi_transmit((uint8_t)(calc));
15
  spi_transmit((uint8_t)(calc >> 8));
16
  spi_transmit((uint8_t)(calc >> 16));
17
  spi_transmit((uint8_t)(calc >> 24));
18
19
  spi_transmit((uint8_t)(DL_END));    // Send data low byte
20
  spi_transmit((uint8_t)(DL_END >> 8));
21
  spi_transmit((uint8_t)(DL_END >> 16));
22
  spi_transmit((uint8_t)(DL_END >> 24));    // Send data high byte
23
24
  ft800_cs_clear();
25
  ft800_inc_cmdoffset(12);  // update the command-ram pointer
26
}

Apart from the luxury of the all-in-one-go "command" it is however not 
necessary to use the graphics primitves like this.

There is no need to always issue begin/end and there is no need to alwas 
send the point_size(), well except when every point is supposed to be a 
different size. :-)

I can't test this right now because I have no TFT here, but this should 
result in four points with only 28 bytes of the FIFO used instead of 64.
1
      ft800_cmd_dl(DL_BEGIN | FT_POINTS);
2
      ft800_cmd_dl(POINT_SIZE(20*16); // size is in 1/16 pixel
3
      ft800_cmd_dl(VERTEX2F(50*16,100*16); // x/y are in 1/16 pixel
4
      ft800_cmd_dl(VERTEX2F(80*16,100*16); // x/y are in 1/16 pixel
5
      ft800_cmd_dl(VERTEX2F(110*16,100*16); // x/y are in 1/16 pixel
6
      ft800_cmd_dl(VERTEX2F(140*16,100*16); // x/y are in 1/16 pixel
7
      ft800_cmd_dl(DL_END);

I tried this in the screen-designer as well and this displays six 
points:
1
CLEAR(1, 1, 1)
2
BEGIN(POINTS)
3
POINT_SIZE(256)
4
VERTEX2II(96, 78, 0, 0)
5
VERTEX2II(164, 136, 0, 0)
6
VERTEX2II(80, 140, 0, 0)
7
POINT_SIZE(125)
8
VERTEX2II(189, 67, 0, 0)
9
VERTEX2II(135, 218, 0, 0)
10
VERTEX2II(266, 154, 0, 0)
11
END()

Notice that the screen-designer always put this in the list for
every point you drag into the screen:
1
BEGIN(POINTS)
2
VERTEX2II(300, 95, 0, 0)
3
END()

So the meta-commands ft800_cmd_point(), ft800_cmd_rect() and 
ft800_cmd_line() come with the price of some overhead.

: Bearbeitet durch User
von Rade P. (rade_p)


Lesenswert?

Thank you,this solved my problem.
      ft800_cmd_dl(DL_BEGIN | FT_POINTS);
      ft800_cmd_dl(POINT_SIZE(20*16)); // size is in 1/16 pixel
      ft800_cmd_dl(VERTEX2F(50*16,100*16)); // x/y are in 1/16 pixel
      ft800_cmd_dl(VERTEX2F(80*16,100*16)); // x/y are in 1/16 pixel
      ft800_cmd_dl(VERTEX2F(110*16,100*16)); // x/y are in 1/16 pixel
      ft800_cmd_dl(VERTEX2F(140*16,100*16)); // x/y are in 1/16 pixel
      ft800_cmd_dl(DL_END);
Now I can print 940 points maximum and it just work for me.
Thanks again

von peter (Gast)


Lesenswert?

Ich habe eine Frage über die Verbindung
wie zur Verfügung haben FT810CB HY50D
und M644, wenn Sie das Programm versuchen, bekomme ich nur einen weißen 
Bildschirm
was ist falsch?>

von Rudolph R. (rudolph)


Lesenswert?

Also ein weisser Bildschirm ist ziemlich ungewöhnlich.
Damit scheint zumindest die Initialsierung schon mal soweit 
durchzulaufen, dass die Hintergrund-Beleuchtung eingeschaltet wird.

Ist das mit meinem Test_M644_FT810.zip von weiter oben?
Ein weisses Bild deutet auf Anpassungen hin, welche?
Oder ist das ganz neuer Code?

Wie ist der M644 genau verschaltet bei Dir?

Ist die FT800_config.h richtig eingestellt?

Ohne Informationen wird das hier nichts.
Und ein Support-Forum ist das hier auch nicht, etwas Mühe musst Du Dir 
schon geben - und das gilt auch für das abgelieferte Geschreibsel.

von peter (Gast)


Lesenswert?

Hallo
In der Tat, äußerte ein paar präzise
TEST M644 ist so im Voraus eingestellt FT800_config zu HY50D und AVR8

Verbindung zum LCD

GND - GND
5V - 5V
MISO - PB6
SCK - PB7
CS - PB4
MOSI - PB5
PD - PB3
INT - PB2

F_CPU 16MHz
ATmega 644

Ich habe auf verschiedene Weise versucht, leider, erreicht nur einen 
weißen Bildschirm
Nichts anderes zeigt
auf dem Bildschirm ... manchmal ist dieser Effekt, dass das trübe Licht 
nach einer Weile und grau ist,

Ich habe auch versucht die FT811 auch mit 5 "LCD dachte ich, dass etwas 
nicht in Ordnung ist und vielleicht beschädigt sind, aber die mbed zu 
betreiben beide Nucleo

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

Okay, German is not your native language, no problem.
But please refrain from sending text thru a translator, thank you.

And please also provide some source-code that can be checked for erros.
Preferably in a project that can be build.

In the meantime I modified my example from above a little, please check 
if that works.

In addition, check if your controller really is running at 16 MHz.
Is the crystal really activated? Is the CKDIV8 fuse off?

von peter (Gast)


Angehängte Dateien:

Lesenswert?

Hi

I'm sorry for the google translator, I do not speak German
Annex setting fusebits. I use AS7.790 Atmel Tolchain

I downloaded the program and I have uploaded to the microcontroller
the effect on the screen

ATmega 644 is working properly at 16Mhz CKdiv8 Off

Thank you for your help.

von peter (Gast)


Angehängte Dateien:

Lesenswert?

Compilation proceeds without errors

von peter (Gast)


Lesenswert?

Thank you very much for help

it turned out that my ATmega is defective
I mentioned the new and everything works properly

Thanks again for your help
Excellent work with the library

von Rudolph (Gast)


Lesenswert?

I am still perplexed about the white screen, that shouldn't even be 
possible.

A few observations though.

You have the M644 running at 3,3V.
-> 16MHz is out of spec then
-> the HY50D expects 5V as supply and on the SPI

You are using ISP with the M644 so there might be a conflict
with the attached programmer.

If you already use 5V as supply for the FT810CB-HY50HD, is this supply 
stable and does it deliver enough current?
The specifications for the FT810CB-HY50HD can be called weak at best but 
the 5V supply should be at least able to supply 200mA.

And if you are using 5V for the FT810CB-HY50HD, there should be an 
additional level-shifter in place.

So at first I would supply 5V to the M644 as well, given that the
rest of the board is fine with it.

von Rudolph (Gast)


Lesenswert?

peter schrieb:
> it turned out that my ATmega is defective
> I mentioned the new and everything works properly

Oh, that went a bit in parallel. :-)

If this new M644 is still running at 3.3V it might not live that long. 
:-)

von peter (Gast)


Lesenswert?

Hi

ATmega 644 runs on 5V
I am available to 2000mA so enough power
Disconnect the LCD for programming.

For some reason, it is damaged and PB2 PB7 in the microcontroller, 
strange because
He is giving the program and LCD Nokia 3310 worked, but Analaizator 
Logical showed, however, that the SPI is not working properly ...

Fortunately, a new working properly and mute any problems :)
So once again thank you for your help.

von Torsten C. (torsten_c) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo Rudolph,

wie Du im anderen Thread schon gelesen hast, arbeite ich aktuell mit 
einem A137 TouchTFT 320x240[1]. Ich finde aber Deine Lib sehr 
interessant, obwohl ich noch nicht ganz verstanden habe, wie sich diese 
von den anderen Libs, z.B. [2], [3] oder [4] abgrenzt.

Magst Du Deine Lib auf ein GIT Oder SVN einstellen?

Ich würde mein Display [5] gern über die gleiche API (daher der 
Interface-Lolli im Bild) ansprechen, über die ich auch eine Lib für das 
A137 anspreche.

BTW: Um zu vergleichen, ob sich beide Displays über das SW-Interface 
wirklich gleich verhalten, hatte ich mir überhaupt nur das [5] gekauft.

[1]
https://github.com/TorstenC/A137_TouchTFT_320x240
[2]
http://www.ftdichip.com/Support/Documents/AppNotes/AN_318_Arduino_Library_For_FT800_Series.pdf
[3]
http://www.ftdichip.com/Support/SoftwareExamples/FT800_Projects.htm
[4]
https://github.com/guillaumesmo/FT800
[5]
ebay 172251933809

von Rudolph R. (rudolph)


Lesenswert?

Torsten C. schrieb:
> obwohl ich noch nicht ganz verstanden habe, wie sich diese
> von den anderen Libs, z.B. [2], [3] oder [4] abgrenzt.

Naja, sie ist von mir. :-)
Ich wollte einfach tiefer einsteigen in die Dinger und nicht einfach 
eine fertige Library benutzen.

Meine Library hat zum Beispiel weniger Overhead als die von FTDI.

Es gibt auch noch mehr da draussen, etwa von Glyn oder für das 
Gameduino2.

> Magst Du Deine Lib auf ein GIT Oder SVN einstellen?

Zu diesem Zeitpunkt, nein, ich habe zwar versucht das vorzubereiten 
indem ich die Header entsprechend gestaltet habe, rein praktisch würde 
mir das im Moment aber nichts bringen.

Ich habe da auch gerade einen Studenten dran sitzen der sich damit 
austoben darf in der Firma, ich muss mal schauen was ich davon noch 
alles hier einstellen kann.
Zumindest ein schickeres Beispiel könnte dabei abfallen. :-)

> BTW: Um zu vergleichen, ob sich beide Displays über das SW-Interface
> wirklich gleich verhalten, hatte ich mir überhaupt nur das [5] gekauft.

Ich weiss nicht, was ein "A137" Display ist.
Aber ich habe gerade mal das Datenblatt von dem SSD1325 überflogen und 
der spielt nicht nur in der Kreisliga dagegen, der spielt auch ein 
anderes Spiel.
Das Ding kann gerade mal 128x80 Pixel mit 16 Graustufen und hat kaum 
Hilfsfunktionen.
Der kann auch kein Touch.

Der FT800 ist aus der ersten Generation und kann bis 512x512 Pixel mit 
18 Bit Farben.
Die FT81x können bis 800x600 bei 24 Bit Farben.
Inklusive Touch.

Die FT8xx werden in aller Regel auch nicht mit Pixeln beschrieben, es 
gibt sogar nicht mal die direkte Möglichkeit einzelne Pixel zu setzen.
Es gibt keinen Framebuffer in den man direkt schreiben könnte um etwa 
ein Pixel an Position 155/62 direkt zu manipulieren.

Wenn man ein "Hallo" schreiben will muss man denen nur mitteilen wohin 
und mit welchem der eingebauten Zeichensätze.
Passt einem der Zeichensatz nicht gibt man dem FT8xx einen eigenen.
Danach baut sich der FT8xx das Bild für "Hallo" selber aus den Daten vom 
Zeichensatz zusammen.

Bilder werden in den Speicher des FT8xx geladen und nur referenziert.
In diversen Formaten.

Der Bildaufbau beim FT8xx passiert über eine Liste mit Anweisungen
die der sogenannte Kommando Co-Prozessor abarbeitet.
Eine Einschränkung dabei ist, dass die Liste nur 4096 Bytes lang sein 
kann, eine andere dass man die Liste nicht schneller schicken sollte als 
der Bild-Refresh ist, also typisch 60 Hz.

Also wenn man eine Anwendungs-Schicht schafft für beide Display-Chips, 
dann müsste da drunter der SSD1325 Treiber erheblich mehr tun.
Das ist wie Äpfel mit Toastern zu vergleichen. :-)

Mein bescheuertes Spielplatz-Beispiel kommt übrigens auf 108 Bytes RAM 
Nutzung, mindestens 37 Bytes sind für nichts anderes benutzt als die 
dynamische Interaktion per Touch mit dem TFT.
Natürlich war mir das in dem Beispiel völlig egal, das sind 2,6% von den 
4k die der 90CAN128 an SRAM hat.

von Markus (Gast)


Lesenswert?

Hallo Rudolph,

könntest Du ein Bild hier rein stellen, welches die Fähigkeiten Deiner 
Lib. zeigt? Ich habe kein FT800, aber es wäre vielleicht interessant.

Gruß,
Markus

von Rudolph R. (rudolph)


Lesenswert?

Ein Bild das die Fähigkeiten der Library zeigt macht wenig Sinn.
Das hier ist keine Grafik-Library für dumme Pixel-Displays die Funktion 
ft800_cmd_line() zum Beispiel berechnet nicht Punkt für Punkt jeden 
Pixel zwischen zwei Punkten.

Die FT8xx sind quasi Grafik-Karten für MikroController, gibt man denen 
den Auftrag zwischen zwei Punkten eine Linie zu ziehen, dann machen die 
das selbstständig - mit Anti-Aliasing.

Diese Library hier macht "nur" die vorhandenen Funktionen der FT8xx 
leichter zugänglich, statt sowas hier "von Hand" über den SPI zu 
schicken:

0x0c 0xff 0xff 0xff
0xc8 0x00 0xc8 0x00
0x1a 0x00 0x00 0x00
0x48 0x61 0x6c 0x6c
0x6f 0x00 0x00 0x00

Kann man das hier schreiben:
ft800_cmd_text(200, 200, 26, 0, "Hallo");

Eine Übersicht was die FT8xx können findet sich in den Datenblättern 
sowie auf der Homepage von FTDI.

Ein Anhaltspunkt ist vielleicht noch meine FT800_commands.h.
Neben den Wrapper-Funktionen für die FT8xx Kommandos gibt es auch noch 
Support-Funktionen wie ft800_init(), ft800_busy() und 
ft800_get_touch_tag().

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Rudolph R. schrieb:
> Also wenn man eine Anwendungs-Schicht schafft für beide Display-Chips,
> dann müsste da drunter der SSD1325 Treiber erheblich mehr tun.

Ja. Meine Projektidee ist, die FT800-Funktionalität in SW auf einem 
STM32 zu realisieren (FT8xxx.png: Rechts in der Mitte) und über eine 
identische API (FT8xx.h) wahlweise den FT800 oder die Lib für den STM32 
anzusprechen.

Ziel ist:
Im Ergebnis verhalten sich beide Systeme gleich, hinter der API.

Rudolph R. schrieb:
> Ich weiss nicht, was ein "A137" Display ist.

Das war auch nur ein Beispiel, da billig und mit Touch, siehe
Beitrag "A137 Touch TFT 320 x 240 für 3€"

> Aber ich habe gerade mal das Datenblatt von dem SSD1325 überflogen …
Das wäre OLED, kein TFT und hat - wie Du selbst schreibst - kein Touch.

Rudolph R. schrieb:
>> Magst Du Deine Lib auf ein GIT Oder SVN einstellen?
> Zu diesem Zeitpunkt, nein …

Deine API sieht recht 'angenehm programmierbar' aus, daher liegt es 
nahe, sie für so ein Projekt zu branchen. Irgendwann laufen sie dann 
natürlich auseinander.

von Rudolph R. (rudolph)


Lesenswert?

Torsten C. schrieb:
> Ziel ist:
> Im Ergebnis verhalten sich beide Systeme gleich, hinter der API.

Der Sinn der Übung erschliesst sich mir nicht wirklich.
Eine Grafik-Lib zu erweitern das die auch den FT8xx untersüttzt würde 
irgendwie mehr Sinn ergeben.

> Das war auch nur ein Beispiel, da billig und mit Touch, siehe
> Beitrag "A137 Touch TFT 320 x 240 für 3€"

Ah, okay, FD5408 Display-Controller mit Parallel-Interface.
Der kann soweit auch nichts, ebenfalls kein Touch.
Das Display hat eine 4-Draht Resistiv Touch Folie drauf die man selber 
auswerten muss.

> Deine API sieht recht 'angenehm programmierbar' aus,

Nochmal, das sind mehr Wrapper-Funktionen für die Funktionalität vom 
Chip.
Das ist einerseits ziemlich dicht am Datenblatt, zum anderen bin ich 
auch noch nicht wirklich mit dem Ergebnis zufrieden.

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Rudolph R. schrieb:
> … zum anderen bin ich
> auch noch nicht wirklich mit dem Ergebnis zufrieden.

Womit zum Beispiel?

> Der Sinn der Übung erschliesst sich mir nicht wirklich.

Ich erwarte nicht, dass das jemand die Übung toll findet.
Es ist ein Vorschlag bzw. die Idee zur Wiederverwendung,
also Deinen 'wrapper' als Quasi-Standard-API zu nutzen.

Trotzdem zum besseren Verständnis ein Beispiel:
Nimm eine Schüler-Arbeitsgemeinschaft, bei der Du die Kinder von 'nicht 
reichen' Eltern nicht benachteiligen willst. Mit wenigen Original 
30€-FT800CB-HY43B können einige Schüler ihre GUI-Programme gegen die API 
programmieren und testen, wärend die anderen Schüler dafür sorgen, dass 
später alle ein Billig-LCD nehmen können.

> Das Display hat eine 4-Draht Resistiv Touch Folie drauf die man selber
> auswerten muss.
Richtig, ein STM32 hat aber A/D-Umsetzer eingebaut.

: Bearbeitet durch User
von Rudolph R. (rudolph)


Lesenswert?

Torsten C. schrieb:
>> auch noch nicht wirklich mit dem Ergebnis zufrieden.
>
> Womit zum Beispiel?

Mir gefällt zum Beispiel der "FT800_" Präfix noch nicht so richtig.
Zum einen bin ich aktuell mit einem FT813 unterwegs, zum anderen wird 
das nicht mal durchgängig verwendet, weil ich einen Teil der Includes 
von FTDI übernommen habe.

"FT8_" wäre eine Idee das zu lösen, dann würde das auch zu einem 
potentiellen FT821 passen den es noch nicht gibt. :-)

>> Der Sinn der Übung erschliesst sich mir nicht wirklich.
>
> Ich erwarte nicht, dass das jemand die Übung toll findet.
> Es ist ein Vorschlag zur Wiederverwendung,
> also Deinen 'wrapper' als Quasi-Standard-API zu nutzen.
>
> Trotzdem zum besseren Verständnis ein Beispiel:
> Nimm eine Schüler-Arbeitsgemeinschaft, bei der Du die Kinder von 'nicht
> reichen' Eltern nicht benachteiligen willst. Mit wenigen Original
> 30€-FT800CB-HY43B können einige Schüler ihre GUI-Programme gegen die API
> programmieren und testen, wärend die anderen Schüler dafür sorgen, dass
> später alle ein Billig-LCD nehmen können.

Auch für den Fall würde ich das anders herum machen.
Eine Funktion mit den Namen FT800_cmd_text() macht doch weniger Sinn als 
eine Funktion tft_text() die wahlweise das eine der das andere macht.

Was ist mit so Libraries wie u8lib oder ucglib?
Ist die API da so hässlich, dass man das neu machen muss?
Ich weiss es nicht, bisher habe ich sowas nicht benötigt.

Grundsätzlich liegen da auch Welten zwischen den Dingern in der 
Performance.
Wie ist das, man braucht drei Transfers bei dem billig Display für einen 
Pixel? Das sind dann 256 Transfers für einen 16x16 Pixel Buchstaben.
Dazu noch die notwendige Adressierung.

https://www.mikrocontroller.net/attachment/291101/VM800B35_FT800_1.JPG

Das ist auf einem 3,5" 320x240 TFT mit resistiv Touch.
-40 Bilder pro Sekunde
-das "12345" ist eine Tastatur, bei Betätigung wird ein zusätzlicher 
grüner Kreis gemalt in unterschiedlichen Größen
-die großen Bilder werden bei Touch-Events sofort getauscht
-das Ding unter der "TAG: 0" Ausgabe ist ein Fortschrittsbalken der 
durchläuft
-mit dem Slider ganz unten kann man den kompletten restlichen 
Bild-Inhalt links/rechts verschieben (VM800B35_FT800_4.JPG)
-betätigt man den Toggle-Button der im Bild auf "aus" steht werden 
sofort die grossen Bilder gegen einen Rotary-Dial und eine Gauge 
getauscht
-das Bild mit den kleinen Quadraten fängt an sich zu drehen - gefiltert

Und so weiter, die Bilder werden dem nicht mal ansatzweise gerecht, 
dabei "reserviere" ich 25% Rechenleistung eines 8-Bit AVR auf 16 MHz, 
genuzt wird nur ein kleiner Teil davon.
Der SPI läuft dabei auch "nur" auf 8 MHz - der AVR kann eben nicht mehr 
als 1/2 Takt.

Damit dürfte auch ein STM32 ins Schwitzen kommen mit dem billig TFT, das 
ganze notwenige Gefummel mit den Portpins ist ja sowieso schon keine 
Stärke der ARMs, in Summe dürfte das tödlich sein.

Die "Spirale" die gedreht wird hat 64x64 Pixel.
Das sind >12k Schreibzugriffe für das $3 Display.
Gedreht wird in 1,4° Schritten mit einfachem Anti-Aliasing.
Die Auflösung wäre 1/65536 Teile eines Kreises aber ich addiere 40 Mal 
pro Sekunde 256.

Die größeren Bilder haben 96x96 Pixel.

Also "nicht benachteiligen" ist ja richtig, man kann für die 3$ aber 
nicht mal ansatzweise zum gleichen Ergebnis kommen.

Ein Grund für mich das hier öffentlich zu machen ist die FT8xx damit zu 
supporten.
In der Hoffnung, dass die irgendwann billiger zu haben sind.

Das günstigste mir bekannte ist das FT800CB-HY43B mit FT800, 4,3" mit 
480x272 Pixeln für $25.
Dem vorziehen würde ich aber das FT800CB-HY50B mit 5" für $28.

Und so richtig gut sind die auch nicht, der Blickwinkel ist etwas klein.

Also nicht benachteiligen wäre eher, jedem das gleiche zu geben.
Und zwischen dem $3 und einem TFT mit FT800 muss es auch noch was geben 
das zwar immer noch einfach und preiswert aber deutlich performanter 
ist. :-)

>> Das Display hat eine 4-Draht Resistiv Touch Folie drauf die man selber
>> auswerten muss.
> Richtig, ein STM32 hat aber A/D-Umsetzer eingebaut.

Die AD-Werte sind eine Sache, das bekommt man auch mit einem AVR hin.
Dann muss man daraus noch Koordinaten berechnen und heraus finden, 
welches Objekt überhaupt an den Koordinaten liegt.
Man müsste für jedes Objekt das touchbar sein soll zwei Kordinaten 
speichern die ein Rechteck aufspannen.

Der FT8xx könnte sogar per Interrupt melden wenn getoucht wird - und 
zwar was genau.
Da ich die Abfrage per pollen 40 Mal pro Sekunde einfach nebenbei machen 
kann, ist mir das mit dem Interrupt aber zu albern.

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Danke, Rudolph, für Deine ausführlichen Antworten. Ich will Deinen 
Thread auch nicht weiter mit diesem "Exkurs" verwässern.

Präfix "FT800_" oder "FT8_" ist ja schon "jammern auf hohem Niveau". Ich 
dachte, Du siehst essentielle Probleme. Gut. Die ucglib schaue ich mir 
an, nochmal danke.

Rudolph R. schrieb:
> … man braucht drei Transfers bei dem billig Display für einen Pixel? …
Ja, es sind drei Transfers á 8 Bits.
> Damit dürfte auch ein STM32 ins Schwitzen kommen mit dem billig TFT, das
> ganze notwenige Gefummel mit den Portpins ist ja sowieso schon keine
> Stärke der ARMs, …
Mit nWR und nRD über Timer und Daten über PB0..7 und DMA läuft der 
Transfer im Hintergrund, ohne die CPU zu belasten.

> Also "nicht benachteiligen" wäre eher, jedem das gleiche zu geben.
Das FT800CB-HY43B ist nur für die "Design-Time",
nicht für die "Run-Time".

Um bei dem oben genannten Beispiel zu bleiben: Das bzw. die 
FT800CB-HY43B werden anschließend natürlich wieder eingesammelt.

> … man kann für die 3$ aber nicht mal ansatzweise zum gleichen Ergebnis
> kommen.
Das wird sich zeigen. Vielleicht wirst Du Recht haben.
Ich würde aber trotzdem gern ein proof-of-concept umsetzen.

Ich sehe gerade:
Den Sound Synthesizer hatte ich noch gar nicht auf dem Schirm. :-(

> … 40 Bilder pro Sekunde …
> Die "Spirale" die gedreht wird hat 64x64 Pixel. …
Gute Beispiele, die man für einen Performance-Vergleich nutzen sollte.
40 Bilder pro Sekunde wird der STM32 mit 3€-TFT nicht schaffen, aber 15 
Bilder pro Sekunde wären auch noch halbwegs ruckelfrei.

Rudolph R. schrieb:
> Dem vorziehen würde ich aber das FT800CB-HY50B mit 5" für $28.

Habe ich weder in der Bucht noch bei Ali für den Preis gefunden.
Hast Du einen Link?

: Bearbeitet durch User
von Markus (Gast)


Lesenswert?

>Das ist auf einem 3,5" 320x240 TFT mit resistiv Touch.
Das hier hat die gleich Auflösung, ist aber ein wenig klein:

Beitrag "Re: 2.2'TFT ILI9340 und Arduino"

 Torsten C. (torsten_c) Benutzerseite
>Ich erwarte nicht, dass das jemand die Übung toll findet.
>Es ist ein Vorschlag bzw. die Idee zur Wiederverwendung,
>also Deinen 'wrapper' als Quasi-Standard-API zu nutzen.

Ich finde Deine Übung gut. Es macht ziemlich viel Sinn, einen Wrapper 
für verschiedene TFTs zu schreiben. Dann kann man das TFT einfach 
austauschen.
Ich würde aber den Prefix für die Funktionen nicht FT800 nennen, sondern 
eher was allgemeines wie z.B. TFT_drawLine(..) o.ä.

von Werner (Gast)


Lesenswert?

Hallo Rudolph,

hast du schon mal mit den Schriftgrößen 32-34 gearbeitet?
Ich komme irgendwie nicht daruf, wie ich die Ansteuerun muß.
Werner

von Rudolph R. (rudolph)


Lesenswert?

Ich habe die noch nicht benutzt, in meinem aktuellen Projekt mit dem 
RVT70UQFNWC00 hätte ich eher noch einen kleineren unter 26 gebraucht. 
:-)

Aber nach FT81X_Series_Programmer_Guide.pdf ist das eigentlich ganz 
einfach.
Man benutzt CMD_ROMFONT um ein Bitmap-Handle auf einen der Fonts zu 
setzen und gibt das dann bei CMD_Text mit an:

cmd_romfont(1, 31);
cmd_text( 0, 0, 1, 0, "31");
cmd_romfont(1, 32);
cmd_text( 0, 60, 1, 0, "32");
cmd_romfont(1, 33);
cmd_text(80,-14, 1, 0, "33");
cmd_romfont(1, 34);
cmd_text(60, 32, 1, 0, "34");


Ich muss auch mal wieder ein Update machen, auch wenn das jetzt keine 
gravierenden Änderungen gab bisher.

Das Beispiel kann ich auch mal überarbeiten, ich teile mein Layout jetzt 
in einen statischen und einen dynamischen Teil auf,
der statische Teil wird nur einmal übertragen und dann mit CMD_APPEND 
immer wieder in die aktuelle Liste gehängt - das spart je nach Layout 
ordentlich was an Übertragungen auf dem SPI.
Mein aktuelles Projekt ist ein Stand-alone Test-System, da werden 
diverse Messwerte ausgegeben, drei Slider und ein Toggle-Button als 
Bedien-Elemente.
Der ganze sonstige Text, einige Linien, ein Logo, farbige Flächen, das 
ist alles statisch, machen aber mehr als 2/3 der Daten aus die ohne 
CMD_Append immer mit über den SPI geschickt werden müssten.

von Werner (Gast)


Lesenswert?

Hallo Rudolph,
danke für deine schnelle Antwort. Ich bin inzwischen auch dahinter 
gekommen und habe folgende Funktion in deine Lib eingefügt:

void ft800_cmd_romfont(uint32_t font, uint32_t romslot)
{
  ft800_start_cmd(CMD_ROMFONT);

  spi_transmit((uint8_t)(font));    // Send data low byte
  spi_transmit((uint8_t)(font >> 8));
  spi_transmit((uint8_t)(font >> 16));
  spi_transmit(0x00);
  spi_transmit((uint8_t)(romslot));  // Send data low byte
  spi_transmit((uint8_t)(romslot >> 8));
  spi_transmit((uint8_t)(romslot >> 16));
  spi_transmit((uint8_t)(romslot >> 24));

  ft800_inc_cmdoffset(8);  // update the command-ram pointer
  ft800_cs_clear();

}

Benutzt du eigentlich den ScreeDesigner von FTDI?
Ich mach momentan Macros, damit die Ausgaben vom ScreenDesigner 
möglichst 1zu1 übernommen werden können.

Werner

von Rudolph (Gast)


Lesenswert?

Ups, stimmt, es gibt in der veröffentlichten Version noch gar kein 
ft800_cmd_romfont() :-)
1
#ifdef FT_81X_ENABLE
2
void ft800_cmd_romfont(uint32_t font, uint32_t romslot)
3
{
4
  ft800_start_cmd(CMD_ROMFONT);
5
  
6
  spi_transmit((uint8_t)(font));
7
  spi_transmit((uint8_t)(font >> 8));
8
  spi_transmit(0x00);
9
  spi_transmit(0x00);
10
  
11
  spi_transmit((uint8_t)(romslot));
12
  spi_transmit((uint8_t)(romslot >> 8));
13
  spi_transmit(0x00);
14
  spi_transmit(0x00);  
15
  
16
  ft800_inc_cmdoffset(8);
17
  ft800_cs_clear();
18
}
19
#endif

Also kein wesentlicher Unterschied. :-)

Den Screen-Editor benutze ich im Moment nicht, ich hatte mal angefangen 
das Python-Script von Glyn umzuschreiben.
Nur habe ich bisher weder was mit Python gemacht, noch war der 
Leidensdruck das zu tun hoch genug. :-)

von Thomas (Gast)


Lesenswert?

Hallo zusammen,
in der Hoffnung, dass mir jemand weiter helfen kann poste ich unten 
folgenden (kleinen) code der im Prinzip von Rudolf übernommen wurde.
Das Problem was ich habe ist, dass ich einfach nicht die chipid 0x7C 
zurück bekomme. Der Wert den ich am Anfang zurück bekomme ist immer 0, 
nach einigen Millisekunden 255.

Was mache ich falsch? ich bin langsam am Verzweifeln.
Ich verwende Arduino Teensy 3.6 180MHz und das HAOYU FT811CB Display.
(Vielleicht klappt der code ja bei Eurem Display)

Vielen Dank für eure Hilfe im Voraus.

LG

Thomas


#include <SPI.h>

#define ACTIVE  0x00  // Place FT800 in active state
#define CLKEXT  0x44  // Select external clock source
#define CLK48M  0x62  // Select 48MHz PLL output

#define REG_ID        0x102400UL
#define REG_PWM_DUTY  0x1024c4UL

#define MEM_WRITE 0x80  // FT800 Host Memory Write
#define MEM_READ  0x00  // FT800 Host Memory Read

#define intPin 6
#define pdnPin 7
#define csPin 10

void ft800_cmdWrite(uint8_t data)
{
  digitalWrite(csPin,LOW);
  SPI.transfer(data);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
  digitalWrite(csPin,HIGH);
}

uint8_t ft800_memRead8(uint32_t ftAddress)
{
  uint8_t ftData8 = 0;
  digitalWrite(csPin,LOW);
  SPI.transfer((uint8_t)(ftAddress >> 16) | MEM_READ);
  SPI.transfer((uint8_t)(ftAddress >> 8));
  SPI.transfer((uint8_t)(ftAddress));
  SPI.transfer(0x00);
  ftData8 = SPI.transfer(ftData8);
  digitalWrite(csPin,HIGH);
  return ftData8;
}

void setup() {

  pinMode(intPin,INPUT);
  pinMode(csPin,OUTPUT);
  pinMode(pdnPin,OUTPUT);
  digitalWrite(csPin,HIGH);
  digitalWrite(pdnPin,HIGH);

  Serial.begin(9600);
  delay(500);
  SPI.begin();
  delay(500);
  SPI.beginTransaction(SPISettings(5000000, MSBFIRST, SPI_MODE0));
  delay(500);

  digitalWrite(pdnPin,LOW);
  delay(6);
  digitalWrite(pdnPin,HIGH);
  delay(21);

  ft800_cmdWrite(CLKEXT);
//  ft800_cmdWrite(FT_CLK48M);
  ft800_cmdWrite(ACTIVE);

  byte chipid = ft800_memRead8(REG_ID);
  while(chipid != 0x7C)
  {
    Serial.println(chipid);
    chipid = ft800_memRead8(REG_ID);
  }
  Serial.println("chipID is 0x7C");
}

void loop() {
}

von Rudolph R. (rudolph)


Lesenswert?

Thomas schrieb:
> #define REG_ID        0x102400UL

Für den FT811 wäre das aber:
#define REG_ID 3153920UL

Warum übernimmst Du nicht einfach den kompletten Code?

Das ist ja nicht ganz grundlos im wesentlichen portierbar gehalten und 
läuft auch ohne Probleme mit Arduino. :-)

Ja, ich muss mal wieder ein Update posten, ist in Arbeit. :-)

von here (Gast)


Lesenswert?

Rudolph R. schrieb:
> Der SPI ist auf 8 MHz eingestellt, mehr geht mit den AVR nicht.
> Wenn man das an einem schnelleren Controller verwendet ist zu beachten,
> dass der SPI beim Aufruf der ft800_init() noch langsamer als 11 MHz
> eingestellt sein muss, danach darf der dann bis 30MHz laufen.

@Thomas:
Wie ist Deine SPI-Frequenz? 5 MHz?
Hast Du mal mit dem Scope nachgemessen?

von Rudolph R. (rudolph)



Lesenswert?

Okay, hier mal das Update.

Das Archiv enthält ein Atmel-Studio 7 Projekt für einen 90CAN64.
Das benutzte TFT ist ein RVT70UQFNWC0x von Riverdi mit einem FT813 
drauf.

FT800.h version 2.2
FT800_commands.c version 2.4
FT800_commands.h version 2.3
FT800_config.c version 2.5
FT800_config.h version 2.5

Die "Spielplatz" Anwendung habe ich durch ein etwas ernster gemeintes 
Beispiel ersetzt. :-)

main.c - AVR spezifisch, macht aber kaum was

tft.c / tft.h - Plattform unabhängig, hier wird das TFT bedient
tft_data.c / tft_data.h - nur ein einfaches Logo als Beispiel-Bild

Im Moment läuft in der Mitte einfach nur eine Uhr durch, da wollte ich 
eigentlich eine Stoppuhr mit Start/Stop und Reset Button draus machen.
Und Rechts sind nur einmal die eingebauten Zeichensätze dargestellt, 
Nummer 17 und 19 sind übrigens spezielle Fonts mit Symbolen.

Für ernst gemeinte Vorschläge was man in der Mitte und Rechts 
demonstrieren könnte bin ich aber durchaus offen. :-)

Ach ja, das Beispiel demonstriert auch die Verwendung von 
ft800_cmd_append().
Die Anzeige ist jetzt aufgeteilt in einen statischen Teil der in der 
Funktion initStaticBackground() nur ein einziges Mal im Speicher des 
FT81x erzeugt wird und einen deutlich kleineren dynamischen Teil der in 
der Funktion FTF_loop() erzeugt wird.
Auf die Art müssen erheblich weniger Daten über den SPI geschickt 
werden.

von Thomas (Gast)


Lesenswert?

Hallo Rudolph,

danke das hat das Problem gelöst. Vielen vielen Dank!!!

Schöne Weihnachten!

LG

Thomas

von Paweł P. (Firma: none) (pawcuq)


Lesenswert?

Hello Rudolph,

many thanks for your library, it's great! Do you happen to know how to 
display JPEG image which size is greater than 4kB FIFO (is it even 
possible)?

Best regards,
Paweł.

von Rudolph R. (rudolph)


Lesenswert?

Yes, loading images larger than the size of the FIFO is possible, and I 
already have code for it that a colleague of mine provided.
I only did not have much use for it so I did not evaluate it properly so 
far.

What is needed is to extend ft800_cmd_loadimage() to handle buffers that 
are larger than 4k in chunks of a little less than 4k.
It's like this:
start-command
send 4k data
execute
wait
send 4k data
execute
wait
send remaining data
execute
done

On FT810/FT811/FT812/FT813 however ft800_cmd_mediafifo should be the 
better option, you reserve for example the upper 64k of gfx-mem, put 
your data there and then tell loadimage to load its data from there.

Although I very much prefer FT81x, I did not test this either so far.

von Paweł P. (Firma: none) (pawcuq)


Lesenswert?

Thanks Rudolph for your reply. I tried to implement your suggestions on 
FT800 using project which you provided. When I load only one JPG file to 
FTDI main RAM memory:

  ft800_cmd_loadimage(0, FT_OPT_NODL, sam, 3708);
  ft800_cmd_execute();
  while(ft800_busy() == 1);

then I can display that image multiple times on my screen and everything 
works just fine as I want (that's how I do it - correct me please if I'm 
doing something wrong):

  ft800_cmd_dl(CMD_DLSTART);
  ft800_cmd_dl(DL_CLEAR_RGB | GREEN);
  ft800_cmd_dl(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG);

  ft800_cmd_dl(DL_BEGIN | FT_BITMAPS);
  ft800_cmd_dl(BITMAP_SOURCE(0));
  ft800_cmd_dl(BITMAP_LAYOUT(FT_RGB565,96*2,96));
  ft800_cmd_dl(BITMAP_SIZE(FT_NEAREST,FT_BORDER,FT_BORDER,96,96));
  ft800_cmd_dl(VERTEX2II(0,0,0,0));

  ft800_cmd_dl(DL_BEGIN | FT_BITMAPS);
  ft800_cmd_dl(BITMAP_SOURCE(0));
  ft800_cmd_dl(BITMAP_LAYOUT(FT_RGB565,96*2,96));
  ft800_cmd_dl(BITMAP_SIZE(FT_NEAREST,FT_BORDER,FT_BORDER,96,96));
  ft800_cmd_dl(VERTEX2II(96,0,0,0));

        ft800_cmd_execute();
  while(ft800_busy() == 1);

        ft800_cmd_dl(DL_DISPLAY);
        ft800_cmd_dl(CMD_SWAP);
  ft800_cmd_execute();

But when I try to load another JPG:

  ft800_cmd_loadimage(0, FT_OPT_NODL, sam, 3708);
  ft800_cmd_execute();
  while(ft800_busy() == 1);

  ft800_cmd_loadimage(3709, FT_OPT_NODL, jpg3, 2488);
  ft800_cmd_execute();
  while(ft800_busy() == 1);

and then when I try to display it:

  ft800_cmd_dl(CMD_DLSTART);
  ft800_cmd_dl(DL_CLEAR_RGB | GREEN);
  ft800_cmd_dl(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG);

  ft800_cmd_dl(DL_BEGIN | FT_BITMAPS);
  ft800_cmd_dl(BITMAP_SOURCE(0));
  ft800_cmd_dl(BITMAP_LAYOUT(FT_RGB565,96*2,96));
  ft800_cmd_dl(BITMAP_SIZE(FT_NEAREST,FT_BORDER,FT_BORDER,96,96));
  ft800_cmd_dl(VERTEX2II(0,0,0,0));

  ft800_cmd_dl(DL_BEGIN | FT_BITMAPS);
  ft800_cmd_dl(BITMAP_SOURCE(3709));
  ft800_cmd_dl(BITMAP_LAYOUT(FT_RGB565,96*2,96));
  ft800_cmd_dl(BITMAP_SIZE(FT_NEAREST,FT_BORDER,FT_BORDER,96,96));
  ft800_cmd_dl(VERTEX2II(96,0,0,0));

        ft800_cmd_execute();
  while(ft800_busy() == 1);

        ft800_cmd_dl(DL_DISPLAY);
        ft800_cmd_dl(CMD_SWAP);
  ft800_cmd_execute();

It displays second image just fine but the first image is a mixed 
combination of first and second JPG (here's photo - 
https://s24.postimg.org/v2ngd1cw5/FT800.jpg). I noticed that in your 
project you load JPGs to certain memory locations and if I change jpg4 
address from 18432 to another e.g 4000 - I get same mixed JPGs result. 
Is there any rule at which locations I should load different JPGs? I'm 
using project which you uploaded on 18.08.2016 23:40.

von Rudolph R. (rudolph)


Lesenswert?

The problem is that cmd_loadimage() is unpacking the JPG to the given 
memory location, not storing the data you feed it.
With FT_RGB565 format the space necessary is 2 byte per pixel.

That is why my "Spielplatz" = playground example is using lines like 
these:
[code]
ft800_cmd_loadimage(74000 + (8192 * 0), FT_OPT_NODL, blitz, 1638);
...
ft800_cmd_loadimage(74000 + (8192 * 1), FT_OPT_NODL, figure, 2314);
...
ft800_cmd_loadimage(74000 + (8192 * 2), FT_OPT_NODL, frog, 1639);
...
ft800_cmd_loadimage(74000 + (8192 * 3), FT_OPT_NODL, map1, 2476);
[code]

von Paweł P. (Firma: none) (pawcuq)


Lesenswert?

Thanks Rudolph for your explanation, now I get it :)

von Paweł P. (Firma: none) (pawcuq)


Lesenswert?

Hi Rudolph,

have you managed to get PNG-8 files displayed right? With JPG there's no 
problem but when I load PNG-8 (using the same method as described 
before) on my FT810, I just get black screen with some artifacts. Here's 
my image - https://s29.postimg.org/fwdd8wcyv/7_8.png/.

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

I believe that I tried it before and that it worked but now I am not so 
sure anymore.
I just used paint to pixel the attached image and it's not working.
1
#define MEM_PIC1 0x00000900 /* start of 100x100 pixel test image, needs 20000 bytes of memory */
2
3
ft800_cmd_loadimage(MEM_PIC1, FT_OPT_NODL, pngpic, 1572);
4
ft800_cmd_execute();
5
while(ft800_busy() == 1);
1
ft800_cmd_dl(DL_BEGIN | FT_BITMAPS);
2
ft800_cmd_setbitmap(MEM_PIC1, FT_RGB565, 100, 100);
3
ft800_cmd_dl(VERTEX2F((LAYOUT_X2 + ((LAYOUT_W - 100) / 2)) *16, 380*16));
4
ft800_cmd_dl(DL_END);

The result is odd, the colors are completely wrong and there are two
stars next to each other with half the resolution.

Right now I have no idea what the problem is.

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

Okay, the picture itself was the problem.
The FT81x only supports bit-depth 8 for .png.
I knew that and setup the image to use 256 colors although the palette 
only had six entries.
Still, somehow this does not work and interestingly the first file I 
uploaded even automatically got converted thru µc.net. :-)

To increase the amount of colors in use I used a blur filter which also 
more than doubled the size of the binary.

I guess it highly depends on the images.
But so far I found .jpg to be far better in terms of binary size for 
small pictures.

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

Hmm, the picture above also does not work, at least not after whatever 
µc.net automatically did to it.

Attached is the modified project with the picture added to it.

: Bearbeitet durch User
von Paweł P. (Firma: none) (pawcuq)


Lesenswert?

Hi Rudolph, I've solved my PNG problem (they were Palleted not RGB) and 
with PNG files less than 4kB there is no problem. Did you try to display 
image which is >4kB using mediafifo and load whole image at once? I've 
got problem with that. Thanks for your help!

von Rudolph (Gast)


Angehängte Dateien:

Lesenswert?

I did not really check that so far, but now I did. :-)

First thing I noticed is that cmd_loadimage() needed to be improved to 
not send any daten in case FT_OPT_MEDIAFIFO is given.

Next I had to add a function to copy directly to the memory of the 
FT8xx.

And using it within my last test-example from above:
1
...
2
/* memory-map defines */
3
...
4
#define MEM_FIFO 0x000ef000 /* start of buffer for MEDIA-FIFO, total of 64k with the following list-buffer */
5
#define MEM_DL_STATIC 0x000ff000 /* start-address of the static part of the display-list, upper 4k of gfx-mem */
6
...
7
8
/*
9
    ft800_cmd_loadimage(MEM_PIC1, FT_OPT_NODL, pngpic, 3867);
10
    ft800_cmd_execute();
11
    while(ft800_busy() == 1);
12
*/
13
    
14
    ft800_cmd_mediafifo(MEM_FIFO, 0x10000); /* setup media-fifo */
15
    ft800_memWrite_flash_buffer(MEM_FIFO, pngpic, 3867); /* write data directly to memory */
16
    ft800_cmd_loadimage(MEM_PIC1, FT_OPT_NODL+FT_OPT_MEDIAFIFO, 0, 0); /* tell the co-pro to fetch the data from the media-fifo */
17
    ft800_cmd_execute();
18
    while(ft800_busy() == 1);

This is completely untested though.
It compiles fine but I do not have my display right now.

von Rudolph (Gast)


Lesenswert?

Aaand I just noticed it is not exactly correct.
Since ft800_cmd_mediafifo() is a co-prozessor command it needs to be 
executed first to have an effekt.

This should work anyways but it may be wise to use
1
ft800_cmd_mediafifo(MEM_FIFO, 0x10000); /* setup media-fifo */
2
ft800_cmd_execute();
3
while(ft800_busy() == 1);

separately.

von Rudolph R. (rudolph)


Lesenswert?

It's not working at all.
We see it hang after ft800_cmd_loadimage() with FT810 and FT813.
Upon further investigation ft800_cmd_mediafifo() does not seem to do 
anything at all apart from resetting the REG_MEDIAFIFO_READ and 
REG_MEDIAFIFO_WRITE registers to default null.

At least ft800_memWrite_flash_buffer() looks good, we read parts of the 
data back and found it correct.

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

I just implemented a cmd_loadimage() which sends the data in chunks of 
4000 bytes thru the command-fifo. Tested on my FT810 equipped HY50B with 
a 15kb 200x200 pixel .jpg.

Still no idea why CMD_MEDIAFIFO completely fails to work.

von Rudolph R. (rudolph)


Lesenswert?

Oh yes, I had some help with finally getting it done, thx Stefan and 
Cass!

von Paweł P. (Firma: none) (pawcuq)


Lesenswert?

Hi Rudolph! Thanks again for your help and effort, just tested your new 
version of cmd_loadimage and it works flawlessly - tested with 800x480 
40kB PNG ;) If you solve problem with CMD_MEDIAFIFO please let know!

von Rudolph (Gast)


Lesenswert?

This CMD_MEDIAFIFO, well...

Next up would be CMD_INFLATE and the manual does not even mention 
OPT_MEDIAFIFO for it.

And it's overdue to check out SVN and WIKI options here...

von Werner (Gast)


Lesenswert?

Hallo Rudolph,
ich wollte mal deine neuste Version testen, bekomme aber immer einen 
Fehler (implicit declaration of function 'pgm_read_byte_far').
Vielleicht liegt es daran, daß ich mit AVR Studio 6.2 arbeite. Kannst du 
das Projekt mal für das 6.2 Studio reinstellen?
Danke, Werner

von Werner (Gast)


Lesenswert?

Hallo Rudolph,
ich habe den Fehler gefunden, es lag am device, da ich einen ATMega64 
verwende.

von Rudolph R. (rudolph)



Lesenswert?

Annother test-version, again for my 7" Riverdi with 800x480.
I reworked the middle section and replaced the clock with an 
oszilloscope like display utilising a line-strip with 64 points that is 
scrolling when the toggle-button on top is set to "on".

Below that is a bar-display with 16 bars that are 16 pixels wide.

The displays share the same static and limited data for this little 
demonstration.

von Rudolph R. (rudolph)


Lesenswert?

Ich habe mal mit dem Wiki-Artikel dazu angefangen:
https://www.mikrocontroller.net/articles/FT8xx_Library

von Rudolph R. (rudolph)


Lesenswert?

As it turned out, CMD_MEDIAFIFO works, if used correctly.

1
#define MEM_MEDIAFIFO_START 0x000f0000
2
#define MEM_MEDIAFIFO_LEN 0x000f000
3
4
ft800_cmd_mediafifo(MEM_MEDIAFIFO_START,MEM_MEDIAFIFO_LEN);/* init MEDIAFIFO */
5
ft800_cmd_execute();
6
while(ft800_busy()==1);
7
               
8
                ft800_memWrite_flash_buffer(MEM_MEDIAFIFO_START,pngpic,pngpic_size);
9
                ft800_memWrite32(REG_MEDIAFIFO_WRITE,pngpic_size);
10
11
                ft800_cmd_loadimage(MEM_PIC1,FT_OPT_NODL|FT_OPT_MEDIAFIFO,0,0);
12
                ft800_cmd_execute();
13
while(ft800_busy()==1);

First of all, REG_MEDIAFIFO_READ and REG_MEDIAFIFO_WRITE do not contain 
absolute addresses as it is documented in the programmers guide.
These hold offsets.

Then, these work exactly like REG_CMD_READ and REG_CMD_WRITE, so when 
you write data to the FIFO you need to write to REG_MEDIAFIFO_WRITE to 
tell the co-prozessor where your data ends.
And after the co-prozessor is done with the data it updates 
REG_MEDIAFIFO_READ.
Difference is that when writing to that FIFO you have to wrap-around the 
end of it in your own code, this is not done automatically.
With the command-FIFO you only have to take care of your pointer 
eventually.

After init of MEDIAFIFO both REG_MEDIAFIFO_READ and REG_MEDIAFIFO_WRITE 
are set to 0x0000.
And cmd_loadimage() reads that data from MEM_MEDIAFIFO_START + 
REG_MEDIAFIFO_READ to MEM_MEDIAFIFO_START + REG_MEDIAFIFO_WRITE.

This needs a bit of support-code to make things easier, but within a few 
boundaries it works as it is.

von Rafal D. (drzewko)


Angehängte Dateien:

Lesenswert?

Hallo all,
  I have problem with load jpg file but PNG working. When i try load jpg 
file i give empty ( white ) picture. Any ideas?

: Bearbeitet durch User
von Rudolph R. (rudolph)


Lesenswert?

I am a bit out of words here.

- fotos of a monitor instead of screenshots while posting these lines 
would be the obvious thing to do
- manipulated code, no way to know what else is different other then the 
prefix
- no information at all about the system this is running on or the TFT
- no information at all about the images
- no information how the images are displayed
- some rather strange file-sizes

And you still expect someone to guess what is going on in your code?


Is that a FT811CB-HY50HD? Running on what?
Is that JPEG corect? "Regular baseline JPEG (JFIF)" - please attach
Is the geometry of the .jpeg really the same as the .png?

von Rafal D. (drzewko)


Angehängte Dateien:

Lesenswert?

Hallo Rudolph R.

   Yes, my mistake sorry of my photos.

   I use tft FT811CB-HY50HD with ATXmega128a3u. Your code but I changed 
to shorter names like ft800_cmd_dl -> FT_cmd_dl.

- "some rather strange file-sizes"  good but I made a typo kb <-> b. The 
given values are obviously in bytes.

- File is regular baseline JPEG.

  When i load small jpg 100x100px all work but with bigger file not 
work. How to load images with a size of over 4 kb?

Thank you

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

Rafal D. schrieb:
> Your code but I changed to shorter names like ft800_cmd_dl -> FT_cmd_dl.

While I have no objection against you doing that and I am also planning 
on changing the prefix to FT8_ myself, it's still not the same code and 
you have to modify it each time I put out a new version you deem worth 
upgrading to.


Okay, I just converted the two images to .hex and added them to my 
tft_data.c.

Then I modified my tft.c to load these:
1
#define MEM_PIC2 0x00006000 /* start of 100x100 pixel test image, needs 20000 bytes of memory */
2
#define MEM_PIC3 0x0000AF00 /* start of 200x200 pixel test image, needs 80000 bytes of memory */
3
4
...
5
6
ft800_cmd_loadimage(MEM_PIC2, FT_OPT_NODL, work100x100, work100x100_size);
7
ft800_cmd_execute();
8
while(ft800_busy() == 1);
9
10
ft800_cmd_loadimage(MEM_PIC3, FT_OPT_NODL, image2, image2_size);
11
ft800_cmd_execute();
12
while(ft800_busy() == 1);

And then I added them to be displayed:
1
ft800_cmd_dl(DL_BEGIN | FT_BITMAPS);
2
ft800_cmd_setbitmap(MEM_PIC1, FT_RGB565, 100, 100);
3
ft800_cmd_dl(VERTEX2F(20*16, 40*16));
4
5
ft800_cmd_setbitmap(MEM_PIC2, FT_RGB565, 100, 100);
6
ft800_cmd_dl(VERTEX2F(20*16, 160*16));
7
8
ft800_cmd_setbitmap(MEM_PIC3, FT_RGB565, 200, 200);
9
ft800_cmd_dl(VERTEX2F(140*16, 40*16));
10
11
ft800_cmd_dl(DL_END);

So maybe you are just not using the latest FT800_commands.c which would 
be 2.7 from 2017-02-19?

von Rafal D. (drzewko)


Lesenswert?

I did not know how it happened but the header was described 2.7 
2017-02-19 and the old loadimage function.

I updated it and now work it. Thank you for pointing to the problem.

BTW. Have you met for FT811 to blink and freeze?

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

Rafal D. schrieb:
> I did not know how it happened but the header was described 2.7
> 2017-02-19 and the old loadimage function.

Yes, I know I need to move the project to some repository...

> BTW. Have you met for FT811 to blink and freeze?

Not for some time now. :-)
I may happen when you update the list faster than 60hz.



And I am in the process of updating the whole thing to use FT8_ all over 
it instead of FT800_ or FT_.

As a first preview I attached the reworked FT8.h.
I have to admit that it feels inconsistent though, all the CMD_, REG_ 
and macro defines do not have a FT8_ prefix.
Most general defines like the bitmap formats have the FT8_ prefix but 
not all.
I feel it should be FT8_DL_END as well and not just DL_END.
The CMD_ and REG_ defines should be fairly unique already.
Which leaves the macros, these also should have the FT8_ prefix.

Thoughts?

von Rudolph R. (rudolph)



Lesenswert?

Okay, this is 3.0, again as complete project.

I just tested modifying the project myself, I changed all files in a 
different project, then renamed the FT800?.? files to FT8?.?, copied the 
new ones from the other project over them.

And at last I modified tft.c with replacing all ft800_ prefixes with 
FT8_ and most FT_ prefixes with FT8_.

I do not have my RVT70UQFNWC0x based TFT here right now but the project 
compiles fine without warnings.
And my other project works with my FT810 based HY50B.
I am going to test this tomorow morning.

von Rafal D. (drzewko)


Lesenswert?

Add this procedures to custom fonts

void FT_cmd_setfont(uint32_t font, uint32_t ptr)
{
  FT_start_cmd(CMD_SETFONT);

  spi_transmit((uint8_t)(font));
  spi_transmit((uint8_t)(font >> 8));
  spi_transmit((uint8_t)(font >> 16));
  spi_transmit((uint8_t)(font >> 24));

  spi_transmit((uint8_t)(ptr));
  spi_transmit((uint8_t)(ptr >> 8));
  spi_transmit((uint8_t)(ptr >> 16));
  spi_transmit((uint8_t)(ptr >> 24));

  FT8_cs_clear();
  FT_inc_cmdoffset(8);
}

void FT_cmd_setfont2(uint32_t font, uint32_t ptr, uint32_t firstchar)
{
  FT_start_cmd(CMD_SETFONT2);

  spi_transmit((uint8_t)(font));
  spi_transmit((uint8_t)(font >> 8));
  spi_transmit((uint8_t)(font >> 16));
  spi_transmit((uint8_t)(font >> 24));

  spi_transmit((uint8_t)(ptr));
  spi_transmit((uint8_t)(ptr >> 8));
  spi_transmit((uint8_t)(ptr >> 16));
  spi_transmit((uint8_t)(ptr >> 24));

  spi_transmit((uint8_t)(firstchar));
  spi_transmit((uint8_t)(firstchar >> 8));
  spi_transmit((uint8_t)(firstchar >> 16));
  spi_transmit((uint8_t)(firstchar >> 24));

  FT8_cs_clear();
  FT_inc_cmdoffset(12);
}

von Rudolph (Gast)



Lesenswert?

Done, thanks for pointing that out, I obviously did not try to add 
custom fonts so far. :-)

The attached archive just proved to be working.

von Rudolph R. (rudolph)



Lesenswert?

Okay, annother update.
I went over all commands now and cross-checked them with both the 
datasheets as well as the programmers guide.

I found several commands that are undocumented but still somehow made it 
into the includes from FTDI from which I generated my FT8.h
I moved this to "#if 0" blocks.

FT8_cmd_interrupt() was using CMD_SNAPSHOT, copy-paste in action...

I removed several commands that have no arguments and therefore can be 
used with FT8_cmd_dl().
FT8_cmd_logo() -> FT8_cmd_dl(CMD_LOGO)

I added FT8_cmd_snapshot2() and FT8_cmd_setscratch()


There are still several commands "missing" like CMD_CRC but most of 
these return some "result" and the documentation from FTDI leaves it 
unclear how.

It looks like the values are written to the FIFO location just after the 
command which I find rather strange.

So you have to wait for the command to execute and then read (fifo_ptr - 
4) to fetch the result.

If that really is the case this hints that these commands are not meant 
to be used while building a display list.
So I should make them auto-execute like cmd_loadimage() already is, that 
makes it easier to save the pointer and read back the data.

von Rudolph R. (rudolph)



Lesenswert?

This update implements some more of the "missing" commands, namely those 
that return values by writing to the command-fifo:

FT8_cmd_memcrc()
FT8_cmd_getptr()
FT8_cmd_regread()
FT8_cmd_getprops()

example of using FT8_cmd_memcrc:

 offset = FT8_cmd_memcrc(my_ptr_to_some_memory_region, 
some_amount_of_bytes);
 FT8_cmd_execute();
 crc32 = FT8_memRead32(FT8_RAM_CMD + offset);

FTDI handles that a bit different and I am not sure why:

uint16_t x = rd16(REG_CMD_WRITE);
cmd_crc(0, 1024, 0);
...
printf("%08x\n", rd32(RAM_CMD + x + 12));

I have no idea why they insist on passing "result" as an argument to the 
function when this only marks the offset the command-prozessor is 
writing to, it may even be okay to not transfer anything at all.

But then FTDI is taking a different aproach on some bits and pieces.
Like actually reading REG_CMD_WRITE for their 
Ft_Gpu_Hal_WaitCmdfifo_empty() function over and over again instead of 
relying on the value written to it by their Ft_Gpu_Hal_Updatecmdfifo() 
function.
And then after REG_CMD_WRITE and REG_CMD_READ found to be the same, 
REG_CMD_WRITE is read annother time to update the offset in their 
structure.

My offset to the command-fifo is a global var that is updated by all 
functions and relied upon.
This makes my FT8_busy() function somewhat more efficient as it only 
reads REG_CMD_READ and compares that to the value that is supposed to be 
held in REG_CMD_WRITE.


And I took it even a step further and had the functions return offsets, 
at least this is what return-values are good for.


This is untested so far as I have no use right now for these functions.

von x20011 (Gast)


Lesenswert?

Hallo Rudolph R.
ich habe ein paar Verstandnisfragen zu dem Media Fifo....
Bei meiner eigenen Lib hängt sich cmd_loadimage nämlich bei der 
Verwendung des Media Fifos auch auf. :( (Achtung benutze eine andere 
Bibliothek, die vorgehsnweise sollte aber die gleiche sein.)

Zu meiner groben Vorgehensweise:

1. Ich ermittel die JPG Bildgröße in Byte:
1
do
2
        {
3
            status = fx_file_read(&g_file, imbuff, 1, &actual_bytes);
4
            file_size_in_byte++;
5
        }while(status != FX_END_OF_FILE);

2. Erstelle den MediaFifo
1
cmd_mediafifo(0x100000-(file_size_in_byte+4), file_size_in_byte+4); //Sets up a streaming media FIFO in RAM_G (+4Byte als Sicherheit falls ich noch ein paar byte für 4Byte alignment anhängen muss.) 
2
flush(); //Flush Coprocessor FIFO
3
copro_idle(); //Wartet bis Coprozessor alle Befehle abgearbeitet hat

3. Immer 1 Byte aus der JPG Datei lesen und auf addresse 
mem_mediafifo_start schreiben.
1
 do{
2
            status = fx_file_read(&g_file, &imbuff_test, 1, &actual_bytes);
3
            wr8(mem_mediafifo_start, imbuff_test); //Function to write 8 bits to intended address location
4
            mem_mediafifo_start++;
5
        }while(status != FX_END_OF_FILE);
4. Für 4Bit alignment sorgen
1
        while((mem_mediafifo_start % 4) != 0)
2
        {
3
            wr8(ram_g_address, 0x00);
4
            mem_mediafifo_start++;
5
        }
5. Neuen Offset für den Schreibzeiger des Media Fifo schreiben
1
wr32(REG_MEDIAFIFO_WRITE,mem_mediafifo_start);
6. Bild laden
1
cmd_loadimage(64*64*4, OPT_MEDIAFIFO | OPT_NODL); 
2
        flush();
Ab diesem Punkt hängt sich das Programm aus. (Prinzipiell funktioniert 
die Funktion loadimage ohne mediafifo ohne Probleme.)

Vielleicht habe ich auch einfach nur einen Denkfehler im Code ;)

von Rudolph (Gast)


Lesenswert?

x20011 schrieb:
> 5. Neuen Offset für den Schreibzeiger des Media Fifo
> schreibenwr32(REG_MEDIAFIFO_WRITE,mem_mediafifo_start);

REG_MEDIAFIFO_WRITE muss auf das Ende der Daten zeigen, nicht auf den 
Anfang.
Der CoPro liest von REG_MEDIAFIFO_READ bis REG_MEDIAFIFO_WRITE und 
aktualisiert dann REG_MEDIAFIFO_READ.

Ich würde den MEDIAFIFO auch nicht mit der Größe des Bildes erstellen, 
sondern schon eher etwas üppiger.

von x20011 (Gast)


Lesenswert?

Vielen Dank Rudolph R. für die Hilfe! Es funktioniert :)
Jetzt kann es weiter Richtung Videos von USB gehen...

von Bernd I. (Gast)


Lesenswert?

Gibt es Jemanden, der noch wirklich weiß, was an Bytes' (konkret) dem 
FT800 per SPI zugeschoben werden muss, damit er macht, was er soll?
Ich wende mich völlig verzweifelt an Euch, da ich seit ca. 3 ganzen 
Tagen probiere und probiere. Mehr als Streifen oder ein blaues Display 
geht nicht.
Habe das Demo_board VM800C50 mit 5'Display.
Habe bei der Initialisierung das Beispiel im Programmer-Guide benutzt.
Ich möchte den FT800 mit meinem PIC (PIC18F4620) einfach nur ansteuern. 
Definiere dazu die SPI-Schnittstelle meines PIC und sende ...
EIGENTLICH ganz einfach, wenn Datenblätter nicht immer so kompliziert 
formuliert wären. Ganz am Ende liest man dann vielleicht, was man ganz 
am Anfang hätte zuerst tun müssen.
ALSO, mir nützen keine C-Codes oder gar Arduino-Software und und und.
Ich möchte (und muss) es verstehen, was per SPI konkret gesendet werden 
muss.
ACKTIVE z.B.sende ich 3 x Byte $00 (Dummy-Read) und für CLKEXT dann also 
$44, $00, $00
Dass der FT800 mich versteht (SPI ist also richtig) beweißt, dass ich 
per Taster den Register REG_PWM_DUTY beschreiben und somit auf- und 
abdimmen konnte.
D.h. Register beschreiben sollte alles richtig sein, also auch die 
Timing-Register (H-/VSYNC usw.)
Die DL-Liste (DL-RAM) verstehe ich einfach nicht? Muss man zuerst die 
DL-Adresse und dann die Display-Befehle oder NUR die Display-Befehle 
senden. Woher weiß FT800 dann, dass jetzt eine Display-Liste beginnt? 
Enden soll sie ja mit "DISPLAY". Und dann muss man in den REG_DLSWAP 
stets eine 2 schreiben??? Na ich habe jedenfalls alles durchprobiert. 
Jedes mal ein anderes Chaos-Bild. Einfach nur einen Farbbildschirm mit 
Rot oder Grün .. am Anfang mit CLEAR_COLOR_RGB würde mir genügen, um das 
UR-Prinzip zu verstehen. Das andere ist dann probieren und EIGENTLICH 
gut beschrieben.
HELP !!!

von Rudolph R. (rudolph)


Lesenswert?

Boah, wie soll man den Chip erklären mit wenigen Worten aber ohne 
Programmcode und noch dazu besser als das Datenblatt/Handbuch? :-)

Programmierst Du den PIC18F4620 in C?
Wie wäre es denn, wenn wir meinen Code ein wenig erweitern damit das 
auch auf dem PIC läuft? Klingt für mich irgendwie schlauer als 
durchzukauen was man alles machen muss um das noch mal komplett neu 
aufzusetzen.

Es gibt von FTDI zum Beispiel aber auch das hier:
http://www.ftdichip.com/Support/SoftwareExamples/FT800_Projects.htm#FT81x_Simple_PIC_Application

Das ist für einen PIC18F46K22 und das Dokument dazu erklärt auch noch 
mal:
http://brtchip.com/wp-content/uploads/Support/Documentation/Application_Notes/ICs/EVE/BRT-AN-006-FT81x-Simple-PIC-Example.pdf

Den Code dazu habe ich mir aber nur kurz angesehen.


Aber grundsätzlich, was haben wir da eigentlich.
Von aussen ist ein FT8xx erstmal ein großer Speicher der mit einer 23 
Bit Adresse bedient wird, das 24. Bit dient der Unterscheidung ob 
geschrieben oder gelesen werden soll.
Es gibt grundsätzlich vier Speicher-Bereiche:
RAM_G  graphics-memory  Objekt-Speicher: 256k / 1MB ab Adresse Null
RAM_DL: 8k ab 0x100000 für FT80x und 0x300000 für FT81x
RAM_CMD: 4k ab 0x108000 für FT80x und 0x308000 für FT81x
Register: ab 0x102400 für FT80x und 0x302000 für FT81x

RAM_G dürfte soweit klar sein.
RAM_DL ist wo die eigentlich Aktion passiert, da steht die Liste drin 
die abgearbeitet wird um die Anzeige zu erstellen, jeder Eintrag hat 32 
Bit.
Besonders an RAM_DL ist noch, das gibt es doppelt, es sind zwei Mal 8k 
im gleichen Speicher-Bereich und der Zugriff erfolgt immer auf die 
Version die nicht für die Anzeige benutzt wird.
RAM_CMD wird benutzt um dem Co-Prozessor eine Anweisungsliste zu geben 
nach der dieser RAM_DL füllen soll, das besondere dabei ist, das ist ein 
Ringpuffer mit automatischem Überlauf. Und der wird immer 32 Bit breit 
beschrieben, ein "Hallo" muss entsprechend als "Hall" + "o" + 0x000000 
geschrieben werden.
Die Register sind soweit auch klar.

Man schreibt also zuerst einen Satz Daten passend zum angeschlossenen 
TFT in die Register.
Und eine quasi leere Liste in RAM_DL damit der Chip sauber los laufen 
kann.
Danach kann man in Ruhe die Daten in RAM_G packen und den Touch-Screen 
initialisieren.

Dann benutzt man RAM_CMD um den Co-Prozessor zyklisch RAM_DL neu 
schreiben zu lassen.

FT8_cmd_dl(CMD_DLSTART);
 0x00FFFFFF
FT8_cmd_dl(DL_CLEAR_RGB | WHITE);
 0xffffff02
FT8_cmd_dl(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG);
 0x07000026
FT8_cmd_text(50, 50, 28, 0, "Hallo");
 0x0cFFFFFF
 0x32003200
 0x00001c00
 "Hall"
 "o" 0x000000
FT8_cmd_dl(DL_DISPLAY);
 0x00000000
FT8_cmd_dl(CMD_SWAP);
 0x01FFFFFF

Und schliesslich muss man noch dem Co-Prozessor mitteilen, dass er das 
ausführen soll, dafür schreibt man den neuen Offset in REG_CMD_WRITE.
In dem Fall und wenn man bei Null gestartet ist wäre der Offset 36.

Edit, ich habe unterschlagen, dass man natürlich auch adressieren muss.
0x908000 wäre die Sequenz um dem FT81x mitzuteilen, dass an Adresse 
0x108000 geschrieben werden soll, ja, das sind nur drei Bytes.
Danach dann die Daten.
Also Chip-Select Low, 0x9080, 0x00FFFFFF, ... , Chip-Select High.
Lustig ist auch, dass die Adresse High-Byte -> Low-Byte gesendet wird, 
die ganzen Kommandos aber Low-Byte -> High-Byte.

Meine Library adressiert im Moment mit jedem Kommando neu.

: Bearbeitet durch User
von Bernd I. (Gast)


Lesenswert?

Hallo Rudolph. Vielen Dank erstmal. Bin zwar.Zt. im Auto unterwegs. 
Alles gut - Meine liebe Frau fährt. Werde mir deine Ausführungen morgen 
tiefer verinnerlichen. Nur schon mal soviel: Ich arbeite mit Basic 
(Proton-Compiler). Und da sehe ich förmlich, was "hinten" raus kommt. 
Hab auch mit dem Osszi SPI Daten und Clock kontrolliert. Aber im 
Endeffekt, sagt mir das Datenblatt bzw. Der Programmierung Guide manche 
entscheidende Sachen nicht. Ich benötige stets eine TECHNISCHE 
Beschreibung und setze danach meinen Code um. Nicht umgekehrt: C-Code 
und dann sieh zu. Was hinten raus kommt, brauchst Du nicht zu wissen. 
Das kann ich nicht. OK, melde mich wieder. Schönes Wochenende bis dahin. 
Gruß Bernd.

von Rudolph R. (rudolph)


Lesenswert?

BASIC? Schauder. :-)
Auf jeden Fall könnten da BRT_AN_006 und BRT_AN_007 hilfreich sein.
Das zielt zwar auch auf C ab, aber da werden auch Grundlagen erklärt und 
die ganzen Funktionen erläutert.
Der Code dazu ist auch noch eine Stufe stumpfer.

von Bernd I. (Gast)


Angehängte Dateien:

Lesenswert?

Meinen Dank, siehe Foto!!!
Woran hat's gelegen?
Dank Deiner "lustigen" Bemerkung, dass MSB-LSB bei Adressierung und 
umgekehrt bei Daten gesendet werden muss!!!
Wo steht das denn??? Eine gaaaaanz böse Falle. Danke für den 
Doku-Hinweis (BRT_AN..). Dort hat sich nur noch mal alles bestätigt, was 
mir bis dahin eigentlich schon alles klar war. Und wie schön 
beschrieben! Bit für Bit. Super. Deshalb meine aller erste Frage: Gibt 
es hier jemanden ...
Die liebe Mühe, mir den Chip-Aufbau zu erklären, hättest Du wirklich 
nicht machen brauchen. Das habe ich ja auch gelesen. Danke für Deine 
Zeit!
So, nun kannst Du das Lesen beenden, oder Dir die Zeit nehmen, weiter zu 
lesen:
BASIC? Schauder...
So wie Dein angefügtes Smilie, darfst Du auch meine Ausführungen 
keinesfalls irgentwie als böse werten!!!
Warum Schauder? Ich bin seit 17 Jahren professioneller Entwickler und 
Fertiger. Wir liefern im Jahr ca. 20.000 Platinen an Industrie- und 
Fachhandelskunden aus. Alle ca. 50 (Serien-)Projekte selbst entwickelt - 
mit BASIC.
Auch Du bist sicher meinen Platinen schon begegnet, steht nur nicht 
daruf, was drin ist. Gehe durch eine Glas-Schiebtür eines Super-Marktes 
mit der Aufschrift "Assa Abloy" und/oder "Besam" und denke an mich. 
Benutze die Parkplatzschranke eins bestimmten Herstellers... Womöglich 
heizt Du mit einer Junkers-/Buderus-Therme und nutzt das 
Netcom10/50/100. Ist von mir. Bosch-Thermotechnik hatte auch kein 
Problem mit BASIC.
Bei Europas größtem Lieferant für Fluchtwegartikel steckt in JEDEM 
elektronischen Artikel meine Platine. Schweizer Schlosstechnik wird mit 
einer intelligenten Motorschloss-Steuerung betätigt, die kann auch mit 
einem Fingerscanner direkt kommunizieren, können vernetzt werden und 
mehr.
Viele meiner Geräte können ein Update per RS485 erhalten mit meinem 
Bootloader...
Vernetzung ist ein riesen Thema, dazu gehört immer die Zentrale. Viele 
Einzelstücke habe ich schon gefertigt, aber dann zur Anzeige entweder 
mit diskreten LED oder Text-Display z.B. 2 x 20. Habe ein eigenes 
BUS-System entwickelt, was kurz vor der Serienreife für alle möglichen 
Anwendungen steht (Smart-Home). Als reine vernetzte Türüberwachungen hat 
es sich schon seit über 10 Jahren bewährt. So z.B. Flughafen Lübeck wird 
"durch mich" überwacht.
Für dieses BUS-System brauchte ich ein Grafik-Display und habe dafür das 
DEM480272TMH-PW-N (mit Touch) genutzt. Das hat "nur" ein 
8-Bit-Interface, also nur 256 Farben, was für diese technischen Zwecke 
völlig ausreicht und es läßt sich einfach ansteuern, aber ganz direkt: 
Also Steuerpin auf Befehl: X-Y-Koordinaten mitteilen, Steurpin auf 
Daten, RGB-Byte (je 3 Bit für R und G, 2 für B)anlegen, ein Takt und 
fertig ist der Pixel. Dass der FT8xx nun schon so viel Grafik enthält, 
ist natürlich super. Ich habe mir aber MIT BASIC eine Art Betriebssystem 
auf dem PIC geschaffen(inzwischen schon der 18F67K22, weil die Zentrale 
immer mehr kann) sowie 2 Fonts-Größen für alle Zeichen selbst erstellt, 
Push-Buttoms-Grafik ("Erhaben" und "Versenkt") und und und.
Die Zentrale kann alle BUS-Teilnehmer im vernetzten Zustand Updaten und 
natürlich auch sich selbst. Dazu hat sie einen USB-Stick integriert, den 
ich über FTI-Chip (VNC1L) anspreche. Und alles mit BASIC!!!
Abgesehen vom Preis des eben genannten Display (recht teuer, da mit 
integrierter Platine mit Controller drauf), ist die Größe 4,3' 
ausgereizt, auch wenn es diesen noch in 5' gibt, dann ist Schluss. Ich 
möchte aber große Paneels (10 - 12') bedienen oder auch noch kleinere 
für Glas-Paneels an der Wand, statt Licht-/Jalousieschalter usw. mit 
weiteren Info's drauf...
OK. Soll reichen. Also ich weiß genau, was mein PIC macht. Den Eindruck 
habe ich eben bei Euch "C-lern" nicht. Ich schreibe z.B. RCSTA = 
b10101010, TXSTA = xxx... Mein Compiler kennt ALLE Register des 
jeweiligen PIC's mit dem Namen, wie sie im Datenblatt stehen und hier 
übrigens auch so was von genial Bit für Bit jedes Registers beschrieben. 
SO kann man arbeiten!
Wenn ich Dir mal irgentwie helfen kann...
Liebe BASIC-Grüße, Bernd
Kommt noch ein Foto mit meiner Zentrale. Warum auch immer ich hier nicht 
2 gleichzeitig anhängen kann ?

von Bernd I. (Gast)


Angehängte Dateien:

Lesenswert?

Und hier noch das versprochene Foto.

von Rudolph R. (rudolph)


Lesenswert?

Natürlich kann man auch in BASIC programmieren.
Das einzige was C besser macht als alle anderen Sprachen ist das man 
sagen kann, dass das weltweit der Standard schlechthin ist.

Muss jetzt >20 Jahre her sein das ich gefragt habe, welche richtige 
Sprache ich nach ein wenig BASIC, viel 6502 und etwas 68k Assembler 
anfangen sollte.
Und auch damals gab es zwar genug Auswahl, aber C war schon Standard.
Ob es was besseres gibt ist gar nicht die Frage, C ist überall, BASIC 
nicht. :-)
Das was mein Arbeitsgeber so macht findet sich im Auto und ich bin als 
Hardware-Entwickler einer Software-Entwicklungsabteilung zugeordnet.
Da kann ich zwar nicht so aus dem Nähkästchen plaudern da wir wenige bis 
keine eigenen Produkte haben auf denen unser Firmenname zu finden wäre, 
aber wir stecken da sehr breit und tief drin. :-)

Bernd I. schrieb:
> OK. Soll reichen. Also ich weiß genau, was mein PIC macht. Den Eindruck
> habe ich eben bei Euch "C-lern" nicht. Ich schreibe z.B. RCSTA =
> b10101010, TXSTA = xxx... Mein Compiler kennt ALLE Register des
> jeweiligen PIC's mit dem Namen, wie sie im Datenblatt stehen

Den Absatz verstehe ich nicht, bei so einfachen Sachen wie Zuweisungen 
gibt es doch gerade mal gar keinen Unterschied zwischen BASIC und C.

RCSTA = 0b10101010;
TXSTA = xxx;

Und natürlich kennt der Compiler die Register beim Namen.

Ich will auch wissen, was mein Controller so treibt. Daher der Code 
hier. :-)
Aber man muss irgendwann einsehen, dass man nicht alles selber machen 
und alles verstehen kann. Einen TCP/IP Stack oder ein FAT Dateisystem 
würde ich dann eher versuchen fertig zu benutzen.

Die FT8xx sind toll bezüglich der benötigten Resourcen.
Die 50 Bilder pro Sekunde in 800x480 die mein Test-Code 
überflüssigerweise gerade macht kosten weniger als 25% Rechenzeit auf 
einem 16 MHz AVR.

Bei 7" ist für mich allerdings leider auch gerade Schluss, da die FT81x 
"nur" bis 800x600 können und es mir noch nicht gelungen ist ein 10" TFT 
in der Auflösung zu finden das auch noch kapazitiv Touch bietet.
Alle aktuellen Displays haben bei der Größe eine höhere Auflösung.

Teuer ist der Spass auch noch, aber im Grunde genommen nur weil TFTs 
keine Commodity Items sind die überall eingebastelt werden.
Wenn man da auf vier-stellige Stückzahlen kommen könnte, das wäre 
zumindest ein Anfang. :-)
Aber einzeln, tja, dann kostet das halt 110 Euro.

von Bernd I. (Gast)


Lesenswert?

https://www.schukat.com/schukat/schukat_cms_de.nsf/index/CMSDF15D356B046D53BC1256D550038A9E0?OpenDocument&wg=W6837&refDoc=CMSBCD816749EB85BF2C125707C004F3A35

Sieh mal dort nach. Hier gibt es wenigstens 10 Zoll mit 800x600 und mit 
Touch. Ich glaube aber nur resistiv. Für kapazitiv gehe bei Schukat auf 
Warengruppe W6835, hier das selbe aber OHNE Touch. Dann gehst Du zu RS 
und kaufst das kapazitive Touch separat dazu:

http://de.rs-online.com/web/c/displays-und-optoelektronik/displays-und-industriemonitore/touchscreen-sensoren/?sra=p

Aber was machen wir beide nun, wenn wir das 12-zöller z.B. mit 1024 x 
768 benutzen möchten/müssen ??? Hast Du schon eine Idee?

Du hast so Recht: C ist die Weltsprache. In meinen Anfangs PIC-Jahren 
war das schon bitter, sich mit niemanden austauschen zu können. Nun geht 
es ja. Und bei solchen Problemen, wie eben mit dem FT800, spielt die 
Sprache keine Rolle. Und alles wissen muss und kann ich natürlich auch 
nicht. Sonst würde ich ein Display selbst ansteuern - ohne FT800 (Oje 
!!! Fahrrad neu erfinden).

Text und ein "Springball" läuft schon. 1. Problem beim Rechteck 
BEGIN[RECTS].
Muss ich hier die Koordinaten für links-oben und rechts unten im Bereich 
480 - 272 oder das Ganze mal 16 oder sogar noch + 16384 (X/Y * 16 + 
16384) in VERTEX2F eingeben, um in den sichtbaren Bereich zu kommen? 
Also egal, was ich mache, es kommt stets nur ein kleiner Strich, sowohl 
bei x-y z.B. 100 x 100, als auch bei 1600 x 1600 als auch mal 16384 
beides. Nur stets mal hier und mal da. Habe X/Y auch wandern lassen von 
null bis 32300. Kleine Striche, meißt 3, wandern über den Schrim.
Sicher wieder etwas grundsätzliches falsch bei mir.

Und gelesen habe ich, dass der RamDL allein um 4 erhöht wird, wenn ich 
nach der Ram-Adresse dann Daten im vielfachen von 4 sende. Wenn ich 
"Hallo" sende im ganzen: low Enable, RamDl; VERTEXII,H; VERTEXII,o; ... 
usw, High Enable, erscheint nur das "H". Sende ich jeden Buchstaben mit 
selbst erhöhtem RamDL und komplett mit Startadresse, erscheint "Hallo".

Ist noch ein steiniger Weg...

von Rudolph R. (rudolph)


Lesenswert?

Das klappt so leider nicht.
Erstmal bekommt man das Touch-Interface niemals so angebracht als wenn 
das so vom Band fallen würde, das verbessert auf gar keinen Fall die 
ohnehin nicht so tollen optischen Eigenschaften von dem TFT.
Und bei den TFTs von Riverdi habe ich jetzt eine Glas-Oberfläche.

Dann ist bei den freundlichen 169 Euro für das Touch-Interface eine 
Platine dabei die Anfang 2011 designed wurde und einen nur mit sehr viel 
Glück zu den FT8xx kompatiblen Touch-Chip enthält.
Mich würde nicht mal wundern, wenn die Dinger seit Jahren bei RS im 
Regal liegen, wer braucht sowas auch und vor allem zu dem Preis?

Über 800x600 geht im Moment gar nicht mit den FT8xx.
Sicher geht das anders, das interessiert mich hier in dem Kontext aber 
nicht. :-)

FTDI habe ich die Frage nach größeren Displays auch schon gestellt, da 
haben die im Moment auch keine Lösung für.
Ich finde ja, es wird langsam Zeit für die FT82x. :-)

Von Riverdi habe ich die Andeutung, dass da eventuell bis Ende des 
Jahres was in 10" kommen könnte.
Für konkretere Ansagen bin ich als Kunde einfach nicht ernst zu nehmen.

Oh, dabei fällt mir ein, die könnten die TFTs auch optisch deutlich 
verbessert liefern durch den Einsatz einer zusätzlichen Folie, die 
Mindest-Menge die mir dafür genannt wurde sehe ich nicht mal in 10 
Jahren als Bedarf...


Rechtecke habe ich im Beispiel-Programm mit 1 Pixel Auflösung angegeben 
für VERTEX2F, per Default ist die Auflösung aber 1/16 Pixel.
Links-Oben / Rechts-Unten ist dabei richtig.

Das sollte dann so aussehen:
1
FT8_cmd_dl(LINE_WIDTH(1*16));
2
FT8_cmd_dl(DL_COLOR_RGB | RED);
3
FT8_cmd_dl(DL_BEGIN | FT8_RECTS);
4
FT8_cmd_dl(VERTEX2F(0,0));
5
FT8_cmd_dl(VERTEX2F(100*16,50*16));
6
FT8_cmd_dl(DL_END);

Wobei in dem Context mit BASIC jetzt ganz praktisch ist, dass 
FT8_cmd_dl() nichts weiter macht als die vier Byte an RAM_CMD+Offset zu 
schreiben die sich aus den Argumenten ergeben.

Okay, das ist mit den Macros nicht unbedingt sofort durchschaubar, das 
macht im Handbuch irgendwie mehr Sinn. :-)

LINE_WIDTH(width) ((14UL<<24)|(((width)&4095UL)<<0))
VERTEX2F(x,y) ((1UL<<30)|(((x)&32767UL)<<15)|(((y)&32767UL)<<0))

Die Konstanten sind da einfach:
DL_COLOR_RGB  0x04000000UL
RED      0xff0000UL
DL_BEGIN  0x1F000000UL
FT8_RECTS                9UL
DL_END    0x21000000UL

Hmm, da gäbe es noch einiges Optmierungs-Potential. :-)
Das ganze Geschubse mit 32 Bit Werten ist dann sicher eher nicht so 
effizient auf einem 8-Bit Controller.

Mein Beispiel-Programm benötigt inzwischen auch schon knapp 4ms von den 
10ms Umlauf insgesamt.
Okay, fairerweise nur die Hälfte davon weil nur jeder 2. Aufruf ein Bild 
baut und sich das ohne Probleme auf zwei Hälften verteilen lässt, damit 
sind das dann so 20% Rechenzeit für die 50 Bilder pro Sekunde.

Bernd I. schrieb:
> Und gelesen habe ich, dass der RamDL allein um 4 erhöht wird, wenn ich
> nach der Ram-Adresse dann Daten im vielfachen von 4 sende. Wenn ich
> "Hallo" sende im ganzen: low Enable, RamDl; VERTEXII,H; VERTEXII,o; ...
> usw, High Enable, erscheint nur das "H". Sende ich jeden Buchstaben mit
> selbst erhöhtem RamDL und komplett mit Startadresse, erscheint "Hallo".

Ich schreibe gar nicht direkt in RAM_DL, das überlasse ich komplett dem 
Co-Prozessor weil man auch nur über diesen die eingebauten Objekte wie 
Scroller und Buttons bekommt.

Aber auf Seite 14 im FT81X_Series_Programmer_Guide.pdf  ist eine Sequenz 
zu sehen bei der direkt in RAM_DL ein Text geschrieben wird.
Geschickterweise braucht das da vier Bytes pro Zeichen per VERTEX2II.
Ich kann nur hoffen, dass das per CMD_TEXT platzsparender in der RAM_DL 
landet. :-)
Auf jeden Fall benutze ich so oder so VERTEX2II nicht mehr, die 
Beschränkung auf 0...511 für X und Y ist einfach zu lästig, VERTEX2F 
kommt bei der Default-Auflösung von 1/16 Pixel auf -1024...1023.

von Rudolph R. (rudolph)



Lesenswert?

Some time ago I promised an example for Arduino.
However I am not really using Arduino and did not have new request on 
building something with an Arduino board.

Last week a co-worker came up to with a NodeMCU Devkit board which has a 
ESP8266 12E module on it.
I remembered that there is an Arduino core for it so I started playing 
with the board to help my co-worker getting started.
While I currently have no use for WLAN I figured it would be nice to use 
my 7" Riverdi with the ESP8266.

So here it is as example project.
I have not tried to open this with the Arduino IDE, I am using Atmel 
Studio with a plugin for Arduino, it should be fine though.

There are close to no changes, I only had to rename the .c files to .cpp 
and a add a few lines to FT8_config.h.

von Rudolph R. (rudolph)


Lesenswert?

And a new display to play with, well, sort of, I bought a FT811CB-HY50HD 
from HAOYU which is practically the same than the FT810CB-HY50HD which I 
had for some time now - but it has capacitve touch instead of 
resisitive.

I ordered it here two days ago:
http://www.watterott.com/de/5-800x480-Display-mit-kapazitivem-Touchscreen-FT811CB-HY50HD

I would not had ordered it in China directly as I am rather annoyed by 
how long it takes.

Compared to the RVT70UQFNWC0x the FT811CB-HY50HD has several advantages 
for me.
The first and most obvious is the price.
The FT811CB-HY50HD costs less than a third of what I pay for the 
RVT70UQFNWC0x when buying a single unit.
And secondly I am not even sure if I could buy a RVT70UQFNWC0x 
privately.
Yes, I know, apples and oranges 7" TFT with good quality against 5" with 
okay quality, the RVT70UQFNWC0x does not just cost more, you get more!

Third is something I did not expect to be a problem: current 
consumption.
The RVT70UQFNWC0x draws around 450...540mA from its 5V supply for the 
backlight and annother 70...130mA from its 3,3V supply for the logic.
The FT811CB-HY50HD however draws around 250mA from a single 5V supply.
And in comparision I found a 9" 800x480 TFT which is specified to draw 
1200...1600mA from its 5V supply for the backlight.
I am pretty sure this comparision is not fair either as it may be very 
well the case that the three TFTs offer different levels of brightness.

Regarding features I have to admit that the FT811CB-HY50HD wins over the 
RVT70UQFNWC0x.
- single 5V supply with 3.3V regulator on board
- 5V tolerant input buffer on board
- 12pin FPC sockel instead of 20 pin and comes with a FPC cable
- additional 10pin 2,54mm header
- crystal for the FT811 populated

Yes, the RVT70UQFNWC0x has more pins because it supports QSPI but I am 
not using that.
And yes the RVT70UQFNWC0x has a FT813 which can display more colors but 
this is hardly a limitation for HMI applications.

von Bernd I. (Gast)


Lesenswert?

Danke für den Link zu Watterott. Dort war ich auch des Öfteren wegen 
anderer Dinge, ist aber schon ne Weile her. Bei meinen Recherchen der 
letzten 4 Wochen hatte ich die schon vergessen. Interessant!!!

Bin die letzten Tage nicht dazu gekommen, weiter am FT800 zu arbeiten - 
liegt so viel anders herum.
Setze mich aber schon mit dem Gedanken auseinander, Dir ein Geschäft 
vorzuschlagen. Dann aber nicht über dieses Portal. Hast Du 
grundsätzliches Interesse?

Ein schönes lange Wochenende, Gruß Bernd

von Rudolph R. (rudolph)


Lesenswert?

Bernd I. schrieb:
> Setze mich aber schon mit dem Gedanken auseinander, Dir ein Geschäft
> vorzuschlagen. Dann aber nicht über dieses Portal. Hast Du
> grundsätzliches Interesse?

Jain. :-)
Da ich nicht selbständig angestellt bin müsste ich sowas ja mit meinem 
Arbeitgeber abstimmen und mich zudem auch noch mit dem Finanzamt 
rumärgern.
Dazu habe ich eh schon zu viele "Projekte" offen die nicht vorwärts 
kommen, wie das so ist. :-)
Also ich nehme grundsätzlich kein Geld für irgendwas, nicht mal die "5 
Euro für die Kaffeekasse" die mir schon öfter angeboten wurden.
Und Langeweile habe ich ganz sicher nicht.

Die Geschichte mit dem EPS8266 und dem FT811CB ist auch schon wieder so 
eine Sache die nicht für mich ist. :-)

Also ich helfe ja gerne, das darf nur nicht in Arbeit ausarten. ;-)

von Rudolph R. (rudolph)


Lesenswert?

Just to be fair I should also mention this:

https://riverdi.com/product/rvt50uqfnwc0x/
http://www.tme.eu/de/details/rvt50uqfnwc00/intelligente-displays/riverdi/

I do not have one of these and no connection whatsoever to Riverdi.
But in a project for my company I would always choose this one or the 
RVT70UQFNWC0x instead of the FT811CB-HY50HD just for the look and feel.

The current consumption of the RVT50UQFNWC0x is higher than what the 
FT811CB-HY50HD needs but close enough to be considered similar.


Unfortunately that seem to be all options on the market for FT811/FT813 
based TFTs.

von Bernd I. (Gast)


Lesenswert?

Hallo Rudolph,
mir ist schon klar, dass Du keine lange Weile hast. Deshalb ja meine 
"Kopfschmerzen", immer nur einseitig zu Fragen. Wie könnte ich Dir 
helfen?
Na gut, dann frage ich noch mal.
Bin so weit ganz gut vorangekommen und benötige deshalb doch wesentlich 
weniger Hilfe, als gedacht. Habe eigentlich (fast) alles, was ich 
benötige: Push-Buttoms (durch ineinander verschachtelte RECTS), Text, 
ein paar Linien, mehr brauche ich nicht. Alles ohne Co-Prozessor (Extra 
Thema, vielleicht später).
Nun ist der Touch dran. Warum gibt es hier gefühlte 27 verschiedene 
Register????????????
Habe mir mal die Register REG_TOUCH_DIRECT_XY  REG_TOUCH_DIRECT_Z1Z2  
REG_TOUCH_SCREEN_XY ausgelesen. Kann hier zwar die Koordinaten jeweils 
erkennen, ABER alle diese Register spucken die Koordinaten NUR aus, so 
lange ich mit dem Finger auf dem Screen bin. 100ms später auslesen, dann 
kommen schon die Reset-Werte. Zwar kann ich durch Interrupt-Definitionen 
einen Touch melden, aber ehe mein Prozessor eventuell dazu kommt, den 
Register auszulesen, kann der Touch schon wieder vorbei sein (je nach 
Situation). Es muss doch irgentwo einen Register geben, der sich die 
Koordinaten merkt (und mit jedem Touch überschreibt)... Oder?
Wozu sind die 5 Register REG_TOUCH_TRANSFORM_A - F und die ganze 
Geschichte mit den TAG-Registern (TAG  Touch_TAG  nur X/Y / TAG_XY ... 
??????) begreife ich auch nicht so richtig. Offenbar kann man mit deren 
Hilfe Koordinaten definieren, die berührt werden sollen und mir dann 
irgentwo als "berührt" angezeigt werden. Da mir das aber alles so extrem 
kompliziert erscheint, würden mir die Screen-Koordinaten genügen, wenn 
sie dann gespeichert bleiben!!! Den Rest (Vergleichen usw.) kann ich 
selbst, ohne erst einen halb-jährigen Programmier-Lehrgang zu 
absolvieren... :-)

von Rudolph (Gast)


Lesenswert?

Meine Software pollt den Touch, dafür lese ich nur immer wieder 
REG_TOUCH_TAG aus, mehr nicht.
Das Register wird bei jedem Bild-Aufbau aktualisiert, also bei jedem 
internen Bild-Aufbau auf dem TFT.

Für Live-Werte bei einem Slider benutze ich noch REG_TRACKER.

Meine Software sieht im Moment so aus, dass meine Funktion zur Anzeige 
alle 10ms aufgerufen wird.
Beim ersten Aufruf wird REG_TOUCH_TAG ausgewertet und bei Events 
entsprechend reagiert, beim zweiten Aufruf wird die Display-Liste über 
den Co-Prozessor gebaut.
Ich gönne mir also 50 Abfragen pro Sekunde und 50 Bilder pro Sekunde.

Man kann das auch per Interrupt machen irgendwie, das habe ich nur nicht 
mal ausprobiert, weil das Polling zum einen quasi keine Rechnenzeit 
kostet, zum anderen per Default mit dem Bildaufbau synchron läuft.

Ich benutze den Touch auch nur im Single-Point Modus, die fünf Punkte 
die mit kapzitiv Touch möglich sind habe ich noch nicht gebraucht.


In REG_TOUCH_TAG steht direkt drin welches Objekt oder welche 
Objekt-Gruppe als getouched erkannt wurde.
Man weist einfach einen Wert allem zu was man zusammen erkannt haben 
will.

TAG(0) // ignorieren
bild1
bild2
text1
TAG(10)
rechteck1
rechteck2
punkt
text2
TAG(20)
bild3
TAG(0)
text3

foo = REG_TOUCH_TAG
if(foo == 10)
{
 rechteck1.farbe = rot
 text2 = "an"
}
else
{
 rechteck1.farbe = grün
 text2 = "aus"
}


Naja, so in etwa, was spontaner Pseude-Code so hergibt. :-)

von Rudolph (Gast)


Lesenswert?

Bernd I. schrieb:
> Wozu sind die 5 Register REG_TOUCH_TRANSFORM_A - F

Ach so, ja, das sind die Kalibrier-Werte.
Die Werte ermittel ich im Moment für jedes Display nur einmal mit der 
Kalibrier-Funktion und schreibe die nach erfolgreichem init in die 
Register.

von Bernd I. (Gast)


Lesenswert?

Im REG_TOUCH_MODE kann man den Sampling-Modus festlegen. Da dachte ich 
schon: Ich hab's!!! Habe den Wert auf 01 (Single mode) gesetzt. Nun 
sollten doch eigentlich die Koordinaten EINMAL bestimmt werden ("01: 
Single mode. Cause one single sample to occur.") und somit erhalten 
bleiben. Leider auch nicht.
So lange ich gezielt auf eine Eingabe warte, ist das ständige Pollen 
kein Problem. Aber oft laufen beim BUS-System Zeit-relevante Abläufe ab, 
die ich nicht unterbrechen kann, was teilweise schon mal bis zu 250ms 
dauert. Dann ist ein kurzer Touch weg!

Und woher weiß ich hinterher, welches der im REG_TOUCH_TAG 
zusammengefassten Objekte (Push-Bottom 1 oder 2 oder ...) berührt wurde?
Dieses Zusammenfassen in diesem Register habe ich auch nicht verstanden. 
Dieser Register hat 255 Werte (8 Bit), wenn man mal die Null als "Aus" 
ausklammert. Wenn ich da eine "15" z.B. reinschreibe, was passiert dann?

von Rudolph R. (rudolph)


Lesenswert?

Bernd I. schrieb:
> So lange ich gezielt auf eine Eingabe warte, ist das ständige Pollen
> kein Problem. Aber oft laufen beim BUS-System Zeit-relevante Abläufe ab,
> die ich nicht unterbrechen kann, was teilweise schon mal bis zu 250ms
> dauert. Dann ist ein kurzer Touch weg!

Äh, ja, warum das so ist und ob das wirklich so sein muss ist von aussen 
nicht zu bewerten und wenn ich das in BASIC sehen würde, wäre das 
vermutlich nicht hilfreich. :-)

Einen richtigen Taster kann man so dann auch nicht einlesen.
Ebenso wäre ein Interrupt da wenig hilfreich, der dauert nämlich länger 
als das bloße Pollen.

Auf jeden Fall wäre speichern von Ereignissen auch nicht unbedingt 
hilfreich, schliesslich ist das wie bei einem Taster nicht nur ein 
Event, sondern zwei, drücken und los lassen.

> Und woher weiß ich hinterher, welches der im REG_TOUCH_TAG
> zusammengefassten Objekte (Push-Bottom 1 oder 2 oder ...) berührt wurde?

Es werden unterschiedliche Tag-Werte geliefert.

> Dieses Zusammenfassen in diesem Register habe ich auch nicht verstanden.
> Dieser Register hat 255 Werte (8 Bit), wenn man mal die Null als "Aus"
> ausklammert. Wenn ich da eine "15" z.B. reinschreibe, was passiert dann?

Hoffentlich nichts da dort nicht rein geschrieben wird. :-)

Beim Bau den Anzeigen Liste weist man die Werte zu, siehe oben.

TAG(0) - mache nix
strich
text
TAG(14)
Push-Button 1
TAG(15)
Push-Button 2
TAG(0)
noch was

Man kann jedem Objekt einen TAG-Wert zuweisen und wenn ein Touch-Event 
erkannt wird, steht diese Nummer dann in REG_TOUCH_Tag drin.

Mit zusammen fassen meinte ich, dass man nicht nur einzelne Objekte, 
sondern auch ganze Gruppen einen TAG-Wert zuweisen kann.

TAG(0) - mache nix
strich
text1
TAG(14)
kleines rechteck
grosses rechteck
Push-Button 1
text2
TAG(15)
Push-Button 2
TAG(0)
noch was

Also wenn man "kleines rechteck", "grosses rechteck", "Push-Button 1" 
oder "text2" berührt, dann steht in REG_TOUCH_TAG eine 14 drin.

Von daher ist die Verwendung von TAG(0) auch wichtig, damit wird 
verhindert, dass nach einem Button nicht etwa auch der ganze Rest des 
Displays als zu dem Button gehörig erkannt wird.

von Bernd I. (Gast)


Lesenswert?

OK, dass mit dem Speichern eines Touch war wohl Wunschdenken. Bei meinem 
separaten Touchcontroller AR1021 ist das ja auch nicht so. Ich weiß, was 
ich zu tun habe. Habe zwischen den Zeitrelevanten Routinen doch noch 
immer wieder Zeit zum Pollen ...
Das mit den TAG-Registern werde ich mir noch mal genauer ansehen...
Bleibt aber dennoch die Frage, was macht der REG_TOUCH_MODE ? Habe ich 
das falsch verstanden??? Sollte der nicht im Single-Modus nur einmal bei 
Berührung den Wert lesen?

Ich habe nun noch ein (vorläufig) letztes Problem:
Wenn ich eine Display-List z.B. mit BEGIN_RECTS schreibe, mit END_LIST, 
DISPLAY und REG_DLSWAP.. beende - soweit alles gut. Beginne ich eine 
neue, also den RAMDL von vorn beginne z.B. BEGIN_BITMAP werden die ASCI 
als senkrechte Striche gesetzt (Bildschirm-Hintergrundfarbe ist 
plötzlich auch anders). Hat das was mit dem REG_DLSWAP zu tun? Hier 
schreibe ich stets eine "2" als Zeichen für den FT800, dass der RAM neu 
beschrieben wurde. Kommt hier jetzt eine "1" (im wechsel mit "2" nach 
jeder neuen List)?
Da werde ich morgen noch ein bisschen testen, falls ich nicht weiter 
komme ... :-)

von Rudolph (Gast)


Lesenswert?

Bernd I. schrieb:
> Bleibt aber dennoch die Frage, was macht der REG_TOUCH_MODE ? Habe ich
> das falsch verstanden??? Sollte der nicht im Single-Modus nur einmal bei
> Berührung den Wert lesen?

Der liest einmal den Wert sobald man in REG_TOUCH_MODE eine '1' rein 
schreibt.
Wofür auch immer das gut ist, vielleicht EMV, ich lasse das einfach auf 
Default stehen.

Bernd I. schrieb:
> Ich habe nun noch ein (vorläufig) letztes Problem:

Äh, ja, das mache ich ja so gar nicht und vor allem nicht so direkt.
Ich wurde von der Beschreibung zu REG_DLSWAP allerdings vermuten, dass 
man da immer nur eine '2' rein schreiben sollte, auf gar keinen Fall 
abwechselnd mit '1'.

"Bit 1 - 0: These bits can be set by the host to validate the display 
list buffer
. The graphics engine will determine when to render the screen , 
depending
on what values of these bits are set:
01: Graphics engine will render the screen immediately after current 
line is scanned
out. It may cause tearing effect.
10: Graphics engine will render the screen immediately after current 
frame is
scanned out. This is recommended in most of cases.
00: Do not write this value into this register.
11: Do not write this value into this register"

Also "2" ist der Wechsel nach dem Frame, "1" nach der aktuellen Zeile.

Keine Ahnung, wofür es da überhaupt eine Option gibt, das einzig 
sinnvolle ist ja der Wechsel nach dem Frame.

von Bernd I. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Rudolf,
im Prinzip bin ich mit der ganze Probiererei soweit, dass ich mit dem 
eigentlichen Projekt beginnen kann.
Da gibt es zwar 2-3 Phänomene, die ich zwar austricksen kann, aber 
vielleicht geben sie ja auch Einsicht in irgendwelche prinzipiellen 
Fehler.

Da wäre Phänomen-Nr.1, wie schon am 3.5. geschildert. Die senkrechten 
Strich von Oben bis Unten, dort wo eigentlich Buchstaben stehen. Das 
selbe hatte ich auch schon mit RECTS. Ein RECT definieren, RamDL 
abschließen, einen neuen beginnen, RECTS setzen - das RECT ist zwar 
breit, wie definiert, aber geht von Oben bis Unten des Bildschirms, auch 
wenn ich die Höhe nur auf 2 Pixel z.B. definiere.
Hingegen 2 - 3 ... RECTS innerhalb einer List setzen - geht!

2. Phänomen:
Ich konstruiere Push-Buttoms (PB), indem ich mehrere RECTS mit je einen 
Pixel kleiner und je sich ändernder Farbe ineinander setze. Siehe Bild 
"PB_Erhaben". Bei Touch hier mal zur Demo, "versenken" sich alle (später 
natürlich nur der berührte) PB, indem die Farbeveränderung an den 
Rändern getauscht wird ("PB_Senk").
Ebenso kannst Du sehen, dass ich den Hintergrund nicht mit 
CLEAR_COLOR_RGB einfach nur z.B. auf Grün setze, sondern hier ebenso ein 
PB setze mit der Größe 480 x 272 und damit diesen effektvollen 
Bildschirmrand habe.
Nun das Problem: Es wird eine Schleife durchlaufen, um diese 10 RECTS 
ineinander zu setzen. Sobald ich diese Schleife auf 11 (im Bild z.B. 12 
mal "PB_12mal") setze, um den Rand des PB noch breiter zu machen, oder 
sogar auf 16 Durchläufe erhöhe, sieht es so aus ("PB_16mal").
Genau 10 mal macht er alle richtig, was passiert ab dem 11. mal??? Es 
gibt definitiv keine falsche Koordinaten-Berechnung ab dem 11. mal, habe 
auch um ganz sicher zu gehen, alles schon mit Konstanten getestet. 
Dachte auch, ob der RamDL wohl voll ist. Quatsch, zumal dieser Effekt 
auch dann auftritt, wenn ich nur einen einzigen PB mit 12 Rändern setze 
!! Was soll das???

3. Phänomen:
Habe ich jetzt nicht noch mal fotografiert. Der erste von den hier im 
Beispiel 14 PB's sieht grundsätzlich anders aus, als alle übrigen. Der 
hat keinen Schatten. Um das aus zu tricksen, setze ich diesen ersten 
außerhalb des sichtbaren Bereichs. Aber ist doch unlogisch!!!

In dem Zusammenhang würde mich auch interessieren, ob man diesen 
automatischen Schatten "abschalten" kann. Ich staune auch nur, wie gut 
eigentlich die PB's aussehen. Eigentlich müssten die Schatten eines 
jeden "inneren RECTS sich widerspiegeln. Statt dessen ist der saubere 
Farbverlauf, wie definiert. Wo hingeben das ERSTE RECT eines jeden PB 
(das Äußere also) einen Schattenrand hat. Im Bild "PB_Erhaben" gut zu 
sehen: Der hellblaue Rand um den "meinen" schwarz-grau verlaufenden Rand 
stammt nicht von mir. Ist wohl der automatische Schatten.

Sind alles "Probleme" mit denen ich leben kann, aber ... schön ist 
anders.

Guten Abend!!!

von Rudolph (Gast)


Lesenswert?

Das lässt sich so etwas schwer nachvollziehen, so ohne Quellcode und 
sowieso als Problem das nichts mit dem hier veröffentlichten Code zu tun 
hat. :-)

Du lässt 10...16 Rechtecke aufeinander malen für einen einzelnen Button?
Sowas fällt ja quasi schon unter Missbrauch der Engine. :-)
Mal schauen, 14 Buttons, 140 Rechtecke, 280 VERTEX2 -> 1120 Bytes nur 
für die Rechtecke, dazu noch die Farben.
Und das nur, weil die vorhandenen Buttons optisch nicht gefallen?

Nimm doch einfach zwei Bilder dafür.
Mit VERTEX2II kann man die Cell-Nummer angeben, dazu hängt man Bilder 
mit gleicher Größte direkt hintereinander in den Speicher, die Nummer 
gibt dann an, welches Bild man will.
1
cmd_dl(BITMAP_SOURCE(74000));
2
cmd_dl(BITMAP_LAYOUT(FT_RGB565,64*2,64));
3
cmd_dl(BITMAP_SIZE(FT_NEAREST,FT_BORDER,FT_BORDER,64,64));
4
5
cmd_dl(DL_BEGIN | FT_BITMAPS);
6
cmd_dl(VERTEX2II(10+64*0,10,0,0));
7
cmd_dl(VERTEX2II(10+64*1,10,0,1));
8
cmd_dl(VERTEX2II(10+64*2,10,0,0));
9
cmd_dl(VERTEX2II(10+64*3,10,0,0));
10
cmd_dl(DL_END);

-> 14 Buttons = 14x VERTEX2II -> 56 Bytes

Übrigens, der FTDI EVE Screen Editor ist da richtig praktisch zum 
Rumspielen, nicht zu verwechseln mit dem Screen Designer.

Der zeigt sogar die aus den Kommandos resultierenden Rohwerte an.

von Bernd I. (Gast)


Lesenswert?

Gut gerechnet "Löwe" :-) UND??? Was stören mich 1100 Bytes? Und das 
"NUR" weil ich mir nicht von einer (Grafik-) Maschine aufdiktieren 
lasse, wie mein Design auszusehen hat.
Der Quellcode ist soooo was von einfach und kostet dem PIC vielleicht 
lumpige 50 Bytes, wenn man mal die einmalig erstellten Unterroutinen 
ausklammert.


RamDL = $00900000                   //Start RamDL bei Hx100000 | 
Hx800000
Gruen = 255 : Rot = 100 : Blau = 60   //Hintergrundfarbe (Grün)
DDis0 = Blau
DDis1 = Gruen
DDis2 = Rot                       //definierte Var. Untermenü übergeben
Befehl = bCOLOR_RGB
    GoSub Bef32                   //SPI senden

Befehl = bBEGIN : DDis0 = RECTS     //Start Treiber Rechteck
GoSub Ram4                         // Untermeü: RamDL = RamDL + 4
GoSub Bef32                        //SPI senden

RECTS mit 480 x 272 nach selben Schema setzen, wie folgt beschrieben:

Befehl = bLINE_WIDTH
DatW = 80                        // Linienstärke (5*16) für die 14 PB's
DDis0 = DatW.Byte0
DDis1 = DatW.Byte1
GoSub Ram4                         // Untermeü: RamDL = RamDL + 4
GoSub Bef32                        //SPI senden

Befehl = bCOLOR_RGB : Rot = 0 : Gruen = 0 : Blau = 0   // Farbe schwarz
DDis0 = Blau
DDis1 = Gruen
DDis2 = Rot
GoSub Ram4                         // Untermeü: RamDL = RamDL + 4
GoSub Bef32                        //SPI senden

'===== Ende Vorgeplänkel =======
'===== Push-Button setzen ======
Hoehe = 50 : Breite = 50                // Höhe und Breite der PB 
(50x50)
Zeile = 2047 - 200 : Spalte = 2047 - 200    'Koordinaten der RECTS
    GoSub VersPB
// Das erste RECTS ausserhalb des sichtbaren Bereichs (wegen Phönomen1)

Zeile = 2047 + 30 : Spalte = 2047 + 30   // Koord. der RECTS Oben-Links
    GoSub VersPB                         //1.versenkten PB setzen
Spalte = 2047 + 90
    GoSub VersPB                         //2.versenkten PB setzen
Spalte = 2047 + 150
    GoSub VersPB                         //3. usw..
....
// Nächste Zeile, die 14 PB von vorn:
Zeile = 2047 + 100 : Spalte = 2047 + 30
    GoSub VersPB                         //1.versenkten PB setzen
Spalte = 2047 + 90
    GoSub VersPB                         //2.versenkten PB setzen
Spalte = 2047 + 150
    GoSub VersPB                         //3. usw..

    GoSub EndList                   //RamDL + 4, END Senden

// es folgt die Beschriftung der PB, ist aber unwichtig, da der Effekt 
auch ohne auftritt:
Farbe auf weiß, BEGINN[BITMAPS] ...

    GoSub EndList                   'RamDL + 4, END Senden
Befehl = bDISPLAY
    GoSub Ram4 : GoSub Bef32
Regi = REG_DLSWAP : DatW = 2 : GoSub Reg8       'Reg_DLSWAP 2 setzen

==== Warten auf Touch === .... Reaktion, zurück zu "Schleife"


=== DAS Unterprogramm "VersPB": ====

VersPB:                               //Sprungmarke
For HpB = 0 To 9           // Schleife 10 mal durchlaufen
XKo = (Spalte + HpB) * 16 : YKo = (Zeile + HpB) * 16  //X/Y Oben-Links
GoSub Vertex2F              //X/Y gemäß VERTEX2F an Bit-Pos. schieben,
                            //RamDl+4, SPI übergeben
XKo = (Spalte + Breite - HpB) * 16
YKo = (Zeile + Hoehe - HpB) * 16       // X/Y Unten-Rechts
GoSub Vertex2F

Befehl = bCOLOR_RGB
DDis0 = Rot + (HpB * 16)     //Farbe schwarz mit jedem Durchlauf um 16 
inc.
DDis1 = Gruen + (HpB * 16)
DDis2 = Rot + (HpB * 16)
GoSub Ram4 : GoSub Bef32
Next                         // Schleife von vorn
Return                      // Zurück zum Hauptprogramm


======================================================================== 
===
Ich durchlaufe also EIN und DIE SELBE Schleife (X/Y berechnen, Vertex2F 
ausführen) immer wieder nur. Mache ich das mehr als 10 mal innerhalb der 
Schleife = Chaos, springe ich mit Return zurück und beginne mit einer 
anderen Spalte von vorn, geht es ???

Du schreibst es einfach so: "Dann nimm doch 2 Bilder, füge an ..."
Wir reden seit Wochen glaube ich aneinander vorbei. Bisher (und so soll 
es bleiben) programmiere ich PIC's, rede per I2C/SPI/UART mit 
ON-Board-Controllern bzw. externen Geräten mit klaren Befehlen gemäß 
Datenblatt. Dieser FT8xx jedoch ist ja eine kleine Maschine, die eine 
Anwendersoftware haben möchte, also so, als ob ich auf Windows ein 
Programm schreibe. Und das kann ich nicht, also wühle ich mich durch 
dieses "wischi-waschi" Datenblatt mit seinen vielen Druckfehlern und 
schlammigen Formulierungen.
Nur mal 2 Beispiele:
Befehl END, sinngemäß: Es st empfohlen, nach jedem BEGINN ein END zu 
setzen. Der erfahrene User kann es aber auch weglassen ??????????
Was soll ich damit anfangen?
COLOR_RGB: Hier stehen die Farben im Register R B G, richtig muss aber R 
G B sein...
Oder allein diese Unklarheit mit dem REG_DLSWAP...

Wie soll ich nur mal rein physikalisch gesehen eine Datei (Bild) vom PC 
mit USB als Schnittstelle in den Speicher des FT mit Schnittstelle SPI 
begommen? Klar habe ich das schon x-mal registriert und wie man es 
herausholt mit Source und so, ist ja auch noch relativ leicht 
durchschaubar. Aber wie kommt es da erst einmal rein????????????????????
Das geht doch wohl nur wieder mit entspr. Adapterplatine und Software 
???

von Bernd I. (Gast)


Lesenswert?

Nachtrag:
Ich habe einfach keine Zeit, einen Computer-Lehrgang zu absolvieren. Es 
ist schon extrem sündhaft, was ich bisher mit diesem FT an Zeit 
verdaddelt habe.
Deshalb werden mir auch die sicherlich vielen interessanten 
Möglichkeiten der Grafik-Maschine verborgen bleiben, zumindest vorerst.
Verschwende bitte auch deine kostbare Zeit nicht so sehr wegen der 
Phänomenen. Klar wurmt es mich, aber kann damit leben. Es ist nur, dass 
vielleicht daraus erkennbar ist, dass ich nach wie vor einen generellen 
(Denk-) Fehler habe und sich später daraus noch weitere Fehler 
ergeben...

Wie ich ein JPG aber in den FT bekomme (rein physikalisch!!!) würde mich 
schon interessieren!

von Rudolph (Gast)


Lesenswert?

Bernd I. schrieb:
> Gut gerechnet "Löwe" :-) UND??? Was stören mich 1100 Bytes?

Das muss über den SPI geschoben werden und das kostet Zeit, und zwar 
immer und immer wieder, obwohl man das ganze in dem Fall eben auch 
"vorher berechnen" kann im Form von zwei Bildern.
Mit Farben zu jedem "Rechteck" sind das auch gar >1680 Bytes.

Bernd I. schrieb:
> Du schreibst es einfach so: "Dann nimm doch 2 Bilder, füge an ..."
> Wir reden seit Wochen glaube ich aneinander vorbei.
> Bisher (und so soll es bleiben) programmiere ich PIC's,
> rede per I2C/SPI/UART mit ON-Board-Controllern bzw. externen Geräten
> mit klaren Befehlen gemäß Datenblatt.

Da reden wir nicht aneinander vorbei, das ist mir soweit schon klar.
Letzlich mache ich ja auch nichts weiter als den Chip per SPI zu 
bedienen, das ich das in C und aktuell mit einem AVR mache ist da nur 
ein Detail. :-)

Über den SPI purzeln bei mir am Ende die gleichen Daten.

Nur habe ich mir Funktionen geschaffen die mir das Gefummel mit den 
Rohdaten abnehmen, das geht ganz sicher auch in BASIC.
Die Namen meiner Funktion sind ganz stark an das angelehnt was FTDI so 
dokumentiert hat, die Funktionen haben weitgehend die gleichen Parameter 
mit den gleichen Typen und in der gleichen Reihenfolge wie die 
Kommandos.

In C wäre das wahrscheinlich für jemanden der sich damit auskennt ein 
Witz das auf einen PIC anzupassen.


Und ja, das Datenblatt und das Programmier-Handbuch sind nicht so der 
Bringer.
Und gemeldete Fehler werden zwar gerne entgegen genommen, aber nicht 
eingepflegt.

Bernd I. schrieb:
> Wie ich ein JPG aber in den FT bekomme (rein physikalisch!!!) würde mich
> schon interessieren!

Da gibt es verschiedene Wege.
Grundsätzlich konvertiere ich die Binär-Daten erstmal in Code der 
mitcompiliert wird und als Array im FLASH-Speicher landet, das wird 
BASIC sicher auch können.

Das einfachste für Dich wird sein, ein Bild mit dem "Image Convert Tool" 
von FTDI zu konvertieren, vorzugsweise mit V0.7 davon.
Das ist ein Kommandozeilen Tool und das schreibt immer vier Dateien:
xxx.bin - gepackt, binär
xxx.binh - gepackt, text
xxx.raw - ungepackt, binär
xxx.rawh - ungepackt, text

img_cvt -i xxx.png -f 7 -d

Das xxx.rawh kann man nehmen, entsprechend der Sprache in ein Array 
packen, das Array per SPI an die gewünschte Adresse schicken.
Nur kostet ein Farb-Bild in RGB565 2 Byte pro Pixel, also mal eben 8kb 
für 64x64 Pixel, da geht schnell der Platz im Controller aus.

Die gepackten Daten lädt man mit cmd_inflate über den Co-Prozessor, da 
werden die Daten in den CMD-FIFO geschrieben, direkt nach dem Kommando.

Und zuletzt gibt es noch cmd_loadimage mit dem man beim FT80x .jpg vom 
Co-Prozessor entpacken lassen kann.

Hier sind ja auch genug Fotos im Thread.
Die ganzen Bilder die man da auf den diversen Displays sehen kann sind 
alle in meinem Controller gespeichert und werden beim Programmstart in 
den FT8xx geschoben.

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

Ich habe gerade mal versucht das Programm nachzuvollziehen, so mit Excel 
und im Screen-Editor.

Das Ergebnis sieht auf den ersten Schritt nicht so ganz korrekt aus, vor 
allem die Farben.

Im Screen Editor sieht das so aus:
1
CLEAR(1, 1, 1)
2
3
LINE_WIDTH(80)
4
5
BEGIN(RECTS)
6
COLOR_RGB(100, 255, 100)
7
VERTEX2F(480, 480)
8
VERTEX2F(1280, 1280)
9
10
COLOR_RGB(116, 16, 116)
11
VERTEX2F(496, 496)
12
VERTEX2F(1264, 1264)
13
14
COLOR_RGB(132, 32, 132)
15
VERTEX2F(512, 512)
16
VERTEX2F(1248, 1248)
17
18
COLOR_RGB(148, 48, 148)
19
VERTEX2F(528, 528)
20
VERTEX2F(1232, 1232)
21
22
COLOR_RGB(164, 64, 164)
23
VERTEX2F(544, 544)
24
VERTEX2F(1216, 1216)
25
26
END()

Die RAM_DL Ausgabe konnte ich leider nicht im Text raus kopieren.

Ausserdem habe ich zwei spontane Versuche mit Paint angehängt für 
fürchterliche hässliche Knopf-Bilder. :-)

von Flo (Gast)


Lesenswert?

Also ich habe große Probleme mit dem Chip warm zu werden.
Man wird mit Doku und Notes gerade zu erschlagen und ich habe 
Schwierigkeiten die für mich relevanten Dinge zu filtern.

Ich habe mir die Spielplatz_90CAN_FT800.zip Routinen mal angeschaut. Der 
Code ist wirklich verständlich und einfach gehalten.

Ich frage mich allerdngs woher die defines für die Display 
Initialiserung herkommen. Im Code z.B.
// VM800B35A: FT800 320x240 3.5" FTDI
Gelten die nun für jedes 320x240 Punkte LCD, bzw würde jedes 320x240 
Punkte LCD mit diesen defines out of the box was anzeigen ?

Nach der ft800_init() Routine hört es dann auch mit meinem Verständnis 
auf.
Folgende Befehle sollen wohl ein Bild darstellen. An welchem Pixel 
Offset wird das Bild angezeigt, ab 0 bzw. 18432 ?
1
while(ft800_busy() == 1);
2
ft800_get_cmdoffset();
3
ft800_cmd_memset(0, 0xff,1L*96*96*2);  // Clear the memory at location 0 - any previous junk or bitmap data
4
ft800_cmd_execute();
5
6
while(ft800_busy() == 1);
7
ft800_cmd_loadimage(0, FT_OPT_NODL, jpg3, 3708);
8
ft800_cmd_execute();
9
10
while(ft800_busy() == 1);
11
ft800_cmd_loadimage(18432, FT_OPT_NODL, jpg4, 3708);
12
ft800_cmd_execute();

Ab wann wird das Bild angezeigt, soabld die Daten in der Funktion 
ft800_cmd_loadimage übertragen werden oder nach dem Befehl 
ft800_cmd_execute() ?

Was hat es mit diesen Listen auf sich, das verstehe ich überhaupt nicht 
:-(

Gruß
Flo

von Bernd I. (Gast)


Lesenswert?

Flo schrieb:
> Also ich habe große Probleme mit dem Chip warm zu werden.
> Man wird mit Doku und Notes gerade zu erschlagen und ich habe
> Schwierigkeiten die für mich relevanten Dinge zu filtern.

Willkommen im Klub...
Ein bloßes Kopieren vorhandener Codes, trägt - Meiner Meinung nach - 
nicht gerade zum Verständnis bei, jedenfalls nicht für den Anfang.
Zuerst müssen alle Register für das Display gesetzt werden (REG_HCYCLE, 
REG_HOFFSET, usw...). Die Register sind eigentlich gut beschrieben, 
incl. einem Taktdiagramm, was enorm zum Verständnis beiträgt, was mit 
diesem Register gemeint ist (Vergleiche mit dem Taktdiagramm im 
Datenblatt des Display).
Dann muss grundsätzlich eine List geschrieben werden, so ist das 
Grundprinzip. Die Beschreibungen "mittendrin" lassen viele Details als 
Selbstverständlich einfach weg. Wenn im Betriebshandbuch eines Autos 
steht, dass das Auto sich nach links bewegt, wenn man das Lenkrad nach 
links dreht, dann ist es selbstverständlich, dass man zunächst das Auto 
starten muss, Kupplung treten, Gang einlegen ... Das steht aber an einer 
ganz anderen Stelle im Handbuch. Und beim FT8xx steht das "am besten" 
ganz hinten, obwohl mich das zuerst interessiert ...
Mit den Codes im "Spielplatz" kann ich dir nun absolut nicht weiter 
helfen, da ich mit "C" nichts am Hut habe. Frag Rudi :-)
Es gibt aber sicher C-Befehle, die dafür sorgen, dass der FT8xx gesagt 
bekommt: "Setze Register REG_HCYCLE auf den Wert 43" ... Vielleicht ist 
das ZUNÄCHST etwas umständlicher, aber du verstehst, was du da machst.

von Rudolph R. (rudolph)


Lesenswert?

Naja, der "Spielplatz" ist schon länger nicht mehr aktuell.

Flo schrieb:
> Ich frage mich allerdngs woher die defines für die Display
> Initialiserung herkommen.

Teilweise aus Beispiel-Programmen, teilweise direkt aus den 
Datenblättern der TFTs.

Flo schrieb:
> // VM800B35A: FT800 320x240 3.5" FTDI
> Gelten die nun für jedes 320x240 Punkte LCD, bzw würde jedes 320x240
> Punkte LCD mit diesen defines out of the box was anzeigen ?

Ist einen Versuch wert, aber nein, nicht unbedingt.
Die Timing-Parameter sollten eigentlich ähnlich sein, im Zweifel muss 
man das aber mit dem Datenblatt vergleichen.
Da das nicht ganz so einfach ist habe ich eben einige Konfigurationen 
mit zur Verfügung gestellt.

Flo schrieb:
> Folgende Befehle sollen wohl ein Bild darstellen. An welchem Pixel
> Offset wird das Bild angezeigt, ab 0 bzw. 18432 ?

Das zeigt noch gar nicht an, das dient lediglich dazu die Bild-Daten in 
den Objekt-Speicher des FT8xx zu bekommen.

Hier steht noch etwas mehr Erläuterung zu dem Ding:
https://www.mikrocontroller.net/articles/FT8xx_Library

Das Anzeigen von Bildern erfolgt in der Display-Liste, zum Beispiel so:
1
FT8_cmd_dl(DL_BEGIN | FT8_BITMAPS);
2
FT8_cmd_setbitmap(MEM_LOGO, FT8_L8, 38, 59);
3
FT8_cmd_dl(VERTEX2F(100, 20));
4
FT8_cmd_dl(VERTEX2F(150, 20));
5
FT8_cmd_dl(VERTEX2F(200, 20));
6
FT8_cmd_dl(DL_END);

Damit wird das gleiche Bild aus Adresse MEM_LOGO des Objekt-Speichers 
mit 38x59 Pixel drei Mal angezeigt.

Was hast Du denn für ein Display, mit welchem FT8xx und mit welchem 
Controller möchtest Du das benutzen?

von Flo (Gast)


Lesenswert?

Rudolph R. schrieb:
> Hier steht noch etwas mehr Erläuterung zu dem Ding:
> https://www.mikrocontroller.net/articles/FT8xx_Library
Vielen Dank dafür das hatte ich noch nicht gefunden, werde ich mal 
durchgehen

Rudolph R. schrieb:
> Was hast Du denn für ein Display, mit welchem FT8xx und mit welchem
> Controller möchtest Du das benutzen?
https://www.glynshop.com/erp/owweb/Daten/DSS/EDT/Products/Specifications/Active%20Displays/ET035009DM6.pdf
FT800
LPC1768

Ich habe Deinen "Spielplatz" als Grundlage genommen weil ich ihn für den 
Anfang als sehr übersichtlich empfand. Ich brauchte lediglich den SPI 
Treiber auf den LPC umschreiben und sofort hatte ich Verbindung zum 
Chip.
Die Init läuft komplett durch, auch die ChipID wird korrekt gelesen.

Nach der Init bin ich dann etwas verunsichert was ich machen muss, Touch 
oder Audio brauche ich nicht. Möchte erst einmal Bilder und Text 
darstellen.

von Flo (Gast)


Lesenswert?

Nach der Init Routine rufe ich aktuell folgenden Code auf
Ergebnis bleibt ein weißes Display
1
ft800_memWrite8(REG_ROTATE, 1);  // rotate display by 180°
2
3
while(ft800_busy() == 1);
4
ft800_get_cmdoffset();
5
6
ft800_cmd_memset(0, 0xff,1L*96*96*2);  // Clear the memory at location 0 - any previous junk or bitmap data
7
ft800_cmd_execute();
8
9
while(ft800_busy() == 1);
10
11
ft800_cmd_loadimage(0, FT_OPT_NODL, jpg3, 3708);
12
ft800_cmd_execute();
13
14
while(ft800_busy() == 1);
15
16
ft800_cmd_loadimage(18432, FT_OPT_NODL, jpg4, 2640);
17
ft800_cmd_execute();
18
19
while(ft800_busy() == 1);
20
21
ft800_cmd_loadimage(40000, FT_OPT_NODL, leopard, 3741);
22
ft800_cmd_execute();
23
24
while(ft800_busy() == 1);
25
26
ft800_cmd_loadimage(56800, FT_OPT_NODL, schneehase, 1833);
27
ft800_cmd_execute();
28
29
while(ft800_busy() == 1);
30
31
ft800_cmd_loadimage(74000 + (8192 * 0), FT_OPT_NODL, blitz, 1638);
32
ft800_cmd_execute();
33
34
while(ft800_busy() == 1);
35
36
ft800_cmd_loadimage(74000 + (8192 * 1), FT_OPT_NODL, figure, 2314);
37
ft800_cmd_execute();
38
39
while(ft800_busy() == 1);
40
41
ft800_cmd_loadimage(74000 + (8192 * 2), FT_OPT_NODL, frog, 1639);
42
ft800_cmd_execute();
43
44
while(ft800_busy() == 1);
45
46
ft800_cmd_loadimage(74000 + (8192 * 3), FT_OPT_NODL, map1, 2476);
47
ft800_cmd_execute();
48
49
while(ft800_busy() == 1);
50
51
ft800_cmd_loadimage(106768, FT_OPT_NODL, spiral, 2618);
52
ft800_cmd_execute();
53
54
while(ft800_busy() == 1);
55
56
57
ft800_cmd_dl(CMD_DLSTART); // Start the display list
58
ft800_cmd_dl(DL_CLEAR_RGB | BLACK); // Set the default clear color to black
59
ft800_cmd_dl(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG); // Clear the screen - this and the previous prevent artifacts between lists, Attributes are the color, stencil and tag buffers
60
ft800_cmd_dl(TAG(0));
61
62
#define FT8_BITMAPS              1UL
63
#define FT8_L8                   3UL
64
65
ft800_cmd_dl(DL_BEGIN | FT8_BITMAPS);
66
ft800_cmd_setbitmap(0, FT8_L8, 38, 59);
67
ft800_cmd_dl(VERTEX2F(100, 20));
68
ft800_cmd_dl(VERTEX2F(150, 20));
69
ft800_cmd_dl(VERTEX2F(200, 20));
70
ft800_cmd_dl(DL_END);

von Rudolph R. (rudolph)


Lesenswert?

Flo schrieb:
>> Was hast Du denn für ein Display, mit welchem FT8xx und mit welchem
>> Controller möchtest Du das benutzen?
> 
https://www.glynshop.com/erp/owweb/Daten/DSS/EDT/Products/Specifications/Active%20Displays/ET035009DM6.pdf

Hmm, spontan komme ich mit dem Datenblatt nicht klar, ist einfach zu 
lange her, dass ich die Timing-Parameter durchgeschüttelt habe.
Das Problem ist, dass die Angaben zwischen FT8xx und Datenblatt vom 
Display unterschiedlich angegeben werden.

Zumindest kann ich sagen, dass der Takt passt. :-)

Wobei mir gerade einfällt, dass Glyn auch eine Library hat, das würde 
ich aber so in Richtung tot einordnen, aber vielleicht ist da was zum 
Init zu finden. Ein Display von Glyn habe ich auch in meinen Daten, nur 
habe ich von denen nie was in die Finger bekommen.

> FT800

Auf was für einem Board sitzt der? Hat das Ding einen Quarz?

> LPC1768

Auch interessant.
Benutzt Du GCC als Compiler? Was setzt der Compiler denn so automatisch 
an Symbolen für den Controller?
Und poste mal bitte den modifizierten Code aus FT800_config.c

Flo schrieb:
> Ich habe Deinen "Spielplatz" als Grundlage genommen weil ich ihn für den
> Anfang als sehr übersichtlich empfand.

Ist nur eben alt, der Code ist inzwischen etwas weiter gekommen.

Flo schrieb:
> Nach der Init Routine rufe ich aktuell folgenden Code auf
> Ergebnis bleibt ein weißes Display

Na, zum einen ist die Liste nicht abgeschlossen, wird also gar nicht 
angezeigt, zum anderen kennt der FT800 gar kein cmd_setbitmap().
1
ft800_init();
2
3
while(ft800_busy() == 1);
4
ft800_get_cmdoffset();
5
6
ft800_cmd_loadimage(0, FT_OPT_NODL, jpg3, 3708);
7
ft800_cmd_execute();
8
while(ft800_busy() == 1);
9
10
11
ft800_cmd_dl(CMD_DLSTART); // Start the display list
12
ft800_cmd_dl(DL_CLEAR_RGB | BLACK); // Set the default clear color to black
13
ft800_cmd_dl(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG); // Clear the screen - this and the previous prevent artifacts between lists, Attributes are the color, stencil and tag buffers
14
ft800_cmd_dl(TAG(0));
15
16
ft800_cmd_dl(DL_BEGIN | FT_BITMAPS);
17
ft800_cmd_dl(BITMAP_SOURCE(0));
18
ft800_cmd_dl(BITMAP_LAYOUT(FT_RGB565,96*2,96)); // jpg3
19
ft800_cmd_dl(BITMAP_SIZE(FT_NEAREST,FT_BORDER,FT_BORDER,96,96)); // jpg3
20
ft800_cmd_dl(VERTEX2F(50*16,50*16));
21
ft800_cmd_dl(DL_END);
22
23
ft800_cmd_dl(DL_DISPLAY);  // Instruct the graphics processor to show the list
24
ft800_cmd_dl(CMD_SWAP); // Make this list active
25
ft800_cmd_execute();

von Flo (Gast)


Lesenswert?

Rudolph R. schrieb:
> Auf was für einem Board sitzt der? Hat das Ding einen Quarz?
Der FT800 und der lpc sitzen je auf einem breakoutboard und sind mit 
kurzen leitungen verbunden.
Ich habe wie im Beispiel Design ein 12MHz externen Quarz angeschlossen.

Rudolph R. schrieb:
> Benutzt Du GCC als Compiler? Was setzt der Compiler denn so automatisch
> an Symbolen für den Controller?
> Und poste mal bitte den modifizierten Code aus FT800_config.c
Benutze Eclipse mit GNU ARM Embedded toolchain
Benutze ein Makefile, also keine Standard Symbole
Ich habe Deinen Code der config.c kopiert und lediglich die SPI Lese- 
und Schreibe Routinen auf die Register des LPC abgeändert. Also so gut 
wie keine Änderung.

Rudolph R. schrieb:
> Na, zum einen ist die Liste nicht abgeschlossen, wird also gar nicht
> angezeigt, zum anderen kennt der FT800 gar kein cmd_setbitmap().
Ok das ist ein Argument :-)
Habe es mit Deinem Code oben versucht aber es tut sich nach wie vor 
nichts.
Kann man hier systematisch Fehlersuche betreiben ?
Der Init Code ist ja absolut identisch zu Deinem. Ich behaupte der SPI 
funktioniert auch gleich.
Was wäre der kleinste Aufwand nach der Init was auf dem Display zu sehen 
?
Z.B. ein Pixel oder sowas ?

von Rudolph R. (rudolph)


Lesenswert?

Flo schrieb:
>> Auf was für einem Board sitzt der? Hat das Ding einen Quarz?
> Der FT800 und der lpc sitzen je auf einem breakoutboard und sind mit
> kurzen leitungen verbunden.
> Ich habe wie im Beispiel Design ein 12MHz externen Quarz angeschlossen.

Hmm, interessant, was ist denn das für ein Breakoutboard auf dem der 
FT800 sitzt? Sowas könnte ich auch noch gebrauchen.

> Rudolph R. schrieb:
>> Benutzt Du GCC als Compiler? Was setzt der Compiler denn so automatisch
>> an Symbolen für den Controller?
>> Und poste mal bitte den modifizierten Code aus FT800_config.c
> Benutze Eclipse mit GNU ARM Embedded toolchain
> Benutze ein Makefile, also keine Standard Symbole

Oh doch, klar, es wird immer ein Satz Symbole per Default generiert.
Zum Beispiel eben "__GNUC__" für GCC, sowas wie "__ARM__" oder noch 
besser noch "__LPC1768__" muss auch da sein.

Was bräuchte ich denn im besonderen so um das hier bauen zu können?

> Ich habe Deinen Code der config.c kopiert und lediglich die SPI Lese-
> und Schreibe Routinen auf die Register des LPC abgeändert. Also so gut
> wie keine Änderung.

Mich interessieren ja gerade die Controller-spezifischen Änderungen um 
das in meinen Code mit einbauen zu können.

Wie schnell hast Du den SPI laufen?
Zum Init darf das nicht schneller als 11MHz sein, danach 30MHz.

Das ganze SPI Setup ist ja bewusst nicht Teil von meinem Code.

> Rudolph R. schrieb:
>> Na, zum einen ist die Liste nicht abgeschlossen, wird also gar nicht
>> angezeigt, zum anderen kennt der FT800 gar kein cmd_setbitmap().
> Ok das ist ein Argument :-)
> Habe es mit Deinem Code oben versucht aber es tut sich nach wie vor
> nichts.
> Kann man hier systematisch Fehlersuche betreiben ?
> Der Init Code ist ja absolut identisch zu Deinem. Ich behaupte der SPI
> funktioniert auch gleich.
> Was wäre der kleinste Aufwand nach der Init was auf dem Display zu sehen
> ?
> Z.B. ein Pixel oder sowas ?

Pixel gibt es nicht in dem Sinne, jedenfalls nicht so einfach.

Das einfachste wäre die Farbe zu ändern.
1
ft800_init();
2
3
while(ft800_busy() == 1);
4
ft800_get_cmdoffset();
5
6
ft800_cmd_dl(CMD_DLSTART); // Start the display list
7
ft800_cmd_dl(DL_CLEAR_RGB | 0xff0000); // rot
8
ft800_cmd_dl(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG);
9
10
ft800_cmd_dl(DL_DISPLAY);
11
ft800_cmd_dl(CMD_SWAP);
12
ft800_cmd_execute();

Aber da bei Dir der Bildschirm weiss bleibt und in der Liste schwarz 
steht ist davon auszugehen, dass schon das ft800_init() nicht richtig 
durch läuft.

Wobei in der ft800_init() auch schon eine aller erste Liste geschrieben 
wird:
1
ft800_memWrite32(FT_RAM_DL, DL_CLEAR_RGB);
2
ft800_memWrite32(FT_RAM_DL + 4, (DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG));
3
ft800_memWrite32(FT_RAM_DL + 8, DL_DISPLAY);  // end of display list
4
ft800_memWrite32(REG_DLSWAP, FT_DLSWAP_FRAME);

Das sieht anders aus weil das direkt in den Listen-Speicher geschrieben 
wird, oben geht das über den Command-co-prozessor.
Wie auch immer, auch diese Display-Liste macht einen schwarzen 
Hintergrund mit der ersten Zeile. Das BLACK ist ja nur 0x000000.

Also noch einfacher wäre, nur das ft800_init() zu machen und dort die 
Farbe zu ändern um zu schauen ob sich das manipulieren lässt.

von Rudolph (Gast)


Lesenswert?

Ich habe gerade im Code von Glyn nachgesehen und es gibt eine Config für 
das ET0350, probier mal das hier:
1
// ET0350 Glyn, untested: 320x240 3.5"
2
#ifdef FT_ET0350
3
#define FT_VSYNC0  (0L)  // Tvf Vertical Front Porch
4
#define FT_VSYNC1  (3L)  // Tvf + Tvp Vertical Front Porch plus Vsync Pulse width
5
#define FT_VOFFSET  (4L)  // Tvf + Tvp + Tvb Number of non-visible lines (in lines)
6
#define FT_VCYCLE  (263L)  // Tv Total number of lines (visible and non-visible) (in lines)
7
#define FT_VSIZE  (240L)  // Tvd Number of visible lines (in lines) - display height
8
#define FT_HSYNC0  (0L)  // Thf Horizontal Front Porch
9
#define FT_HSYNC1  (30L)  // Thf + Thp Horizontal Front Porch plus Hsync Pulse width
10
#define FT_HOFFSET   (33L)  // Thf + Thp + Thb Length of non-visible part of line (in PCLK cycles)
11
#define FT_HCYCLE   (408L)  // Th Total length of line (visible and non-visible) (in PCLKs)
12
#define FT_HSIZE  (320L)  // Thd Length of visible part of line (in PCLKs) - display width
13
#define FT_PCLKPOL   (0L)  // PCLK polarity (0 = rising edge, 1 = falling edge)
14
#define FT_SWIZZLE   (0L)  // Defines the arrangement of the RGB pins of the FT800
15
#define FT_PCLK    (8L)  // 48MHz / REG_PCLK = PCLK frequency
16
#define FT_TOUCH_RZTHRESH (1200L)  // touch-sensitivity
17
#endif

von Flo (Gast)


Lesenswert?

Hallo Rudolph,

vielen dank für Deine Mühe. Ich habe das Display nun mehr oder weniger 
zufällig zum Laufen gebracht. Sobald das DISP Signal deaktiviert ist 
läuft alles wie gewünscht.
ft800_memWrite8(REG_GPIO, 0);
Verstehe ich zwar nicht aber ok

Lasse mir nun Dein jpg3 am Display anzeigen. Das funktioniert soweit.
Nun möchte ich das gegen ein 320x240 Bild austauschen. Ich habe mir nun 
ein Bild auf die Größe konvertiert und es durch den Image Converter von 
FTDI durchlaufen lassen. Der schmeißt nun einige Ausgabedateien.

Das PNG aus dem Converter habe ich wieder in jpg gewandelt und will die 
ersten 4k am Display anzeigen. Das funktioniert nicht. es bleibt der 
schwarze Hintergrund.
Ich hätte erwartet dass die ersten 4k Bildmaterial im 320x240 Frame 
angezeigt werden.

Wenn ich den Pointer meines Bildes auf den des jpg3 ändere dann erkennt 
man in der oberen Hälfte die Farben des jpg3 und der Rest ist Pixel 
Random.

Gehe davon aus dass es an meinem Bild liegt. Vieleicht gibt es ja 
320x240 Bild was funktioiert so dass ich das besser Testen kann.

von Rudolph R. (rudolph)


Lesenswert?

Äh okay, das liegt dann an dem immer noch nicht näher beschriebenen 
Breakout-Board. :-)

Ein Bild mit 320x240 wird mit dem alten Code nicht klappen, das 
cmd_loadimage kann nämlich nur 4k Daten laden bzw. knapp unter 4k.
Was aus dem Bilder-Converter von FTDI purzelt wird mit cmd_inflate 
geladen, das kann aber ebenfalls nur 4k so wie das programmiert ist.

In der aktuellen Version kann cmd_loadimage() bis 64k laden.
Aber cmd_inflate() habe ich noch nicht weiter aufgebohrt, weil das eher 
für sowas wie Icons und Logos Sinn macht und dabei die 4k nicht so 
einschränkend sind.

von Flo (Gast)


Lesenswert?

Rudolph R. schrieb:
> Ein Bild mit 320x240 wird mit dem alten Code nicht klappen, das
> cmd_loadimage kann nämlich nur 4k Daten laden bzw. knapp unter 4k.
Das hatte ich schon gelesen aber wenn ich die ersten 4k des Bildes lade 
müsste man ja schon den oberen Teil des Bildes sehen oder habe ich da 
einen Denkfehler ?

Rudolph R. schrieb:
> What is needed is to extend ft800_cmd_loadimage() to handle buffers that
> are larger than 4k in chunks of a little less than 4k.
> It's like this:
> start-command
> send 4k data
> execute
> wait
> send 4k data
> execute
> wait
> send remaining data
> execute
> done
Funktioniert das so nicht ?

von Flo (Gast)


Lesenswert?

Rudolph R. schrieb:
> Äh okay, das liegt dann an dem immer noch nicht näher beschriebenen
> Breakout-Board. :-)
Das ist ein ganz normales breakout board für das qfn48 gehäuse wobei 
jeder pin auf eine Steckleiste geführt ist und dann auf einem steckbrett 
weiter verbunden werden kann
ähnlich wie dieses
https://electronic-things.co.uk/wp-content/uploads/2014/08/PCB-ADP-QFN48-01A.jpg

Achso eine Sache interessiert mich noch
FT8_cmd_loadimage(0, FT_OPT_NODL, jpg3 , jpg3_size);
stellt mir ja Dein jpg3 am Bildschir dar.

Übertrage ich 100 Bytes weniger dann bleibt der ganze Bildschirm schwarz
FT8_cmd_loadimage(0, FT_OPT_NODL, jpg3 , jpg3_size-100);
Warum muss das ganze Bild übertragen werden, woher weiß der Chip das ?
Wenn ich 100 Bytes weniger übertrage müsste das Bild doch fast komplett 
dargestellt werden und die letzten 100 Bytes Pixel eben Random Farben. 
Der Header ist doch ganz am Anfang ?

von Rudolph R. (rudolph)


Lesenswert?

Flo schrieb:
> Das hatte ich schon gelesen aber wenn ich die ersten 4k des Bildes lade
> müsste man ja schon den oberen Teil des Bildes sehen oder habe ich da
> einen Denkfehler ?

Das funktioniert nicht mit der Kompression, die Daten sind dann einfach 
nicht vollständig.

> Rudolph R. schrieb:
>> What is needed is to extend ft800_cmd_loadimage() to handle buffers that
>> are larger than 4k in chunks of a little less than 4k.
>> It's like this:
>> start-command
>> send 4k data
>> execute
>> wait
>> send 4k data
>> execute
>> wait
>> send remaining data
>> execute
>> done
> Funktioniert das so nicht ?

Doch, im Grunde genommen ja, das ist nur im der "Spielplatz" Version 
noch nicht implementiert, in der aktuellen Version aber schon.
Mit der "Spielplatz" Version bekommt man das nur hin indem man die 
Funktion umschreibt, mit den Funktionen die da sind geht es nicht.

Flo schrieb:
> Das ist ein ganz normales breakout board für das qfn48 gehäuse wobei
> jeder pin auf eine Steckleiste geführt ist und dann auf einem steckbrett
> weiter verbunden werden kann

Ach so, dann ist eben die Frage wie das konkret verdrahtet ist.

: Bearbeitet durch User
von Rudolph R. (rudolph)


Lesenswert?

Ich habe mal ein Github Repository dafür angelegt:
https://github.com/RudolphRiedel/FT810-FT813

Ist ein Anfang und noch nicht ganz auf dem aktuellen Stand, da ich die 
neuesten Dateien gar nicht hier habe im Moment.

Was noch pro-forma gefehlt hat war eine Lizenz dafür, ich habe mich für 
die MIT-Lizenz entschieden.

von Rudolph R. (rudolph)


Lesenswert?

Kann nicht mehr editieren, hab das nochmal umbenannt:

https://github.com/RudolphRiedel/FT800-FT813

von Peter (Gast)


Lesenswert?

Hallo,

Super Lib! Vielen Dank dafür!
Bin gerade mich dabei einzuarbeiten, bringe schon manchmal auch Text 
aufs Display, habe aber seltsames Verhalten welches ich mir nicht 
erklären kann:

Zum Beispiel ich gebe sowas aus:

const Long_t items1[] = {
  CLEAR_COLOR_RGB(0,0,0),
  CLEAR(1,1,1),
  COLOR_RGB(255,255,255),
  BEGIN(FT8_BITMAPS),
    VERTEX2II(220,110,31,'F'),
    VERTEX2II(244,110,31,'T'),
    VERTEX2II(270,110,31,'D'),
    VERTEX2II(299,110,31,'I'),
  END(),

  COLOR_RGB(160,22,22),
  POINT_SIZE(320),
  BEGIN(FT8_POINTS),
    VERTEX2II(192,133,0,0),
  END(),
};
#define LIST_ELEMENTS(x) (sizeof(x)/sizeof(Long_t))

  FT8_start_cmd_burst();
  FT8_cmd_dl(CMD_DLSTART);
  for (i=0; i<LIST_ELEMENTS(items1); i++) {
    FT8_cmd_dl(items1[i]);
  }
  FT8_cmd_dl(COLOR_RGB(255,255,0));
  FT8_cmd_text(5, 30, 28, 1, "TEST!");
  FT8_cmd_dl(DISPLAY());
  FT8_cmd_dl(CMD_SWAP);
  FT8_end_cmd_burst();
  FT8_cmd_execute();

Das funktioniert soweit.
So, weiter im Code wenn ich jetzt wieder etwas ausgeben will mit:

  FT8_cmd_dl(CMD_DLSTART);
// FT8_cmd_dl(CLEAR(1,1,1));
  FT8_cmd_dl(COLOR_RGB(255,255,255));
  FT8_cmd_text(55, 30, 28, 31, "TEXT!");
  FT8_cmd_dl(DISPLAY());
  FT8_cmd_dl(CMD_SWAP);
  FT8_cmd_execute();

bekomme ich nur weisse vertikale Linien von oben bis unten angezeigt, 
und zwar an der Stelle wo der Text zu erwarten wäre.
Wenn ich nach dem CMD_DLSTART den Bildschirm lösche (dh: CLEAR(1,1,1)) 
kommt der Text. Der Punkt ist: ich will nicht den Bildschirm löschen. 
Irgendwie ergibt das keinen Sinn.
Was mache ich falsch?

Viele Grüße
Peter

von Rudolph R. (rudolph)


Lesenswert?

Hmm, keine Mail dazu erhalten...

Peter schrieb:
> Wenn ich nach dem CMD_DLSTART den Bildschirm lösche (dh: CLEAR(1,1,1))
> kommt der Text. Der Punkt ist: ich will nicht den Bildschirm löschen.
> Irgendwie ergibt das keinen Sinn.

Das CLEAR hat im Handbuch die Beschreibung "Clear buffers to preset 
values" und macht wohl noch mehr als beschrieben wird.
Aber ein clear-screen macht es im eigentlich Sinne nicht da es ja gar 
kein Bildschirm-RAM gibt das gelöscht werden könnte, das Bild wird ja 
immer wieder neu zusammen gebaut.
Natürlich hat es den Effekt von clear-screen wenn sowieso nichts anderes 
in der Liste steht, das bereitet aber offenbar eher das neu-zeichnen vor 
indem irgendwelche Werte zurück gesetzt werden, also zusätzlich zu den 
Parametern.

Die Display-Liste wird mit der Wiederhol-Rate die sich aus den 
Display-Parametern ergibt abgearbeitet, typischerweise mit 60Hz.
Gibt man dem eine neue Liste wird am Ende der vorher benutzen auf die 
neue umgeschaltet und dann diese mit 60Hz abgearbeitet.
Das ist auch eines der Limits, man darf nicht versuchen die Liste öfter 
zu schreiben als sie abgearbeitet wird.

An den Dingern ergibt vieles wenig Sinn wenn man tiefer rein schaut.
Zum einen ist die Dokumentation an ein paar Stellen schlicht falsch oder 
einfach nur schwach und FTDI/Bridgetek bekommt es nicht gebacken 
gemeldete Fehler auch mal in ein Update zu giessen.
Andere Dinge wie zum Beispiel die VERTEX2II und VERTEX2F Kommandos die 
man ja zur Positionierung von Objekten benötigt sind ziemlich blöd 
angelegt.
Statisch ist das noch okay, da kümmert sich der Prä-Prozessor um die 
Berechnung der Konstanten, dynamisch kostet der Murks aber plötzlich 
richtig Rechenzeit auf den als Ziel-Gruppe auserkorenen 8-Bit 
Controllern.

Also einfach machen, das CLEAR tut nicht weh indem das etwa zu einem 
flackern des Bildschirms führt oder zu einer deutlichen Verzögerung wie 
das bei einfachen LCDs der Fall wäre.

Dennoch kann man sich ja ersparen statische Inhalte immer und immer 
wieder an den FT8xx zu schicken, das habe ich in dem Beispiel ja mit dem 
CMD_APPEND umgesetzt, da wird einfach einmal ein Listen-Fragment 
generiert im Speicher vom FT8xx und anschliessend immer wieder in die 
Liste eingebaut. Da gehen dann pro Update nicht die vcllen 1500 Bytes 
über den SPI die für die Liste gebraucht werden, sondern vielleicht nur 
noch die 300 mit den veränderlichen Inhalten.
Das lässt sich auch problemlos mit mehreren Seiten umsetzen indem 
einfach mehrere Listen-Fragmente vorab generiert werden.

Welches Display hast Du eigentlich und welchen Controller setzt Du ein?

von Peter (Gast)


Lesenswert?

Hallo Rufolph,

Vielen Dank für Deine Antwort. Ich habe hier Atmel SAM4E mit FT810 und 
einem 800x480 Display.
Habe vorher mit ATmega2560 und einem eDIP128 gearbeitet, da konnte ich 
nur ausgewählte Bereiche löschen und neu beschreiben, das ging relativ 
ressourcenschonend weil nicht das ganze Bild durch die langsame 
Schnittstelle des eDIP durch musste. Deshalb habe ich angenommen, daß 
ich hier auch so arbeiten kann.
Bei dem FT8xx musste ich dann feststellen, daß das Vorgehen so nicht 
geht. Es hat dann irgednwann klick gemacht und ich habe begriffen, daß - 
egal bei welcher Änderung - ich das Bild neu aufgbauen muss. Ja, das mit 
dem Append habe ich verstanden, ist mir aber zu unsicher, weil ich nie 
wissen kann was gerade angezeigt wird und manchmal muss man eben paar 
Elemente ausblenden, also neu aufbauen erscheint mir schon sicherer.

Ich arbeite viel mit Bildelementen, das erfordert einen 
Ressourcenmangement.
Dafür habe ich mir einen Ressourcen Manager gebaut, der nimmt die 
Ressourcen (BIN/PNG/JPG Daten), dekomprimiert sie im RAM_G und hängt sie 
dicht an dicht hintereinander, dann referenziere ich sie nur:
zB:
resmgr_load(tabelle);
resmgr_set(bildref, x,y);

Die Ressourcen sind in Tabellen organisiert die bei Bedarf umgeladen 
werden. Dabei spielt es keine Rolle ob Inflate oder Loadimage benutzt 
wird, was benutzt wird in der Tabelle vermerkt. So kann ich JPG mit PNG 
und BIN gemischt benutzen. Für die Erstellung von Ressorce-Tabellen habe 
ich einen Python Script, der mir die Bilder umwandelt (img_cvt.exe), die 
Offsets nach dem INFLATE ermittelt und die Tabelleneinträge zum 
Copy&Paste ausgibt. Das erspart mir das manuelle Setzen von Adressen per 
Konstanten.

Habe schon etliche PNG Bilder als BIN reingeladen und auch PNGs und JPG. 
PNGs und BINs hatten Transparenzen, klappte auch alles.
Dabei habe ich eine Beobachtung gemacht: ich habe hier ein Bild, das 
habe ich als BIN reingeladen und es wird einfach nicht dekomprimiert.

Zunächst ein Gut Fall zum Vergleich:
Zum Testen habe ich ein Bild an RAM_G Adresse geladen (INFLATE) und 
angezeigt.
Zum Prüfen habe ich:
1) vor dem INFLATE die ersten 4 bytes zunächst mit 0x12345678 
beschrieben
2) ein INFLATE mit einem BIN (aus PNG) an RAM_G Adresse ausgeführt
3) und die 4 ersten Bytes wieder gelesen
da waren meine 4 bytes mit den Daten vom RAW Bild überschrieben, also 
alles wie erwartet. Bild wird später ohne Probleme angezeigt.

Dann habe ich ein anderes Bild genommen, BIN (ARGB1555) Länge 25960 und 
RAW Länge nach dem INFLATE sind 142800 Bytes. Hier funktionierte das 
INFLATE nicht!
Die o.g. 4 Bytes waren immer noch die selben und das Bild wurde auch 
nicht angezeigt. Waren hier drin noch Daten vom anderen Bild drin, dann 
konnte ich die verzerrte Darstellung des alten Bildes erkennen (wegen 
der unterschiedlichen Bild-Auflösung).

Ich habe keine Ahnung warum gerade dieses Bild nicht funktioniert, mit 
den anderen viel kleineren habe ich keine Probleme.
Habe sogar (linux) das BIN Bild manuell inflated und mit dem RAW bild 
verglichen, passt. Es ist so, als ob INFLATE eine Beschränkung auf dem 
Chip hat.

Habe die Kommunikation mit dem Oszi überprüft. Alles ist scheinbar wie 
immer. Habe den Anfang und Ende der Daten verglichen, auch den 
wiederholten FT8_busy() am Ende wo auch der Zähler immer weiter zählt 
bis er fertig ist.

Sind Dir irgendwelche Einschränkungen bei der Benutzung von INFLATE 
bekannt? Größe? Sonst was?

In Deinem Artikel auf www.mikrocontroller.net/articles/FT8xx_Library 
schreibst Du, daß INFLATE mehr für Monochrome Bilder geeignet ist, 
warum? Ich habe keine Hinweise im Programmer Guide gefunden.

Gruß
Peter

von Peter (Gast)


Lesenswert?

Mist! Sorry, habe Deinen Namen falsch geschrieben :-/

von Rudolph R. (rudolph)


Lesenswert?

Da habe ich mich gerade gewundert, warum ich wieder keine Benachrichtung 
erhalten habe, aber es wurde gepostet zwischen checken der Mails und 
checken des Threads, die Mails sind da. :-)

Peter schrieb:
> Mist! Sorry, habe Deinen Namen falsch geschrieben :-/

Man kann man hier aber editieren, auch für solche erste-Welt Probleme. 
:-)

Peter schrieb:
> Sind Dir irgendwelche Einschränkungen bei der Benutzung von INFLATE
> bekannt? Größe? Sonst was?

Yup, cmd_inflate hat immer noch die 4k Beschränkung drin.
Ich hatte mal versucht da was dran zu drehen, hat aber nicht geklappt, 
warum auch immer - das kommt davon wenn man den Code zu lange nicht 
aktiv braucht und das gelegentliche Projekt nur ein Subset der 
Möglichkeiten benötigt...

Peter schrieb:
> In Deinem Artikel auf www.mikrocontroller.net/articles/FT8xx_Library
> schreibst Du, daß INFLATE mehr für Monochrome Bilder geeignet ist,
> warum?

Naja, nicht ganz meine Wortwohl. :-)
Da gehen verschiedenen Dinge ein.
Und ich bekomme das gerade nicht zufriedenstellend klar ausformuliert. 
:-)

Monochrom, bzw. mit bis zu 256 Graustufen benutze ich Symbole und Icons, 
da speichert .jpg nicht nur zu viele Informationen mit, es erzeugt durch 
die Kompression auch noch Artefakte, vor allem in Flächen.
Das ist jetzt schwer den Finger da drauf zu legen und sicher nicht 
allgemeingültig, aber ein Bild mit komprimierten 4kB hat in Inflate 
gefühlt eine höhere Qualität als in .jpg.
Man könnte zwar noch .png anführen für Verlust-freie Kompression, gerade 
bei technischen Zeichungen packt das ja besser als .jpg und dazu ohne 
Artefakte, dafür sind die FT81x aber auch etwas zickig bei .png.

Bei Farb-Bildern, vielleicht gar Fotos, kann sich .jpg voll austoben.

Bringt natürlich auch nichts, wenn man monochrome Bilder nicht 
konsequent als .bmp oder .png bearbeitet, sobald man das als .jpg 
speichert sind Artefakte drin die man nicht mehr raus bekommt.

Ech ja, grundsätzlich hätte ich ja interesse an den 
Anpassungs-Funktionen für den SAM4E. :-)

: Bearbeitet durch User
von Peter (Gast)


Lesenswert?

Hallo Rudolph,

ah, danke, 4K, das werde ich berücksichtigen.

Zum Code: bitte schön:

im FT8_config.h zusätzlich:

// SPI kommt aus dem ASF
#define FT8_SPI        SPI

// SPI_TIMEOUT kommt aus dem ASF
#define FT8_SPI_TIMEOUT    SPI_TIMEOUT

// delay_ms von ASF
#define DELAY_MS       delay_ms

// habe 12MHz Quarz am FT810
#define FT8_HAS_CRYSTAL 1

#define FT8_RETURN_ERROR  0xff

#define CS_FT800        IOPORT_CREATE_PIN(PIOA, 8)
#define PD_DISP         IOPORT_CREATE_PIN(PIOD, 22)

//uint8_t fetch_flash_byte(const uint8_t *data);
#define fetch_flash_byte(addr)  (*(addr))


dann habe ich eine eigene FT8_io.c:


void FT8_pdn_set(void)
{
  ioport_set_pin_level(PD_DISP, IOPORT_PIN_LEVEL_LOW);
}

void FT8_pdn_clear(void)
{
  ioport_set_pin_level(PD_DISP, IOPORT_PIN_LEVEL_HIGH);
}

void FT8_cs_set(void)
{
  ioport_set_pin_level(CS_FT800, IOPORT_PIN_LEVEL_LOW);
}

void FT8_cs_clear(void)
{
  ioport_set_pin_level(CS_FT800, IOPORT_PIN_LEVEL_HIGH);
}

void spi_transmit(uint8_t data)
{
  uint32_t timeout = FT8_SPI_TIMEOUT;
  while (!spi_is_tx_ready(FT8_SPI)) {
    if (!timeout--) {
      return;
    }
  }
  spi_write_single(FT8_SPI, data);

  timeout = FT8_SPI_TIMEOUT;
  while (!spi_is_rx_ready(FT8_SPI)) {
    if (!timeout--) {
      return;
    }
  }
}

uint8_t spi_receive(uint8_t data)
{
  uint8_t val;

  uint32_t timeout = FT8_SPI_TIMEOUT;
  while (!spi_is_tx_ready(FT8_SPI)) {
    if (!timeout--) {
      return FT8_RETURN_ERROR;
    }
  }
  spi_write_single(FT8_SPI, data);

  timeout = FT8_SPI_TIMEOUT;
  while (!spi_is_rx_ready(FT8_SPI)) {
    if (!timeout--) {
      return FT8_RETURN_ERROR;
    }
  }
  spi_read_single(FT8_SPI, &val);

  return val;
}

Die Funktionen spi_... stammen aus dem ASF, welches sich beim SAM 
ohnehin empfiehlt. Damit sie gehen setzt natürlich voraus, daß man ASF 
richtig initialisiert hat, was aber mit Atmel Studio kein Problem ist. 
Man braucht dafür eigentlich keine Hardware-Register anfassen :-)
Der o.g. Kram dürfte damit mit allen SAMs funktionieren.

Hierbei sei angemerkt, daß ich die CS manuell bediene, vielleicht ein 
wenig untypisch bei den SAMs mit ASF.
Dort gibt es eigentlich eine Möglichkeit über die Systemfunktionen, dh. 
CS wird dann automatisch bedient. Ist aber bei mir wegen der Hardware 
nicht anders möglich.

Gruß
Peter

von Peter (Gast)


Lesenswert?

Ähmm..habe jetzt das Bild als PNG (das <name>_Converted.png) mit 
Loadimage ARGB1555 und das wird nun angezeigt aber mit falschen Farben 
und ohne Transparenz.

Eine Idee?

von Peter (Gast)


Lesenswert?

die Transparenz ist doch da, aber die Farben sind falsch.

von Rudolph R. (rudolph)


Lesenswert?

Mehr als das ich dem .png Support nach ersten Versuchen nicht mehr so 
richtig vertraue fällt mir da spontan auch nicht ein. :-)
Transparenz und so, die FT8xx können noch eine Menge was ich noch gar 
nicht ausprobiert habe. :-)
Und wie wir oben im Thread gelernt haben kann man .png auch nicht mal 
eben einfach so zum testen anhängen, weil die Forums-Software die 
automatisch durchmangelt.

von Mark (Gast)


Lesenswert?

Hi after a long experiments with different STM32 discovery boards using 
HAL drivers and a FT810 display it seems the initial setup of the FT810 
chip has to be done at a SPI speed between 375 and 600kHz. (not exactly)

The first test was at 48mHz and a SPI speed of 375kHz. Driver works ok.

The next STM32F407 was running at 168mhz so my SPI speeds was 656kHz or 
one step lower 328kHz so that is too low or too high. The low speed init 
seems to work. The 0x7C is replied but nothing on screen. It took lots 
of debugging to find out the hardware was not the problem.
With a main clock of 150Mhz and SPI 585kHz it all works ok.

The datasheet talks only of a low speed and high speed lower than 30mHz 
no exact numbers.

von Rudolph R. (rudolph)


Lesenswert?

Mark schrieb:
> Hi after a long experiments with different STM32 discovery boards using
> HAL drivers and a FT810 display it seems the initial setup of the FT810
> chip has to be done at a SPI speed between 375 and 600kHz.

Not quite.
While it is correct that the SPI speed has to be lower during setup than 
the maximum of 30MHz, it is not that low.

It just needs to be 11MHz or less.
As the AVR "only" allow up to 8MHz I do not even bother to use different 
speeds.
For faster CPUs such as the RH850 I switched to more than 11 MHz after 
init.

As for the documentation, this is interesting.
While the datasheet and programmers manual for the FT800 clearly state 
it:

4.2.3 Clock Enable
"If  SPI  is  used  as  host  interface,  the  SPI  clock  shall  not 
exceed  11MHz  before  system  clock  is
enabled. After system clock is properly enabled, the SPI clock is 
allowed to go up to 30MHz."

2.2.5 Initialisation Sequence
"This section describes the initialization sequence in the different 
scenario.
  Initialization Sequence during the boot up:
1.  Use MCU SPI clock not more than  11MHz"

The datasheet and programmers guide for FT81x have these limitations 
removed.

See 4.2.3 of the datasheet and 2.3 of the programmers manual.
The example in the programmers manual however still is the same and 
reads:
"MCU_SPI_CLK_Freq(<11MHz);//use the MCU SPI clock less than 11MHz"

So maybe, this limitation does not even aply anymore to the FT81x 
series.

In any case, if you can't go higher than 600kHz during init it is not 
because the FT8xx won't go any higher.

Is DELAY_MS() working correctly?
It is only used during FT8_init() but is has to be good enough to meet 
the power-down cycle requirements of the FT8xx.
If a DELAY_MS(1) is below 950µs it is possible that the FT8xx won't even 
take any commands when FT8_init() starts sending them out.

von stromverdichter (Gast)


Lesenswert?

@Marc
I use the FT800 with different processors from atmel and even a STM407 
with the SPI-Clock of ~8 Mhz at startup and ~24Mhz later without any 
issues. So you seem to have a problem with your personal composition. 
The chip is working here as described in the datasheet.

von mark (Gast)


Angehängte Dateien:

Lesenswert?

Was someone able to use the FT8_cmd_setfont2 command? It nearly works 
there should be numbers only.The font is generated by eve studio.
The commands are:
FT8_cmd_inflate(0, fonts_Art,sizeof(fonts_Art));
FT8_cmd_setfont2(0, 0, 116);
FT8_cmd_text(96, 207, 0, 0, "tuvwxyz{|}~");

This is because i want real big numbers so only char 116-127 are used. 
So the t is shown as 0

von Roberto (Gast)


Lesenswert?

Hallo Freunde des FT8xx,

ich möchte meine Erfahrungen zum Thema FT8xx und jpg’s einbringen. 
Vielleicht kann ich ein wenig helfen.

1.  Der FT8xx mag nur reine jpg’s  ohne Exif oder sonstige integrete 
Infos.
2.  Tritt beim laden des jpgs ein Fehler auf wird REG_CMD_READ auf 0xFFF 
gesetzt, der FT hängt.

Siehe FT81X_Series_Programmer_Guide ---  5.6 Fault Scenarios.
Mein Vorschlag für Rudolphs Lib, das REG_CMD_READ abfragen und wenn 
0xFFF den Co-Processor zu reseten.

Zu 1.
Meine jpgs  passe ich mit meiner Bildsoftware der Displaygröße oder 
kleiner an und speichere diese. Danach rufe ich  Irfanview auf und 
speichere die Bilder erneut, aber ohne Dateiinfos. Damit läuft alles 
prima.
Gruß

von Peter (Gast)


Lesenswert?

Hallo Rudolph,

ich glaube das ist ein Copy&Paste Fehler in der FT8_commands.c:

uint16_t FT8_cmd_getptr(void)
{
  uint16_t offset;

  FT8_start_cmd(CMD_MEMCRC);  // soll das nicht CMD_GETPTR heissen?
  ...

Gruß
Peter

von Rudolph R. (rudolph)


Lesenswert?

Danke, ist gefixt, Kommandos die keiner braucht... :-)

Ich habe schon wieder viel zu lange nichts aktiv damit gemacht, sind 
zwar immer alle schwer beeindruckt wenn ich das vorführe und was dazu 
erzähle, konkrete Projekte ergeben sich daraus aber eher nicht so wie 
ich mir das erhofft hatte...

von Peter (Gast)


Lesenswert?

Hallo Rudolph,

ich arbeite konkret damit und bin Dir für Deine Arbeit dankbar :-)

Habe mir noch eine FT8_cmd_execute() Variante ohne wait gemacht, weil 
dann der Controller auch anderes erledigen kann statt Däumchen zu drehen 
während er auf ein gesetztes Bit wartet nur um sauber abzuschliessen. 
Die Busy-Prüfung mache ich dann beim nächsten Eröffnungskommando, dh. 
wenn ich den Bildschirm neu aufbaue.
Ansonsten funzt die Lib sehr stabil, mach auch kleine Animationen damit 
(durch Bilder umschalten).

Gute Arbeit!

Viele Grüße
Peter

von Rudolph R. (rudolph)


Lesenswert?

Hallo,

ich habe gerade eine FT8_cmd_start() Funktion implementiert die nicht 
wartet und mit der die Liste nach einem größeren Update aktualisiert 
werden kann.
Naja, eigentlich habe ich alles bis auf das busy() aus FT8_cmd_execute() 
in FT8_cmd_start() verschoben und FT8_cmd_execute() ruft jetzt 
FT8_cmd_start() auf und busy().

Vielen Dank für den Hinweis, keine Ahnung wie ich das übersehen habe.
Ich hatte zwar mal geprüft wie lange die Ausführung von einigen 
Kommandos so dauert, aber nicht für das Update der grossen Liste.

In meiner Test-Version die ich über einen Timer mit eifachem Profiling 
versehen habe geht die Zeit von 2600µs auf 1900µs zurück, der FT811 der 
in diesem Display ist braucht also 700µs alleine nur um dieses 
Bildschirm-Update zu verarbeiten, sehr nice, schlapp 27% der Zeit hat 
die Funktion also noch sinnlos den Controller blockiert.

Darf ich fragen, was Du damit machst, mit welchem Display und welchem 
Controller?

Ich nutze das hauptsächlich beruflich, da ich das alles aber in meiner 
Freizeit entwickelt habe auf privat gekaufter Hardware und es dann in 
den Job eingebracht habe um Projekte zu starten, habe ich mir halt auch 
erlaubt das zu veröffentlichen.
Nur hatte ich damit bisher weniger Projekte als erhofft.

von pgue (Gast)


Lesenswert?

Hallo Rudolph und Experten,

ist das Thema abgeschlossen oder bietet sich die Chance noch paar Fragen 
anzuschließen ?

Ein gutes 3/4 Jahr zu diesem Thema und echt viele Erkenntnisse. Ich gehe 
zwar einen etwas anderen Weg, habe aber immer mal paar grundsätzliche 
Probleme.

Zu meinem Projekt: Ich benutze (noch) den FT800 und als Host einen 
pobligen PIC (18F2550, low cost!). Programmiert habe ich ausschließlich 
in asm, um mir die Kosten für einen brauchbaren C-Compiler für den PIC 
zu sparen (die free-Version von Microchip ist zu schlecht, die Liz. 
unerschwinglich teuer). Mittlerweile ist genug implementiert, dass ich 
meine Oberflächen nur noch mit dem FTDI Screen Editor entwerfe, das 
Ergebnis als .proj-Datei mit einem "Code-Generator" zu Assembler-Code 
für den Pic umsetze. Der Code-Generator liefert mir Include-Files, die 
einfach in die Applikation includiert werden. Um die Bilder auch in der 
App ändern zu können werden vom Code-Generator Funktionen generiert, mit 
denen der Bildinhalt verändert werden kann. Ist zwar alles noch nicht 
fertig, aber geht  soweit ganz ordentlich. Eine expliz. Library verwende 
ich nicht, sie ist quasi Bestandteil des Appl.Bodys (jede Menge simple 
Funktionen). Diese Grundfunktionen schreiben in einen Ring-Buffer 
Display-Adresse und Daten, die zum FT800 über die SSP-Schnittstelle 
übertragen werden. Und zwar nur dann, wenn am Bild sich etwas ändert 
(die Daten werden direkt in die DisplayListe des FT800 geschrieben).

Nun aber zu meinem (ungelösten) Problem: Zwar bekomme ich mit schöner 
Regelmäßigkeit einen INT_TOUCH und INT_TAG Interrupt, wenn ich aber das 
REG_TOUCH_TAG Rgister auslese, bekomme ich nur 0x00 Resultate. Den 
INT_TAG bekomme ich (korrekt) immer dann, wenn ich auch die deklarierten 
TAG's touche. Dazu  als Auszug vom Screen-Editor:

CLEAR_COLOR_RGB(0,0,48)
CLEAR(1, 1, 1)
CMD_TEXT(80, 50, 25, 0, "Auswahl Anwendung")
CMD_TEXT(5, 250, 21, 0, "@ Bla Bla")
CMD_FGCOLOR(0x700000)
TAG(12)
TAG_MASK(1)
CMD_BUTTON(360, 200, 70, 35, 27, 0, "OFF")
TAG_MASK(0)
CMD_FGCOLOR(0x003000)
TAG(13)
TAG_MASK(1)
COLOR_A(0)
BEGIN(RECTS)
VERTEX2II(40, 130, 0, 0)
VERTEX2II(230, 170, 0, 0)
END()
COLOR_A(255)
CMD_BUTTON(40, 130, 190, 40, 27, 0, "PedelecMonitor")
TAG_MASK(0)
TAG(14)
TAG_MASK(1)
CMD_BUTTON(245, 130, 190, 40, 27, 0, "WindRichtungsMesser")
TAG_MASK(0)
DISPLAY()
(Das Bild ist auf dem Screen, der Assembler-Code dazu ist zu 
umfangreich, um ihn hier zu zitieren ! Könnte aber die 
gesendeten/empfangenen Daten ggf. für paar -welche?- Kommandos hier 
zitieren, wenn's wem nutzt)

Übrigens: Der Code-Gen. liefert mir auch C++ Code, mit dem kann ich mit 
meinem Lapi auch testen (FTDI USB/SPI Kabel direkt zwischen Lapi und 
Display, Glyn/Adam Display). Auch da gibt es keine TAG-Werte, ausser 
0xFF oder 0x00.

Wer verrät mir, warum dieses wunderbare Wunder ? Sonst wird das einfache 
Bild korrekt angezeigt, auch die XY-Touch-Position wird korrekt 
ausgelesen, nur der TAG-Wert nicht !

Bitte HILFE :-((
Gruss pgue

von pgue (Gast)


Lesenswert?

Hallo liebe Leute

die Ursache ist gefunden :-)
Fehler: Y_HIGH (BIT20) in VERTEX2II nicht richtig gesetzt !!!

Also:
INT_TAG -> read REG_TOUCH_TAG: REG_TOUCH_TAG value = TAG value
danach
INT_TAG -> read REG_TOUCH_TAG: REG_TOUCH_TAG value = 0x00

ansonsten wenn irgendwo getoucht wrd:
INT_TAG -> read REG_TOUCH_TAG: REG_TOUCH_TAG value = 0xFF

(alles im PIC getestet)

Gruss pgue

von Rudolph R. (rudolph)


Lesenswert?

Das Thema ist für mich noch nicht abgeschlossen, ich hoffe gerade wieder 
auf das nächste Projekt dazu.
Aber zum Interrupt kann ich nichts sagen, ich habe die Interrupt-Leitung 
nicht mal angeschlossen, ich polle einfach nur.
Meine Display-Funktion wird alle 10ms aufgerufen. Abwechselnd wird darin 
entweder das Bild aktualisiert oder Touch abgefragt.
Also 50 Bilder pro Sekunde und 50 Abfragen pro Sekunde.

Bisher hat sich das so bewährt, obwohl das tendenziell auch weniger 
Bilder pro Sekunde und mehr Abfragen pro Sekunde sein könnten.
Nur ist das Feedback eh visuell, 120 Abfragen pro Sekunde führen bei 30 
FPS zu keinem schnelleren Feedback.

Mit dem doch recht aufwendigen Test-Projekt bin ich so bei 1900µs für 
ein Bild. Also reserviere ich grade rund 20% Laufzeit für das TFT.
Da kann man aber nicht meckern wenn man bedenkt, dass das 800x480 in 50 
FPS aus einem 16 MHz AVR sind. :-)
Den statischen Teil der Anzeige halte ich dabei im Speicher vom FT813.
Wenn mein SPI schneller wäre würde die Zeit ausserdem verkürzt werden.
In den echten Anwendugen die ich bisher hatte war die Zeit für ein Bild 
sehr viel kürzer, weil der dynamische Teil der Anzeige auch viel kürzer 
war.

Interrupt-gesteuert und nur Änderungen darstellen macht den Aufwand 
etwas schwerer abzuschätzen.
Ich weiss jetzt, dass ich 7+ms Rechenzeit habe um was anderes zu machen, 
und zwar alle 10ms, da könnte ich mich anders nicht unbedingt drauf 
verlassen.
Wenn das nicht mehr reichen sollte würde ich ernsthaft überlegen das 
anders zu machen.

Oh, Du musst bei Interrupts auch aufpassen das die Bildwechsel nicht zu 
schnell aufeinander folgen. Mehr als 60 Hz mögen die FT8xx nicht.

von Robi (Gast)


Angehängte Dateien:

Lesenswert?

Hallo, ich habe mit dem FT8xx vor 2 Jahren ein Projekt (MP3-Player) 
begonnen und meine eigene Lib dazu geschrieben. Meine Hardware besteht 
aus
PIC18F67J50, FT810, VS1053B und Display 3.5" mit 320x480 und MicroSD bis 
max.
64GB. Die FAT32 Lib ist von Elm-chan (FATFS).
Compiler: Mikroe mikroC PRO for PIC. Das Gehäuse habe ich drucken 
lassen.

Gruss

von Rudolph R. (rudolph)


Lesenswert?

Ich bin nicht sicher, was Du uns damit in diesem Thread mitteilen 
möchtest.

von Robi (Gast)


Lesenswert?

Dachte du sucht nach einem Projekt.
Gruss

von Rudolph R. (rudolph)


Lesenswert?

Ah okay, danke für den Vorschlag.
Einfach so zum Spass hätte ich da schon das eine oder andere.
Aber auch schon genug anderes was nicht fertig wird. :-)
So speziall nach einem 3,5" oder kliner mit FT811/FT813 könnte ich mal 
schauen.

Ich nutze die Teile im Job, ich hoffe also darauf das mich mal wieder 
jemand dafür bezahlt das ich ihm was schick visualisiere.
Macht schon was her wenn man für den Prüfstand ein 7" TFT hat.
Ein Kunde hat zum Beispiel für einen Komponententest so ein Teil von uns 
bekommen bei der auf der vebauten Platine noch eine CAN 
Restbus-Simulation lief.
Naja, mein Markt dafür ist etwas begrenzt.

Die Teile sind schon toll, aber gefühlt nehmen die gar keine Fahrt auf.
Mit dem Wechsel von FTDI zu Bridgetek ist nicht mal die Doku besser 
geworden,
geschweige denn, dass da mal was von FT82x zu sehen wäre.
Das Cleo Forum ist auch praktisch tot.

Fairerweise muss man aber auch sagen, TFTs sind keine Commodity Items 
wie 16x2 Text-Displays. Die werden nicht einfach als Standard-Ware auf 
Halde produziert.
Bei den kleinen größen bis vielleicht 3,5" kommt inzwischen auch noch 
die Konkurrenz durch die billigen Chinesischen TFTs dazu.
Die spielen zwar nicht mal ansatzweise in der gleichen Leistungs-Klasse, 
dazu fällt mir nicht mal ein schlechter Vergleich ein, aber hauptsache 
billig.

von Manfred W. (manfred53)


Lesenswert?

Hallo Rudolf und andere FT810 Freunde

ich setze den FT811CB von Watterott ein und habe nach einem 
erfolgreichen Start jetzt plötzlich Probleme mit sporadischen Flackern 
und falschen Touch Werten.

Zum Umfeld: ArduinoMega 2560, SPI an FT811 und an SD Karte, I2C an RTC, 
Servo PWM und TIC Stepper Controller, .

Das ganz soll eine Steuerung für einen Vapor Phase Reflow Ofen werden 
(Umbau eines IMDES Ofens)

Refresh und Auslesen Touch erfolgt mit 10 Hz, also eigentlich nicht zu 
schnell. Aussetzer unabhängig vom Bild Inhalt Auch wenn nur 5 Knöpfe und 
zwei Texte gezeichnet werden.

Ich lasse in der Loop im Sekundentakt Pin13 toggeln als "Lebenszeichen". 
Dieses stockt auch manchmal und der Prozessor hängt.

Hatte sogar mehrmals den eingebauten FTDI Screen.

Verwende im Großen und Ganzen Rudolfs Lib. Um optische Feedback für 
Knöpf zu erhalten werden die CMD Befehle stets wiederholt.

Hat jemand Ähnliches beobachten können oder eine Idee was nicht korrekt 
sein könnte?

von Rudolph R. (rudolph)


Lesenswert?

Flackern hatte ich schon lange nicht mehr, kam eigentlich auch nur bei 
zu schnellen Updates.

Da hilft wohl erstmal nur alles andere abzuschalten und nach und nach
dazu zu packen.
Es gibt zum Beispiel auch SD-Karten Module die den SPI falsch bedienen.

von Manfred W. (manfred53)


Lesenswert?

[solved]

Es war wohl die Standard Arduino SPI Bibliothek.

Ich habe für die Ansteuerung des FT811 eine direkt auf die benutzen 
Ports gehende Software SPI Lösung geschaffen und jetzt läuft's ohne 
flackern und
verwendet 5 nebeneinander liegende Ports 3 bis 7.

von Rudolph R. (rudolph)


Lesenswert?

Also die Standard SPI Lib habe ich auch schon benutzt, von einem 
pro-mini aus, das sollte eigentlich soweit kein Problem sein.

von Juergen (Gast)


Lesenswert?

Hallo Freunde,

erstmal auch recht Herzlichen Dank an Rudolf für den sehr verständlichen 
Code, der so einiges Licht ins Dunkle gebracht hat..

Habe derzeit ein Projekt mit einen FT813. Nun muss ich eine kleine 
Videosequenz darstellen können und möchte hierzu ein AVI-Video abspielen 
können.

Gibt es ein Code-Beispiel, AVI-Videos über den Media-Fifo abzuspielen?

Juergen

von Rudolph R. (rudolph)


Lesenswert?

FTDI hat ja ein Beispiel dafür, oder gar zwei, nicht, dass ich aus dem 
Code den FTDI so verzapft wirklich schlau werden würde. :-)
Aber an dem beigefügten Video sieht man schon mal, dass Format dafür ist 
relativ exotisch.

Na, Media-FIFO an den Start bringen und dann irgendwas machen mit 
CMD_PLAYVIDEO, CMD_VIDEOSTART und CMD_VIDEOFRAME. :-)

Nein, ernsthaft, damit habe ich noch gar nicht gespielt, diese 
Funktionalität geht mir dann doch zu weit.
Und neben der schwachen Beschreibung dazu sieht das auch noch so aus das 
die Geschichte über das Video-Format eingeschränkt ist.
MJPEG ist jetzt nicht so prall für Videos, wenn ich das richtig verstehe 
ist das quasi ein JPEG nach dem anderen, also immer volle Frames.
Das frisst Speicher ohne Ende, die Daten muss man erstmal anständig von 
einer SD-Karte und in den FT813 schaufeln können.
Im Gegensatz zu DIVX und anderen Codecs die nur immer mal wieder einen 
kompletten Frame im Stream haben und dazwischen Differenz-Daten.

Also ich würde mir höchstens eine kurze Animation aus Einzel-Bildern 
schnitzen, dafür brauche ich kein Video-Playback.

Eine andere Sache ist, ich verzichte bewusst auf Massen-Speicher am 
Display, der Fokus liegt für mich darauf das einfach zu halten.
Also liegen meine Bild-Daten auch komplett im Controller.
Selbst ein kurzes Video geht Ruckzuck über 10MB.

: Bearbeitet durch User
von Rudolph (Gast)


Lesenswert?

Oha, es gibt wohl was neues: BT815.
Der wird nächste Woche auf der Embedded-World vorgestellt, ich bin 
gespannt.

von GrzegorzK (Gast)


Lesenswert?

Hello, I am looking for a library for FT813 to nucleo STM32, MBED 
compiler. Could you help me?.
I use Arduino_Riverdi_TFT_shield_Rev.1.2 and Nucleo STM32F103RBT6

https://www.unisystem.pl/pl/products/development-kit/arduino-riverdi-tft-shield.html

best regards
Grzegorz

von Rudolph R. (rudolph)


Lesenswert?

Well, I can not directly help you but it should be pretty easy to adapt 
my code-library to your needs.
That "mbed compiler" should be GCC anyways.

Take a look at FT8_config.c and FT8_config.h.
Only these two carry plattform specific code.
The target the code is compiled for is identified by defines that are 
set by the build enviroment such as "__GNUC__".
You need to look for a define like "__STM32__" or similar and add new 
sections like with the two examples provided.

The "__AVR__" and "__v851__" parts I provided show what could be done.
More clean in the AVR part where you only need to edit the .h, more 
direct in the V851 part where you would need to edit the .c to adapt the 
code to a different board.

Also your code has to provide proper initialisation of the port-pins and 
the SPI, I did not include that at all as I consider it part of main.c.

The clock of the SPI must be below 11 MHz during init of the display.
After init it can be as high as 30MHz but I doubt that will work with a 
setup like this where the signals go thru an Arduino shield.

Note that my code does a busy-wait for the SPI transfers to be complete.
This is not so bad for the AVR since that are only 16 clock-cycles with 
8MHz SPI clock and 16MHz system-clock.
Even with the rather low-end STM32F103 things are a bit different.
The function spi_transmit() could be changed to write to a memory-buffer 
and FT8_cs_clear() could trigger a DMA transfer of that buffer.
FT8_cs_set() could be used to ensure that the buffer is already 
transfered.
The function spi_receive() is then a problem to solve though, I guess it 
could be possible to let it call spi_transmit()/FT8_cs_clear() to 
trigger a transfer of just one byte, read the result and write that 
back.

Does the STM32 support 32 bit SPI transfers?
I only recently checked what a SAME51 can do and regardless of it having 
a Cortex-M4F core it can only do 8/9 bit SPI transfers.
That could be used to speed things up but this would require a complete 
re-write of FT8_commands.c.

The display and type of FT8xx also has to be selected in FT8_config.h.
You did not say which display from Riverdi you use.
I only have a profile for RVT70AQxxxxxx so far, if you do not use one of 
these you need to use one of the other profiles and tweek it, best would 
be to copy one of the blocks under a a new name.

And as always, please share the bits and pieces you need to adapt the 
library to your needs so that I could include it into the repository.
Sadly no-one contributed so far and most of my questions are left open.

von Rudolph R. (rudolph)


Lesenswert?

Part of the documentation for the new BT815 is up: 
http://brtchip.com/bt815-6/

It's all a bit thin by now, the programming guide is yet to be updated.

-Support Adaptive Scalable Texture Compression (ASTC) format to save 
considerable memory space for larger fonts and graphics images
-Support external QSPI NOR flash to fetch graphic elements(image, font, 
widget etc)

And that is all what is different to the FT81x series, at least for now.
The programmers guide should reveal some more things.

I had a nice talk at the Embedded World earlier today with a guy from 
Bridgetek and say a few demos at their booth.
One additional feature would be support for Unicode fonts thru an 
additional font command.

And I had some more nice talks but I have to wait a little to see how 
these turn out. :-)

von Walter L. (charly2)


Angehängte Dateien:

Lesenswert?

Hallo,
bevor ich Geld ausgebe:

Eignet sich das VM800C50A ( FT800) für die Darstellung von Messwerten 
über der Zeit (z. B. zwei Temperaturen, zwei rel. Feuchte-Werte über 12 
Stunden)?
Kann man direkt in das RAM_G schreiben, um Pixel zu setzen und somit 
die Messwerte darzustellen?
Bisher benutze ich ein 2,8 ZOLL TFT, parallel, mit IL9341, das mir aber 
zu klein ist.
Danke für Hinweise.
VG Walter

: Bearbeitet durch User
von pedrem (Gast)


Lesenswert?

Hallo
Ich spreche kein Deutsch und diese Übersetzung ist Google.
Ich entschuldige mich vor allem.
Ich änderte den ATMEGA644-Mikrocontroller-Code zu ATMEGA328.
Die Show findet statt, aber das Bild ist fehlerhaft. Die Seite wird 
aktualisiert und ist nicht klar.
Was denkst du ist das Problem?
Vielen Dank

von pedrem (Gast)


Angehängte Dateien:

Lesenswert?

pedrem schrieb:
> Hallo
> Ich spreche kein Deutsch und diese Übersetzung ist Google.
> Ich entschuldige mich vor allem.
> Ich änderte den ATMEGA644-Mikrocontroller-Code zu ATMEGA328.
> Die Show findet statt, aber das Bild ist fehlerhaft. Die Seite wird
> aktualisiert und ist nicht klar.
> Was denkst du ist das Problem?
> Vielen Dank

von Manfred W. (manfred53)


Angehängte Dateien:

Lesenswert?

Walter L. schrieb:
> Hallo,
> bevor ich Geld ausgebe:
>
> Eignet sich das VM800C50A ( FT800) für die Darstellung von Messwerten
> über der Zeit (z. B. zwei Temperaturen, zwei rel. Feuchte-Werte über 12
> Stunden)?

Ja, sogar mit 800x480 Auflösung für unter 40€ (FT811CB von HAOYU)

> Kann man direkt in das RAM_G schreiben, um Pixel zu setzen und somit
> die Messwerte darstellen?

Das sollte man nicht tun sondern die vielen vorhandenen Funktionen 
nutzen, die ein schön gerendertes und nicht pixeliges Bild ergeben. 
Anbei ein Beispiel.

von Rudolph R. (rudolph)


Lesenswert?

Was geht denn hier ab? :-)

Walter L. schrieb:
> Kann man direkt in das RAM_G schreiben, um Pixel zu setzen und somit
> die Messwerte darzustellen?

Das geht zwar, die FT8xx arbeiten allerdings eher Objekt-orientiert und 
nicht Pixel-für-Pixel.
Eine Messwert-Reihe kann man zum Beispiel als Linien-Zug ausgeben.
Meine Beispiel-Applikation macht sowas mit einem festen Array aus 64 
Werten.

command(farbe)
command(linien-breite)
command(starte line-strip)
command(koordinate(x,y))
command(koordinate(x,y))
command(koordinate(x,y))
command(koordinate(x,y))
command(ende)

Und schon hat man drei Linien auf dem Schirm.

Was ich allerdings feststellen musste, dynamische Koordinaten-Kommandos 
kosten etwas Zeit, zumindest auf kleinen 8-Bit Controllern, aus den X/Y 
Werten einen 32 Bit Wert zu machen ist ein wenig aufwendig.

Ich habe mich da drüber bei FTDI gestern "beschwert", bin aber nicht 
sicher, ob das so angekommen ist, so im Gespräch auf Englisch. :-)

Naja, dürfte immer noch um mehrere Grössenordnungen schneller sein als 
komplette Linien zu berechnen und Pixel-für-Pixel zu übertragen, an 
Anti-Aliasing wäre da auch nicht zu denken.

Die FT8xx sind vor allem schnell und Resourcen-freundlich. Eindrucksvoll 
sieht man das auch an den Gameduino Demos.
Aber eben wenn man die auch machen lässt. :-)



pedrem schrieb:
> Ich spreche kein Deutsch und diese Übersetzung ist Google.

Please don't. Just use Englisch instead.
You could attach the source-code you modified that would be a bit 
easier.
As well as telling what display that actually is.
However, the code you used is rather old.
Please check out a current version here:
https://github.com/RudolphRiedel/FT800-FT813

The provided example projects are not updated to the latest versions of 
the
files but should do fine after an update.

The "90CAN" example should be a good starting point.

One thing, in FT8_config.c
1
  uint8_t fetch_flash_byte(const uint8_t *data)
2
  {
3
    return(pgm_read_byte_far(data));
4
}

That should be "pgm_read_byte(data)" for any AVR with 64k of FLASH or 
less.
Hmm, it should be possible to auto-detect that during compilation but I 
did not try that so far.

von Manfred W. (manfred53)


Lesenswert?

Nicht unerwähnt bleiben sollte, dass das, was man "malt" also die 
commands, nicht unbegrenzt ist.
Daher stößt man bei langen Vektorzügen schnell and die Grenze. Ich 
sammele 600 Messpunkte für ein 10 Minuten Log.

Aber da gibt es Abhilfe.

Man zeichnet zunächst den statischen Teil seiner Graphik und kopiert das 
Ergebnis in einem RAM Bereich des FT8xx.

void SaveRTL()
{
        FT8Snapshot2(FT8_ARGB4, 10000L, 0, 44, RTLWIDTH, RTLHEIGHT);
}

Dann ruft man diese Hintergrundgraphik mit wenigen Commands auf und kann 
dann wieder mit etwas mehr Luft darüber malen.

void RestoreRTL()
{
  FT8Cmd(COLOR_UINT(White));
  FT8DrawRect(0, 44, RTLWIDTH, RTLHEIGHT, White);
  FT8SetBitmap(10000L, FT8_ARGB4, RTLWIDTH, RTLHEIGHT);
  FT8Cmd(BEGIN(FT8_BITMAPS));
  FT8Cmd(VERTEX2II(0, 44, 0, 0));
}

RTL ist meine Abkürzung für die Reflow-Temperatur-Log Graphik.

Beim Zeichnen der beiden Kurven zeichne ich live nur die letzten 5 
Sekunden "punktgenau". Der Rest wird im 5 Sekunden Abstand gezeichnet, 
was zu 120 Vektoren führt.

von Walter L. (charly2)


Lesenswert?

Hallo Manfred und Rudolph,
herzlichen Dank für Eure Hinweise.
Ich hatte das schon geahnt, dass für meine Zwecke die Controller mit 16 
Bit-Interface besser geeignet sind (z.B. SSD1963, o. ILI9341).
VG Walter

von Manfred W. (manfred53)


Lesenswert?

Walter L. schrieb:
> Hallo Manfred und Rudolph,
> herzlichen Dank für Eure Hinweise.
> Ich hatte das schon geahnt, dass für meine Zwecke die Controller mit 16
> Bit-Interface besser geeignet sind (z.B. SSD1963, o. ILI9341).
> VG Walter

Das kann ich absolut nicht teilen!


Ich arbeite kommerziell seit vielen Jahren mit ATMEL 8 Bit Prozessoren 
vom Mega8 bis zum Mega2560.
Früher mit AVR-Pascal & Assembler jetzt mit Arduino/Visual Studio mit 
VisualMicro.


Es kommt immer darauf an, was man machen will.


Man darf 8 Bit nicht verallgemeinern. Einen 8bit PIC und einen ATMEGA 
trennen Performance Welten. Nicht umsonst findet man in vielen CNC und 
3D Drucker Steuerungen ATMEL Prozessoren.

Parallel dazu programmiere ich übrigens auch 16 Bit (PIC24F256GB206 
32Mhz) in einer WiFi IoT Anwendung (FlyPort Pro) mit über I2C und SPI 
angeschlossenen Sensoren. Hier musste ich nach langen Fehlversuchen, es 
mit dem PIC24 alleine zu schaffen, einen extra ATMEL Mega8 spendieren, 
um ein Timing kritisches Signal zur Ansteuerung von 350 WS2812 RGB LEDs 
zu produzieren.

Wichtig ist die richtige Bibliothek zu finden.


Hier (FT8x) hat Rudolf eine exzellente Vorlage geschaffen, für die ich 
Ihm meinen Dank aussprechen möchte!

: Bearbeitet durch User
von Walter L. (charly2)


Lesenswert?

Hallo Manfred,

ich schrieb vom TFT-Controller, nicht von dem Controller, der das TFT 
ansteuert.

Als ansteuernder Controller kommt der TSM320F2806x zum Einsatz.

Soweit ich Deine "REFLOW"-Graphik verstanden habe, sind die Messwerte 
zunächst erfasst worden und danach ist die "REFLOW"-Grafik erstellt 
worden.
Ich brauche aber eine "Oszilloskop-Funktion".

VG Walter

P.S.: Auch von meiner Seite ein herzliches Danke an Rudolf für die 
exzellente Vorlage.

: Bearbeitet durch User
von Manfred W. (manfred53)


Lesenswert?

Walter:

Ich brauche aber eine "Oszilloskop-Funktion".

Um es vorweg zu nehmen: Bosch... ist schon möglich!

Der FT811 ist ein "intelligenter" TFT Controller mit Objektorientiertem 
Graphik Modell nicht nur Linien, Rechtecke, Polygone, Bitmaps sondern 
auch UI Objekte wie Knöpfe, Texte, Schalter, u.m.. Diese werden im 
Aufruf mit einer Zahl (0..255) zur Identifikation (Tag genannt) 
versehen.

Dabei kann das "Bild" mit bis 60 Hz vom steuernden MC in der üblichen 
Loop refreshed werden und gleichzeitig wird der oben genannte Tag bei 
einer eventuellen Touch Positionen als OBJEKT Referenz geliefert. Damit 
kann man sehr einfach "Klick Ereignisse" produzieren.

Das der FT811 hervorragend live rendert kann man an meinem Screenshot 
sicher erkennen.

Mit der von mir beschrieben Bitmaps Hintergrundmethode kann man dass 
Messraster schnell pro Frame laden und dann die Kurve darüber legen. So 
mache ich das in dem in Entwicklung befindlichen Reflow Controller bei 
dem auch blinkende und Farben wechselnde Texte und Knöpfe vorkommen.

Ich empfehle mal sich die diversen Videos zum FT8x und dem damit 
realisierten Gamduino anzuschauen.

von Rudolph R. (rudolph)


Lesenswert?

Manfred W. schrieb:
> Hier (FT8x) hat Rudolf eine exzellente Vorlage geschaffen, für die ich
> Ihm meinen Dank aussprechen möchte!

Walter L. schrieb:
> P.S.: Auch von meiner Seite ein herzliches Danke an Rudolf für die
> exzellente Vorlage.

Danke!
Das Feedback die letzte Zeit war ganz schön positiv. :-)

Interessant war auch mein Besuch der Embedded World.
Ob nun am Stand von FTDI/Bridgetek, Matrix Orbital oder Glyn, die 
Herrschaften waren positiv überrascht als ich ihnen erzählt habe das ich 
eine FT8xx Library auf Github eingestellt habe.
Obwohl ich mich schon über zwei Jahre damit beschäftige und der Thread 
hier auch fast zwei Jahre alt ist, einfach so im Netz drüber stolpern 
ist wohl nicht so leicht.
Mal schauen, ob der Firmen-Kontakt die User-Basis etwas hoch bringt. :-)

Weil ich da gerade Bock drauf hatte habe ich heute mal ein bisschen was 
gemacht und https://github.com/RudolphRiedel/FT800-FT813 aktualisiert.
Nichts tiefgreifendes.
Die Support-Funktionen habe ich auf Inlining umgestellt und somit ist 
FT8_config.c verschwunden, das ist messbar schneller.
Weil ich diese Kombination gerade hier habe gibt es jetzt noch ein 
Beispiel Projekt "FT8xx_Test_90CAN_FT811_HY50HD".
Da hatte ich schon länger das Inlining drin und auch simples Profiling 
für die tft_loop(), das habe ich jetzt mal Release fähig gemacht.
Die anderen beiden Beispiel-Projekte habe ich auch mal auf den aktuellen 
Stand gebracht.
Und da ich FT8_config.h sowieso schon auf hatte, habe ich mal die ganzen 
Konfigurationen für die Matrix Orbital TFTs ergänzt.

Und ja, ich weiss, dass ich mich mit Github nicht hinreichend gut 
auskenne. :-)
Aber das sind ja im Grunde genommen nur vier Dateien und jede davon hat 
einen Header mit Versions-Nummer und Änderungen.

Ich hatte auch überlegt schon was für den BT815 einzubauen. Aber nur das 
Vorläufige Datenblatt ist mir dafür noch zu dünn. Ich weiss schon, dass 
das Teil mehr kann als da drin steht, schauen wir mal wann das 
User-Manual kommt und wann überhaupt Hardware verfügbar wird.

von Walter L. (charly2)


Lesenswert?

Hallo,

Frage an die mit dem THAOYU FT811CB bewanderten Fachmenschen:
Auf der linken Seite des PCB befindet sich zwischen zwei 
Kreutzschlitzschrauben der 7-pinnige P1 Anschluss.
Wozu ist dieser? Vermutliche der Anschluss zum TOUCH-CONTROLLER.

Kennt jemand die PIN-Belegung?

Danke für Hinweise.

VG Walter

P.S.: In den Schaltplänen habe ich nichts gefunden.

von Manfred W. (manfred53)


Lesenswert?

Ja, im bekannten FT81xCB_SCH.pdf ist P1 nicht zu finden.

Aber was soll's?

Über J2 oder, wer den Adapter hat, über J1 ist alles verfügbar, was man 
so braucht.
Auf den INT kann man eigentlich verzichten, wenn man in der Loop das 
FT8GetTouchTag() ausführt.

Für den "Sound" auf AUDIO PWM braucht man noch einen Tiefpass nebst 
Verstärker und Pin 10 Gnd ist auf der PCB mit PIN 2 verbunden.

von Walter L. (charly2)


Lesenswert?

Ohne Gewähr:

pin 7 NC      -> FT5206GE1
pin 6 INT
pin 5 WAKE
pin 4 MISO
pin 3 SSEL/SCL
pin 2 GND
pin 1 VDD3

pin1 = quadratisch

VG Walter

von Rudolph R. (rudolph)


Lesenswert?

Walter L. schrieb:
> Auf der linken Seite des PCB befindet sich zwischen zwei
> Kreutzschlitzschrauben der 7-pinnige P1 Anschluss.
> Wozu ist dieser? Vermutliche der Anschluss zum TOUCH-CONTROLLER.

Oh, der ist mir noch gar nicht aufgefallen, die anderen aus der Serie 
haben den auch nicht.

http://www.haoyuelectronics.com/Attachment/FT811CB-HY50HD/FT811CB-4.jpg

Also dem Bild nach würde ich auch sagen, der ist nur mit dem 
Touch-Controller verbunden, vielleicht sowas wie ein Test-Zugang.
Mein erster Reflex war jetzt auch das Gehäuse aufzuschrauben in dem ich 
das Display hier rum liegen habe, aber dafür lohnt sich das irgendwie 
nicht. :-)

Edit: Beitrag zu lange offen gehabt Fehler. :-)

Vorhin habe ich eine EMail von Glyn bekommen, die ADAM Module gibt es 
auch immer noch.
Ich wüsste jetzt zwar nicht, wie ich da privat rankommen könnte und auch 
im B2B ist das nicht einfach Katalog-Ware.
Aber ich finds erstmal gut, dass es die auch noch gibt.

: Bearbeitet durch User
von Rudolph R. (rudolph)


Lesenswert?

Minor update of FT8_config.h.
- Arduino for ESP8266 has a spi.write() function, plain Arduino only has 
a spi.transmit() function - the correct function is used automatically 
now.
- AVR with more than 64kB are auto-detected now and pgm_read_byte_far() 
is used instead of pgm_read_byte_near().

von Rudolph (Gast)


Angehängte Dateien:

Lesenswert?

Neues Spielzeug. :-)

Läuft gerade so zum ersten Mal, das sind 10,1" mit 1024x600 Pixeln.
Kapazitiv-Touch natürlich, die Schutzfolie ist auch noch drauf.
Da klemmt gerade ein Wattuino Uno hinter - #oberfettestftshield :-)

Wie man gerade so auf dem Bild erkennen kann sind das 588 Bytes die pro 
Bild auf dem SPI übertragen werden und ein Frame dauert da gerade 2,9ms.
Der SPI läuft dabei auf nur 4MHz.
Ich lasse das Bild gerade 33 Mal pro Sekunde neu ausgeben.

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

Was, niemand der fragt was für ein Display das ist? Ich bin enttäuscht. 
:-)

Das ist ein ADAM101-LCP-SWVGA-NEW von der Firma Glyn.
Da ich die Freigabe dafür habe und das sonst noch nicht zu finden ist 
hänge das Datenblatt dazu einfach mal hier an.

Ich wüsste jetzt nicht ob ich da privat überhaupt rankommen könnte, das 
ist jetzt von der Arbeit aus beschafft für die Arbeit.
Und die kosten jetzt auch etwas mehr als ich privat bereit wäre 
auszugeben.

Wie man auf der ersten Seite im Datenblatt erkennen kann verfügt das 
Display auf der Platine über einen kompletten Satz Pins für einen 
Arduino.
Da ist aber auch der bei Glyn EVE Displays übliche 16polige FPC 
Anschluss drauf.

Man kann in etwa erahnen wie gross das Teil ist wenn man sich überlegt, 
dass der Arduino nicht über die Platine hinaus ragt.

Zum Testen benutze ich das jetzt auch erstmal als Arduino-Shield.
Da ich keine Hardware für den 16pol FPC habe, weil ich bisher eben auch 
kein Display von Glyn in die Finger bekommen konnte, war das schlicht 
der einfachste Weg das Monster in Betrieb zu nehmen.
Das hätte mich jetzt auch nur 10 Minuten aufgehalten wenn ich ncht einen 
Fehler in meinen aktuellen Arduino Beispiel-Code eingebaut hätte der den 
SPI gekillt hat.

Im Github liegt auch schon die aktualisierte FT8_config.h.

Was technisches noch, mit 6V Versorgung und ungefähr 70% 
Hintergrundbeleuchtung zieht der Aufbau knapp unter 400mA.
Das ist jetzt deutlich weniger als ich erwartet habe.
Ermittelt mit der Strombegrenzung von meinem Labor-Netzteil muss die 
Versorgung aber auch mindestens 1A liefern können damit das sauber 
anläuft - da ist eben ein Schaltregler drauf, und auf dem Panel selber 
sitzt noch einer für die Beleuchtung.

von Rudolph R. (rudolph)


Lesenswert?

Okay, something for a wider audience, so in Englisch.

I already mentioned above that I visited the booth of Matrix Orbital at 
Embedded World in Nürnberg. https://www.matrixorbital.com
Last week I received two of their modules which they provided as samples 
for me to play with.
https://www.matrixorbital.com/ftdi-eve/EVE%20FT812/eve2-38a
https://www.matrixorbital.com/ftdi-eve/EVE%20FT812/eve2-35g

I chose the EVE2-38 for its form-factor.
At 480x116 and 1U it is sawn out of a 4.3" TFT.
I did not have anything like this in my collection.
The only thing that perplexed me was that the panel actually is the 
lower half of that 4.3", so it does not start at 0/0 but 0/155.

The EVE2-35G is annother story.
First of I have an application for it but it is way too soon to tell.
This is a very nice panel, from the looks and feel very much like the 
RVT70 module from Riverdi I worked with before.
So it has an all glas front and tape on the back to glue it into a case.
I very much like that, this makes using TFTs so much easier than using 
this naked panels with metal-frame.
I dare to say that I believe that the EVE2-35G looks better than the 
RVT70, it maybe has a higher viewing-angle and the backlight definately 
is brighter.
Unfortunately I do not have a 3.5 from Riverdi for a fair comparision.

Both modules come with FT81x, namely FT812 and FT813, Matrix Orbital 
does not use FT80x for any of their modules which I also like a lot.
So the EVE2-35G is a 3.5 320x230 TFT with 24 bit color and 1MB of 
object-memory.

I ran into one problem with the EVE2-35G though.
These come with a Goodix GT911 touch-controller and these are not 
suported by the FT813 out-of-the-box.
FTDI/Bridgetek released AN_336 though which I was aware of and it holds 
the solution for this problem.
The FT813 is patched with a binary-blob provided by FTDI/Bridgetek to 
support the GT911.
And yesterday I got this to work.

Check https://github.com/RudolphRiedel/FT800-FT813 for the update.

I also uploaded a much simpler example to play with the EVE2-35G.

von TFTL (Gast)


Angehängte Dateien:

Lesenswert?

Hello from México. Congratulations for visit the Embedded World. Many 
things to see!.

I am very interest in the 10.1 TFT, that you have, it's amazing.

I have a FT813 NHD displays: 3.5", 4.3" y 5" and my teal and I has been 
working on the mod of the gameduino 2/3 library in order to work in 
STM32 boards like F746IG (Core7XXI) or the new nucleo-F767.

Congratulations for two years of EVE-fan life!

Our project: ft81xmania.com

von Rudolph R. (rudolph)


Lesenswert?

TFTL schrieb:
> I am very interest in the 10.1 TFT, that you have, it's amazing.

It's big, it's bright and the panel panel really is much better than the 
RVT70 from Riverdi.
It has a few problems though and I am waiting for a response from Glyn.
I am afraid that if anyone wants one of these he has to contact Glyn and 
ask for a quote.

> I have a FT813 NHD displays: 3.5", 4.3" y 5"

I have seen these online after Embedded World so I totally missed the 
oportunity to visit their booth.
Could not order one of these so far, Digikey is not a real option for me 
and while a co-worker will order at Mouser later this week they have no 
stock.

But I do not like these "naked" TFTs anways.
With the RVT70 or the EVE2-35G you just cut a hole in your case and 
throw the panel in there, with the ADAM101 or all NHD modules you have 
to construct a case around them.
The mounting holes are only a minor improvement.

> and my teal and I has been working on the mod of the gameduino 2/3
> library in order to work in STM32 boards like F746IG (Core7XXI)
> or the new nucleo-F767.
>
> Our project: ft81xmania.com

Yes, I came across that before. :-)
And yes, STM32 is the hype, for whatever reason. There are no automotive 
versions of STM32 however which kept me from playing with them.
At work we just adapted my library for use with Infineon Aurix TC222.

von Rudolph (Gast)


Angehängte Dateien:

Lesenswert?

I felt a picture of the EVE2-35G is missing.

That is my new example code in action.
That button is implemented as radio-button, push once to activate, touch 
a second time to de-activate.
When activated the star picture will rotate, deliberately off-center.

The EVE2-35G is running at almost the lowest possible brightness,
I tuned it down as I have no sunlight at my desk at home. :-)

I just noticed that the whole setup only draws around 50mA.


Below is the EV2-38 and a 2x16 LCD just for reference.

von Axel V. (axel-f)


Lesenswert?

Klasse Arbeit, vielen Dank. Und vor allem ist der Code (für mich) sehr 
gut verständlich.

Nun mein Problem: ich verwende den FT812 an einem SAM4S; mußte also die 
SPI ein wenig anpassen. Aber prinzipiell kann man das am Oszi gut 
nachvollziehen.
Die Krux ist, daß die Schaltung zwar aufgeweckt wird, aber dann nicht 
mehr viel passiert.
init:
PIOA->PIO_CODR = PD_FT812;  // PD aktiv
delay_ms(6);
PIOA->PIO_SODR = PD_FT812;  // PD inaktiv
delay_ms(21);
FT8_cmdWrite(FT8_CLKEXT);
FT8_cmdWrite(FT8_ACTIVE);
delay_ms(500);        // TEST
chipid = FT8_memRead8(REG_ID);
while(chipid != 0x7C)
{
  chipid = FT8_memRead8(REG_ID);
  delay_ms(5);
  timeout++;
  if(timeout > 200)
     return 0;
}
delay_ms(10);
return 1;

Das funktioniert soweit, der ext. Quarz wird aktiv, das REG_ID wird 
ordnungsgemäß gelesen (return ==1).
Wenn ich jetzt als einfachen Test  FT8_memWrite8(REG_PWM_DUTY, 70);
absende, passiert nichts, kein PWM aktiv am Backlight. Auch alle anderen 
Initialisierungen bzgl. Display zeigen keine Wirkung. Das einzige, was 
ich noch beobachtet habe, daß nach dem ersten Zugriffnach dem Aufwachen 
(hier:FT8_memRead8(REG_ID)) der Audioausgang mit 117 kHz taktet.

Spannungen sind natürlich nachgemessen.
Ich bin ein bißchen mit meinem Latein am Ende. Hast Du noch einen guten 
Tip, was man versuchen sollte?

Gruß
Axel

von Rudolph R. (rudolph)


Lesenswert?

Axel V. schrieb:
> Hast Du noch einen guten Tip, was man versuchen sollte?

Oh, mir fallen da bestimmt ein paar ein. :-)

Als erstes Mal wäre gut zu wissen, welches Display Du überhaupt 
verwendest.
Und dann, warum machst Du die Anpassung an den SAM4S nicht da wo ich das 
vorgesehen habe und zwar in der FT8_config.h? :-)

Mit etwas Hilfe zum SAM4S könnte ich Dir das Beispiel bestimmt soweit 
anpassen das es läuft, mein Atmel-Studio kann auch für ARM compilieren.
Ich plane auch gerade eine SAME51 Platine.

Hier, spontan ein Projekt erstellt und das hier in der FT8_config.h 
eingefügt, das compiliert sogar fehlerfrei durch:
1
    #if defined (__SAM4S8C__)
2
    
3
      #include "sam.h"
4
5
      #define DELAY_MS(ms)
6
      
7
      #define PD_FT812 12
8
      #define CS_FT812 11
9
10
      static inline void FT8_pdn_set(void)
11
      {
12
        PIOA->PIO_CODR = PD_FT812;
13
      }
14
15
      static inline void FT8_pdn_clear(void)
16
      {
17
        PIOA->PIO_SODR = PD_FT812;
18
      }
19
20
      static inline void FT8_cs_set(void)
21
      {
22
        PIOA->PIO_CODR = CS_FT812;
23
      }
24
25
      static inline void FT8_cs_clear(void)
26
      {
27
        PIOA->PIO_SODR = CS_FT812;
28
      }
29
30
      static inline void spi_transmit(uint8_t data)
31
      {
32
33
      }
34
35
      static inline uint8_t spi_receive(uint8_t data)
36
      {
37
38
        return 1;
39
      }
40
41
      static inline uint8_t fetch_flash_byte(const uint8_t *data)
42
      {
43
        return *data;
44
      }
45
    
46
    
47
    #endif

Da fehlt halt noch einiges, wie das delay().

: Bearbeitet durch User
von Axel V. (axel-f)


Lesenswert?

Ah, danke für die spontane Antwort.

Beim SAM4 wollte ich meistenteils die Möglichkeit der 16 Bit Ausgabe 
nutzen. Macht aber wohl eher mehr Arbeit. Allerdings sehen, die Routinen 
etwas anders aus, da ich die Automatik für den CS nutzen möchte.
Delay() habe ich, funktioniert auch.
Mittlerweile habe ich weitergeforscht und weiß, wo der Fehler lag: Das 
Lesen ist 4 Byte vorgesehen, das schreiben nur mit 3. Aaargh!
Jetzt kommen die Reaktionen vom FT, wie sie sein sollen, also PWM, PCLK 
usw.

Display:
https://www.pollin.de/p/lcd-modul-et043003dh6-tft-480x272-121498
auch interessant:
https://www.pollin.de/p/tft-modul-et020007dmu-tft-176x220-121299
https://www.pollin.de/p/lcd-modul-tm080sdh01-tft-8-800x600-4-3-121575

Für den Preis MUSSTE ich das einfach ausprobieren!

von Rudolph R. (rudolph)


Lesenswert?

Ah, Du hast dann den FT812 und den SAM4 auf einem eigenen Board?
Interessant.
Das würde ich gerne mal sehen.

Ja, 16 oder gar 32 Bit machen mit dem FT8xx nur begrenzt Sinn.
Die SPI-Kommandos haben 24 Bit mit 22 Bit Adresse, die Co-Prozessor 
Kommandos die ich praktisch ausschliesslich nutze haben 32 Bit.
Bei den Lese-Funktionen wird auch immer ein Dummy-Byte gesendet, weil 
SPI ja immer ein Byte Versatz hat zwischen Lesen und Schreiben.

Mit dem RH850 wollte ich auch schon mal automatisches Chip-Select 
benutzen, habe das dann aber letztlich verworfen weil dem Controller 
nicht beizubringen war das flexibel wieder auf High zu setzen.
Da müssen drei Bytes am Stück gesendet werden, oder vier, fünf, sechs, 
sieben, acht - das sind die Basis-Operationen.
Mit den Listen sende ich jetzt über den "Burst-Modus" auch mal >700 
Bytes am Stück.

Für sowas wie den SAM4 würde DMA Ausgabe vielleicht Sinn machen, bisher 
habe ich aber noch gar keinen Controller benutzt der DMA kann.
Das wäre aber vor allem auch nur für die Listen interessant, bei einem 
einsamen FT8_get_touch_tag() kann man sich den Luxus erlauben, dass der 
Controller damit beschäftigt wird, 8 Bytes per DMA ist jetzt nicht so 
hilfreich und auf das Ergebnis der Aktion muss eh gewartet werden.

Hmm, kurz drüber nachgedacht wie man DMA einbauen könnte, das ist gar 
nicht so leicht.
Zum einen ist mit cmd_burst, bzw. 
FT8_start_cmd_burst()/FT8_end_cmd_burst(() schon ein Mechanismus 
eingabaut um viele Kommandos am Stück abzusetzen ohne immer wieder neu 
adressieren zu müssen.
Mit einem Define FT8_DMA oder so könnte man bewirken das die Funktionen 
für DMA was anderes machen.
Wobei eigentlich nicht mal das, FT8_cs_set() und FT8_cs_clear() müssten 
sich zunächst anders verhalten, nämlich bei DMA gar nichts machen.
Das spi_transmit() müsste bei DMA dann in einen Puffer schreiben wenn 
cmd_burst aktiv ist.
Am Ende muss FT8_cmd_start() den DMA Transfer anschieben - und jetzt 
wird es nervig - für einen DMA-complete Interrupt den Offset im 
FT8_RAM_CMD zur Verfügung stellen der ins REG_CMD_WRITE Register 
geschrieben wird.
Bis zum Abschluss der Aktion muss der SPI komplett gelocked sein.
Und nach dem Interrupt ist der Co-Prozessor ja erstmal damit beschäftigt 
die Kommandos zu verarbeiten.
Der ganze Aufriss dient auch nur dazu ein paar Hundert µs alle 20ms oder 
so früher aus der tft_loop() raus zu kommen.

Ein Argument dafür wäre jetzt das der Controller früher wieder schlafen 
gehen kann, aber selbst ein 3,5" TFT benötigt ja mit runter-gedimmter 
Hintergund-Beleuchtung immer noch sehr viel mehr Strom als der 
Controller.

Wenn der Controller dicker ist und die Hardware das her gibt kann man 
auch einfach den SPI auf einen höheren Takt setzen und schon werden 
alleine dadurch aus 700µs nur noch 300µs für den SPI-Transfer.

Das nächste was ich mir für die Applikations-Schicht, sprich meine tft.c 
überlegt habe ist tft_loop() quasi Event-gesteuert zu machen.
Also den zweiten Teil der das Bild aktualisiert nicht immer auszuführen, 
sondern nur wenn es notwendig ist.
Etwa wenn der erste Teil ein Touch-Event erkannt hat.
Einer der Auslöser für den Refresh sollte dabei auch ein simples Timeout 
sein das alle zwei Sekunden mal dafür sorgt das neu gemalt wird.
Für statische HMI könnten die Bilder pro Sekunde auch generell gesenkt 
werden in der tft_loop(), also gar nicht jeder zweite Aufruf macht 
(potentiell) ein Bild, sondern jeder vierte.
Die für den Bildaufbau notwendigen 1-4ms sollten aber den restlichen 
Ablauf im Controller nicht aus der Bahn werfen, das darf man auch nicht 
vergessen.

Bisher habe ich mir sowas nicht gegeben, weil ich zum einen gar kein 
Problem mit der Laufzeit habe, als nächstes das "Profiling" machen will 
und dann Animation mit einer festen Zeitbasis einfach besser 
kontrollierbar sind.
Für die Arbeit habe ich gerade eine Oberfläche gebaut die Rechts fünf 
Touch-Buttons mit Status-Anzeige hat und Links eine Status-Ausgabe für 
11 Variablen hat mit Punkten die ihre Farbe ändern und vom Status der 
Variablen abhängigen Text.
Das verlangt geradezu nach einem Event-gesteuertem Refresh, nur einen 
echten Vorteil sehe ich damit nicht.

von Axel V. (axel-f)


Lesenswert?

Was genau möchtest Du denn sehen? Ein Foto vom Board oder den passenden 
Schaltplan? Falls gewünscht und sobald es funktioniert, kann ich meine 
config.h posten.

Ich werde dann mal den Code auf 8 Bit umstellen und in die config.h 
einbauen. Prinzipiell arbeite ich nicht mit dem Atmel Studio sondern mit 
Eclipse (unter Linux), deswegen sieht das bei mir in Teilen etwas anders 
aus.

An DMA hatte ich auch gedacht, das schien sich hier anzubieten. 
Allerdings sind hier zu viele Fallunterscheidungen, womit die Sache 
einfach nur nervig wird. Ich werde dafür nach dem init das SPI auf 24 
MHz hochtakten, das muß reichen (ist ja kein 4k Display).

Womit ich noch ein wenig Probleme habe: ich kann ja direkt in die 
Display List schreiben (über FT8_memWrite32(FT8_RAM_DL, ...) und ich 
kann das über die Coprozessor Kommandos machen (dann schreibt der in die 
DL).
Ich habe im Init den Bildschirm auf Blau eingestellt und das 
funktioniert auch. Dann habe ich das hier versucht:

void draw_welcome(void)
{
FT8_memWrite32(FT8_RAM_DL, (DL_CLEAR_RGB | 0xff00));  //Grün
FT8_memWrite32(FT8_RAM_DL + 4, (DL_CLEAR | CLR_COL | CLR_STN | 
CLR_TAG));
FT8_memWrite32(FT8_RAM_DL + 8, COLOR_RGB(160, 22, 22)); // change to red
FT8_memWrite32(FT8_RAM_DL + 12, BEGIN(FT8_BITMAPS));
FT8_memWrite32(FT8_RAM_DL + 16, VERTEX2II(220, 110, 31, 'A'));
FT8_memWrite32(FT8_RAM_DL + 20, END());
FT8_memWrite32(FT8_RAM_DL + 24, DL_DISPLAY);  /* END OF DISPLAY LIST */
FT8_memWrite32(REG_DLSWAP, FT8_DLSWAP_FRAME);
}

.. aber das hat nichts gebracht. Geht das prinzipiell nicht oder muß ich 
dem FT noch irgendwie sagen 'Fang eine neue DL an!'?

von Rudolph R. (rudolph)


Lesenswert?

Axel V. schrieb:
> Was genau möchtest Du denn sehen? Ein Foto vom Board oder den passenden
> Schaltplan?

Na alles, inklusive Layout. :-)
Nein, nicht so wichtig, gibt ja genug freie Unterlagen dazu. :-)
Wie zum Beispiel im User-Manual von Matrix Orbital.

> Falls gewünscht und sobald es funktioniert, kann ich meine
> config.h posten.

Ja gerne, das übernehme ich dann auch gerne, bisher gab es zwar viel 
positives Feedback, aber wenig bis keinen Beitrag in der Form von 
Konfigurationen.
Wobei, da oben steht noch was zum SAM4E das ich irgendwie nie eingebaut 
habe.

> Ich werde dann mal den Code auf 8 Bit umstellen und in die config.h
> einbauen. Prinzipiell arbeite ich nicht mit dem Atmel Studio sondern mit
> Eclipse (unter Linux), deswegen sieht das bei mir in Teilen etwas anders
> aus.

Na, die IDE ist ja soweit egal, die Kollegen denen ich zuarbeite bauen 
nur per Build-Script und Makefile.
Nur einen anderen Compiler als den GCC hatte ich noch nicht.
Keine Ahnung was passiert wenn man da zum Beispiel einen GHS drauf los 
lässt, sollte aber eigentlich anpassbar sein.

> An DMA hatte ich auch gedacht, das schien sich hier anzubieten.
> Allerdings sind hier zu viele Fallunterscheidungen, womit die Sache
> einfach nur nervig wird. Ich werde dafür nach dem init das SPI auf 24
> MHz hochtakten, das muß reichen (ist ja kein 4k Display).

24MHz ist schon sportlich für die Signale, aber SPI ist ja robust.

> Womit ich noch ein wenig Probleme habe: ich kann ja direkt in die
> Display List schreiben (über FT8_memWrite32(FT8_RAM_DL, ...) und ich
> kann das über die Coprozessor Kommandos machen (dann schreibt der in die
> DL).
> Ich habe im Init den Bildschirm auf Blau eingestellt und das
> funktioniert auch. Dann habe ich das hier versucht:

Ich schreibe gar nicht in die Liste weil das zu eingeschränkt ist, 
insofern kann ich da jetzt auch nicht so viel sagen.
Ich fange auf jeden Fall immer mit CMD_DLSTART an und nach der 
Beschreibung setzt das wohl vor allem REG_CMD_DL auf Null.
Aber wie das funktioniert das eine zweite Liste gebaut wird bin ich 
gerade überfragt, möglicherweise wird zwischen zwei Bänken von RAM_DL 
umgeschaltet.

> void draw_welcome(void)
> {
> FT8_memWrite32(FT8_RAM_DL, (DL_CLEAR_RGB | 0xff00));  //Grün
> FT8_memWrite32(FT8_RAM_DL + 4, (DL_CLEAR | CLR_COL | CLR_STN |
> CLR_TAG));
> FT8_memWrite32(FT8_RAM_DL + 8, COLOR_RGB(160, 22, 22)); // change to red
> FT8_memWrite32(FT8_RAM_DL + 12, BEGIN(FT8_BITMAPS));
> FT8_memWrite32(FT8_RAM_DL + 16, VERTEX2II(220, 110, 31, 'A'));
> FT8_memWrite32(FT8_RAM_DL + 20, END());
> FT8_memWrite32(FT8_RAM_DL + 24, DL_DISPLAY);  /* END OF DISPLAY LIST */
> FT8_memWrite32(REG_DLSWAP, FT8_DLSWAP_FRAME);
> }
>
> .. aber das hat nichts gebracht. Geht das prinzipiell nicht oder muß ich
> dem FT noch irgendwie sagen 'Fang eine neue DL an!'?

Auf jeden Fall sieht das viel zu kompliziert aus. :-)
1
FT8_cmd_dl(CMD_DLSTART);
2
FT8_cmd_dl(DL_CLEAR_RGB | 0xff00);
3
FT8_cmd_dl(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG);
4
FT8_cmd_dl(COLOR_RGB(160, 22, 22));
5
FT8_cmd_text(220, 110, 31, 0, "A");
6
FT8_cmd_dl(DL_DISPLAY);  
7
FT8_cmd_dl(CMD_SWAP);
8
FT8_cmd_execute();

Und das ist nur die vereinfachte Version inklusive Adress-Overhead durch 
jedes einzelne Kommando.

Also eine wichtige Aufgabe die meine Library für mich hat ist das 
Gefummel mit dem Offset beim Schreiben zu verbergen.

Und die Handbremse ist gelöst.
Zum einen wird nicht ständig getestet ob im FIFO auch noch genug Platz 
ist, weil der Test fast immer überflüssig ist.
Man muss eben aufpassen das man nicht mehr als 4k am Stück in den FIFO 
schreibt, das ist aber gar nicht mal so wenig.
Also es gilt die Annahme, dass der FIFO quasi leer ist und für geöhnlich 
trifft das auch zu.

FT8_cmd_loadimage() könnte ein Problem haben mit grossen Bildern bei 
hohen SPI Geschwindigkeiten, aber der Co-Pro wühlt sich schon ordentlich 
flott durch die Daten, ich weiss gar nicht wie schnell man sein müsste 
um den Co-Pro beim Abarbeiten einzuholen.

Mein FT8_busy() macht auch nicht drei Lese-Zugriffe wie das Original von 
FTDI, sondern nur einen.

Meine Implementierung mag nicht kugelsicher sein, ich möchte aber mal 
ganz frech behaupten das sie deutlich fixer ist als das was FTDI 
vorgelegt hat.

von Axel V. (axel-f)


Lesenswert?

Deinen Programmvorschlag habe ich eingebaut, funktioniert aber noch 
nicht; vielleicht stimmt was mit meiner Funktion 'FT8_cmd_dl' nicht. Das 
werde ich dann mal morgen mit dem Oszi anschauen.

Was mir noch aufgefallen ist: in Deinem init() sprichst Du nur die gpio 
Register an, nicht die gpiox. Obwohl die gpio angeblich veraltet sind. 
Ist das zufällig so?

von Rudolph R. (rudolph)


Lesenswert?

Die GPIOX habe ich bisher nur einfach nicht gebraucht.
In der FT8_command.c vom Github benutze ich jetzt das erste Mal 
REG_GPIOX_DIR um GPIO3 zu bedienen - für den Touch der Matrix Orbital 
Module.

von Axel V. (axel-f)


Lesenswert?

SPI Geschwindigkeit: sehe ich mal nicht als kritisch an. Wenn man sieht, 
daß serielle Flash mit 90 MHz und mehr betrieben werden, sollte das kein 
Problem sein. Außerdem sehen die Pulse am Oszi sehr sauber aus, exakte 
und stabile Flanken.

Die Matrix Orbitalmodule sehen sehr interessant aus, vor allem die 
Produtpalette läßt kaum Wünsche übrig. Was meinst Du zu den 
Pollin-Modulen? Über die Anzeigequalität kann ich erst später was 
sagen...

Schaltplan kannst Du prinzipiell bekommen (als PM). Kannst auch das 
Layout haben. Einfacher wäre es allerdings, wenn ich Dir einfach eine 
Platine schenke, sozusagen als Danke für die FT Lib (bei China 
Bestellungen bekommt man automatisch min. 5 Stück). Es handelt sich um 
einen Frequenzgenerator per DDS plus digitaler Frequenzgeber per PLL 
Synthese. Kann man aber auch prinzipiell als Spielwiese für den SAM4S 
verwenden.

von Rudolph R. (rudolph)


Lesenswert?

Axel V. schrieb:
> SPI Geschwindigkeit: sehe ich mal nicht als kritisch an. Wenn man sieht,
> daß serielle Flash mit 90 MHz und mehr betrieben werden, sollte das kein
> Problem sein. Außerdem sehen die Pulse am Oszi sehr sauber aus, exakte
> und stabile Flanken.

SPI ist recht robust, aber saubere Flanken habe ich da schon länger 
nicht mehr gesehen - ich muss man mein Oszi putzen. :-)

> Die Matrix Orbitalmodule sehen sehr interessant aus, vor allem die
> Produtpalette läßt kaum Wünsche übrig.

Mir "fehlt" aktuell bestenfalls ein etwas kleineres Modell, aber sowas 
hat keiner im Sortiment, so 3,2" oder so, weiss nicht genau, als Ersatz 
für ein 128x64 LCD.
Mir gefallen aus der Matrix Orbital Palette ja am meisten die "G" Typen 
mit der Glasfront die auf das Gehäuse geklebt wird.
Was anderes als kapazititv-touch will ich auch nicht mehr benutzen.

> Was meinst Du zu den Pollin-Modulen?

Na, die sind vor allem sehr preiswert.
Bei sowas mache ich mir dann vor allem eher Sorgen um die 
Nachhaltigkeit, ich habe Zweifel ob man die in einem Jahr noch bekommen 
kann.
Pollin hat ja eher so Artikel die beim Aufräumen in irgendeinem Lager 
noch gefunden wurden.
Womit ich das nicht schlecht reden will, das hat seinen Markt.
Und die Pin-Belegung ist ja auch nicht einheitlich, also einfach mal 
ersetzen kann funktionieren, kann aber auch in Suchen ausarten.

Das erste hat auch zwei Stränge zu sechs LEDs in Reihe -> braucht halt 
noch einen Stepup-Wandler.

Das zweite ist total niedlich mit 2", hat nur keinen Touch.
Aber dafür auch nur zwei LEDs.
Sieht nach einem Display für eine Kamera aus.

Das dritte ist so Kategorie digitaler Bilderahmen, leider ohne 
Datenblatt bei Pollin, aber Google wirft was aus.
Hat wohl auch kein Touch.

> Über die Anzeigequalität kann ich erst später was sagen...

Man wird gut was erkennen können und es wird bunt sein. :-)

> Schaltplan kannst Du prinzipiell bekommen (als PM). Kannst auch das
> Layout haben. Einfacher wäre es allerdings, wenn ich Dir einfach eine
> Platine schenke, sozusagen als Danke für die FT Lib

Danke, aber ich bin wirklich eher neugierig, ein Bild vom fertigen 
Aufbau wäre schon schick.
Ich will zwar langsam auch mal auf ARM wechseln, habe mir dafür aber den 
SAME51 ausgesucht, ein erstes Test-Board läuft auch schon bei einem 
Kollegen.
Für ein Display packe ich da aber nur einen kleinen 7pol. Stecker mit 
drauf und bereite noch eine weitere Platine mit Netzteil für das TFT, 
Level-Shifter und FFC-Anschlüssen vor.

von Axel V. (axel-f)


Lesenswert?

Ja, es ist bunt. Und recht gut ablesbar. Nicht gerade 
4k-crystalclear-Handydisplay aber für meine Zwecke allemal gut. Ich 
nehme an, daß die Touchfolie hier einiges an Schärfe und Klarheit nimmt.
Apropos Touch: was macht die kapazitive Version so wertvoll bzw. was ist 
am res. Touch soo schlecht?

Mittlerweile habe ich bei mir was am laufen und es ist völlig verrückt- 
nach vielem Probieren und kurz vorm wahnsinnig werden habe ich 
herausgefunden, daß ich vor dem Start einer neuen Displayliste meinen 
PCLK auf 0 setzen muß um ihn am Schluß der Liste wieder einzuschalten. 
Gibt's dafür eine Erklärung?

von Rudolph R. (rudolph)


Lesenswert?

Axel V. schrieb:
> Apropos Touch: was macht die kapazitive Version so wertvoll bzw. was ist
> am res. Touch soo schlecht?

Bei resistiv hast Du immer zwei Plastik-Folien die über mechanischen 
Druck zusammen gepresst werden.
Die liegen natürlich vor der Anzeige, machen das Bild von vornherein 
etwas trüber, sind nicht so empfindlich und sind lange nicht so 
widerstandsfähig.
Das schlimmste an Touch-Oberflächen überhaupt ist das man die dauernd 
anfassen muss. :-)
Da ist mir eine Glasplatte über die ich wischen kann echt lieber.
Resistiv-Touch ist auch eher für die Bedienung mit Stift.

Die nächste Steigerung davon sind die Displays wie das EVE2-35G weiter 
oben die keinen Rahmen benötigen und im Gehäuse versenkt werden, sondern 
den Rahmen quasi schon mitbringen.
Ich habe mir auch gerade noch zum Vergleich ein NHD-3.5 gekauft und das 
gefällt mir mechanisch so gar nicht.
Dazu kommt, dass das zwar die gleiche Pin-Belegung wie Riverdi und 
Matrix Orbital hat, bis auf den Audio-Ausgang der einen Pin versetzt 
ist, aber ein Folien-Kabel mit deutlich grösseren Abständen, so kann ich 
das spontan nicht mal irgendwo anschliessen. :-(
Dabei ist die Qualität der Panels wohl sogar ziemlich gut, das "Premium" 
hat einen Blickwinkel von 70° in alle Richtungen.
Aber mit dem Stecker sind die bei mir echt raus.

Axel V. schrieb:
> habe ich
> herausgefunden, daß ich vor dem Start einer neuen Displayliste meinen
> PCLK auf 0 setzen muß um ihn am Schluß der Liste wieder einzuschalten.
> Gibt's dafür eine Erklärung?

Äh nein, nicht wirklich, ich setze PCLK genau einmal.
Schreibst Du jetzt immer noch direkt in die Display-Liste, oder benutzt 
Du den Co-Prozessor dafür?

von Rudolph (Gast)


Angehängte Dateien:

Lesenswert?

I got a NHD-3.5-320240FT_CSVX module with my very first private order 
from DigiKey.
And I can not use it.

The picture shows the NHD-3.5-320240FT_CSVX next to a EVE2-35G from 
Matrix Orbital.
As you can see, the 20pin FFC header on the NHD-3.5 is almost twice the 
size of the connector on the EVE2-35G.

Another idea would be to use jumper-cables to connect to the header on 
the other side of the PCB. But this side also has no level-shifters, so 
directly connecting it to an Arduino for a quick test does not work.

I do not get it, why even bother to copy the pin assignment that Riverdi 
introduced (while shifting the Audio pin) and then use a different 
connector?

von Rudolph (Gast)


Lesenswert?

Something completely different.

I just was curious how much time is needed by the co-prozessor to unpack 
graphics-files into memory.
So I put FT8_cmd_loadimage() in a loop and changed FT8_cmd_execute() a 
bit:
1
void FT8_cmd_execute(void)
2
{
3
  FT8_cmd_start();
4
PORTD |= (1<<PD3);
5
  while (FT8_busy());
6
PORTD &= ~(1<<PD3);
7
}

And the result is interesting.
The ugly star.png I use for the tests with 3867 bytes in length takes 
53ms to process while a .jpg with 3903 bytes takes only 480µs to 
process.
At least with a FT813 this means that processing .jpg is 110 times 
faster than using .png.

That is just annother reason to not use .png with the FT8xx.

von Axel V. (axel-f)


Lesenswert?

Es ist egal, ob ich direkt in die DL schreibe oder via CoProzessor; es 
funktioniert immer nur, wenn ich den PCLK aus und wieder einschalte. An 
der Frequenz vom PCLK liegt es nicht, die habe ich schon von 6-15 MHz 
eingestellt. Vermutlich gibt es einen kurzen Riß im Raum-Zeit-Kontinuum 
;-) , wenn eine neue DL 'rausgelegt' wird. Ich werde mal noch ein wenig 
herumspielen, vielleicht läßt sich noch etwas finden. Im Grunde genommen 
könnte ich damit leben, nur erfahrungsgemäß fallen einem solche dubiosen 
Sachen irgendwann auf die Füße.

Die Matrix Orbitaldisplays- wo kaufst Du die? Soweit ich gesehen habe, 
gibt's die praktisch nur beim Hersteller; nicht in Deutschland.

von Rudolph R. (rudolph)


Lesenswert?

Axel V. schrieb:
> Die Matrix Orbitaldisplays- wo kaufst Du die? Soweit ich gesehen habe,
> gibt's die praktisch nur beim Hersteller; nicht in Deutschland.

Die gibt es bei DigiKey oder Mouser. Da ich die eher nicht Europa 
zuordne habe ich das dem Chef von Matrix Orbital auch so gesagt am 
Messe-Stand und ihm zum Beispiel Watterott empfohlen als Händler, keine 
Ahnung ob da mal was draus wird oder ob da überhaupt Kontakt besteht 
oder Interesse.
Jetzt habe ich gerade meine erste private DigiKey Bestellung durch und 
das war erheblich leichter als ich befürchtet hatte, zudem recht fix.
DigiKey nimmt sogar Paypal an, Sonntag bestellt, Mitwoch morgen da.
Wenn jetzt nicht noch eine der berüchtigten 
Vorlage-Provisions-Rechnungen von UPS kommt ist alles schick.

Die von mir bevorzugten "G" Typen sind allerdings bisher nur gelistet, 
aber nicht verfügbar.
Es gibt ja auch noch Riverdi, die kleinen Module habe allerdings nur 
einen FT801 verbaut, es gibt gar kein 3.5".
RVT50UQFNWC00 gibt es zum Beispiel bei TME.

von Johan S. (johan_s)


Lesenswert?

Guten Tach,
Thank you for the library, I have used it very successfully.
I am using 7"Riverdi screen with FT813.
2 Problems:
1. Simple Cursor for use in menus.
2. I get data to display in text from canbus, varying width.
After using cmd_text, what is the x position?
cmd_text returns void. Where to put next text message?

Vielen Dank
Johan Smit

von Rudolph R. (rudolph)


Lesenswert?

Johan S. schrieb:

Hello,

> Thank you for the library, I have used it very successfully.

I am always like to hear that. :-)

> I am using 7"Riverdi screen with FT813.

Which Controller are you using? I am just curious.

> 2 Problems:
> 1. Simple Cursor for use in menus.

And the problem is what exactly?
You could use a rectangle for this.

> 2. I get data to display in text from canbus, varying width.

I just had a similiar applidation, reading variables from CAN and 
printing text depending on the value.

> After using cmd_text, what is the x position?
> cmd_text returns void. Where to put next text message?

The FT8xx do not provide this information, it can not be retrieved thru 
the command.
And even if somehow there is a way to find out, the co-processor command 
is not executed untill the display-list is complete.
And the result would be calculated during execution of the display-list 
that has been constructed from the co-processer command-list.

This makes it a problem for the application level, you need to calculate 
the resulting width yourself.
But since most of the fonts are proportional and not fixed-width fonts 
this would either require to read back the width of each character from 
the font-tables or to use your own tables in the controller.
So far I just avoid the problem, I am not trying to print text 
dynamically.
I rather setup a table with fixed column positions.
Granted I have to adjust these positions manually.
Annother option would be to build longer strings before feeding them 
thru cmd_txt().

So far the fonts in the FT8xx only have 128 characters.
Looks like the upcoming BT815/BT81 will feature Unicode support but have 
to wait how this works out.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.