#pragma once #include "config.h" // liefert JC_PANEL_TYPE (C-sicher, keine Rueckabhaengigkeit) // ------------------------------------------------------------------------------------- // Waveshare 7" (H): Einbaulage. Haengt das Panel auf dem Kopf (Flachbandkabel oben statt // unten), dreht 1 das Bild UND den Touch um 180 Grad. In der aktuellen Einbaulage steht // das Bild richtig herum -> 0. Der Touch braucht davon unabhaengig eine Spiegelung, // siehe WS7_TOUCH_MIRROR_RAW_X weiter unten. // ------------------------------------------------------------------------------------- #define WS7_ROTATE_180 0 // ------------------------------------------------------------------------------------- // Waveshare 7" (H): Tempo-Schalter // // 1280x720 ist gegenueber den JC-Panels ein Vielfaches an Pixeln. Die drei Schalter // senken die Last und lassen sich einzeln zurueckstellen, falls einer Aerger macht. // // WS7_COLOR_BITS 24 = RGB888. GEPRUEFT: Die Bridge dieses Panels nimmt KEIN RGB565 // an - mit 16 kommt kein brauchbares Bild. Einstellbar bleibt es // nur, weil andere Waveshare-Panels an derselben Firmware // haengen koennten. // 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 // 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, dessen Inhalt // danach kopiert wird. GEPRUEFT: bringt an diesem Panel nichts (die Bildaufbauzeit blieb bei // 240-300 ms) und erzeugt Bildfehler, weil in denselben Speicher gezeichnet wird, aus dem // gerade angezeigt wird. Der Flaschenhals liegt also nicht im Kopieren, sondern im Zeichnen // selbst. Bleibt als Schalter erhalten, damit der Versuch nicht erneut gemacht wird. #define WS7_DIRECT_FB 0 #define WS7_PARALLEL_RENDER 1 #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 // 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 // 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. // Beim Waveshare-Panel waere Vollbild-Neuzeichnen bei 1280x720 zu teuer -> Mode 3 // (Direct-Mode, zwei Puffer, nur geaenderte Bereiche), siehe WS7_PARTIAL_REFRESH. #if (JC_PANEL_TYPE == WS_PANEL_7H) && WS7_PARTIAL_REFRESH #define EXAMPLE_LVGL_PORT_AVOID_TEAR_MODE 3 //range 1 to 3 #else #define EXAMPLE_LVGL_PORT_AVOID_TEAR_MODE 2 //range 1 to 3 #endif #if JC_PANEL_TYPE == WS_PANEL_7H // Waveshare 7" (H): Panel ist nativ 1280x720 Querformat. Bei Einbau auf dem Kopf wird um // 180 Grad gedreht - das erledigt der PPA-Grafikbeschleuniger, der auch RGB888 kann // (die Software-Rotation des Ports rechnet nur in RGB565). #if WS7_ROTATE_180 #define EXAMPLE_LVGL_PORT_ROTATION_DEGREE_ 180 // 0,90,180,270 #define EXAMPLE_LVGL_PORT_PPA_ROTATION_ENABLE 1 #else #define EXAMPLE_LVGL_PORT_ROTATION_DEGREE_ 0 #define EXAMPLE_LVGL_PORT_PPA_ROTATION_ENABLE 0 #endif #elif 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 == WS_PANEL_7H #define LCD_H_RES 1280 #define LCD_V_RES 720 // Das Waveshare-Panel hat weder einen Reset-Pin noch eine PWM-Hintergrundbeleuchtung: // Reset macht die Bridge selbst, die Helligkeit laeuft ueber deren I2C-Register. #define LCD_RST (-1) #define LCD_LED (-1) // ---- MIPI-DSI-Parameter des Waveshare 7inch DSI LCD (H) ----------------------------- // Uebernommen aus dem funktionierenden Funktionstest-Sketch. Wichtig ist die Legacy- // Referenztaktquelle PLL_F20M: nur damit liefert der ESP32-P4 Rev. 1.3 / ECO2 ein Bild. // Das Panel akzeptiert nur RGB888 (24 Bit) - deshalb rechnet LVGL bei diesem Panel // ebenfalls mit 24 Bit (lv_conf.h). #define WS7_DSI_LANES 2 #define WS7_DSI_LANE_MBPS 1250 #define WS7_DPI_CLOCK_MHZ 80 // 1472 x 912 Gesamtraster -> ca. 60 Hz #define WS7_HSYNC_BACK 64 #define WS7_HSYNC_PULSE 64 #define WS7_HSYNC_FRONT 64 #define WS7_VSYNC_BACK 64 #define WS7_VSYNC_PULSE 64 #define WS7_VSYNC_FRONT 64 // Bridge (Helligkeit/Panel-Freigabe) und Touch-Controller am selben I2C-Bus wie GT911. #define WS7_BRIDGE_I2C_ADDR 0x45 #define WS7_TOUCH_I2C_ADDR 0x14 // GT9271 // DCS-Register MADCTL beim Panelstart. Ob die Bridge dieses Panels es auswertet, ist // nicht bekannt; die 180-Grad-Drehung macht deshalb der PPA (WS7_ROTATE_180). #define WS7_MADCTL 0x00 // Der GT9271 meldet im Hochformat: Roh-X 0..720, Roh-Y 0..1280. Fuer das Querformat // werden die Achsen getauscht. Die Spiegelung geschieht VOR dem Tausch, also noch auf den // Rohwerten: Roh-X wird zur Bildschirmhoehe, Roh-Y zur Bildschirmbreite. // WS7_TOUCH_MIRROR_RAW_X = 1 -> dreht OBEN/UNTEN um // WS7_TOUCH_MIRROR_RAW_Y = 1 -> dreht LINKS/RECHTS um // Der Digitizer dieses Panels sitzt gegenueber dem Bild um die Hochachse gedreht, deshalb // ist oben/unten dauerhaft aktiv. #define WS7_TOUCH_RAW_X_MAX 720 #define WS7_TOUCH_RAW_Y_MAX 1280 #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 // Pause zwischen den beiden Helligkeitsuebernahmen der Bridge. Sie uebernimmt eine neue // Helligkeit nicht zuverlaessig beim ersten Mal; der Beispielcode von Waveshare setzt sie // darum zweimal. Ohne die Wiederholung stand das Bild fertig da, blieb aber dunkel - beim // Wechsel in den und aus dem Standby mehrere Sekunden lang. Der Beispielcode wartet 100 ms; // weniger genuegt hier, weil die Wiederholung ohnehin folgt. Bleibt die Beleuchtung wieder // hinterher, diesen Wert erhoehen. #define WS7_BACKLIGHT_LATCH_MS 20 // 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 #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