Compare commits

..
Author SHA1 Message Date
raw-designsandClaude Opus 5 80b6eb810f diag(P4): Prüfbild hält an, statt von LVGL überschrieben zu werden (1.6.17)
Der Störimpulsfilter aus 1.6.16 wirkt - nach dem Panel-Start melden sich
wieder alle drei I2C-Bausteine, keine Bridge- oder Touch-Fehler mehr.

Das Prüfbild aus 1.6.15 war als Test jedoch untauglich: gesetzt bei
esp_lcd_dpi_panel_set_pattern(), aber unmittelbar danach lief
lvgl_port_init() und schrieb in den Framebuffer, womit das Muster wieder
verschwand. Der Test sah damit genauso aus wie der Fehler, den er finden
soll.

Mit WS7_TEST_PATTERN = 1 endet jc_board_bringup() jetzt direkt nach dem
Muster: Backlight an, Rückgabe false, kein LVGL.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 17:24:25 +02:00
thomas 6a9048411e Merge pull request 'fix(P4): I2C-Störimpulsfilter - Ursache des schwarzen Bildes (1.6.16)' (#44) from fix/i2c-stoerimpulsfilter into main 2026-09-01 17:06:15 +02:00
raw-designsandClaude Opus 5 ecb9836510 fix(P4): I2C-Störimpulsfilter - Ursache des schwarzen Bildes (1.6.16)
Der I2C-Scan vor und nach dem Panel-Start war entscheidend:

  vor:   0x14 (Touch)  0x18 (Audio)  0x45 (Bridge)
  nach:  0x18

Es fallen genau die beiden Bausteine weg, die am Displaykabel hängen; der
Audio-Baustein auf der Platine bleibt erreichbar, der Bus arbeitet also.
Sobald die DSI-Ausgabe läuft, stören deren Signale auf das Flachbandkabel
ein. Die Bridge liess sich danach nicht mehr ansprechen
(ESP_ERR_INVALID_STATE), das Panel blieb dunkel.

i2c_master_bus_config_t bekommt für WS_PANEL_7H jetzt glitch_ignore_cnt = 7
und enable_internal_pullup - beides setzt auch das Waveshare-Beispiel. In
unserem Bringup fehlte es, weil die Bus-Einrichtung von den JC-Panels
übernommen wurde, die kein Flachbandkabel dieser Länge haben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 17:04:51 +02:00
thomas c4cb6eb90a Merge pull request 'diag(P4): Schwarzes Bild eingrenzen - Prüfbild und lückenlose Meldungen (1.6.15)' (#43) from diag/schwarzes-bild-eingrenzen into main 2026-09-01 16:52:28 +02:00
raw-designsandClaude Opus 5 c58b901f26 diag(P4): Schwarzes Bild eingrenzen - Prüfbild und lückenlose Meldungen (1.6.15)
Kaltstart, kein einziger Fehler im Log, alle I2C-Bausteine da - und trotzdem
keine Anzeige. Zwei Lücken in der Diagnose:

- Die DCS-Weckbefehle (MADCTL, Sleep Out, Display On) liefen ungeprüft
  durch. Jetzt über BSP_STEP gemeldet.
- Nach dem Panel-Start endete die Ausgabe. "Bringup fertig" vor und
  "LVGL laeuft" nach lvgl_port_init() trennen jetzt ein Hängenbleiben in
  LVGL von einem fehlenden Bild.

Neuer Schalter WS7_TEST_PATTERN nutzt esp_lcd_dpi_panel_set_pattern() für
Farbbalken aus dem DSI-Baustein, ohne Framebuffer und ohne LVGL - wie im
funktionierenden Werks-Testsketch. Erscheinen sie, arbeitet die Kette bis
zum Panel und der Fehler liegt weiter oben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 16:51:04 +02:00
thomas d83619904f Merge pull request 'fix(P4): Touch erst nach Panel-Freigabe initialisieren (1.6.14)' (#42) from fix/touch-nach-panelfreigabe into main 2026-09-01 16:31:55 +02:00
raw-designsandClaude Opus 5 50540179c7 fix(P4): Touch erst nach Panel-Freigabe initialisieren (1.6.14)
Der GT9271 meldete "i2c transaction failed" auch beim Kaltstart, während
alle Panel-Schritte fehlerfrei durchliefen und die Bus-Freitaktung aus 1.6.13
den Bus als frei meldete.

Ursache ist die Reihenfolge: Im funktionierenden Werks-Testsketch steht
initTouch() hinter enableBacklight(). Der GT9271 hängt an derselben
Versorgung wie das Panel und antwortet erst, wenn die Bridge über 0xAD
freigegeben ist. Beim Übertragen in die Firmware war das verloren gegangen -
jc_backlight_set() lief erst nach jc_board_bringup().

- Für WS_PANEL_7H wird die Beleuchtung jetzt innerhalb des Bringups vor der
  Touch-Initialisierung eingeschaltet, mit WS7_TOUCH_POWER_MS Pause.
- Neue Diagnose ws7_i2c_scan() listet die antwortenden I2C-Adressen vor und
  nach dem Panel-Start.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 16:30:31 +02:00
thomas 9bbd7d72aa Merge pull request 'fix(P4): Hängenden I2C-Bus freitakten - Ursache des schwarzen Bildes (1.6.13)' (#41) from fix/i2c-bus-freitakten into main 2026-09-01 16:17:42 +02:00
raw-designsandClaude Opus 5 43c5d5a41a fix(P4): Hängenden I2C-Bus freitakten - Ursache des schwarzen Bildes (1.6.13)
Der Log nach einem Reset zeigte alle Panel-Schritte fehlerfrei, aber
"i2c transaction failed" beim GT911. Bridge und Touch teilen sich den Bus:
Trifft ein Reset des P4 mitten in eine Übertragung, bleibt der Baustein in
seiner Bitausgabe stehen und hält SDA dauerhaft low. Beide hängen an
Dauerstrom, der Zustand überlebt also Reset und Flashen.

- ws7_i2c_bus_recover() taktet SCL vor dem Anlegen des Busses bis zu neunmal
  von Hand, bis SDA freigegeben wird, und erzeugt dann eine Stop-Bedingung.
  Bei freiem Bus läuft die Funktion wirkungslos durch.
- ws7_bridge_write() prüft den Rückgabewert. Bisher liefen fehlgeschlagene
  Schreibzugriffe stillschweigend ins Leere - der eigentliche Grund, warum
  das schwarze Bild keinerlei Spur hinterließ.
- pins_config.h: "#elsealle" statt "#else" seit 1.6.10 korrigiert. Der
  Tippfehler traf nur den JC_PANEL_43-Zweig, der dadurch nicht mehr
  übersetzbar war. Beide Panel-Varianten wieder gegengebaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 16:16:09 +02:00
thomas dfd2aaddd1 Merge pull request 'fix(P4): Abschaltfolge zurücknehmen, Startgrund und LDO prüfen (1.6.12)' (#40) from fix/bridge-abschaltfolge-zuruecknehmen into main 2026-09-01 15:45:24 +02:00
raw-designsandClaude Opus 5 6c783c55de fix(P4): Abschaltfolge zurücknehmen, Startgrund und LDO prüfen (1.6.12)
Die Bridge-Abschaltfolge aus 1.6.11 hat den Fehler nicht behoben, sondern
verschlimmert: Nach C0/C2/AC = 0x00 kam das Panel auch direkt nach dem
Flashen nicht mehr hoch. Der Bringup entspricht wieder 1.6.10.

Stattdessen zwei Diagnosen zur Eingrenzung:
- esp_reset_reason() wird beim Hochlauf ausgegeben, um Kalt- von Warmstart
  unterscheiden zu können.
- esp_ldo_acquire_channel() läuft nicht mehr ungeprüft durch, sondern meldet
  einen Fehler über BSP_STEP. Es war der einzige Schritt ohne Prüfung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 15:44:02 +02:00
raw-designs f38ea3045b Revert "Merge pull request 'fix(P4): Schwarzes Bild nach Reset am Waveshare-Panel (1.6.11)' (#39) from fix/schwarzes-bild-nach-reset into main"
This reverts commit 0a6c6ed869, reversing
changes made to edb1e333f0.
2026-09-01 15:37:29 +02:00
thomas 0a6c6ed869 Merge pull request 'fix(P4): Schwarzes Bild nach Reset am Waveshare-Panel (1.6.11)' (#39) from fix/schwarzes-bild-nach-reset into main 2026-09-01 15:23:35 +02:00
raw-designsandClaude Opus 5 e8308a9182 fix(P4): Schwarzes Bild nach Reset am Waveshare-Panel (1.6.11)
Nach einem Reset des P4 blieb das Bild schwarz, die Hintergrundbeleuchtung
brannte; nur direkt nach dem Flashen lief es.

Die Bridge des Panels hat keine Reset-Leitung und hängt an Dauerstrom. Ein
Reset des P4 setzt sie nicht zurück - ihre Register standen noch auf den
Werten der vorigen Sitzung, während der P4 seine DSI-Strecke komplett neu
aufbaut. Beim Flashen wird die Versorgung getrennt, deshalb trat der Fehler
dort nicht auf.

ws7_bridge_pre_init() schaltet die Bridge jetzt zuerst definiert ab
(AB/AA, AD, dann AC/C2/C0), wartet WS7_BRIDGE_RESET_MS und schreibt erst
danach die Grundinitialisierung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 15:22:11 +02:00
thomas edb1e333f0 Merge pull request 'perf(P4): Teil-Neuzeichnen als Vorgabe, Messeinblendung, deckende Seiten (1.6.10)' (#38) from perf/scrollen-messen-und-vorgaben into main 2026-09-01 14:46:56 +02:00
raw-designsandClaude Opus 5 528c8d5500 perf(P4): Teil-Neuzeichnen als Vorgabe, Messeinblendung, deckende Seiten (1.6.10)
- WS7_PARTIAL_REFRESH = 1 auch im Auslieferungsstand. Am Gerät geprüft: kein
  Flackern; von den drei Tempo-Maßnahmen aus 1.6.4 ist es der größte Gewinn.
- make_page() setzt einen deckenden Hintergrund in COL_BG statt LV_OPA_TRANSP.
  Optisch identisch, spart LVGL beim Scrollen aber das Zeichnen und Mischen
  der darunterliegenden Ebenen.
- Neuer Schalter WS7_PERF_MONITOR schaltet LV_USE_SYSMON/LV_USE_PERF_MONITOR
  ein und blendet Bilder je Sekunde und Prozessorlast ein. Vorgabe 0, mit 1
  gegengebaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 14:45:33 +02:00
thomas 117715dc3b Merge pull request 'fix(P4): Tipp auf einen Knopf löst nicht mehr mehrfach aus (1.6.9)' (#37) from fix/touch-mehrfachausloesung into main 2026-09-01 14:19:51 +02:00
raw-designsandClaude Opus 5 328dc06983 fix(P4): Tipp auf einen Knopf löst nicht mehr mehrfach aus (1.6.9)
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
Abtastrate mit 1.6.8 von 33 auf 16 ms gestiegen ist, wurde daraus sichtbar
Drücken-Loslassen-Drücken-Loslassen.

Vor den Treiber ist jetzt ein eigener get_xy-Aufsatz gesetzt: Er verwirft
unplausible Rohwerte und hält den letzten gültigen Punkt noch
WS7_TOUCH_HOLD_MS lang (Vorgabe 40 ms). Der Aufsatz wird zur Laufzeit in das
Touch-Handle eingehängt, die Herstellerdateien bleiben unverändert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 14:18:28 +02:00
thomas 480708c992 Merge pull request 'perf(P4): Scrollen am Waveshare-Panel flüssiger (1.6.8)' (#36) from perf/scrollen-taktrate into main 2026-09-01 14:02:46 +02:00
raw-designsandClaude Opus 5 9a0761f6da perf(P4): Scrollen am Waveshare-Panel flüssiger (1.6.8)
LV_DEF_REFR_PERIOD steuert nicht nur die Bildrate, sondern auch die
Abtastrate des Touch und die Schrittweite von Animationen. Mit 33 ms waren
das 30 Schritte je Sekunde - beim Ziehen mit dem Finger sichtbar ruckelig.

Für das Waveshare-Panel jetzt 16 ms, passend zu dessen 60 Hz. Kommt das
Zeichnen nicht hinterher, wird ein Bild später fertig; kaputt geht nichts.
Die JC-Panels bleiben unverändert bei 33 ms.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 14:01:23 +02:00
thomas e6c09b7a9a Merge pull request 'fix(P4): Menü-Knopf fängt Tipps auch knapp daneben ab (1.6.7)' (#35) from fix/menue-knopf-trefferflaeche into main 2026-09-01 13:49:17 +02:00
raw-designsandClaude Opus 5 4fa0c81087 fix(P4): Menü-Knopf fängt Tipps auch knapp daneben ab (1.6.7)
Eine Messung mit WS7_TOUCH_DEBUG hat gezeigt, dass die Touch-Zuordnung stimmt:
Der Tipp auf den Menü-Knopf landete bei X=66/Y=27, der Knopf liegt aber bei
X 8..56. Mit 48x36 Pixeln ist er auf dem 7-Zoll-Panel ein sehr kleines Ziel.

lv_obj_set_ext_click_area vergrößert die Trefferfläche um 20 Pixel, ohne den
Knopf optisch zu ändern. Die Vergrößerung wirkt nur innerhalb der Kopfleiste,
weil diese ihre Kinder beschneidet - dem Seiteninhalt darunter wird nichts
weggenommen, und bei offenem Menü liegt ohnehin der Vorhang darüber.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 13:47:54 +02:00
thomas 04eb77fb2d Merge pull request 'feat(P4): Touch-Messausgabe zum Einmessen (1.6.6)' (#34) from diag/touch-einmessen into main 2026-09-01 13:25:39 +02:00
raw-designsandClaude Opus 5 7878f1bafd feat(P4): Touch-Messausgabe zum Einmessen (1.6.6)
Der Menü-Knopf oben links reagiert am Waveshare-Panel nicht. Ob der Touch die
48x36 Pixel grosse Flaeche in der 44 Pixel hohen Kopfleiste ueberhaupt trifft,
liess sich bisher nicht nachsehen.

WS7_TOUCH_DEBUG in pins_config.h gibt jeden Berührpunkt roh und umgerechnet
über esp_rom_printf aus, also auch bei Core-Debug-Level "none". Vorgabe 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 13:24:18 +02:00
thomas 60bb859fc9 Merge pull request 'fix(P4): Menü-Vorhang wieder öffenbar, RGB888 bleibt Vorgabe (1.6.5)' (#33) from fix/waveshare-vollbild-neuzeichnen into main 2026-09-01 13:14:52 +02:00
raw-designsandClaude Opus 5 e8fdc60fea fix(P4): Menü-Vorhang wieder öffenbar, RGB888 bleibt Vorgabe (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:

- WS7_COLOR_BITS = 24: Die Bridge dieses Panels nimmt kein RGB565 an.
- WS7_PARTIAL_REFRESH = 0: Der Menü-Vorhang ist halbtransparent und wird in
  den gerade aktiven Bildpuffer eingemischt. Die nächste Zustandsmeldung der
  S3 zeichnet in den zweiten Puffer, der ihn nie bekommen hat - der Vorhang
  war damit sofort wieder weg und der Knopf schien wirkungslos. Nutzbar wäre
  der Modus erst, wenn der LVGL-Port die geänderten Bereiche zwischen beiden
  Puffern abgleicht.

Beide bleiben als Schalter erhalten, mit Notiz woran sie gescheitert sind.
WS7_PARALLEL_RENDER bleibt eingeschaltet - von den drei Maßnahmen trägt nur
diese.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 13:13:28 +02:00
thomas 8b7978507c Merge pull request 'perf(P4): Darstellung am Waveshare-Panel beschleunigen (1.6.4)' (#32) from perf/waveshare-darstellung-beschleunigen into main 2026-09-01 12:52:55 +02:00
raw-designsandClaude Opus 5 a8ae034911 perf(P4): Darstellung am Waveshare-Panel beschleunigen (1.6.4)
1280x720 sind 2,4-mal so viele Pixel wie beim 4,3-Zöller, und bis 1.6.3 wurde
bei jeder Änderung das komplette Bild in 24 Bit neu gezeichnet. Drei Schalter
in pins_config.h, einzeln zurückstellbar:

- WS7_COLOR_BITS = 16: RGB565 statt RGB888, halbe Datenmenge je Bild.
  lv_conf.h liest den Wert aus pins_config.h, damit Sketch und LVGL-Bibliothek
  dieselbe Farbtiefe benutzen; display_hal.cpp sichert das per static_assert.
- WS7_PARTIAL_REFRESH = 1: Avoid-Tear-Mode 3 (Direct-Mode, zwei Puffer) statt
  Vollbild-Neuzeichnen.
- WS7_PARALLEL_RENDER = 1: LV_USE_OS = FREERTOS und zwei Zeichen-Threads.

Framebuffer-Bedarf sinkt dadurch von rund 8,3 MB auf 3,7 MB PSRAM. Die
JC-Panels sind von allen drei Schaltern nicht betroffen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 12:51:24 +02:00
thomas ee5888ed97 Merge pull request 'fix(P4): UART auf GPIO20/21, Touch oben/unten spiegeln (1.6.3)' (#31) from fix/waveshare-uart-pins-und-touchspiegelung into main 2026-09-01 12:35:54 +02:00
raw-designsandClaude Opus 5 9d9591c26e fix(P4): UART auf GPIO20/21, Touch oben/unten spiegeln (1.6.3)
Nach dem ersten Betrieb am Waveshare ESP32-P4-Pico:

- UART zur Hauptplatine auf TX = GPIO20 / RX = GPIO21 (vorher GPIO17/18).
  Die JC-Panels bleiben bei GPIO33/GPIO31.
- Das Bild steht in der tatsächlichen Einbaulage richtig herum, deshalb ist
  WS7_ROTATE_180 wieder 0. Der Schalter bleibt für den Fall einer anderen
  Montage erhalten.
- Der Touch war oben/unten spiegelverkehrt: Der Digitizer sitzt gegenüber dem
  Bild um die Hochachse gedreht. WS7_TOUCH_MIRROR_RAW_X steht daher auf 1.
  Bild- und Touch-Ausrichtung sind zwei getrennte Schalter, weil sie an diesem
  Panel nicht zusammenfallen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 12:34:27 +02:00
thomas 288aacf1b4 Merge pull request 'fix(P4): Panel-Bringup meldet Fehler im Klartext statt abzustürzen (1.6.2)' (#30) from fix/panel-bringup-diagnose into main 2026-09-01 08:08:39 +02:00
raw-designsandClaude Opus 5 d75708993a fix(P4): Panel-Bringup meldet Fehler im Klartext statt abzustürzen (1.6.2)
Ein fehlgeschlagener Panel-Aufbau endete bisher in einem ESP_ERROR_CHECK
tief im LVGL-Port und damit in einem Speicherauszug ohne erkennbare Ursache.

- Die Schritte des Waveshare-Bringups melden ihren Fehler über esp_rom_printf,
  also auch bei Core-Debug-Level "none". Zusätzlich werden PSRAM-Größe,
  freier PSRAM, größter freier Block und der Framebuffer-Bedarf ausgegeben.
- jc_board_bringup() liefert jetzt einen Status. Kommt das Panel nicht hoch,
  bleibt die Firmware ohne Anzeige lauffähig (UART + OTA), statt beim ersten
  LVGL-Zugriff erneut abzustürzen.
- ui.cpp: alle öffentlichen Funktionen prüfen, ob ui_init gelaufen ist.
- Fehlerbehebung: esp_lcd_touch_new_i2c_gt911 setzt im Fehlerfall einen bereits
  freigegebenen Zeiger. Das Handle wird vorbelegt und der Rückgabewert geprüft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 08:07:10 +02:00
thomas 146420a0bc Merge pull request 'refactor: Display-Firmware neutral als P4_Display_Firmware führen' (#29) from refactor/p4-display-firmware-umbenennen into main 2026-09-01 03:36:57 +02:00
raw-designsandClaude Opus 5 4f9f686d81 refactor: Display-Firmware neutral als P4_Display_Firmware führen
Der Ordner hieß JC_Display_Firmware, bedient seit 1.6.0 aber auch das
Waveshare 7inch DSI LCD (H) am ESP32-P4-Pico. Der Name führte in die Irre.

- JC_Display_Firmware/ -> P4_Display_Firmware/ (samt Sketch, den Arduino
  gleichnamig zum Ordner verlangt)
- Doku/JC-Display_UART-Protokoll.md -> Doku/P4-Display_UART-Protokoll.md,
  Verweise und Titel angepasst
- Verweise in CLAUDE.md, README und Quelltextköpfen nachgezogen

Nur Namen und Pfade, keine Logikänderung. Der Vendor-Ordner
JC_Display_Firmware_7zoll/ behält seinen Namen, ebenso die Bezeichner
JC_PANEL_TYPE/jc_board_bringup im Quelltext.

Enthält außerdem die bereits im Arbeitsverzeichnis liegende, noch nicht
committete Ergänzung des Git-Workflows in CLAUDE.md (PRs über die Gitea-API
statt der hängenden tea-CLI).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 03:30:42 +02:00
thomas e0c6784ecf Merge pull request 'fix(P4): Waveshare-Panel um 180 Grad gedreht ausgeben (1.6.1)' (#28) from fix/waveshare-einbaulage-180-grad into main 2026-09-01 03:12:31 +02:00
raw-designsandClaude Opus 5 72b47f6dd6 fix(P4): Waveshare-Panel um 180 Grad gedreht ausgeben (1.6.1)
Das Panel ist auf dem Kopf eingebaut. WS7_ROTATE_180 in pins_config.h dreht
Bild und Touch gemeinsam; Vorgabe ist gedreht.

Die Drehung übernimmt der PPA-Grafikbeschleuniger (EXAMPLE_LVGL_PORT_PPA_
ROTATION_ENABLE), weil die Software-Rotation des LVGL-Ports nur RGB565
verarbeitet und für dieses RGB888-Panel nicht in Frage kommt. Der Touch wird
im process_coordinates-Hook mitgedreht, sonst läge die Bedienung
spiegelbildlich zum Bild.

MADCTL ist als WS7_MADCTL herausgezogen, falls die Bridge es doch auswertet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 03:11:10 +02:00
thomas 69d35e9a28 Merge pull request 'feat(P4): Waveshare ESP32-P4-Pico mit 7inch DSI LCD (H) unterstützen (1.6.0)' (#27) from feat/waveshare-p4-pico-7zoll-dsi into main 2026-09-01 03:05:49 +02:00
raw-designsandClaude Opus 5 a3034f7c42 feat(P4): UART zum S3 beim Waveshare-Board auf GPIO17/GPIO18 legen
Der 40-polige Header des ESP32-P4-Pico hat eine andere Belegung als die
Expansion-IO der JC-Panels. Für WS_PANEL_7H gilt jetzt TX = GPIO17,
RX = GPIO18; die JC-Panels bleiben bei GPIO33/GPIO31.

README und Changelog entsprechend ergänzt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y
2026-09-01 03:04:28 +02:00
raw-designsandClaude Opus 5 93bb0deba1 feat(P4): Waveshare ESP32-P4-Pico mit 7inch DSI LCD (H) unterstützen (1.6.0)
Dieselbe P4-Firmware läuft jetzt zusätzlich auf einem Waveshare ESP32-P4-Pico
mit dem Waveshare 7inch DSI LCD (H) (1280x720). Auswahl über JC_PANEL_TYPE in
config.h (neu: WS_PANEL_7H, ab jetzt Vorgabe); JC_PANEL_43 und JC_PANEL_70
bleiben unverändert.

- board_bringup.c: DSI-Bus, DBI-Kommandokanal und DPI-Panel werden ohne
  Hersteller-Panel-Treiber direkt angelegt (PLL_F20M, 2 Lanes zu 1250 Mbit/s,
  80 MHz DPI, Austastlücken 64/64/64, RGB888). Panel-Freigabe und Helligkeit
  über die Bridge auf I2C 0x45; Licht erst nach dem Start der DSI-Ausgabe.
- lv_conf.h leitet LV_COLOR_DEPTH aus JC_PANEL_TYPE ab (24 Bit für das
  Waveshare-Panel, 16 Bit für die JC-Panels) und liest dafür config.h.
  display_hal.cpp sichert das mit static_assert ab.
- Touch GT9271 (I2C 0x14) über den GT911-Treiber; Achsentausch und Begrenzung
  auf die Bildfläche im process_coordinates-Hook.
- pins_config.h: Auflösung, DSI-Zeitbasis und Touch-Umrechnung als WS7_*-Werte.
- README und Changelog ergänzt.

Die UART-Pins zum S3 stehen für das Waveshare-Board noch auf den JC-Werten
(GPIO33/31) und müssen nach dem Header-Aufdruck gesetzt werden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxAvqVnrY6YSoGFrNGeRTi
2026-09-01 02:56:23 +02:00
thomas 27a3ee840e Merge pull request 'feat(P4): 7-Zoll-Display JC1060P470C-I-W unterstützen (1.5.0)' (#26) from feat/7zoll-display-JC1060P470C into main 2026-08-22 02:36:52 +02:00
4807 changed files with 1334 additions and 387 deletions
+6 -6
View File
@@ -11,17 +11,17 @@ für zwei Mikrocontroller, die per UART (230400 8N1, JSON-Zeilen) verbunden sind
Änderungshistorie: `Changelog.txt` (Root), Version steht in `String version = "…"`.
- **ESP32-P4 UART-Touch-Display (spiegelt den S3-Zustand).**
Ordner: `JC_Display_Firmware/` (Hauptsketch `JC_Display_Firmware.ino`,
Ordner: `P4_Display_Firmware/` (Hauptsketch `P4_Display_Firmware.ino`,
UI in `ui.cpp`/`ui.h`, UART-Protokoll in `protocol_client.*`, LVGL 9.x).
Hat **kein eigenes WLAN** (der ESP32-C6-Co-Prozessor ist ungenutzt); alle Daten
kommen über UART vom S3. Eigene Version `DISPLAY_FW_VERSION` +
`JC_Display_Firmware/Changelog.txt`.
`P4_Display_Firmware/Changelog.txt`.
Wenn ich „S3/Controller/Maschine" sage, ist `Dual_PID_FastHeatUp.ino` gemeint;
„P4/Display" ist der Ordner `JC_Display_Firmware/`.
„P4/Display" ist der Ordner `P4_Display_Firmware/`.
**Nicht anfassen:** Der Ordner `Sicherungen/` enthält nur datierte Versions-Backups
(`.ino`) — niemals dort editieren. Unter `JC_Display_Firmware/JC4880P443C_I_W/` liegen
(`.ino`) — niemals dort editieren. Unter `P4_Display_Firmware/JC4880P443C_I_W/` liegen
reine Hersteller-Demos/Beispiele (Board-Support), ebenfalls nicht als Projektcode behandeln.
# Agent Instructions
@@ -33,8 +33,8 @@ reine Hersteller-Demos/Beispiele (Board-Support), ebenfalls nicht als Projektcod
## Git-Workflow
- Host: Gitea `git.mueller.black`, Repo `thomas/Dual-PID`, User `thomas`, CLI `tea`.
- Aenderungen immer ueber Feature-Branch + Merge-Request (`tea pr create`), nie direkt auf `main` committen oder pushen.
- Pull/Merge-Requests dürfen immer selbstständig gemergt werden (Auto-Merge, kein grünes CI erforderlich, via `tea pr merge` oder Gitea-API); danach den Merge kurz melden.
- Aenderungen immer ueber Feature-Branch + Merge-Request, nie direkt auf `main` committen oder pushen.
- PR anlegen **und** mergen bevorzugt über die **Gitea-REST-API** (PowerShell `Invoke-RestMethod` auf `https://git.mueller.black/api/v1/repos/thomas/Dual-PID/pulls[/<nr>/merge]`, Token aus `C:\Users\Thomas\AppData\Local\tea\config.yml`, nur in Variable, nie ausgeben), da die `tea`-CLI gegen `git.mueller.black` oft hängt und nie zurückkehrt. `tea pr create`/`tea pr merge` nur als Ausweichweg. PRs dürfen selbstständig gemergt werden (Auto-Merge, kein grünes CI erforderlich); danach den Merge kurz melden.
- Kein Force-Push, kein History-Rewrite auf geteilten Branches.
- Commit-Identitaet bleibt `raw-designs` / `Thomas@raw-designs.de` (globale Git-Config, nicht aendern).
- Commit-Messages im Conventional-Commits-Format (feat/fix/docs/refactor/...).
@@ -1,4 +1,4 @@
# JC4880P443C-I-W Touch-Display — UART-Protokoll & Architektur
# P4-Touch-Display — UART-Protokoll & Architektur
Status: Entwurf v1.0 der Doku · Firmware-Protokollversion: **1** (vorhanden, abgeschaltet) ·
Ziel-Protokollversion: **2** (geplante Erweiterungen)
@@ -16,11 +16,11 @@ Bewusste Designentscheidung (siehe Projektbesprechung):
- Das **Webinterface bleibt auf der Hauptplatine** (ESP32-S3). Es bleibt unverändert
die zentrale Steuerungs- und Konnektivitätsinstanz.
- Das **JC-Display ist ein vollwertiges Touch-Bediengerät**, das über UART angebunden
- Das **P4-Display ist ein vollwertiges Touch-Bediengerät**, das über UART angebunden
ist und denselben Funktionsumfang bietet wie das Webinterface — aber **kein** eigenes
WLAN/Webserver betreibt.
- Das **OLED (SH1106G) bleibt optional** und wird wie bisher über ein **Compile-Flag**
gewählt (`ENABLE_DISPLAY`). Es ist unabhängig vom JC-Display.
gewählt (`ENABLE_DISPLAY`). Es ist unabhängig vom P4-Display.
```
+----------------------------+ UART (GPIO43/44) +---------------------------+
@@ -34,13 +34,13 @@ Bewusste Designentscheidung (siehe Projektbesprechung):
| - OLED (optional) | | ST7701 / GT911 / ES8311 |
+----------------------------+ +---------------------------+
* Der ESP32-C6 auf dem JC-Display (WLAN/BT) wird in diesem Projekt NICHT für die
* Der ESP32-C6 auf dem P4-Display (WLAN/BT) wird in diesem Projekt NICHT für die
Maschinensteuerung benötigt. WLAN/Webinterface laufen weiterhin auf der S3.
```
### Rollenverteilung
| Aufgabe | S3 (Hauptplatine) | P4 (JC-Display) |
| Aufgabe | S3 (Hauptplatine) | P4 (P4-Display) |
|---|---|---|
| Echtzeit-Regelung (PID, SSR, Sicherheit) | **ja** | nein |
| Sensoren (NTC, MAX6675, Waage) | **ja** | nein |
@@ -76,7 +76,7 @@ schickt Bedienwünsche als Kommandos. So bleiben Web-UI, OLED und Touch-Display
```
> **Hinweis (bewusst akzeptiert):** GPIO43/44 sind beim ESP32-S3 zugleich die Standard-
> Pins der seriellen Debug-Konsole (UART0). Solange das JC-Display dort angeschlossen ist,
> Pins der seriellen Debug-Konsole (UART0). Solange das P4-Display dort angeschlossen ist,
> steht die klassische serielle Debug-Ausgabe an diesen Pins nicht parallel zur Verfügung.
> Debug/Logging erfolgt dann über USB-CDC bzw. das Webinterface. Diese Pins wurden
> ausdrücklich beibehalten, weil sie auf der Platine herausgeführt sind.
@@ -519,7 +519,7 @@ Für ein vollwertiges 480×800-Touch-UI fehlen v1 noch einige Daten/Funktionen.
## 9. OLED-Koexistenz (Compile-Flag)
- OLED bleibt über `ENABLE_DISPLAY` (Compile-Flag) wählbar — unverändert.
- Das JC-Display wird über `TOUCH_UART_ENABLED` (Compile-Flag) aktiviert.
- Das P4-Display wird über `TOUCH_UART_ENABLED` (Compile-Flag) aktiviert.
- **Geplante Änderung:** beide Flags strikt **unabhängig** halten, damit alle Kombinationen
baubar sind:
@@ -562,7 +562,7 @@ Puffergrößen/Chunking, optionaler CRC + Handshake, `action`-Stringliste dokume
**Löschen:** Nichts.
**Fully-Kiosk bleibt erhalten** (Entscheidung) — als eigenständige, optionale Funktion
neben dem JC-Display. Lastbewertung der S3:
neben dem P4-Display. Lastbewertung der S3:
- Einziger Aufruf `sendFullyKioskLoadUrl()` wird **nur bei Standby-Zustandswechsel**
getriggert (`if (standbyModeActive != lastStandbyModeActive)`), **nicht periodisch**
(wenige Male pro Tag).
@@ -586,10 +586,10 @@ neben dem JC-Display. Lastbewertung der S3:
6. **[offen, optional]** CRC + ggf. Puffer-Feinjustage (§8.3) — bewusst nicht als toter,
ungetesteter Code eingebaut; bei Bedarf später.
7. **[offen, durch dich]** `TOUCH_UART_ENABLED` auf 1 setzen + Build verifizieren, **sobald**
das JC-Display physisch an Serial1 (GPIO43/44) hängt. Bewusst noch **0**, damit die
das P4-Display physisch an Serial1 (GPIO43/44) hängt. Bewusst noch **0**, damit die
serielle Debug-Konsole (GPIO43/44) im aktuellen Betrieb erhalten bleibt.
### Phase B — P4-Seite (JC-Display, Projekt `JC_Display_Firmware/`)
### Phase B — P4-Seite (P4-Display, Projekt `P4_Display_Firmware/`)
Grundgerüst angelegt (Arduino-ESP32 P4 + LVGL 9 + ArduinoJson 7). Aufteilung:
`config.h`, `machine_state.h`, `protocol_client.*`, `ui.*`, `display_hal.*`, `.ino`, `README.md`.
@@ -603,7 +603,7 @@ Grundgerüst angelegt (Arduino-ESP32 P4 + LVGL 9 + ArduinoJson 7). Aufteilung:
(`display_hal.cpp`, Schalter `JC_USE_REAL_PANEL`): MIPI-DSI/ST7701, GT911 (I²C SDA=7/SCL=8),
Backlight GPIO23, LCD-Reset GPIO5; LVGL-Port mit eigenem Task + Lock. Stub-Modus bleibt für
Schreibtisch-Tests. Vendor-BSP-Dateien sind in den Sketch zu kopieren (siehe Projekt-README).
5. **[festgelegt]** UART-Pins am JC-Display: **P4 GPIO50 (TX) / GPIO51 (RX)** vom Expand-IO-Header
5. **[festgelegt]** UART-Pins am P4-Display: **P4 GPIO50 (TX) / GPIO51 (RX)** vom Expand-IO-Header
JP1 (Schaltplan `4_USB&IO.png`). Gegenseite S3 unverändert GPIO43/44.
6. **[offen]** Weitere Screens: Einstellungen (Brew/Service/Sensor), Profil-Auswahl/-Editor,
PID/AutoTune-Bedienung; Ausrichtung Hochformat (Rotation 0 in `pins_config.h`).
-255
View File
@@ -1,255 +0,0 @@
// =====================================================================================
// board_bringup.c - ESP32-P4 / GT911 Hardware-Bringup
// JC_PANEL_43 = JC4880P443C-I-W (ST7701, 480x800)
// JC_PANEL_70 = JC1060P470C-I-W (JD9165, 1024x600)
// =====================================================================================
// BEWUSST eine .c-Datei (wird als C kompiliert): die esp_lcd-Init-Makros nutzen
// Compound-Literals und Out-of-Order-Designated-Initializer, die in C++ (Arduino .cpp)
// zu Fehlern fuehren. Der Ablauf ist 1:1 aus dem Hersteller-Beispiel
// arduino_examples/lvgl_v9_sw_rotation/lvgl_sw_rotation.c uebernommen - lediglich der
// Demo-Aufruf (lv_demo_widgets) entfaellt; das UI wird ueber display_hal.cpp aufgebaut.
//
// Nur aktiv bei JC_USE_REAL_PANEL == 1. Erwartet die Vendor-BSP-Dateien im Sketch:
// pins_config.h, lvgl_port_v9.h/.c, src/lcd/*, src/touch/*
// =====================================================================================
#include "config.h" // liefert JC_USE_REAL_PANEL (C-sicher)
#if JC_USE_REAL_PANEL
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/ledc.h"
#include "driver/i2c_master.h"
#include "esp_log.h"
#include "esp_cache.h"
#include "esp_ldo_regulator.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_mipi_dsi.h"
#include "src/touch/esp_lcd_touch_gt911.h"
#if JC_PANEL_TYPE == JC_PANEL_70
#include "src/lcd/esp_lcd_jd9165.h"
#else
#include "src/lcd/esp_lcd_st7701.h"
#endif
#include "pins_config.h"
#include "lvgl_port_v9.h"
#define BSP_MIPI_DSI_PHY_PWR_LDO_CHAN (3)
#define BSP_MIPI_DSI_PHY_PWR_LDO_VOLTAGE_MV (2500)
#define BSP_LCD_H_RES (LCD_H_RES) // native Panel-Aufloesung
#define BSP_LCD_V_RES (LCD_V_RES)
#define BSP_I2C_NUM (I2C_NUM_1)
#define BSP_I2C_SDA (GPIO_NUM_7)
#define BSP_I2C_SCL (GPIO_NUM_8)
#define BSP_LCD_TOUCH_RST (GPIO_NUM_NC)
#define BSP_LCD_TOUCH_INT (GPIO_NUM_NC)
#define BSP_LCD_RST ((gpio_num_t)LCD_RST)
#define BSP_LCD_BACKLIGHT ((gpio_num_t)LCD_LED)
#define LCD_LEDC_CH LEDC_CHANNEL_0
static i2c_master_bus_handle_t s_i2c_handle = NULL;
void jc_backlight_init(void)
{
const ledc_channel_config_t ch = {
.gpio_num = BSP_LCD_BACKLIGHT,
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LCD_LEDC_CH,
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = 1,
.duty = 0,
.hpoint = 0
};
const ledc_timer_config_t tm = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = LEDC_TIMER_10_BIT,
.timer_num = 1,
.freq_hz = 5000,
.clk_cfg = LEDC_AUTO_CLK
};
ledc_timer_config(&tm);
ledc_channel_config(&ch);
}
void jc_backlight_set(int percent)
{
if (percent > 100) percent = 100;
if (percent < 0) percent = 0;
uint32_t duty = (1023 * percent) / 100;
ledc_set_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH, duty);
ledc_update_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH);
}
IRAM_ATTR static bool on_vsync(esp_lcd_panel_handle_t panel,
esp_lcd_dpi_panel_event_data_t *edata, void *ctx)
{
return lvgl_port_notify_lcd_vsync();
}
#if JC_PANEL_TYPE == JC_PANEL_70
// Der GT911 des 7,0"-Panels liefert Rohkoordinaten im Raster 800x480 (nicht 1024x600).
// Ohne Umrechnung waere nur das linke obere Rechteck erreichbar. Das Hersteller-Beispiel
// skaliert dafuer im Touch-Treiber; hier ueber den vorgesehenen process_coordinates-Hook,
// damit die Vendor-Datei esp_lcd_touch_gt911.c unveraendert bleibt.
#define JC_TOUCH_RAW_H_RES (800)
#define JC_TOUCH_RAW_V_RES (480)
static void jc_touch_scale(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y,
uint16_t *strength, uint8_t *point_num, uint8_t max_point_num)
{
(void)tp; (void)strength; (void)max_point_num;
if (point_num == NULL) return;
for (uint8_t i = 0; i < *point_num; i++) {
x[i] = (uint16_t)(((uint32_t)x[i] * LCD_H_RES) / JC_TOUCH_RAW_H_RES);
y[i] = (uint16_t)(((uint32_t)y[i] * LCD_V_RES) / JC_TOUCH_RAW_V_RES);
}
}
#endif
// Bringt Panel + Touch + LVGL-Port hoch (LVGL laeuft danach in eigenem Task).
void 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);
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;
esp_lcd_panel_io_handle_t io = NULL;
esp_lcd_panel_handle_t disp_panel = NULL;
#if JC_PANEL_TYPE == JC_PANEL_70
// ---------------- 7,0" JD9165 (1024x600) ----------------
esp_lcd_dsi_bus_config_t bus_config = JD9165_PANEL_BUS_DSI_2CH_CONFIG();
esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus);
esp_lcd_dbi_io_config_t dbi_config = JD9165_PANEL_IO_DBI_CONFIG();
esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &dbi_config, &io);
esp_lcd_dpi_panel_config_t dpi_config = JD9165_1024_600_PANEL_60HZ_DPI_CONFIG(LCD_COLOR_PIXEL_FORMAT_RGB565);
dpi_config.num_fbs = LVGL_PORT_LCD_BUFFER_NUMS;
jd9165_vendor_config_t vendor_config = {
.mipi_config = {
.dsi_bus = mipi_dsi_bus,
.dpi_config = &dpi_config,
},
};
esp_lcd_panel_dev_config_t lcd_dev_config = {
.bits_per_pixel = 16,
.rgb_ele_order = ESP_LCD_COLOR_SPACE_RGB,
.reset_gpio_num = BSP_LCD_RST,
.vendor_config = &vendor_config,
};
esp_lcd_new_panel_jd9165(io, &lcd_dev_config, &disp_panel);
#else
// ---------------- 4,3" ST7701 (480x800) ----------------
esp_lcd_dsi_bus_config_t bus_config = ST7701_PANEL_BUS_DSI_2CH_CONFIG();
esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus);
esp_lcd_dbi_io_config_t dbi_config = ST7701_PANEL_IO_DBI_CONFIG();
esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &dbi_config, &io);
esp_lcd_dpi_panel_config_t dpi_config = ST7701_480_360_PANEL_60HZ_DPI_CONFIG(LCD_COLOR_PIXEL_FORMAT_RGB565);
dpi_config.num_fbs = LVGL_PORT_LCD_BUFFER_NUMS;
st7701_vendor_config_t vendor_config = {
.mipi_config = {
.dsi_bus = mipi_dsi_bus,
.dpi_config = &dpi_config,
},
.flags = {
.use_mipi_interface = 1,
},
};
esp_lcd_panel_dev_config_t lcd_dev_config = {
.bits_per_pixel = 16,
.rgb_ele_order = ESP_LCD_COLOR_SPACE_RGB,
.reset_gpio_num = BSP_LCD_RST,
.vendor_config = &vendor_config,
};
esp_lcd_new_panel_st7701(io, &lcd_dev_config, &disp_panel);
#endif
esp_lcd_panel_reset(disp_panel);
esp_lcd_panel_init(disp_panel);
// Alle Framebuffer einmal auf Schwarz loeschen. Im Avoid-Tear-Direct-Mode (mehrere
// Buffer) kopiert LVGL pro Frame nur die geaenderten Bereiche in den naechsten Buffer;
// bis alle Buffer einmal vollstaendig bemalt sind, wuerde sonst uninitialisierter
// Speicher (weisses Rauschen) durchblitzen. Schwarz faellt gegen das dunkle Theme
// nicht auf. Cache-Writeback noetig, da die Buffer im PSRAM liegen und der DMA liest.
{
void *fbs[3] = { NULL, NULL, NULL };
size_t fb_size = (size_t)BSP_LCD_H_RES * BSP_LCD_V_RES * 2; // RGB565 = 2 Byte/Pixel
#if LVGL_PORT_LCD_BUFFER_NUMS >= 3
esp_lcd_dpi_panel_get_frame_buffer(disp_panel, 3, &fbs[0], &fbs[1], &fbs[2]);
#elif LVGL_PORT_LCD_BUFFER_NUMS == 2
esp_lcd_dpi_panel_get_frame_buffer(disp_panel, 2, &fbs[0], &fbs[1]);
#else
esp_lcd_dpi_panel_get_frame_buffer(disp_panel, 1, &fbs[0]);
#endif
for (int i = 0; i < 3; i++) {
if (fbs[i]) {
memset(fbs[i], 0, fb_size);
esp_cache_msync(fbs[i], fb_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
}
}
}
esp_lcd_dpi_panel_event_callbacks_t cbs = {
#if LVGL_PORT_AVOID_TEAR_MODE
.on_refresh_done = on_vsync,
#else
.on_color_trans_done = on_vsync,
#endif
};
esp_lcd_dpi_panel_register_event_callbacks(disp_panel, &cbs, NULL);
esp_lcd_panel_io_handle_t tp_io_handle = NULL;
esp_lcd_touch_handle_t tp_handle;
esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG();
tp_io_config.scl_speed_hz = 100000;
esp_lcd_new_panel_io_i2c(s_i2c_handle, &tp_io_config, &tp_io_handle);
const esp_lcd_touch_config_t tp_cfg = {
.x_max = BSP_LCD_H_RES,
.y_max = BSP_LCD_V_RES,
.rst_gpio_num = BSP_LCD_TOUCH_RST,
.int_gpio_num = BSP_LCD_TOUCH_INT,
.levels = {
.reset = 0,
.interrupt = 0,
},
.flags = {
.swap_xy = 0,
.mirror_x = 0,
.mirror_y = 0,
},
#if JC_PANEL_TYPE == JC_PANEL_70
.process_coordinates = jc_touch_scale,
#endif
};
esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, &tp_handle);
lvgl_port_interface_t interface =
(dpi_config.flags.use_dma2d) ? LVGL_PORT_INTERFACE_MIPI_DSI_DMA
: LVGL_PORT_INTERFACE_MIPI_DSI_NO_DMA;
lvgl_port_init(disp_panel, tp_handle, interface);
}
#endif // JC_USE_REAL_PANEL
-55
View File
@@ -1,55 +0,0 @@
#pragma once
#include "config.h" // liefert JC_PANEL_TYPE (C-sicher, keine Rueckabhaengigkeit)
#define EXAMPLE_LVGL_PORT_TASK_MAX_DELAY_MS 500 //range 2 to 2000
#define EXAMPLE_LVGL_PORT_TASK_MIN_DELAY_MS 5 //range 1 to 100
#define EXAMPLE_LVGL_PORT_TASK_PRIORITY 4
#define EXAMPLE_LVGL_PORT_TASK_STACK_SIZE_KB 32 //KB (erhoeht: komplexe UI, Listen-Rendering, JSON in Callbacks)
#define EXAMPLE_LVGL_PORT_TASK_CORE -1 //range -1 to 1
#define EXAMPLE_LVGL_PORT_TICK 2 //ragne 1 to 100
#define EXAMPLE_LVGL_PORT_AVOID_TEAR_ENABLE 1
#ifdef EXAMPLE_LVGL_PORT_AVOID_TEAR_ENABLE
// 2 = Triple-Buffer + LVGL Full-Refresh: zeichnet bei jeder Aenderung das komplette
// Bild, daher zeigen statische Flaechen (z.B. Tab-Leiste) nie alten Bufferinhalt.
// (Mode 3 = Direct-Mode flackert bei nie neu gezeichneten Bereichen.)
// Bei Rotation 90 nutzen beide Modi ohnehin 3 Framebuffer -> kein Mehrverbrauch.
#define EXAMPLE_LVGL_PORT_AVOID_TEAR_MODE 2 //range 1 to 3
#if JC_PANEL_TYPE == JC_PANEL_70
// 7,0" JD9165: Panel ist nativ 1024x600 Querformat -> keine Rotation, kein PPA noetig.
#define EXAMPLE_LVGL_PORT_ROTATION_DEGREE_ 0 // 0,90,180,270
#define EXAMPLE_LVGL_PORT_PPA_ROTATION_ENABLE 0
#else
// 4,3" ST7701: Panel ist physisch 480x800 Hochformat.
#define EXAMPLE_LVGL_PORT_ROTATION_DEGREE_ 270 // 0,90,180,270 (270 = Querformat 800x480, um 180 Grad gedreht vs. 90)
#define EXAMPLE_LVGL_PORT_PPA_ROTATION_ENABLE 1
#endif
#endif
// LCD_H_RES/LCD_V_RES = NATIVE Panel-Aufloesung (vor der LVGL-Rotation).
#if JC_PANEL_TYPE == JC_PANEL_70
#define LCD_H_RES 1024
#define LCD_V_RES 600
#define LCD_RST 27
#define LCD_LED 23
#else
#define LCD_H_RES 480
#define LCD_V_RES 800
#define LCD_RST 5
#define LCD_LED 23
#endif
#define TP_I2C_SDA 7
#define TP_I2C_SCL 8
#define TP_RST -1
#define TP_INT -1
@@ -1,3 +1,222 @@
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
sie gescheitert sind.
* WS7_COLOR_BITS wieder 24: Die Bridge dieses Panels nimmt kein RGB565 an, mit 16 Bit
kommt kein brauchbares Bild.
* WS7_PARTIAL_REFRESH wieder 0: Der Menü-Vorhang ließ sich nicht mehr öffnen. Er ist
halbtransparent und wird deshalb in den gerade aktiven Bildpuffer eingemischt; die
nächste Zustandsmeldung der S3 zeichnet aber in den zweiten Puffer, der ihn nie
bekommen hat - der Vorhang war also sofort wieder weg. Nutzbar wäre der Modus erst,
wenn der LVGL-Port die geänderten Bereiche zwischen beiden Puffern abgleicht.
- WS7_PARALLEL_RENDER bleibt eingeschaltet: LVGL zeichnet weiterhin mit zwei Threads auf
beiden Prozessorkernen. Von den drei Maßnahmen trägt nur diese.
Version 1.6.4:
- Waveshare 7" (H): Drei Maßnahmen gegen die träge Bedienung am großen Panel. 1280x720
sind 2,4-mal so viele Pixel wie beim 4,3-Zöller, und bis 1.6.3 wurde bei jeder Änderung
das komplette Bild in 24 Bit neu gezeichnet.
* Farbtiefe RGB565 statt RGB888 (WS7_COLOR_BITS): halbiert die Datenmenge je Bild.
Feinere Farbabstufungen entfallen, sichtbar allenfalls in den dunklen Verläufen der
Rundanzeige - die JC-Panels laufen seit jeher so.
* Nur geänderte Bildbereiche neu zeichnen statt des ganzen Bildes
(WS7_PARTIAL_REFRESH, LVGL-Direct-Mode mit zwei Puffern). Eine sich ändernde
Temperaturanzeige kostet damit ein paar tausend statt 921.600 Pixel.
* LVGL zeichnet mit zwei Threads auf beiden Prozessorkernen (WS7_PARALLEL_RENDER).
- Jeder der drei Schalter steht in pins_config.h und lässt sich einzeln zurückstellen;
die README nennt zu jedem, woran man erkennt, dass er zurück muss. Die JC-Panels sind
von allen dreien nicht betroffen.
- Nebeneffekt: Der Framebuffer-Bedarf sinkt von rund 8,3 MB auf 3,7 MB PSRAM.
Version 1.6.3:
- Waveshare ESP32-P4-Pico: UART zur Hauptplatine liegt jetzt auf TX = GPIO20 und
RX = GPIO21 (vorher GPIO17/GPIO18). Die JC-Panels bleiben bei GPIO33/GPIO31.
- Das Bild steht in der tatsächlichen Einbaulage richtig herum, die 180-Grad-Drehung aus
1.6.1 ist deshalb wieder abgeschaltet (WS7_ROTATE_180 = 0). Sie bleibt als Schalter
erhalten, falls das Panel später anders montiert wird.
- Der Touch war dagegen oben/unten spiegelverkehrt: Der Digitizer sitzt gegenüber dem Bild
um die Hochachse gedreht. WS7_TOUCH_MIRROR_RAW_X steht dafür jetzt auf 1. Bild- und
Touch-Ausrichtung sind damit zwei getrennte Schalter, weil sie an diesem Panel eben
nicht zusammenfallen.
Version 1.6.2:
- Kommt das Panel nicht hoch, stürzt der P4 nicht mehr wortlos ab. Die Bringup-Schritte
melden ihren Fehler jetzt im Klartext auf der seriellen Konsole (auch bei abgeschaltetem
Core-Debug-Level), zusammen mit PSRAM-Größe, freiem PSRAM und dem tatsächlich benötigten
Framebuffer-Bedarf. Vorher endete ein fehlgeschlagener Panel-Aufbau in einem
Speicherauszug, aus dem die Ursache nicht hervorging.
- Schlägt der Panel-Aufbau fehl, läuft die Firmware ohne Anzeige weiter, statt ein zweites
Mal abzustürzen: UART-Verbindung und OTA bleiben offen, die S3 kann also neu flashen.
Alle Oberflächenfunktionen prüfen dafür, ob das Dashboard überhaupt aufgebaut wurde.
- Fehlerbehebung: Findet der Touch-Controller nicht statt, lieferte der Hersteller-Treiber
einen bereits freigegebenen Zeiger zurück, der ungeprüft weiterverwendet wurde. Das
Display läuft in diesem Fall jetzt einfach ohne Bedienung weiter.
Version 1.6.1:
- Waveshare 7" (H): Bild und Touch lassen sich um 180 Grad drehen, wenn das Panel auf dem
Kopf eingebaut ist. Schalter WS7_ROTATE_180 in pins_config.h, Vorgabe ist gedreht.
Die Drehung übernimmt der PPA-Grafikbeschleuniger des ESP32-P4 - die Software-Rotation
des LVGL-Ports rechnet nur in RGB565 und wäre für dieses Panel unbrauchbar.
- Der Touch dreht mit, sonst läge die Bedienung spiegelbildlich zum Bild.
Version 1.6.0:
- Neu: Dieselbe Firmware läuft jetzt auch auf einem Waveshare ESP32-P4-Pico mit dem
Waveshare 7inch DSI LCD (H) (1280x720). Umgeschaltet wird über „JC_PANEL_TYPE" in
config.h; WS_PANEL_7H ist ab dieser Version die Vorgabe, JC_PANEL_43 und JC_PANEL_70
bleiben unverändert verfügbar.
- Das Waveshare-Panel hängt hinter einer Bridge, die ausschließlich RGB888 annimmt. LVGL
rechnet für dieses Panel deshalb mit 24 statt 16 Bit Farbtiefe. lv_conf.h liest dazu
JC_PANEL_TYPE aus config.h, damit Sketch und LVGL-Bibliothek garantiert dieselbe
Farbtiefe benutzen; display_hal.cpp bricht den Build ab, falls sie auseinanderlaufen.
Der Panelwechsel muss aus diesem Grund in config.h erfolgen und nicht per Compiler-Flag.
- Bringup ohne Hersteller-Panel-Treiber: DSI-Bus, Kommandokanal und DPI-Panel werden direkt
angelegt. Entscheidend ist die Legacy-Referenztaktquelle PLL_F20M - mit der Standardquelle
bleibt der Bildschirm auf ESP32-P4 Rev. 1.3 / ECO2 schwarz. Die Zeitbasis (2 Lanes zu
1250 Mbit/s, 80 MHz DPI-Takt, Austastlücken 64/64/64, rund 60 Hz) steht als WS7_*-Werte
in pins_config.h und ist dort anpassbar, falls das Bild reißt.
- Panel-Freigabe und Helligkeit laufen beim Waveshare nicht über einen PWM-Pin, sondern über
Register der Bridge auf I2C-Adresse 0x45. Die Hintergrundbeleuchtung wird bewusst erst
eingeschaltet, wenn die DSI-Ausgabe steht - sonst blitzt beim Start Bildrauschen auf.
Standby-Abdunklung und „Uhrzeit im Standby" funktionieren wie bei den JC-Panels.
- Touch: Der GT9271 des Waveshare-Panels benutzt dieselbe Registerbelegung wie der GT911,
liegt aber auf I2C-Adresse 0x14 und meldet im Hochformat. X und Y werden deshalb getauscht
und auf die Bildfläche begrenzt; Ausreißer des Controllers landen nicht mehr als Klick am
Bildrand. Sollte die Bedienung spiegelverkehrt reagieren, lässt sich das mit
WS7_TOUCH_MIRROR_RAW_X / _Y in pins_config.h umdrehen.
- Der Framebuffer wächst auf 3 x 2,8 MB (rund 8,3 MB PSRAM). Auf dem P4-Pico mit 32 MB
PSRAM ist das unkritisch.
- Die UART-Pins zur Hauptplatine sind für das Waveshare-Board getrennt eingestellt, weil
dessen 40-poliger Header eine andere Belegung hat als die JC-Panels: TX = GPIO17,
RX = GPIO18 (JC-Panels unverändert TX = GPIO33, RX = GPIO31).
Version 1.5.0:
- Neu: Dieselbe Firmware unterstützt jetzt auch das 7-Zoll-Display Guition JC1060P470C-I-W
(JD9165, 1024x600) zusätzlich zum bisherigen 4,3-Zöller JC4880P443C-I-W (ST7701, 480x800).

Some files were not shown because too many files have changed in this diff Show More