Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16d8465b0c | ||
|
|
407d938031 | ||
|
|
33ce2b3ab9 | ||
|
|
d4d4f2b9d2 | ||
|
|
9fef4f8a6e | ||
|
|
0f5b681421 | ||
|
|
01d960258a | ||
|
|
3c333f0280 | ||
|
|
b6c6214b41 | ||
|
|
63290afa07 | ||
|
|
cf57e11ccb | ||
|
|
6d345d2145 | ||
|
|
a410da6e72 | ||
|
|
f0a214d712 | ||
|
|
21f273aae4 | ||
|
|
e42d2b3de2 | ||
|
|
785f64331d | ||
|
|
40aabe48bc | ||
|
|
ca3a9c1264 | ||
|
|
bcd9ecf0c8 | ||
|
|
e5c61d42d4 | ||
|
|
d77b0795ea | ||
|
|
7ebffdab8f | ||
|
|
b73fc798c3 | ||
|
|
5defbe362c | ||
|
|
749f50097f | ||
|
|
95373dc619 | ||
|
|
a1c047e1ef | ||
|
|
52391c46c9 | ||
|
|
5d47228eed | ||
|
|
a3461fe960 | ||
|
|
1a05f8e1b3 | ||
|
|
dd8e641aa7 | ||
|
|
6201c1bc36 | ||
|
|
6d710f0129 | ||
|
|
5cc71ffa92 | ||
|
|
6bef94b8e1 | ||
|
|
95e97e5937 | ||
|
|
8db8e166a2 | ||
|
|
1def9e45dc | ||
|
|
c2a8b21917 | ||
|
|
6d7d544ac7 | ||
|
|
992796345c | ||
|
|
5e2d0f7af8 | ||
|
|
b6fdaa9ad7 | ||
|
|
08d07bd1a0 | ||
|
|
ee74c700bf | ||
|
|
750a6fb78c | ||
|
|
80b6eb810f | ||
|
|
6a9048411e | ||
|
|
ecb9836510 | ||
|
|
c4cb6eb90a | ||
|
|
c58b901f26 | ||
|
|
d83619904f | ||
|
|
50540179c7 | ||
|
|
9bbd7d72aa | ||
|
|
43c5d5a41a | ||
|
|
dfd2aaddd1 | ||
|
|
6c783c55de | ||
|
|
f38ea3045b | ||
|
|
0a6c6ed869 | ||
|
|
e8308a9182 | ||
|
|
edb1e333f0 | ||
|
|
528c8d5500 | ||
|
|
117715dc3b | ||
|
|
328dc06983 | ||
|
|
480708c992 | ||
|
|
9a0761f6da | ||
|
|
e6c09b7a9a | ||
|
|
4fa0c81087 | ||
|
|
04eb77fb2d | ||
|
|
7878f1bafd | ||
|
|
60bb859fc9 |
@@ -1,3 +1,465 @@
|
||||
Version 1.9.0:
|
||||
- Die Messung aus 1.8.8 hat die Ursache der Trägheit gefunden: Jeder Bildaufbau kostete
|
||||
240 bis 300 Millisekunden - dauerhaft, auch im Leerlauf. Fünf Sekunden für den
|
||||
Aufweckdialog waren also rund zwanzig solcher Durchgänge.
|
||||
- Grund war, dass zweimal durch den Bildspeicher gearbeitet wurde: LVGL zeichnete in einen
|
||||
eigenen Puffer, und dessen Inhalt wurde anschließend vollständig in den Bildspeicher
|
||||
kopiert. Bei 1280x720 in 24 Bit sind das zwei Durchgänge durch je 2,7 MB.
|
||||
- LVGL zeichnet jetzt direkt in den Bildspeicher. Der Treiber lässt das Kopieren dann weg,
|
||||
und LVGL zeichnet nur noch die geänderten Bereiche statt jedes Mal die ganze Fläche.
|
||||
Schalter WS7_DIRECT_FB in pins_config.h.
|
||||
- Die Anzeigen von Shot-Timer und Waage bleiben während eines Bezugs in der normalen
|
||||
Schrift; der fette Wechsel ist entfernt. Der Bereich bekommt weiterhin mehr Platz.
|
||||
- Neu: Die Größe der Standby-Uhr lässt sich einstellen (Klein, Mittel, Groß - 120, 180 oder
|
||||
240 Pixel), zu finden auf der Info-Seite unter Darstellung. Anders als die allgemeine
|
||||
Schriftgröße wirkt sie sofort, weil sie an einem einzigen Textfeld hängt.
|
||||
- Die Knöpfe des Aufweckdialogs berücksichtigen jetzt ebenfalls die eingestellte
|
||||
Schriftgröße und wachsen mit.
|
||||
|
||||
Version 1.8.8:
|
||||
- Der Aufweckdialog berücksichtigt jetzt die eingestellte Schriftgröße vollständig: Die
|
||||
Knöpfe bekommen dieselbe Schrift wie der Text und wachsen mit (150 / 210 / 280 Pixel).
|
||||
Bisher erbten sie die kleine Grundschrift und behielten eine feste Breite - neben dem
|
||||
größeren Text wirkten sie dadurch verloren.
|
||||
- Die große Standby-Uhr bleibt bewusst bei ihrer festen Größe: Sie ist bereits auf die
|
||||
Bildschirmhöhe abgestimmt, eine Umschaltung würde sie nur schlechter passend machen.
|
||||
- Neu: eine Zeitmessung für langsame Bildaufbauten. Überschreitet ein Zeichenzyklus
|
||||
200 Millisekunden, meldet die serielle Konsole seine Dauer. Damit lässt sich feststellen,
|
||||
welcher Vorgang tatsächlich Zeit kostet - die bisherigen Erklärungen für die Verzögerung
|
||||
beim Aufweckdialog haben sich als falsch erwiesen, und weiteres Raten hilft nicht.
|
||||
Im Normalbetrieb bleibt die Ausgabe still.
|
||||
|
||||
Version 1.8.7:
|
||||
- Vom Fingertipp auf die Standby-Uhr bis zum Aufweckdialog vergingen rund fünf Sekunden mit
|
||||
schwarzem Bildschirm. Ursache war der halbdurchsichtige Vorhang, den der Dialog über den
|
||||
ganzen Bildschirm legt: Dafür muss LVGL einen Vollbild-Zwischenpuffer anlegen und die
|
||||
gesamte Fläche mischen - bei 1280x720 in 24 Bit die teuerste Operation überhaupt.
|
||||
- Der Vorhang ist auf dem Waveshare-Panel jetzt deckend. Verloren geht dabei nichts: Im
|
||||
Standby liegt dahinter ohnehin nur Schwarz.
|
||||
- Aus demselben Grund ist auch der Vorhang des Menüs deckend, in einem dunklen Ton. Auf
|
||||
dunklem Grund sieht das praktisch genauso aus wie halbdurchsichtig, spart aber dieselbe
|
||||
Mischarbeit. Die JC-Panels behalten in beiden Fällen die Transparenz.
|
||||
- Der Aufweckdialog wird mit größerer Schrift auch breiter (420 / 640 / 900 Pixel), damit
|
||||
der Text nicht an unglücklichen Stellen umbricht.
|
||||
|
||||
Version 1.8.6:
|
||||
- Die Uhrzeit verschwindet nicht mehr, wenn die Hauptplatine ihre Zeit gerade neu abgleicht.
|
||||
Der P4 merkt sich die zuletzt empfangene Uhrzeit und zählt zwischen den Meldungen selbst
|
||||
weiter; sobald die Hauptplatine wieder eine Zeit schickt, gilt deren Wert.
|
||||
- Der P4 stellt dabei nichts richtig und ersetzt keine Zeitquelle - er überbrückt nur die
|
||||
Lücke. Hat er noch nie eine Uhrzeit bekommen, bleibt die Anzeige wie bisher leer.
|
||||
- Gilt für die Uhr in der Kopfleiste und für die große Standby-Uhr.
|
||||
|
||||
Version 1.8.5:
|
||||
- Die Verzögerung von rund zwei Sekunden rund um den Standby ist behoben. Sie lag nicht an
|
||||
der Helligkeitsumschaltung, sondern daran, dass die Standby-Uhr bei JEDER Zustandsmeldung
|
||||
der Hauptplatine nach vorn geholt wurde. Das ordnet die Ebenen neu und lässt LVGL den
|
||||
gesamten Bildschirm neu zeichnen - einmal pro Sekunde, jedes Mal 1280x720 in 24 Bit.
|
||||
Dadurch hing die Oberfläche dauerhaft ein bis zwei Sekunden hinterher. Nach vorn geholt
|
||||
wird die Uhr jetzt beim Einblenden, danach bleibt sie dort.
|
||||
- Der Aufweckdialog schließt sich nach 30 Sekunden ohne Auswahl von selbst und wird wie
|
||||
„Abbrechen" gewertet. Vorher blieb das Display hell stehen - der Dialog schaltet auf
|
||||
normale Helligkeit, und ein versehentlicher Tipp auf die Uhr hätte die Maschine die ganze
|
||||
Nacht leuchten lassen.
|
||||
- Die Verlaufskurve hat keinen eigenen Hintergrund mehr; sie liegt jetzt direkt auf der
|
||||
Karte. Die abgesetzte Fläche war nur nötig, solange die Kurve vor dem ersten Messwert
|
||||
leer blieb - seit sie beim aktuellen Wert startet, ist immer eine Linie da.
|
||||
- Auf der Statistikseite erschien ein leeres Rechteck, wenn ohne Waage bezogen wurde. Dort
|
||||
stand ein typografischer Gedankenstrich, den der Zeichensatz der Schrift nicht enthält.
|
||||
Jetzt ein einfacher Bindestrich.
|
||||
|
||||
Version 1.8.4:
|
||||
- Standby-Uhr und Aufweckdialog erscheinen jetzt sofort statt mit spürbarer Verzögerung.
|
||||
Ursache waren die weichen Ein- und Ausblendungen: Eine Deckkraft-Animation ist bei einem
|
||||
Bildspeicher in RGB888 das Teuerste, was die Oberfläche tun kann, weil für jedes Einzelbild
|
||||
die gesamte Fläche unter der Ebene neu gezeichnet und mit ihr gemischt werden muss. Auf
|
||||
1280x720 dauerte eine solche Blende deutlich länger als die 450 ms, die vorgesehen waren.
|
||||
Auf dem Waveshare-Panel laufen die Übergänge deshalb ohne Animation; die JC-Panels
|
||||
behalten sie.
|
||||
- Beim Wechsel der Schriftgröße blitzte kurz ein blaues Bild auf. Das kommt nicht von der
|
||||
Firmware: Das Panel zeigt von sich aus Blau, sobald kein Videosignal anliegt - und beim
|
||||
nötigen Neustart reißt das Signal kurz ab. Die Beleuchtung wird jetzt vorher abgeschaltet;
|
||||
dunkel ist unauffälliger als blau.
|
||||
- Neue Einstellung unter Darstellung: „Temperaturzahl in der Zustandsfarbe". Aus bleibt die
|
||||
Zahl weiß, die Zustandsfarbe steckt dann allein im Balken darunter - ruhiger, und die Zahl
|
||||
bleibt eine Zahl. Ein bedeutet, sie färbt sich mit, wie bisher. Vorgabe ist aus.
|
||||
Warnungen bleiben in jedem Fall rot; das ist keine Gestaltung, sondern eine Meldung.
|
||||
|
||||
Version 1.8.3:
|
||||
- Fehlerbehebung: Bei allen Darstellungen stand hinter der Temperatur ein leeres Rechteck
|
||||
statt des C. Die beiden großen Schriften waren auf Ziffern, Komma, Punkt, Minus und
|
||||
Gradzeichen beschränkt - das C fehlte darin schlicht. Es ist jetzt enthalten, ebenso g
|
||||
und s für die Gewichts- und Zeitanzeige während eines Bezugs.
|
||||
- Fehlerbehebung: Bei der Darstellung „Verlauf" war keine Kurve zu sehen. Ein frisch
|
||||
angelegtes Diagramm enthält lauter „kein Wert"-Punkte und zeichnet deshalb nichts; ohne
|
||||
Hintergrund war der Bereich vollständig unsichtbar, bis nach einer Minute genug Messwerte
|
||||
zusammengekommen wären. Die Kurve startet jetzt beim aktuellen Messwert, und ihre Fläche
|
||||
ist leicht abgesetzt.
|
||||
- Die großen Zahlen des Dashboards stehen jetzt im fetten Schnitt und etwas enger, wie im
|
||||
Entwurf. Erzeugt aus der variablen Maven-Pro-Datei mit Gewicht 700 - dieselbe Schriftart
|
||||
wie bisher, nur kräftiger. Die übrige Oberfläche bleibt unverändert.
|
||||
|
||||
Version 1.8.2:
|
||||
- Die Liste der letzten Bezüge auf der Statistikseite ist jetzt eine Tabelle mit festen
|
||||
Spalten: Zeitpunkt, Dauer, Gewicht und gegebenenfalls die Kennzeichnung „kalt".
|
||||
- Vorher war es ein einziges mehrzeiliges Textfeld, in dem die Werte durch Leerzeichen
|
||||
getrennt aneinandergereiht standen. Weil Zahlen unterschiedlich breit sind, stand nichts
|
||||
untereinander - zwei Bezüge ließen sich nicht vergleichen, ohne jede Zeile einzeln zu
|
||||
lesen. Genau das sah unruhig aus.
|
||||
- Ziffern haben jetzt gleiche Breite, jede zweite Zeile ist leicht abgesetzt, und eine
|
||||
Kopfzeile benennt die Spalten. Wurde ohne Waage bezogen, bleibt die Gewichtsspalte leer,
|
||||
statt eine Null vorzutäuschen.
|
||||
- Die Zeilen werden einmal angelegt und danach nur gefüllt oder ausgeblendet, statt bei
|
||||
jeder Aktualisierung neu zu entstehen.
|
||||
|
||||
Version 1.8.1:
|
||||
- Die Bezugsanzeige ist da, und zwar für alle vier Darstellungen gemeinsam: Sobald ein
|
||||
Bezug oder Dampfbezug läuft, schrumpft der Temperaturbereich und die untere Zeile wächst.
|
||||
Shot-Timer und Gewicht werden dabei auf 96 Pixel vergrößert - während eines Bezugs zählen
|
||||
Zeit und Gewicht, die Kesseltemperaturen sind dann Nebensache.
|
||||
- Es gibt keine zweite Ansicht: Die Seite verschiebt nur das Gewicht zwischen ihren beiden
|
||||
Bereichen. Damit bleibt alles an seinem Platz, und es gibt nichts doppelt zu pflegen.
|
||||
- Der Wechsel hält nach dem Bezug noch vier Sekunden an. Ohne dieses Nachhalten würde die
|
||||
Seite bei jeder kurzen Unterbrechung hin- und herspringen - das wäre unruhiger als gar
|
||||
kein Wechsel.
|
||||
|
||||
Version 1.8.0:
|
||||
- Das Dashboard hat vier neue Darstellungen, die die bisherigen fünf ersetzen. Sie sind
|
||||
keine Varianten desselben Bildes, sondern vier Antworten auf die Frage, was die große
|
||||
Fläche des 7-Zöllers leisten soll:
|
||||
* Gewichtet - Wasser bekommt zwei Drittel der Fläche, Dampf ein Drittel. Beim Espresso
|
||||
zählt die Wassertemperatur; die Asymmetrie ist die Aussage.
|
||||
* Verlauf - unter jeder Temperatur eine flache Kurve der letzten Minute. Die eigentliche
|
||||
Frage an eine PID-Regelung ist nicht „wie warm", sondern „hält sie" - und das kann eine
|
||||
Zahl grundsätzlich nicht zeigen. Der Ausschnitt hängt am Sollwert, damit die Abweichung
|
||||
sichtbar wird statt in der Skala unterzugehen.
|
||||
* Flächen - keine Kartenkanten, zwei Felder mit einem Hauch Helligkeitsunterschied.
|
||||
* Band - ein farbiges Band über die volle Breite sagt den Zustand, bevor eine Zahl
|
||||
gelesen wird: bereit, heizt, Bezug, Cold Extraction oder Standby. Neue Vorgabe.
|
||||
- Dafür gibt es zwei neue Schriftgrade (96 und 140 Pixel). Sie enthalten nur Ziffern,
|
||||
Komma, Punkt, Minus und Gradzeichen - mit vollem Zeichensatz wären sie um ein Vielfaches
|
||||
größer, ohne etwas beizutragen. Die größte Textschrift hatte bisher 48 Pixel, was für die
|
||||
großen Zahlen nicht reichte.
|
||||
- Ältere Stände haben in den Einstellungen noch die Nummer einer der früheren Darstellungen
|
||||
gespeichert; liegt sie außerhalb, fällt sie auf die Vorgabe zurück.
|
||||
- Der Aufbau der Bezugsanzeige - untere Zeile wechselt während eines Bezugs auf große
|
||||
Timer- und Gewichtsanzeige - folgt als nächster Schritt.
|
||||
|
||||
Version 1.7.3:
|
||||
- Die Schriftgröße steht jetzt auf der Info-Seite im Abschnitt „Darstellung", zusammen mit
|
||||
der Wahl der Temperaturanzeige und dem Live-Bezugsschirm. Dort gehört sie hin: Es ist
|
||||
eine Einstellung dieses Displays, keine Wartungsaufgabe.
|
||||
- Die Seite Reinigung & Wartung hat damit wieder vier Karten in zwei Spalten.
|
||||
- Die Auswahl selbst ist unverändert: drei Stufen, Neustart nach der Auswahl.
|
||||
- Sie steht auf allen Panels zur Verfügung, nicht nur auf dem 7-Zöller.
|
||||
|
||||
Version 1.7.2:
|
||||
- Die Schriftgröße lässt sich jetzt einstellen: Klein, Mittel oder Groß, zu finden auf der
|
||||
Seite Reinigung & Wartung in der neuen Karte „Darstellung".
|
||||
- LVGL-Schriften sind fest einkompilierte Bilddaten; es gibt sie nur in den Größen, die im
|
||||
Projekt liegen (14, 18, 28, 40 und 48 Pixel). Stufenlos skalieren lässt sich also nichts.
|
||||
Stattdessen gibt es drei Rollen - klein, normal, hervorgehoben -, die je nach Einstellung
|
||||
eine Stufe höher greifen.
|
||||
- Die großen Anzeigen für Temperatur und Uhrzeit bleiben unverändert: Sie sind bereits auf
|
||||
die Bildschirmgröße abgestimmt und sollen nicht mitwachsen.
|
||||
- Die Einstellung liegt lokal im Display, nicht auf der Hauptplatine - sie betrifft nur
|
||||
dieses Gerät. Nach der Auswahl startet der P4 neu, weil die Schriften in bereits
|
||||
angelegten Bedienelementen stecken und sich nicht nachträglich umhängen lassen.
|
||||
- Zu erwarten: In der Stufe Groß brauchen die Karten mehr Platz. Ob alle Seiten dann noch
|
||||
vollständig auf den Bildschirm passen, zeigt erst das Gerät.
|
||||
|
||||
Version 1.7.1:
|
||||
- Cold Extraction ist auf dem 7-Zoll-Panel dreispaltig: oben die drei Karten mit
|
||||
Erklaerungstext (Modus, Vorbenetzung, Bezugsende), darunter die knappen (Grundeinstellung,
|
||||
Hauptbezug, Pumpenschutz), der Speichern-Knopf frei unter allen sechs. Drei statt zwei
|
||||
Spalten, weil die Erklaerungstexte keine volle Zeilenbreite brauchen und so am Ende keine
|
||||
halbleere Reihe stehen bleibt.
|
||||
- Der Warnhinweis stand bisher als eigene Zeile am Seitenende, weit entfernt von dem
|
||||
Schalter, auf den er sich bezieht. Er sitzt jetzt in der Modus-Karte.
|
||||
- Reinigung & Wartung ist zweispaltig und besteht aus vier Karten: Wartungszaehler,
|
||||
Flush-Zeiten, Display-Helligkeit sowie Reinigung & Entkalkung. Bisher standen dort lose
|
||||
Zeilen unter blossen Zwischenueberschriften, dazwischen freistehende Knoepfe.
|
||||
- Anders als bei Bruehen und Cold Extraction sitzt der Speichern-Knopf hier IN der Karte:
|
||||
Jede Karte speichert etwas anderes, deshalb gehoert der Knopf zur Karte statt unter die
|
||||
Seite.
|
||||
- Alle drei umgestellten Seiten passen jetzt vollstaendig auf den Bildschirm. Die JC-Panels
|
||||
behalten ihr einspaltiges Layout.
|
||||
|
||||
Version 1.7.0:
|
||||
- Brew-Control ist auf dem 7-Zoll-Panel zweispaltig: Pre-Infusion und Brew-by-Weight oben,
|
||||
Brew-by-Time und Dampf-Timer darunter, der Speichern-Knopf frei unter allen Karten.
|
||||
Damit passt die Seite vollstaendig auf den Bildschirm und muss nicht mehr gescrollt
|
||||
werden - der teuerste Vorgang der Oberflaeche entfaellt dort ersatzlos.
|
||||
- Die Anordnung folgt der Bedeutung: links steht, was den Bezug startet, rechts, was ihn
|
||||
beendet.
|
||||
- Der Speichern-Knopf sitzt bewusst nicht in einer der Karten. Er speichert die ganze Seite
|
||||
und wuerde in einer einzelnen Karte so wirken, als gaelte er nur fuer diese.
|
||||
- Die JC-Panels bleiben einspaltig - dort ist der Platz knapp, nicht ueppig.
|
||||
- Cold Extraction und Reinigung/Wartung folgen als naechstes.
|
||||
|
||||
Version 1.6.27:
|
||||
- Beim Waveshare-Panel rollen scrollbare Listen nach dem Loslassen nicht mehr aus, sondern
|
||||
folgen nur dem Finger. Ohne Doppelpufferung entsteht beim Scrollen jedes Bild komplett
|
||||
neu; am staerksten faellt das beim Ausrollen auf, wo sich das Bild ohne fuehrenden Finger
|
||||
weiterbewegt und jedes Stocken unmittelbar sichtbar ist.
|
||||
- Die JC-Panels sind ausgenommen, ihr Bediengefuehl bleibt unveraendert.
|
||||
|
||||
Version 1.6.26:
|
||||
- Fehlerbehebung: Beim Bildlauf blitzten blaue Zwischenbilder auf. Ursache war der zweite
|
||||
Zeichenpuffer aus 1.6.25. Der Panel-Treiber lehnt eine Uebertragung ab, solange die
|
||||
vorige noch laeuft; mit zwei Puffern schickt LVGL die naechste aber sofort los. Die
|
||||
abgelehnte Uebertragung faellt ersatzlos aus, und der betroffene Bildbereich behaelt
|
||||
seinen alten Inhalt.
|
||||
- Der zweite Zeichenpuffer ist deshalb wieder entfernt, die Herstellerdatei lvgl_port_v9.c
|
||||
damit wieder unveraendert. Der eigentliche Gewinn beim Bildlauf bleibt erhalten: Der
|
||||
Zwischenpuffer hat weiterhin volle Bildhoehe, ein Bildlauf braucht also einen Durchgang
|
||||
statt sechs.
|
||||
|
||||
Version 1.6.25:
|
||||
- Der Bildlauf war nach der Umstellung auf einen Bildspeicher sehr zaeh. Grund war der
|
||||
Zwischenpuffer, in den LVGL zeichnet: Mit 120 Zeilen brauchte ein Bildlauf ueber die
|
||||
ganze Seite sechs Durchgaenge, jeder mit eigener Uebertragung in den Bildspeicher.
|
||||
- Der Zwischenpuffer hat jetzt volle Bildhoehe - ein Durchgang statt sechs. Dazu kommt ein
|
||||
zweiter Puffer, damit LVGL bereits den naechsten Bereich zeichnen kann, waehrend der
|
||||
vorige noch uebertragen wird.
|
||||
- Kosten: 2 x 2,8 MB PSRAM zusaetzlich, bei 32 MB unkritisch. Am Startverhalten aendert
|
||||
sich nichts: Diese Puffer sind Zeichenpuffer, keine Bildspeicher der Anzeige - es bleibt
|
||||
bei EINEM Bildspeicher, und nur der war fuer den Startfehler verantwortlich.
|
||||
|
||||
Version 1.6.24:
|
||||
- Ursache des unzuverlaessigen Starts gefunden und behoben: die Anzahl der Bildspeicher.
|
||||
Mit zwei Bildspeichern kam nach dem Einschalten kein Bild - der Hochlauf meldete
|
||||
durchgehend Erfolg, das Panel blieb dunkel, und erst ein Reset half. Mit genau einem
|
||||
startet es zuverlaessig. Belegt wurde das mit den Prueffarbbalken: Sie erscheinen mit
|
||||
einem Speicher sofort, mit zweien nicht. Der Werks-Testsketch benutzt ebenfalls einen -
|
||||
das war der letzte verbliebene Unterschied zu ihm.
|
||||
- Die Oberflaeche laeuft deshalb ohne Doppelpufferung: LVGL zeichnet in einen
|
||||
Zwischenpuffer von 120 Zeilen im PSRAM, der dann in den einen Bildspeicher uebertragen
|
||||
wird. Bei schnellen Bildwechseln kann kurz eine Kante sichtbar werden; ein zuverlaessig
|
||||
startendes Display wiegt das auf.
|
||||
- Schalter WS7_SINGLE_FB in pins_config.h. WS7_PARTIAL_REFRESH ist damit wirkungslos, weil
|
||||
es ohne Doppelpufferung nichts umzuschalten gibt.
|
||||
- Der PSRAM-Bedarf sinkt von 5,4 MB auf 2,8 MB.
|
||||
- Die Umgehungen aus den Vorversionen bleiben erhalten: Anlaufzeit, wiederholte
|
||||
Bridge-Grundeinstellung, wiederholte Weckbefehle und der Neustart nach Kaltstart. Ob
|
||||
jede davon noch noetig ist, laesst sich jetzt einzeln pruefen - der Startfehler selbst
|
||||
ist behoben.
|
||||
|
||||
Version 1.6.23:
|
||||
- Der Selbst-Neustart aus 1.6.22 reicht nicht: Ein Software-Neustart setzt offenbar nicht
|
||||
dasselbe zurueck wie die Reset-Taste. Der Schalter bleibt eingeschaltet, er schadet nicht,
|
||||
loest das Problem aber nicht allein.
|
||||
- Zurueck zu dem einen Unterschied zum funktionierenden Werks-Testsketch, der bisher nie
|
||||
ueberprueft wurde: Dieser legt EINEN Bildspeicher an, die Firmware zwei. Der Pruefbild-Test
|
||||
lief bislang ebenfalls mit zwei und war damit nie ein echter Nachbau des Testsketches - er
|
||||
wich an genau der Stelle ab, die noch offen ist.
|
||||
- Mit WS7_TEST_PATTERN = 1 wird jetzt genau ein Bildspeicher angelegt, wie im Testsketch.
|
||||
Erscheinen die Farbbalken damit zuverlaessig, liegt es an der Anzahl der Bildspeicher, und
|
||||
die Oberflaeche laesst sich darauf umstellen.
|
||||
|
||||
Version 1.6.22:
|
||||
- Der Ab- und Wiederaufbau der DSI-Strecke aus 1.6.21 hat nicht geholfen, sondern das Bild
|
||||
um einen Schritt verschlechtert: Nach dem Einschalten kam gar nichts mehr, nach dem
|
||||
ersten Reset nur die Beleuchtung, erst nach dem zweiten das Bild. Ein Ab- und Wiederaufbau
|
||||
im laufenden Betrieb ist einem echten Chip-Reset also nicht gleichwertig. WS7_DSI_RESTART
|
||||
steht deshalb wieder auf 0; der Schalter bleibt samt Begruendung erhalten.
|
||||
- Stattdessen der Weg, den die Messungen eindeutig stuetzen: Nach einem Kaltstart startet
|
||||
der P4 sich genau einmal selbst neu, sobald der erste Hochlauf durch ist. Damit passiert
|
||||
genau das, was bei jedem Versuch zuverlaessig geholfen hat - ohne dass jemand die
|
||||
Reset-Taste druecken muss.
|
||||
- Eine Schleife ist ausgeschlossen: Beim zweiten Durchlauf ist der Startgrund kein Kaltstart
|
||||
mehr, die Bedingung greift nicht erneut. Der Fruehstart-Zaehler der Absturzsicherung wird
|
||||
vor dem gewollten Neustart zurueckgesetzt, damit dieser nicht als Absturz zaehlt.
|
||||
- Kostet rund drei Sekunden, und nur beim Einschalten. Schalter WS7_COLD_BOOT_RESTART in
|
||||
pins_config.h.
|
||||
- Das ist eine Umgehung, keine Erklaerung: Warum das Panel den ersten Anlauf nach dem
|
||||
Einschalten nicht annimmt, ist weiterhin offen. Der Hochlauf meldet durchgehend Erfolg.
|
||||
|
||||
Version 1.6.21:
|
||||
- Der Hochlauf lief zuletzt vollstaendig fehlerfrei durch - Bridge zweimal eingestellt,
|
||||
Panel zweimal geweckt, alle I2C-Bausteine erreichbar - und trotzdem kam beim ersten
|
||||
Einschalten kein Bild. Erst ein Reset half, und der zuverlaessig. Es fehlte also kein
|
||||
Befehl mehr; es fehlte der Vorgang selbst.
|
||||
- Ein Reset unterscheidet sich an dieser Stelle in genau einem Punkt: Die DSI-Verbindung
|
||||
geht einmal weg und neu auf, waehrend Bridge und Panel bereits versorgt und eingestellt
|
||||
sind. Weder die wiederholte Grundeinstellung noch die wiederholten Weckbefehle ersetzen
|
||||
das - beide laufen ueber eine Verbindung, die durchgehend bestand.
|
||||
- Der Hochlauf baut die DSI-Strecke jetzt einmal komplett ab und wieder auf: Bildausgabe,
|
||||
Kommandokanal und Bus werden freigegeben und neu angelegt. Damit passiert ohne Reset,
|
||||
was vorher erst der zweite Start brachte. Schalter WS7_DSI_RESTART in pins_config.h,
|
||||
Pause dazwischen WS7_DSI_RESTART_MS (Vorgabe 200 ms).
|
||||
- Der DSI-Aufbau steckt dafuer in einer eigenen Funktion, damit der Vorgang wiederholbar
|
||||
ist statt zweimal im Quelltext zu stehen.
|
||||
|
||||
Version 1.6.20:
|
||||
- Nach 1.6.19 lief es reproduzierbar so ab: Beim Einschalten ging nach zwei bis drei
|
||||
Sekunden die Hintergrundbeleuchtung an, dann kam nichts mehr; nach einem Reset ging die
|
||||
Beleuchtung kurz aus und danach erschien Beleuchtung samt Bild. Daraus folgt der letzte
|
||||
fehlende Schritt: Auch die Grundeinstellung der Bridge lief bisher nur einmal, und zwar
|
||||
bevor die DSI-Strecke ueberhaupt existierte. Beim Reset half es nur deshalb, weil die
|
||||
Bridge ihre Einstellung aus dem vorigen Durchlauf noch hatte und diesmal ein DSI-Signal
|
||||
vorfand.
|
||||
- Die Grundeinstellung der Bridge wird jetzt ein zweites Mal geschrieben, sobald die
|
||||
Videoausgabe laeuft - dasselbe Vorgehen wie bei den Weckbefehlen des Panels in 1.6.19.
|
||||
Damit wird ohne Reset erreicht, was vorher erst der zweite Durchlauf brachte.
|
||||
- Im Start-Log sind beide Durchgaenge benannt ("Bridge-Grundeinstellung vor dem DSI-Start"
|
||||
und "... nach dem Start der Videoausgabe").
|
||||
|
||||
Version 1.6.19:
|
||||
- Die Wartezeit aus 1.6.18 hat den Start deutlich verbessert, aber noch nicht zuverlässig
|
||||
gemacht. Aus dem verbliebenen Fehlerbild folgt der nächste Schritt: Die Beleuchtung ging
|
||||
an, das Bild fehlte. Die Beleuchtung hängt an der Bridge und wird über I2C geschaltet -
|
||||
sie funktioniert also. Verloren gehen die Weckbefehle an das Panel selbst.
|
||||
- Diese Befehle wurden bisher genau einmal geschickt, bevor die Videoausgabe lief. War der
|
||||
Panel-Controller in dem Moment noch nicht aufnahmebereit, waren sie weg, und danach hat
|
||||
nie wieder jemand nachgefragt. Sie werden jetzt ein zweites Mal gesendet, sobald die
|
||||
Videoausgabe steht. Die Befehle sind wiederholbar, der zweite Anlauf kostet nichts.
|
||||
- Die Pause dazwischen steht als WS7_PANEL_SETTLE_MS in pins_config.h (Vorgabe 200 ms).
|
||||
- Im Start-Log ist jeder Anlauf einzeln zu sehen ("Weckbefehle vor/nach dem Start der
|
||||
Videoausgabe").
|
||||
|
||||
Version 1.6.18:
|
||||
- Ursache des unzuverlässigen Starts gefunden: Der P4 sprach Bridge und Panel sofort nach
|
||||
dem Einschalten an. Das Displaymodul braucht danach aber einen Moment, bis es bereit ist.
|
||||
Kam der Hochlauf zu früh, nahm die Bridge ihre Register nicht an oder das Panel zeigte
|
||||
trotz korrekt gesendeter DSI-Daten nichts - beides ohne Fehlermeldung, weil aus Sicht des
|
||||
P4 jeder Schritt geklappt hatte. Das Ergebnis war ein Display, das mal ansprang und mal
|
||||
nicht, und beim ersten Anstecken meist gar nicht.
|
||||
- Der Hochlauf wartet jetzt WS7_PANEL_WARMUP_MS (Vorgabe 2000 ms), bevor er beginnt. Der
|
||||
Werks-Testsketch wartet aus demselben Grund 2 Sekunden am Anfang.
|
||||
- Damit erklärt sich auch, warum es mit geöffnetem seriellen Monitor fast immer klappte:
|
||||
Dessen USB-Anmeldung verzögert den Start und ersetzte damit unbeabsichtigt die Wartezeit.
|
||||
- Der Wert steht in pins_config.h. Läuft der Start zuverlässig, lässt er sich vorsichtig
|
||||
senken; springt die Anzeige nicht an, ist er der erste Wert zum Erhöhen.
|
||||
|
||||
Version 1.6.17:
|
||||
- Der I2C-Stoerimpulsfilter aus 1.6.16 wirkt: Nach dem Panel-Start melden sich wieder alle
|
||||
drei Bausteine, Bridge und Touch bleiben ansprechbar.
|
||||
- Das Pruefbild aus 1.6.15 war allerdings wirkungslos und damit als Test untauglich: Es
|
||||
wurde zwar gesetzt, doch unmittelbar danach startete LVGL und schrieb in den Bildspeicher,
|
||||
womit das Pruefbild wieder verschwand. Der Test sah deshalb genauso aus wie der Fehler,
|
||||
den er finden sollte.
|
||||
- Mit WS7_TEST_PATTERN = 1 endet der Hochlauf jetzt direkt nach dem Pruefbild: Beleuchtung
|
||||
an, Farbbalken stehen, kein LVGL. Damit ist die Frage eindeutig zu beantworten, ob die
|
||||
Anzeigekette bis zum Panel arbeitet.
|
||||
|
||||
Version 1.6.16:
|
||||
- Ursache des schwarzen Bildes gefunden. Der Start-Log zeigte es eindeutig: Vor dem
|
||||
Panel-Start meldeten sich alle drei I2C-Bausteine (Touch 0x14, Audio 0x18, Bridge 0x45),
|
||||
danach nur noch der Audio-Baustein. Es fielen also genau die beiden weg, die am
|
||||
Displaykabel haengen - der Bus selbst arbeitete weiter. Sobald die DSI-Ausgabe laeuft,
|
||||
stoeren deren schnelle Signale auf das lange Flachbandkabel ein, und ohne Filterung
|
||||
bringen diese Stoerspitzen die I2C-Uebertragung aus dem Tritt. Die Bridge liess sich
|
||||
daraufhin nicht mehr ansprechen, das Panel blieb dunkel.
|
||||
- Der I2C-Bus laeuft fuer das Waveshare-Panel jetzt mit Stoerimpulsfilter und internen
|
||||
Abschlusswiderstaenden, so wie es auch das Waveshare-Beispiel tut. Beides fehlte, weil
|
||||
die Bus-Einrichtung urspruenglich von den JC-Panels uebernommen wurde, die kein
|
||||
Flachbandkabel dieser Laenge haben.
|
||||
- Das erklaert rueckwirkend auch, warum sich der Fehler so sprunghaft verhielt: Ob eine
|
||||
Uebertragung durchkam, hing von der Stoerlage ab.
|
||||
|
||||
Version 1.6.15:
|
||||
- Diagnose fuer das schwarze Bild, das der Log bisher nicht erklaeren konnte: Alle Schritte
|
||||
liefen fehlerfrei durch, trotzdem blieb die Anzeige leer.
|
||||
- Die drei Weckbefehle an das Panel (MADCTL, Sleep Out, Display On) liefen bislang
|
||||
ungeprueft durch und sind jetzt in die Fehlerausgabe einbezogen.
|
||||
- Neuer Schalter WS7_TEST_PATTERN in pins_config.h: zeigt statt der Oberflaeche
|
||||
Prueffarbbalken an. Sie entstehen im DSI-Baustein selbst und benutzen weder Bildspeicher
|
||||
noch LVGL. Damit laesst sich in einem Durchgang trennen, ob die Anzeigekette bis zum
|
||||
Panel arbeitet oder ob der Fehler weiter oben liegt.
|
||||
- Das Ende des Hochlaufs wird gemeldet ("Bringup fertig" / "LVGL laeuft"). Bisher endete
|
||||
die Ausgabe nach dem Panel-Start, und ein Haengenbleiben in LVGL war von einem
|
||||
fehlenden Bild nicht zu unterscheiden.
|
||||
|
||||
Version 1.6.14:
|
||||
- Der Touch-Controller wird jetzt erst angesprochen, nachdem die Bridge freigegeben und die
|
||||
Hintergrundbeleuchtung eingeschaltet ist. Der GT9271 haengt an derselben Versorgung und
|
||||
antwortet vorher nicht auf I2C - deshalb schlug seine Initialisierung bisher schon beim
|
||||
Kaltstart fehl. In der Werks-Testskizze steht die Touch-Initialisierung aus demselben
|
||||
Grund hinter dem Einschalten der Beleuchtung; beim Uebertragen in die Firmware war diese
|
||||
Reihenfolge verloren gegangen.
|
||||
- Die Wartezeit dazwischen steht als WS7_TOUCH_POWER_MS in pins_config.h (Vorgabe 120 ms).
|
||||
- Neu im Start-Log: eine Liste aller Bausteine am I2C-Bus, einmal vor und einmal nach dem
|
||||
Panel-Start. Erwartet werden 0x45 (Bridge) und 0x14 (Touch). Damit ist auf einen Blick zu
|
||||
sehen, ob ein Baustein gar nicht antwortet, statt aus Treiberfehlern raten zu muessen.
|
||||
|
||||
Version 1.6.13:
|
||||
- Ursache des schwarzen Bildes gefunden: ein haengender I2C-Bus. Trifft ein Reset des P4
|
||||
mitten in eine laufende Uebertragung, bleibt der angesprochene Baustein in seiner
|
||||
Bitausgabe stehen und haelt die Datenleitung dauerhaft auf Masse. Damit schlaegt jede
|
||||
weitere Uebertragung fehl. Bridge und Touch-Controller haengen an Dauerstrom, weshalb
|
||||
dieser Zustand jeden Reset und sogar das Flashen ueberlebt - nur echtes Stromabziehen
|
||||
loest ihn. Die Folge: Die Bridge wird nie initialisiert, das Bild bleibt schwarz, und
|
||||
weil sie ihre Register behaelt, brennt die Hintergrundbeleuchtung weiter.
|
||||
- Vor dem Anlegen des I2C-Busses wird die Taktleitung jetzt von Hand getaktet, bis der
|
||||
Baustein die Datenleitung freigibt, danach folgt eine Stopp-Bedingung. Das ist der in
|
||||
der I2C-Spezifikation vorgesehene Weg und laeuft bei freiem Bus wirkungslos durch.
|
||||
- Fehlerbehebung: Schreibzugriffe auf die Bridge liefen stillschweigend ins Leere. Genau
|
||||
deshalb war der Fehler so schwer zu finden - das Bild blieb ohne jeden Hinweis schwarz.
|
||||
Sie melden Fehler jetzt im Klartext.
|
||||
- Fehlerbehebung: In pins_config.h stand seit 1.6.10 "#elsealle" statt "#else". Der
|
||||
Tippfehler traf nur den Zweig des 4,3-Zoll-Panels, das damit nicht mehr uebersetzbar war.
|
||||
Beide Panel-Varianten sind jetzt wieder gegengebaut.
|
||||
|
||||
Version 1.6.12:
|
||||
- Die Abschaltfolge für die Bridge aus 1.6.11 ist zurückgenommen. Sie hat den Fehler nicht
|
||||
behoben, sondern verschlimmert: Nach dem Nullsetzen von C0/C2/AC kam das Panel auch
|
||||
direkt nach dem Flashen nicht mehr hoch, die normale Einschaltfolge holt es aus diesem
|
||||
Zustand nicht zurück. Der Start entspricht damit wieder 1.6.10.
|
||||
- Stattdessen zwei Diagnosen, um die Ursache des schwarzen Bildes nach einem Reset
|
||||
einzugrenzen: Der Startgrund wird beim Hochlauf ausgegeben (1 = Kaltstart, alles andere
|
||||
Warmstart), und das Anfordern der Stromversorgung für die MIPI-Strecke wird jetzt auf
|
||||
Fehler geprüft - bislang lief dieser Schritt als einziger ungeprüft durch.
|
||||
|
||||
Version 1.6.10:
|
||||
- WS7_PARTIAL_REFRESH ist jetzt auch im Auslieferungsstand 1. Am Gerät geprüft: kein
|
||||
Flackern, und der Gewinn ist der größte der drei Tempo-Maßnahmen - vor allem während
|
||||
eines Bezugs, wo die Zeitanzeige zehnmal je Sekunde weiterläuft.
|
||||
- Der Hintergrund der Seiten ist deckend statt durchsichtig. Sichtbar ändert sich nichts,
|
||||
die Ebenen darunter haben dieselbe Farbe; LVGL muss sie beim Scrollen aber nicht mehr
|
||||
mitzeichnen und durchmischen.
|
||||
- Neuer Schalter WS7_PERF_MONITOR in pins_config.h: blendet unten rechts Bilder je Sekunde
|
||||
und Prozessorlast ein. Damit lässt sich beantworten, ob weitere Mühe beim Zeichnen
|
||||
überhaupt noch etwas bringt, statt ins Blaue zu optimieren.
|
||||
|
||||
Version 1.6.9:
|
||||
- Fehlerbehebung: Ein Tipp auf einen Knopf löste oft mehrfach aus. Der GT9271 lässt
|
||||
gelegentlich einen Messzyklus aus oder liefert ein unplausibles Paket; der
|
||||
Hersteller-Treiber kann "gerade nichts Neues" nicht von "Finger weg" unterscheiden und
|
||||
meldet beides als losgelassen. Seit die Oberfläche mit 1.6.8 doppelt so oft abtastet,
|
||||
wurde daraus sichtbar Drücken-Loslassen-Drücken-Loslassen.
|
||||
- Vor den Treiber ist deshalb ein Filter gesetzt: Er verwirft unplausible Rohwerte und hält
|
||||
den letzten gültigen Berührpunkt noch WS7_TOUCH_HOLD_MS lang (Vorgabe 40 ms). Losgelassen
|
||||
wird erst gemeldet, wenn wirklich nichts mehr kommt. Der Wert steht in pins_config.h;
|
||||
0 schaltet die Überbrückung ab. Zu groß gewählt verzögert er das Loslassen und dämpft
|
||||
den Schwung beim Wischen.
|
||||
- Der Filter hängt sich zur Laufzeit in den Treiber ein, die Herstellerdateien bleiben
|
||||
unverändert.
|
||||
|
||||
Version 1.6.8:
|
||||
- Scrollen und Wischen laufen am Waveshare-Panel flüssiger: LVGL rechnet dort jetzt im
|
||||
16-Millisekunden-Takt statt alle 33 ms. Dieser Wert steuert nicht nur die Bildrate,
|
||||
sondern auch, wie oft der Touch abgetastet und wie fein eine Animation gerechnet wird -
|
||||
mit 30 Schritten je Sekunde war vor allem das Ziehen mit dem Finger sichtbar ruckelig.
|
||||
Das Panel läuft mit 60 Hz, mehr als 16 ms bringt also nichts.
|
||||
- Kommt das Zeichnen einmal nicht hinterher, wird ein Bild später fertig; kaputt geht
|
||||
dabei nichts. Die JC-Panels bleiben bei 33 ms.
|
||||
|
||||
Version 1.6.7:
|
||||
- Der Menue-Knopf oben links fängt Tipps jetzt auch knapp daneben ab. Mit 48x36 Pixeln war
|
||||
er auf dem 7-Zoll-Panel ein sehr kleines Ziel; gemessen wurde ein Fehlgriff von rund
|
||||
10 Pixeln neben der Fläche, weshalb sich das Menü scheinbar nicht öffnen ließ. Optisch
|
||||
bleibt der Knopf unverändert, die Trefferfläche wächst um 20 Pixel nach allen Seiten.
|
||||
Sie wirkt nur innerhalb der Kopfleiste - dem Seiteninhalt darunter wird nichts genommen.
|
||||
- Die Touch-Zuordnung selbst war korrekt: Eine Messung mit WS7_TOUCH_DEBUG hat gezeigt,
|
||||
dass Achsen und Spiegelung stimmen.
|
||||
|
||||
Version 1.6.6:
|
||||
- Neuer Schalter WS7_TOUCH_DEBUG in pins_config.h: Auf 1 gesetzt, gibt jeder Berührpunkt
|
||||
seine Rohwerte und die daraus errechnete Bildposition auf der seriellen Konsole aus.
|
||||
Gedacht zum Einmessen des Touch, wenn Bedienelemente nicht reagieren - insbesondere am
|
||||
oberen Bildrand, wo die 44 Pixel hohe Kopfleiste sitzt.
|
||||
|
||||
Version 1.6.5:
|
||||
- Zwei der drei Tempo-Maßnahmen aus 1.6.4 haben sich am Gerät als untauglich erwiesen und
|
||||
stehen wieder auf ihrem alten Wert. Sie bleiben als Schalter erhalten, mit Notiz, woran
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "protocol_client.h"
|
||||
#include "ui.h"
|
||||
#include "display_hal.h"
|
||||
#include "pins_config.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <Update.h>
|
||||
#include <Preferences.h>
|
||||
@@ -296,6 +297,31 @@ void setup() {
|
||||
g_client.onOta(onOta);
|
||||
|
||||
hal_init(&g_client); // LVGL + Panel/Touch + Dashboard (ruft ui_init intern auf)
|
||||
|
||||
// --- Waveshare-Panel: einmaliger Neustart nach dem Einschalten ---
|
||||
//
|
||||
// Das Panel kommt nach dem Anlegen der Versorgung im ersten Anlauf nicht zuverlaessig
|
||||
// hoch: Die Beleuchtung geht an, ein Bild bleibt aus - obwohl jeder Schritt des
|
||||
// Hochlaufs Erfolg meldet. Ein Reset behebt es zuverlaessig, und zwar nur ein echter
|
||||
// Chip-Reset; die DSI-Strecke im laufenden Betrieb ab- und wieder aufzubauen genuegt
|
||||
// nicht (siehe WS7_DSI_RESTART).
|
||||
//
|
||||
// Deshalb startet der P4 sich nach einem Kaltstart genau einmal selbst neu, nachdem
|
||||
// der erste Hochlauf durch ist. Beim zweiten Durchlauf ist der Startgrund kein
|
||||
// Kaltstart mehr, die Bedingung greift also nicht erneut - eine Schleife ist
|
||||
// ausgeschlossen. Kostet rund drei Sekunden, aber nur beim Einschalten.
|
||||
#if (JC_PANEL_TYPE == WS_PANEL_7H) && WS7_COLD_BOOT_RESTART
|
||||
if (esp_reset_reason() == ESP_RST_POWERON) {
|
||||
// Der Fruehstart-Zaehler wurde oben bereits erhoeht. Diesen gewollten Neustart
|
||||
// darf er nicht mitzaehlen, sonst laeuft die Absturzsicherung nach ein paar
|
||||
// Einschaltvorgaengen in den Update-Modus.
|
||||
{ Preferences p; p.begin("bootguard", false); p.putUShort("early", 0); p.end(); }
|
||||
DBG_SERIAL.println(F("[Panel] Kaltstart - einmaliger Neustart fuer das Displaypanel"));
|
||||
DBG_SERIAL.flush();
|
||||
delay(50);
|
||||
esp_restart();
|
||||
}
|
||||
#endif
|
||||
g_client.begin(); // UART starten, hello folgt automatisch in loop()
|
||||
|
||||
DBG_SERIAL.println(F("Bereit. Warte auf Verbindung zur Hauptplatine..."));
|
||||
|
||||
@@ -50,7 +50,7 @@ Vendor-Pakete: 4,3" im Ordner `JC4880P443C_I_W/`, 7,0" im Repo-Ordner
|
||||
| Touch-Rohkoordinaten | 480×800 (= Panelraster) | **800×480** → wird auf 1024×600 skaliert | **720×1280** (Hochformat) → X/Y werden getauscht |
|
||||
| LCD-Reset | GPIO5 | **GPIO27** | kein Reset-Pin (macht die Bridge) |
|
||||
| Backlight | GPIO23 (LEDC-PWM) | GPIO23 (LEDC-PWM) | **Bridge-Register** auf I²C **0x45** (`AD`/`AB`/`AA`) |
|
||||
| Framebuffer | 3 × 750 KB ≈ 2,3 MB PSRAM | 3 × 1,2 MB ≈ 3,6 MB PSRAM | 3 × 2,8 MB ≈ 8,3 MB PSRAM |
|
||||
| Framebuffer | 3 × 750 KB ≈ 2,3 MB PSRAM | 3 × 1,2 MB ≈ 3,6 MB PSRAM | **1 × 2,8 MB** — mehr verträgt das Panel beim Start nicht |
|
||||
| Freie Expansion-IO | Stiftleiste **JP1**: GPIO 52/51/50/49/35/34/33/32/31/30/29/28 | FPC 1,0 mm 16-pol. **FPC4**: GPIO 34/33/32/31/30/29/28 · **FPC3**: 48/47/46/45/5/4/3/2 | 40-poliger Header im Raspberry-Pi-Pico-Format; belegt sind I²C (7/8), TF-Karte (9/10/11/12/13/53) und Debug-UART0 (37/38) |
|
||||
| UART zur Hauptplatine | TX GPIO33 / RX GPIO31 | TX GPIO33 / RX GPIO31 | **TX GPIO20 / RX GPIO21** |
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "esp_cache.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_ldo_regulator.h"
|
||||
#include "esp_lcd_panel_io.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
@@ -69,6 +71,82 @@
|
||||
|
||||
static i2c_master_bus_handle_t s_i2c_handle = NULL;
|
||||
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
// ------------------------------------------------------------------------------------
|
||||
// Haengenden I2C-Bus befreien
|
||||
//
|
||||
// Trifft ein Reset des P4 mitten in eine laufende I2C-Uebertragung, bleibt der
|
||||
// angesprochene Baustein in seiner Bitausgabe stehen und haelt die Datenleitung dauerhaft
|
||||
// auf Masse. Der Bus ist damit tot: Jede weitere Uebertragung schlaegt fehl. Da Bridge und
|
||||
// Touch-Controller an Dauerstrom haengen, ueberlebt dieser Zustand jeden Reset und sogar
|
||||
// das Flashen - nur echtes Stromabziehen loest ihn.
|
||||
//
|
||||
// Folge: Die Bridge wird nie initialisiert, das Bild bleibt schwarz, und weil sie ihre
|
||||
// Register behaelt, brennt die Hintergrundbeleuchtung weiter. Genau dieses Bild.
|
||||
//
|
||||
// Abhilfe ist der uebliche Weg aus der I2C-Spezifikation: Vor dem Anlegen des Busses die
|
||||
// Taktleitung von Hand takten, bis der Baustein sein letztes Bit ausgegeben hat und die
|
||||
// Datenleitung wieder loslaesst, danach eine Stopp-Bedingung erzeugen.
|
||||
static void ws7_i2c_bus_recover(void)
|
||||
{
|
||||
gpio_config_t io = {
|
||||
.pin_bit_mask = BIT64(BSP_I2C_SDA) | BIT64(BSP_I2C_SCL),
|
||||
.mode = GPIO_MODE_INPUT_OUTPUT_OD, // offener Kollektor, Zustand lesbar
|
||||
.pull_up_en = GPIO_PULLUP_ENABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
};
|
||||
gpio_config(&io);
|
||||
gpio_set_level(BSP_I2C_SDA, 1);
|
||||
gpio_set_level(BSP_I2C_SCL, 1);
|
||||
esp_rom_delay_us(10);
|
||||
|
||||
if (gpio_get_level(BSP_I2C_SDA) != 0) {
|
||||
return; // Bus frei - nichts zu tun
|
||||
}
|
||||
|
||||
esp_rom_printf("[Panel] I2C-Bus haengt - wird freigetaktet\n");
|
||||
|
||||
// Bis zu neun Takte: so viele braucht ein Baustein hoechstens, um ein angefangenes
|
||||
// Byte samt Bestaetigungsbit zu Ende zu schieben.
|
||||
for (int i = 0; i < 9 && gpio_get_level(BSP_I2C_SDA) == 0; i++) {
|
||||
gpio_set_level(BSP_I2C_SCL, 0);
|
||||
esp_rom_delay_us(5);
|
||||
gpio_set_level(BSP_I2C_SCL, 1);
|
||||
esp_rom_delay_us(5);
|
||||
}
|
||||
|
||||
// Stopp-Bedingung: Datenleitung geht bei hoher Taktleitung von Masse auf High.
|
||||
gpio_set_level(BSP_I2C_SDA, 0);
|
||||
esp_rom_delay_us(5);
|
||||
gpio_set_level(BSP_I2C_SCL, 1);
|
||||
esp_rom_delay_us(5);
|
||||
gpio_set_level(BSP_I2C_SDA, 1);
|
||||
esp_rom_delay_us(10);
|
||||
|
||||
esp_rom_printf("[Panel] I2C-Bus nach Freitakten: %s\n",
|
||||
gpio_get_level(BSP_I2C_SDA) ? "frei" : "weiterhin belegt");
|
||||
|
||||
// Pins wieder freigeben, damit der I2C-Treiber sie uebernehmen kann.
|
||||
gpio_reset_pin(BSP_I2C_SDA);
|
||||
gpio_reset_pin(BSP_I2C_SCL);
|
||||
}
|
||||
|
||||
// Zeigt, welche Bausteine sich am I2C-Bus melden. Erwartet werden 0x45 (Bridge) und
|
||||
// 0x14 (GT9271-Touch); 0x18 waere der Audio-Baustein. Fehlt einer, sagt das mehr aus als
|
||||
// jede Fehlermeldung des Treibers.
|
||||
static void ws7_i2c_scan(const char *wann)
|
||||
{
|
||||
esp_rom_printf("[Panel] I2C-Bausteine (%s):", wann);
|
||||
for (uint8_t addr = 1; addr < 127; addr++) {
|
||||
if (i2c_master_probe(s_i2c_handle, addr, 50) == ESP_OK) {
|
||||
esp_rom_printf(" 0x%02X", addr);
|
||||
}
|
||||
}
|
||||
esp_rom_printf("\n");
|
||||
}
|
||||
#endif // JC_PANEL_TYPE == WS_PANEL_7H
|
||||
|
||||
// Klartext-Meldung auf der seriellen Konsole. Bewusst esp_rom_printf: das laeuft auch bei
|
||||
// abgeschaltetem Core-Debug-Level und ohne Heap, also genau dann, wenn es darauf ankommt.
|
||||
#define BSP_STEP(call, what) \
|
||||
@@ -106,11 +184,33 @@ static void ws7_bridge_write(uint8_t reg, uint8_t value)
|
||||
{
|
||||
if (s_bridge_handle == NULL) return;
|
||||
uint8_t buf[2] = { reg, value };
|
||||
i2c_master_transmit(s_bridge_handle, buf, sizeof(buf), 100);
|
||||
esp_err_t err = i2c_master_transmit(s_bridge_handle, buf, sizeof(buf), 100);
|
||||
if (err != ESP_OK) {
|
||||
// Frueher lief das stillschweigend ins Leere. Schlaegt es fehl, wird die Bridge
|
||||
// nie initialisiert und das Bild bleibt schwarz - ohne jeden Hinweis darauf.
|
||||
esp_rom_printf("[Panel] Bridge-Register 0x%02X liess sich nicht schreiben: %s\n",
|
||||
reg, esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
// Bridge am I2C-Bus anmelden und Grundinitialisierung schreiben. Muss VOR dem
|
||||
// DSI-Bringup laufen; die Hintergrundbeleuchtung bleibt dabei noch aus.
|
||||
// Grundeinstellung der Bridge. Bewusst mehrfach aufrufbar, siehe unten.
|
||||
//
|
||||
// Warum zweimal: Beim ersten Aufruf existiert die DSI-Strecke noch gar nicht - die Bridge
|
||||
// bekommt ihre Einstellung also, bevor ein Signal anliegt. Beim ersten Einschalten reichte
|
||||
// das nicht: Die Beleuchtung ging an (die haengt an der Bridge), ein Bild kam aber nicht.
|
||||
// Erst ein Reset half - und dann nur deshalb, weil die Bridge ihre Einstellung aus dem
|
||||
// vorigen Durchlauf noch hatte und diesmal ein DSI-Signal vorfand. Genau das holt der
|
||||
// zweite Aufruf nach, ohne dass ein Reset noetig ist. Die Register sind wiederholbar.
|
||||
static void ws7_bridge_core_init(const char *wann)
|
||||
{
|
||||
esp_rom_printf("[Panel] Bridge-Grundeinstellung %s\n", wann);
|
||||
ws7_bridge_write(0xC0, 0x01);
|
||||
ws7_bridge_write(0xC2, 0x01);
|
||||
ws7_bridge_write(0xAC, 0x01);
|
||||
}
|
||||
|
||||
// Bridge am I2C-Bus anmelden und erstmalig einstellen. Laeuft VOR dem DSI-Bringup;
|
||||
// die Hintergrundbeleuchtung bleibt dabei noch aus.
|
||||
static void ws7_bridge_pre_init(void)
|
||||
{
|
||||
i2c_device_config_t dev_cfg = {
|
||||
@@ -122,9 +222,7 @@ static void ws7_bridge_pre_init(void)
|
||||
s_bridge_handle = NULL;
|
||||
return;
|
||||
}
|
||||
ws7_bridge_write(0xC0, 0x01);
|
||||
ws7_bridge_write(0xC2, 0x01);
|
||||
ws7_bridge_write(0xAC, 0x01);
|
||||
ws7_bridge_core_init("vor dem DSI-Start");
|
||||
}
|
||||
|
||||
void jc_backlight_init(void)
|
||||
@@ -184,6 +282,63 @@ IRAM_ATTR static bool on_vsync(esp_lcd_panel_handle_t panel,
|
||||
}
|
||||
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// Aussetzer des GT9271 ueberbruecken
|
||||
//
|
||||
// Der Controller laesst gelegentlich einen Messzyklus aus und liefert ab und zu ein
|
||||
// unplausibles Paket - die Werks-Testskizze hat solche Pakete ebenfalls verworfen. Der
|
||||
// Hersteller-Treiber kann "gerade nichts Neues" nicht von "Finger weg" unterscheiden und
|
||||
// meldet beides als losgelassen. Seit die Oberflaeche doppelt so oft abtastet, faellt das
|
||||
// auf: Aus einem Tipp wird Druecken-Loslassen-Druecken-Loslassen, der Knopf loest also
|
||||
// mehrfach aus.
|
||||
//
|
||||
// Deshalb liegt hier ein eigener get_xy-Aufsatz vor dem Treiber: Er verwirft unplausible
|
||||
// Rohwerte und haelt den letzten gueltigen Punkt kurz fest. Losgelassen wird erst
|
||||
// gemeldet, wenn WS7_TOUCH_HOLD_MS lang wirklich nichts mehr kam.
|
||||
// ------------------------------------------------------------------------------------
|
||||
static bool (*s_touch_get_xy_orig)(esp_lcd_touch_handle_t, uint16_t *, uint16_t *,
|
||||
uint16_t *, uint8_t *, uint8_t) = NULL;
|
||||
static uint16_t s_touch_last_x = 0;
|
||||
static uint16_t s_touch_last_y = 0;
|
||||
static int64_t s_touch_last_us = 0;
|
||||
static bool s_touch_down = false;
|
||||
|
||||
static bool ws7_touch_get_xy(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y,
|
||||
uint16_t *strength, uint8_t *point_num, uint8_t max_point_num)
|
||||
{
|
||||
bool got = s_touch_get_xy_orig(tp, x, y, strength, point_num, max_point_num);
|
||||
int64_t now = esp_timer_get_time();
|
||||
|
||||
// Unplausible Rohwerte gelten als Aussetzer, nicht als Beruehrung.
|
||||
if (got && *point_num > 0 &&
|
||||
(x[0] > WS7_TOUCH_RAW_X_MAX || y[0] > WS7_TOUCH_RAW_Y_MAX)) {
|
||||
got = false;
|
||||
*point_num = 0;
|
||||
}
|
||||
|
||||
if (got && *point_num > 0) {
|
||||
s_touch_last_x = x[0];
|
||||
s_touch_last_y = y[0];
|
||||
s_touch_last_us = now;
|
||||
s_touch_down = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if WS7_TOUCH_HOLD_MS > 0
|
||||
if (s_touch_down && (now - s_touch_last_us) < ((int64_t)WS7_TOUCH_HOLD_MS * 1000)) {
|
||||
x[0] = s_touch_last_x;
|
||||
y[0] = s_touch_last_y;
|
||||
if (strength) strength[0] = 0;
|
||||
*point_num = 1;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
s_touch_down = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Der GT9271 des Waveshare-Panels meldet im Hochformat (Roh-X 0..720, Roh-Y 0..1280),
|
||||
// das Bild laeuft aber im Querformat 1280x720. Achsentausch (und bei Bedarf Spiegelung)
|
||||
// deshalb ueber den process_coordinates-Hook, der VOR den swap/mirror-Flags von
|
||||
@@ -211,6 +366,10 @@ static void ws7_touch_map(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y,
|
||||
// Bild wird um 180 Grad gedreht ausgegeben -> Touch muss mitdrehen.
|
||||
px = (uint16_t)(LCD_H_RES - 1 - px);
|
||||
py = (uint16_t)(LCD_V_RES - 1 - py);
|
||||
#endif
|
||||
#if WS7_TOUCH_DEBUG
|
||||
esp_rom_printf("[Touch] roh X=%u Y=%u -> Bild X=%u Y=%u\n",
|
||||
(unsigned)x[i], (unsigned)y[i], (unsigned)px, (unsigned)py);
|
||||
#endif
|
||||
x[i] = px;
|
||||
y[i] = py;
|
||||
@@ -238,45 +397,43 @@ static void jc_touch_scale(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y,
|
||||
}
|
||||
#endif
|
||||
|
||||
// Bringt Panel + Touch + LVGL-Port hoch (LVGL laeuft danach in eigenem Task).
|
||||
// Rueckgabe false: Panel kam nicht hoch - der Aufrufer darf dann KEINE LVGL-Funktion
|
||||
// benutzen, sonst folgt ein zweiter Absturz, der die eigentliche Ursache ueberdeckt.
|
||||
bool jc_board_bringup(void)
|
||||
{
|
||||
jc_backlight_init();
|
||||
|
||||
i2c_master_bus_config_t i2c_bus_conf = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.sda_io_num = BSP_I2C_SDA,
|
||||
.scl_io_num = BSP_I2C_SCL,
|
||||
.i2c_port = BSP_I2C_NUM,
|
||||
};
|
||||
i2c_new_master_bus(&i2c_bus_conf, &s_i2c_handle);
|
||||
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
// Bridge des Waveshare-Panels vorbereiten (noch ohne Hintergrundbeleuchtung).
|
||||
ws7_bridge_pre_init();
|
||||
// Panel wecken. Bewusst mehrfach, siehe unten.
|
||||
//
|
||||
// Ein reines DPI-Panel kennt keine reset-Funktion, esp_lcd_panel_reset() wuerde ins Leere
|
||||
// greifen - deshalb nur die DCS-Befehle.
|
||||
//
|
||||
// Warum mehrfach: Verpasst der Panel-Controller diese Befehle, weil er nach dem
|
||||
// Einschalten noch nicht bereit war, bleibt der Bildschirm dunkel, obwohl der P4 alles
|
||||
// korrekt gesendet hat und jeder Schritt Erfolg meldet. Die Hintergrundbeleuchtung geht
|
||||
// trotzdem an, weil sie an der Bridge haengt und nicht am Panel - genau dieses Bild.
|
||||
// Die Befehle sind wiederholbar, ein zweiter Anlauf nach dem Start der Videoausgabe
|
||||
// kostet nichts und faengt den Fall ab.
|
||||
static void ws7_panel_wake(esp_lcd_panel_io_handle_t io, const char *wann)
|
||||
{
|
||||
uint8_t zero = 0x00;
|
||||
uint8_t madctl = WS7_MADCTL;
|
||||
esp_rom_printf("[Panel] Weckbefehle %s\n", wann);
|
||||
BSP_STEP(esp_lcd_panel_io_tx_param(io, 0x36, &madctl, 1), "Panel-Befehl MADCTL");
|
||||
BSP_STEP(esp_lcd_panel_io_tx_param(io, 0x11, &zero, 1), "Panel-Befehl Sleep Out");
|
||||
vTaskDelay(pdMS_TO_TICKS(120));
|
||||
BSP_STEP(esp_lcd_panel_io_tx_param(io, 0x29, &zero, 1), "Panel-Befehl Display On");
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
}
|
||||
#endif
|
||||
|
||||
static esp_ldo_channel_handle_t phy_pwr_chan = NULL;
|
||||
esp_ldo_channel_config_t ldo_cfg = {
|
||||
.chan_id = BSP_MIPI_DSI_PHY_PWR_LDO_CHAN,
|
||||
.voltage_mv = BSP_MIPI_DSI_PHY_PWR_LDO_VOLTAGE_MV,
|
||||
};
|
||||
esp_ldo_acquire_channel(&ldo_cfg, &phy_pwr_chan);
|
||||
|
||||
esp_lcd_dsi_bus_handle_t mipi_dsi_bus;
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
// Baut die komplette DSI-Strecke auf: Bus, Kommandokanal, Bildausgabe, und weckt das
|
||||
// Panel. Bewusst als eigene Funktion, damit der ganze Vorgang wiederholbar ist.
|
||||
static bool ws7_dsi_bringup(esp_lcd_dsi_bus_handle_t *out_bus,
|
||||
esp_lcd_panel_io_handle_t *out_io,
|
||||
esp_lcd_panel_handle_t *out_panel,
|
||||
esp_lcd_dpi_panel_config_t *out_dpi_config)
|
||||
{
|
||||
esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL;
|
||||
esp_lcd_panel_io_handle_t io = NULL;
|
||||
esp_lcd_panel_handle_t disp_panel = NULL;
|
||||
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
// ---------------- Waveshare 7inch DSI LCD (H) (1280x720) ----------------
|
||||
// Kein Hersteller-Panel-Treiber: DSI-Bus, DBI-Kommandokanal und DPI-Panel werden
|
||||
// direkt angelegt. Entscheidend ist die Referenztaktquelle PLL_F20M - mit der
|
||||
// Standardquelle bleibt das Bild auf ESP32-P4 Rev. 1.3 / ECO2 schwarz.
|
||||
bsp_report_psram((size_t)BSP_LCD_H_RES * BSP_LCD_V_RES * BSP_LCD_FB_BYTES_PER_PX
|
||||
* LVGL_PORT_LCD_BUFFER_NUMS);
|
||||
|
||||
esp_lcd_dsi_bus_config_t bus_config = {
|
||||
.bus_id = 0,
|
||||
.num_data_lanes = WS7_DSI_LANES,
|
||||
@@ -301,6 +458,8 @@ bool jc_board_bringup(void)
|
||||
#else
|
||||
.pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB565,
|
||||
#endif
|
||||
// Anzahl der Bildspeicher. Beim Waveshare-Panel genau einer: mit zweien kam nach
|
||||
// dem Einschalten kein Bild (siehe WS7_SINGLE_FB in pins_config.h).
|
||||
.num_fbs = LVGL_PORT_LCD_BUFFER_NUMS,
|
||||
.video_timing = {
|
||||
.h_size = BSP_LCD_H_RES,
|
||||
@@ -325,19 +484,142 @@ bool jc_board_bringup(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Panel wecken (MADCTL / Sleep Out / Display On). Ein Reset gibt es hier nicht:
|
||||
// ein reines DPI-Panel kennt keine reset-Funktion, esp_lcd_panel_reset() wuerde
|
||||
// ins Leere greifen.
|
||||
{
|
||||
uint8_t zero = 0x00;
|
||||
uint8_t madctl = WS7_MADCTL;
|
||||
esp_lcd_panel_io_tx_param(io, 0x36, &madctl, 1); // MADCTL
|
||||
esp_lcd_panel_io_tx_param(io, 0x11, &zero, 1); // Sleep Out
|
||||
vTaskDelay(pdMS_TO_TICKS(120));
|
||||
esp_lcd_panel_io_tx_param(io, 0x29, &zero, 1); // Display On
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
}
|
||||
ws7_panel_wake(io, "vor dem Start der Videoausgabe");
|
||||
|
||||
BSP_STEP(esp_lcd_panel_init(disp_panel), "DPI-Videoausgabe starten");
|
||||
|
||||
// Zweiter Anlauf, jetzt bei laufender Videoausgabe: faengt den Fall ab, dass das
|
||||
// Panel beim ersten Mal noch nicht aufnahmebereit war.
|
||||
vTaskDelay(pdMS_TO_TICKS(WS7_PANEL_SETTLE_MS));
|
||||
ws7_bridge_core_init("nach dem Start der Videoausgabe");
|
||||
ws7_panel_wake(io, "nach dem Start der Videoausgabe");
|
||||
|
||||
*out_bus = mipi_dsi_bus;
|
||||
*out_io = io;
|
||||
*out_panel = disp_panel;
|
||||
*out_dpi_config = dpi_config;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Bringt Panel + Touch + LVGL-Port hoch (LVGL laeuft danach in eigenem Task).
|
||||
// Rueckgabe false: Panel kam nicht hoch - der Aufrufer darf dann KEINE LVGL-Funktion
|
||||
// benutzen, sonst folgt ein zweiter Absturz, der die eigentliche Ursache ueberdeckt.
|
||||
bool jc_board_bringup(void)
|
||||
{
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
// Anlaufzeit abwarten, BEVOR Bridge und Panel angesprochen werden.
|
||||
//
|
||||
// Das Displaymodul braucht nach dem Anlegen der Versorgung einen Moment, bis Bridge
|
||||
// und Panel bereit sind. Faengt der P4 sofort an, laeuft der Hochlauf ins Leere: Die
|
||||
// Bridge nimmt ihre Register nicht an oder das Panel zeigt trotz korrekt gesendeter
|
||||
// DSI-Daten nichts - beides ohne Fehlermeldung, weil aus Sicht des P4 alles geklappt
|
||||
// hat. Das Ergebnis war ein Display, das mal ansprang und mal nicht.
|
||||
//
|
||||
// Der Werks-Testsketch wartet aus demselben Grund 2 Sekunden am Anfang von setup().
|
||||
// Dass es mit geoeffnetem seriellen Monitor fast immer klappte, hatte dieselbe
|
||||
// Ursache: Dessen USB-Anmeldung verzoegert den Start und ersetzte damit die Wartezeit.
|
||||
vTaskDelay(pdMS_TO_TICKS(WS7_PANEL_WARMUP_MS));
|
||||
#endif
|
||||
jc_backlight_init();
|
||||
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
ws7_i2c_bus_recover(); // haengenden Bus vom letzten Reset befreien
|
||||
#endif
|
||||
|
||||
i2c_master_bus_config_t i2c_bus_conf = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.sda_io_num = BSP_I2C_SDA,
|
||||
.scl_io_num = BSP_I2C_SCL,
|
||||
.i2c_port = BSP_I2C_NUM,
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
// Stoerimpulsfilter und interne Abschlusswiderstaende - beides setzt auch das
|
||||
// Waveshare-Beispiel. Ohne den Filter brechen Bridge und Touch weg, sobald die
|
||||
// DSI-Ausgabe laeuft: Deren schnelle Signale stoeren auf das lange Flachbandkabel
|
||||
// ein, und ungefilterte Stoerspitzen bringen die I2C-Uebertragung aus dem Tritt.
|
||||
// Der Audio-Baustein auf der Platine bleibt dabei erreichbar, weil er nicht am
|
||||
// Displaykabel haengt - genau dieses Muster war im Start-Log zu sehen.
|
||||
.glitch_ignore_cnt = 7,
|
||||
.flags.enable_internal_pullup = true,
|
||||
#endif
|
||||
};
|
||||
i2c_new_master_bus(&i2c_bus_conf, &s_i2c_handle);
|
||||
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
ws7_i2c_scan("vor dem Panel-Start");
|
||||
// Bridge des Waveshare-Panels vorbereiten (noch ohne Hintergrundbeleuchtung).
|
||||
ws7_bridge_pre_init();
|
||||
#endif
|
||||
|
||||
// Reset-Grund mitschreiben: 1 = Kaltstart (Strom weg), alles andere ist ein Warmstart.
|
||||
// Nur beim Warmstart behalten die Bausteine ihren alten Zustand - genau dann traten
|
||||
// die schwarzen Bilder auf.
|
||||
esp_rom_printf("[Panel] Startgrund: %d (1 = Kaltstart)\n", (int)esp_reset_reason());
|
||||
|
||||
static esp_ldo_channel_handle_t phy_pwr_chan = NULL;
|
||||
esp_ldo_channel_config_t ldo_cfg = {
|
||||
.chan_id = BSP_MIPI_DSI_PHY_PWR_LDO_CHAN,
|
||||
.voltage_mv = BSP_MIPI_DSI_PHY_PWR_LDO_VOLTAGE_MV,
|
||||
};
|
||||
BSP_STEP(esp_ldo_acquire_channel(&ldo_cfg, &phy_pwr_chan), "Stromversorgung MIPI-D-PHY");
|
||||
|
||||
esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL;
|
||||
esp_lcd_panel_io_handle_t io = NULL;
|
||||
esp_lcd_panel_handle_t disp_panel = NULL;
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
esp_lcd_dpi_panel_config_t dpi_config;
|
||||
#endif
|
||||
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
// ---------------- Waveshare 7inch DSI LCD (H) (1280x720) ----------------
|
||||
// Kein Hersteller-Panel-Treiber: DSI-Bus, DBI-Kommandokanal und DPI-Panel werden
|
||||
// direkt angelegt. Entscheidend ist die Referenztaktquelle PLL_F20M - mit der
|
||||
// Standardquelle bleibt das Bild auf ESP32-P4 Rev. 1.3 / ECO2 schwarz.
|
||||
bsp_report_psram((size_t)BSP_LCD_H_RES * BSP_LCD_V_RES * BSP_LCD_FB_BYTES_PER_PX
|
||||
* LVGL_PORT_LCD_BUFFER_NUMS);
|
||||
|
||||
if (!ws7_dsi_bringup(&mipi_dsi_bus, &io, &disp_panel, &dpi_config)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WS7_DSI_RESTART
|
||||
// Die Strecke einmal komplett ab- und wieder aufbauen.
|
||||
//
|
||||
// Beim ersten Einschalten kam trotz fehlerfreiem Hochlauf kein Bild; erst ein Reset
|
||||
// half, und zwar zuverlaessig. Ein Reset unterscheidet sich an dieser Stelle nur in
|
||||
// einem Punkt von unserem Ablauf: Die DSI-Verbindung geht einmal weg und neu auf,
|
||||
// waehrend Bridge und Panel bereits versorgt und eingestellt sind. Weder die
|
||||
// wiederholte Grundeinstellung der Bridge noch die wiederholten Weckbefehle ersetzen
|
||||
// das. Genau dieser Ab- und Wiederaufbau wird hier nachgeholt - ohne Reset.
|
||||
esp_rom_printf("[Panel] DSI-Strecke wird neu aufgebaut\n");
|
||||
esp_lcd_panel_del(disp_panel);
|
||||
esp_lcd_panel_io_del(io);
|
||||
esp_lcd_del_dsi_bus(mipi_dsi_bus);
|
||||
vTaskDelay(pdMS_TO_TICKS(WS7_DSI_RESTART_MS));
|
||||
|
||||
if (!ws7_dsi_bringup(&mipi_dsi_bus, &io, &disp_panel, &dpi_config)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#if WS7_TEST_PATTERN
|
||||
// Prueffarbbalken: Sie entstehen im DSI-Baustein selbst und benutzen weder den
|
||||
// Bildspeicher noch LVGL. Erscheinen sie, arbeitet die Anzeigekette bis zum Panel und
|
||||
// der Fehler liegt weiter oben. Bleibt es schwarz, liegt es an DSI, Zeitbasis oder
|
||||
// Panel.
|
||||
//
|
||||
// Der Hochlauf endet hier bewusst: Wuerde LVGL danach starten, schriebe es sofort in
|
||||
// den Bildspeicher und das Pruefbild waere wieder weg - der Test saehe dann genauso
|
||||
// aus wie der Fehler, den er finden soll.
|
||||
jc_backlight_set(100); // Beleuchtung an, sonst ist nichts zu sehen
|
||||
BSP_STEP(esp_lcd_dpi_panel_set_pattern(disp_panel, MIPI_DSI_PATTERN_BAR_VERTICAL),
|
||||
"Prueffarbbalken");
|
||||
esp_rom_printf("[Panel] Pruefbild steht - erwartet werden senkrechte Farbbalken.\n");
|
||||
esp_rom_printf("[Panel] Hochlauf endet hier (WS7_TEST_PATTERN = 1, keine Oberflaeche).\n");
|
||||
return false; // ohne LVGL: Anzeige bleibt beim Pruefbild
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#elif JC_PANEL_TYPE == JC_PANEL_70
|
||||
// ---------------- 7,0" JD9165 (1024x600) ----------------
|
||||
esp_lcd_dsi_bus_config_t bus_config = JD9165_PANEL_BUS_DSI_2CH_CONFIG();
|
||||
@@ -427,6 +709,16 @@ bool jc_board_bringup(void)
|
||||
};
|
||||
esp_lcd_dpi_panel_register_event_callbacks(disp_panel, &cbs, NULL);
|
||||
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
// Bridge freigeben und Beleuchtung einschalten, BEVOR der Touch angesprochen wird.
|
||||
// Der GT9271 antwortet erst danach: Die Freigabe der Bridge (Register 0xAD) versorgt
|
||||
// offenbar auch ihn. In der Werks-Testskizze steht die Touch-Initialisierung aus
|
||||
// demselben Grund hinter dem Einschalten der Beleuchtung.
|
||||
jc_backlight_set(100);
|
||||
vTaskDelay(pdMS_TO_TICKS(WS7_TOUCH_POWER_MS));
|
||||
ws7_i2c_scan("nach dem Panel-Start");
|
||||
#endif
|
||||
|
||||
esp_lcd_panel_io_handle_t tp_io_handle = NULL;
|
||||
// MUSS vorbelegt sein: schlaegt die Touch-Initialisierung fehl, gibt der Treiber einen
|
||||
// unbrauchbaren Zeiger zurueck. Ohne Vorbelegung landet Muell im LVGL-Port.
|
||||
@@ -463,11 +755,19 @@ bool jc_board_bringup(void)
|
||||
esp_rom_printf("[Panel] Touch-Controller nicht gefunden - Anzeige laeuft ohne Bedienung.\n");
|
||||
tp_handle = NULL;
|
||||
}
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
if (tp_handle) { // Aussetzer-Filter vor den Treiber haengen
|
||||
s_touch_get_xy_orig = tp_handle->get_xy;
|
||||
tp_handle->get_xy = ws7_touch_get_xy;
|
||||
}
|
||||
#endif
|
||||
|
||||
lvgl_port_interface_t interface =
|
||||
(dpi_config.flags.use_dma2d) ? LVGL_PORT_INTERFACE_MIPI_DSI_DMA
|
||||
: LVGL_PORT_INTERFACE_MIPI_DSI_NO_DMA;
|
||||
esp_rom_printf("[Panel] Bringup fertig - LVGL wird gestartet\n");
|
||||
lvgl_port_init(disp_panel, tp_handle, interface);
|
||||
esp_rom_printf("[Panel] LVGL laeuft\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
// -------------------------------------------------------------------------------------
|
||||
// Firmware
|
||||
// -------------------------------------------------------------------------------------
|
||||
#define DISPLAY_FW_VERSION "1.6.5" // Firmware-Stand der P4-Display-Steuerung (Info-Seite)
|
||||
#define DISPLAY_FW_VERSION "1.6.10" // Firmware-Stand der P4-Display-Steuerung (Info-Seite)
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
// Protokoll
|
||||
|
||||
@@ -91,7 +91,17 @@
|
||||
*====================*/
|
||||
|
||||
/*Default display refresh, input device read and animation step period.*/
|
||||
/* Der Wert bestimmt nicht nur die Bildrate, sondern auch, wie oft der Touch abgetastet
|
||||
* und wie fein eine Animation gerechnet wird. 33 ms sind 30 Schritte je Sekunde - beim
|
||||
* Ziehen mit dem Finger deutlich als Stocken zu sehen. Das Waveshare-Panel laeuft mit
|
||||
* 60 Hz, deshalb dort 16 ms; mehr als das Panel zeigen kann, bringt nichts. Kommt das
|
||||
* Zeichnen nicht hinterher, wird es einfach seltener fertig - kaputt geht dabei nichts.
|
||||
* Die JC-Panels bleiben bei 33 ms, damit sich ihr Verhalten nicht aendert. */
|
||||
#if JC_PANEL_TYPE == WS_PANEL_7H
|
||||
#define LV_DEF_REFR_PERIOD 16 /*[ms]*/
|
||||
#else
|
||||
#define LV_DEF_REFR_PERIOD 33 /*[ms]*/
|
||||
#endif
|
||||
|
||||
/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings.
|
||||
*(Not so important, you can adjust it to modify default sizes and spaces)*/
|
||||
@@ -557,6 +567,10 @@
|
||||
LV_FONT_DECLARE(lv_font_maven_pro_28) \
|
||||
LV_FONT_DECLARE(lv_font_maven_pro_40) \
|
||||
LV_FONT_DECLARE(lv_font_maven_pro_48) \
|
||||
LV_FONT_DECLARE(lv_font_maven_pro_bold_96) \
|
||||
LV_FONT_DECLARE(lv_font_maven_pro_bold_140) \
|
||||
LV_FONT_DECLARE(lv_font_clock_120) \
|
||||
LV_FONT_DECLARE(lv_font_clock_180) \
|
||||
LV_FONT_DECLARE(lv_font_clock_240)
|
||||
|
||||
/*Always set a default font*/
|
||||
@@ -905,14 +919,19 @@
|
||||
#define LV_USE_SNAPSHOT 0
|
||||
|
||||
/*1: Enable system monitor component*/
|
||||
/* Nur fuer die Messeinblendung des Waveshare-Panels, siehe WS7_PERF_MONITOR. */
|
||||
#if (JC_PANEL_TYPE == WS_PANEL_7H) && WS7_PERF_MONITOR
|
||||
#define LV_USE_SYSMON 1
|
||||
#else
|
||||
#define LV_USE_SYSMON 0
|
||||
#endif
|
||||
#if LV_USE_SYSMON
|
||||
/*Get the idle percentage. E.g. uint32_t my_get_idle(void);*/
|
||||
#define LV_SYSMON_GET_IDLE lv_timer_get_idle
|
||||
|
||||
/*1: Show CPU usage and FPS count
|
||||
* Requires `LV_USE_SYSMON = 1`*/
|
||||
#define LV_USE_PERF_MONITOR 0
|
||||
#define LV_USE_PERF_MONITOR 1
|
||||
#if LV_USE_PERF_MONITOR
|
||||
#define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -496,6 +496,32 @@ static lv_display_t *display_init(esp_lcd_panel_handle_t panel_handle)
|
||||
// buf1 = heap_caps_malloc(buffer_size * sizeof(lv_color_t), MALLOC_CAP_DMA);
|
||||
assert(buf1);
|
||||
ESP_LOGI(TAG, "LVGL buffer size: %dKB", buffer_size * sizeof(lv_color_t) / 1024);
|
||||
|
||||
#if WS7_DIRECT_FB
|
||||
// PROJEKTAENDERUNG: LVGL zeichnet direkt in den Bildspeicher.
|
||||
//
|
||||
// Der Hersteller-Port legt einen eigenen Zeichenpuffer an; der fertige Inhalt wird
|
||||
// danach in den Bildspeicher kopiert. Bei 1280x720 in 24 Bit sind das zwei Durchgaenge
|
||||
// durch je 2,7 MB PSRAM - gemessen rund 250 bis 300 ms pro Bild, und das dauerhaft.
|
||||
// Genau deshalb hing die Oberflaeche eine gute Viertelsekunde hinterher, und Vorgaenge
|
||||
// mit mehreren Bildern brauchten Sekunden.
|
||||
//
|
||||
// Ist der Zeichenpuffer derselbe Speicher wie der Bildspeicher, laesst der
|
||||
// esp_lcd-Treiber das Kopieren weg und schreibt nur den Prozessor-Cache zurueck. Dazu
|
||||
// kommt LV_DISPLAY_RENDER_MODE_DIRECT: LVGL zeichnet dann nur die geaenderten Bereiche
|
||||
// neu, statt jedes Mal die ganze Flaeche.
|
||||
//
|
||||
// Preis: Gezeichnet wird in den Speicher, der gerade angezeigt wird - bei schnellen
|
||||
// Wechseln kann kurz eine Kante durchs Bild laufen. Mit nur einem Bildspeicher (den das
|
||||
// Panel verlangt, siehe WS7_SINGLE_FB) ist das ohnehin nicht zu vermeiden.
|
||||
void* fb0 = NULL;
|
||||
if (esp_lcd_dpi_panel_get_frame_buffer(panel_handle, 1, &fb0) == ESP_OK && fb0) {
|
||||
buf1 = fb0;
|
||||
buffer_size = LVGL_PORT_H_RES * LVGL_PORT_V_RES;
|
||||
ESP_LOGI(TAG, "LVGL zeichnet direkt in den Bildspeicher (%dKB)",
|
||||
(int)(buffer_size * sizeof(lv_color_t) / 1024));
|
||||
}
|
||||
#endif
|
||||
#endif /* LVGL_PORT_AVOID_TEAR_ENABLE */
|
||||
|
||||
ESP_LOGD(TAG, "Register display driver to LVGL");
|
||||
@@ -511,7 +537,7 @@ static lv_display_t *display_init(esp_lcd_panel_handle_t panel_handle)
|
||||
display, buf1, buf2, buffer_size * sizeof(lv_color_t),
|
||||
#if LVGL_PORT_FULL_REFRESH
|
||||
LV_DISPLAY_RENDER_MODE_FULL
|
||||
#elif LVGL_PORT_DIRECT_MODE
|
||||
#elif LVGL_PORT_DIRECT_MODE || WS7_DIRECT_FB
|
||||
LV_DISPLAY_RENDER_MODE_DIRECT
|
||||
#else
|
||||
LV_DISPLAY_RENDER_MODE_PARTIAL
|
||||
|
||||
@@ -20,20 +20,29 @@
|
||||
// an - mit 16 kommt kein brauchbares Bild. Einstellbar bleibt es
|
||||
// nur, weil andere Waveshare-Panels an derselben Firmware
|
||||
// haengen koennten.
|
||||
// WS7_PARTIAL_REFRESH 0 = Vollbild neu zeichnen. GEPRUEFT: Mit 1 (nur geaenderte
|
||||
// Bereiche, zwei wechselnde Bildpuffer) laesst sich der
|
||||
// Menue-Vorhang nicht mehr oeffnen. Er ist halbtransparent und
|
||||
// wird in den gerade aktiven Puffer eingemischt; die naechste
|
||||
// Zustandsmeldung der S3 zeichnet in den anderen, der ihn nie
|
||||
// bekommen hat. Am 4,3-Zoll-Panel hatte derselbe Modus
|
||||
// geflackert. Nutzbar erst, wenn der LVGL-Port die geaenderten
|
||||
// Bereiche zwischen beiden Puffern abgleicht.
|
||||
// WS7_PARTIAL_REFRESH 1 = nur geaenderte Bildbereiche neu zeichnen statt jedes Mal des
|
||||
// gesamten Bildes (LVGL-Direct-Mode, zwei wechselnde Puffer).
|
||||
// Groesster Tempogewinn, besonders waehrend eines Bezugs: Die
|
||||
// Zeitanzeige laeuft zehnmal je Sekunde weiter, und mit 0 wuerde
|
||||
// dafuer jedes Mal das ganze Bild neu gezeichnet. Am Geraet
|
||||
// geprueft, kein Flackern - am 4,3-Zoll-Panel hatte derselbe
|
||||
// Modus dagegen geflackert.
|
||||
// WS7_PARALLEL_RENDER 1 = LVGL zeichnet mit zwei Threads auf beiden Prozessorkernen.
|
||||
// Kostet zwei zusaetzliche Task-Stacks im knappen internen RAM;
|
||||
// startet der P4 nicht mehr, hier zuerst auf 0 stellen.
|
||||
// -------------------------------------------------------------------------------------
|
||||
#define WS7_COLOR_BITS 24
|
||||
#define WS7_PARTIAL_REFRESH 0
|
||||
// Ohne Wirkung, solange WS7_SINGLE_FB = 1 ist: Mit nur einem Bildspeicher gibt es keine
|
||||
// Doppelpufferung, zwischen deren Betriebsarten man waehlen koennte.
|
||||
#define WS7_PARTIAL_REFRESH 1
|
||||
// Nur EIN Bildspeicher. Zwei vertraegt die DSI-Ausgabe dieses Panels beim Einschalten
|
||||
// nicht - siehe die ausfuehrliche Begruendung weiter unten beim Avoid-Tear-Schalter.
|
||||
// Auf 0 nur, wenn das Startverhalten erneut untersucht wird.
|
||||
#define WS7_SINGLE_FB 1
|
||||
// LVGL zeichnet direkt in den Bildspeicher, statt in einen eigenen Puffer zu zeichnen und
|
||||
// den danach zu kopieren. Spart pro Bild einen kompletten Durchgang durch 2,7 MB PSRAM
|
||||
// und laesst LVGL nur die geaenderten Bereiche neu zeichnen. Braucht WS7_SINGLE_FB.
|
||||
#define WS7_DIRECT_FB 1
|
||||
#define WS7_PARALLEL_RENDER 1
|
||||
|
||||
#define EXAMPLE_LVGL_PORT_TASK_MAX_DELAY_MS 500 //range 2 to 2000
|
||||
@@ -43,7 +52,32 @@
|
||||
#define EXAMPLE_LVGL_PORT_TASK_CORE -1 //range -1 to 1
|
||||
#define EXAMPLE_LVGL_PORT_TICK 2 //ragne 1 to 100
|
||||
|
||||
// Ruckelfreie Ausgabe braucht mindestens zwei Bildspeicher, aus denen abwechselnd
|
||||
// angezeigt und in die gezeichnet wird.
|
||||
//
|
||||
// Das Waveshare-Panel vertraegt das nicht: Mit zwei Bildspeichern kam nach dem Einschalten
|
||||
// kein Bild - der Hochlauf meldete durchgehend Erfolg, das Panel blieb dunkel, und erst ein
|
||||
// Reset half. Mit genau einem Bildspeicher startet es zuverlaessig; belegt wurde das mit den
|
||||
// Prueffarbbalken, die der Werks-Testsketch ebenfalls mit einem Speicher anzeigt.
|
||||
// Deshalb hier ohne Doppelpufferung: LVGL zeichnet in einen kleinen Zwischenpuffer, der
|
||||
// dann in den einen Bildspeicher uebertragen wird. Bei schnellen Bildwechseln kann dabei
|
||||
// kurz eine Kante sichtbar werden - ein zuverlaessig startendes Display wiegt das auf.
|
||||
#if (JC_PANEL_TYPE == WS_PANEL_7H) && WS7_SINGLE_FB
|
||||
#define EXAMPLE_LVGL_PORT_AVOID_TEAR_ENABLE 0
|
||||
// Zwischenpuffer fuer das Zeichnen. Volle Bildhoehe, damit ein Bildlauf in EINEM Durchgang
|
||||
// gezeichnet und uebertragen wird. Mit 120 Zeilen waren es sechs Durchgaenge samt sechs
|
||||
// Uebertragungen - das war der Grund fuer den zaehen Bildlauf. Kostet 2,8 MB PSRAM.
|
||||
//
|
||||
// Bewusst nur EIN Zeichenpuffer: Ein zweiter wuerde LVGL erlauben, schon den naechsten
|
||||
// Bereich zu zeichnen, waehrend der vorige uebertragen wird. Der Panel-Treiber lehnt eine
|
||||
// Uebertragung aber ab, solange die vorige laeuft (ESP_ERR_INVALID_STATE) - der betroffene
|
||||
// Bildbereich wird dann gar nicht geschrieben und behaelt seinen alten Inhalt. Sichtbar
|
||||
// war das als blaue Zwischenbilder beim Bildlauf.
|
||||
#define CONFIG_EXAMPLE_LVGL_PORT_BUF_PSRAM 1
|
||||
#define CONFIG_EXAMPLE_LVGL_PORT_BUF_HEIGHT LCD_V_RES
|
||||
#else
|
||||
#define EXAMPLE_LVGL_PORT_AVOID_TEAR_ENABLE 1
|
||||
#endif
|
||||
|
||||
#ifdef EXAMPLE_LVGL_PORT_AVOID_TEAR_ENABLE
|
||||
// 2 = Triple-Buffer + LVGL Full-Refresh: zeichnet bei jeder Aenderung das komplette
|
||||
@@ -127,6 +161,57 @@
|
||||
#define WS7_TOUCH_MIRROR_RAW_X 1
|
||||
#define WS7_TOUCH_MIRROR_RAW_Y 0
|
||||
|
||||
// Zeigt unten rechts Bilder je Sekunde und Prozessorlast ein. Nur zum Messen gedacht:
|
||||
// Der Wert sagt, ob sich weitere Muehe beim Zeichnen ueberhaupt lohnt.
|
||||
#define WS7_PERF_MONITOR 0
|
||||
|
||||
// Zum Einmessen des Touch: 1 gibt jeden Beruehrpunkt roh und umgerechnet auf der
|
||||
// seriellen Konsole aus. Danach wieder auf 0, sonst laeuft das Log dauernd mit.
|
||||
#define WS7_TOUCH_DEBUG 0
|
||||
|
||||
// So lange gilt eine Beruehrung nach dem letzten gueltigen Messwert noch als anliegend.
|
||||
// Ueberbrueckt Aussetzer des GT9271, die sonst als Loslassen durchgehen und einen Tipp in
|
||||
// mehrere Klicks zerlegen. 0 schaltet die Ueberbrueckung ab. Nicht zu gross waehlen: Der
|
||||
// Wert verzoegert das Loslassen und daempft dadurch den Schwung beim Wischen.
|
||||
#define WS7_TOUCH_HOLD_MS 40
|
||||
|
||||
// Wartezeit zwischen dem Freigeben der Bridge und dem Ansprechen des Touch. Der GT9271
|
||||
// haengt an derselben Versorgung und braucht nach dem Einschalten einen Moment, bis er
|
||||
// auf I2C antwortet. Meldet sich 0x14 beim Start nicht, diesen Wert erhoehen.
|
||||
#define WS7_TOUCH_POWER_MS 120
|
||||
|
||||
// Prueffarbbalken statt Oberflaeche anzeigen. Sie entstehen im DSI-Baustein selbst und
|
||||
// benutzen weder Bildspeicher noch LVGL. Damit laesst sich trennen, ob die Anzeigekette
|
||||
// bis zum Panel arbeitet (Balken sichtbar) oder nicht (schwarz). Nur zur Fehlersuche.
|
||||
// Anlaufzeit des Displaymoduls, bevor Bridge und Panel angesprochen werden. Ohne diese
|
||||
// Pause startet die Anzeige nur zufaellig - der Werks-Testsketch wartet aus demselben
|
||||
// Grund 2 Sekunden. Springt das Display beim Einschalten nicht zuverlaessig an, ist das
|
||||
// der erste Wert zum Erhoehen; laeuft es sicher, kann er vorsichtig gesenkt werden.
|
||||
#define WS7_PANEL_WARMUP_MS 2000
|
||||
|
||||
// Pause zwischen dem Start der Videoausgabe und dem zweiten Anlauf der Weckbefehle.
|
||||
// Verpasst das Panel den ersten Anlauf, bleibt der Bildschirm dunkel, waehrend die
|
||||
// Beleuchtung brennt - sie haengt an der Bridge, nicht am Panel.
|
||||
#define WS7_PANEL_SETTLE_MS 200
|
||||
|
||||
// Die DSI-Strecke beim Hochlauf einmal ab- und wieder aufbauen. Beim ersten Einschalten
|
||||
// kam sonst trotz fehlerfreiem Ablauf kein Bild; erst ein Reset half. Der einzige
|
||||
// Unterschied dabei: Die DSI-Verbindung geht einmal weg und neu auf, waehrend Bridge und
|
||||
// Panel schon versorgt und eingestellt sind. Genau das holt der zweite Aufbau nach.
|
||||
// Kostet WS7_DSI_RESTART_MS zusaetzliche Startzeit.
|
||||
#define WS7_DSI_RESTART 0
|
||||
#define WS7_DSI_RESTART_MS 200
|
||||
|
||||
// Nach einem Kaltstart einmal selbst neu starten, sobald der erste Hochlauf durch ist.
|
||||
// Das Panel kommt beim ersten Anlauf nach dem Einschalten nicht zuverlaessig hoch;
|
||||
// ein echter Chip-Reset behebt es zuverlaessig, der Ab- und Wiederaufbau der
|
||||
// DSI-Strecke im Betrieb dagegen nicht. Kostet rund drei Sekunden beim Einschalten.
|
||||
// Eine Schleife ist ausgeschlossen: Beim zweiten Durchlauf ist der Startgrund kein
|
||||
// Kaltstart mehr.
|
||||
#define WS7_COLD_BOOT_RESTART 1
|
||||
|
||||
#define WS7_TEST_PATTERN 0
|
||||
|
||||
#elif JC_PANEL_TYPE == JC_PANEL_70
|
||||
|
||||
#define LCD_H_RES 1024
|
||||
|
||||
+875
-380
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user