From 72b47f6dd6eb05c88009062680fd6664c5d97c61 Mon Sep 17 00:00:00 2001 From: raw-designs Date: Tue, 1 Sep 2026 03:11:10 +0200 Subject: [PATCH] fix(P4): Waveshare-Panel um 180 Grad gedreht ausgeben (1.6.1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Claude-Session: https://claude.ai/code/session_018QoLDQeUh1dCQz7yYZVb4Y --- JC_Display_Firmware/Changelog.txt | 7 +++++++ JC_Display_Firmware/README.md | 6 +++++- JC_Display_Firmware/board_bringup.c | 14 +++++++++++--- JC_Display_Firmware/config.h | 2 +- JC_Display_Firmware/pins_config.h | 22 ++++++++++++++++++++-- 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/JC_Display_Firmware/Changelog.txt b/JC_Display_Firmware/Changelog.txt index 0205c31..66c6e3d 100644 --- a/JC_Display_Firmware/Changelog.txt +++ b/JC_Display_Firmware/Changelog.txt @@ -1,3 +1,10 @@ +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 diff --git a/JC_Display_Firmware/README.md b/JC_Display_Firmware/README.md index 29c744b..211be90 100644 --- a/JC_Display_Firmware/README.md +++ b/JC_Display_Firmware/README.md @@ -45,7 +45,7 @@ Vendor-Pakete: 4,3" im Ordner `JC4880P443C_I_W/`, 7,0" im Repo-Ordner | WLAN/BT (hier ungenutzt) | ESP32-C6 | ESP32-C6 | — (kein Funkmodul) | | Display | ST7701, 480×800 IPS, MIPI-DSI | JD9165, 1024×600 IPS, MIPI-DSI | 1280×720 IPS, MIPI-DSI 2 Lanes über Waveshare-Bridge | | Farbformat | RGB565 | RGB565 | **RGB888** (Bridge nimmt nichts anderes) | -| LVGL-Ausrichtung | Rotation **270°** (PPA) → 800×480 | **keine** Rotation, nativ 1024×600 | **keine** Rotation, nativ 1280×720 | +| LVGL-Ausrichtung | Rotation **270°** (PPA) → 800×480 | **keine** Rotation, nativ 1024×600 | nativ 1280×720, bei Einbau auf dem Kopf **180°** (PPA) | | Touch | GT911, I²C SDA=GPIO7 / SCL=GPIO8 | GT911, I²C SDA=GPIO7 / SCL=GPIO8 | **GT9271** (I²C-Adresse **0x14**), SDA=GPIO7 / SCL=GPIO8 | | 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) | @@ -67,6 +67,10 @@ Das Panel hängt hinter einer Waveshare-Bridge und braucht **keinen** Hersteller - Reihenfolge: Bridge-Grundinitialisierung (`C0`/`C2`/`AC`) → DSI → DCS `MADCTL`/`Sleep Out`/ `Display On` → DPI-Start → **erst dann** Hintergrundbeleuchtung. Wird das Licht früher eingeschaltet, blitzt beim Start Bildrauschen auf. +- **Einbaulage:** `WS7_ROTATE_180` in [`pins_config.h`](pins_config.h) dreht Bild **und** + Touch um 180°, wenn das Panel auf dem Kopf montiert ist (Vorgabe: gedreht). Die Drehung + macht der PPA-Grafikbeschleuniger; die Software-Rotation des LVGL-Ports beherrscht nur + RGB565 und käme für dieses Panel nicht in Frage. > Beim 7-Zöller ist die Expansion-IO **kein Stiftleisten-Header**, sondern eine > FPC-Buchse (1,0 mm Raster, 16-polig) — für die UART-Verdrahtung wird ein diff --git a/JC_Display_Firmware/board_bringup.c b/JC_Display_Firmware/board_bringup.c index 97dfb94..3332d85 100644 --- a/JC_Display_Firmware/board_bringup.c +++ b/JC_Display_Firmware/board_bringup.c @@ -181,8 +181,15 @@ static void ws7_touch_map(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y, #endif // Achsentausch + Begrenzung auf die Bildflaeche (der GT9271 liefert vereinzelt // Ausreisser, die sonst als Klick am Rand ankaemen). - x[i] = (raw_y >= LCD_H_RES) ? (LCD_H_RES - 1) : raw_y; - y[i] = (raw_x >= LCD_V_RES) ? (LCD_V_RES - 1) : raw_x; + uint16_t px = (raw_y >= LCD_H_RES) ? (LCD_H_RES - 1) : raw_y; + uint16_t py = (raw_x >= LCD_V_RES) ? (LCD_V_RES - 1) : raw_x; +#if WS7_ROTATE_180 + // 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 + x[i] = px; + y[i] = py; } } #endif @@ -283,7 +290,8 @@ void jc_board_bringup(void) // ins Leere greifen. { uint8_t zero = 0x00; - esp_lcd_panel_io_tx_param(io, 0x36, &zero, 1); // MADCTL + 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 diff --git a/JC_Display_Firmware/config.h b/JC_Display_Firmware/config.h index b1541e6..fab1ab1 100644 --- a/JC_Display_Firmware/config.h +++ b/JC_Display_Firmware/config.h @@ -126,7 +126,7 @@ // ------------------------------------------------------------------------------------- // Firmware // ------------------------------------------------------------------------------------- -#define DISPLAY_FW_VERSION "1.6.0" // Firmware-Stand der P4-Display-Steuerung (Info-Seite) +#define DISPLAY_FW_VERSION "1.6.1" // Firmware-Stand der P4-Display-Steuerung (Info-Seite) // ------------------------------------------------------------------------------------- // Protokoll diff --git a/JC_Display_Firmware/pins_config.h b/JC_Display_Firmware/pins_config.h index 7fd94ab..81fa2a9 100644 --- a/JC_Display_Firmware/pins_config.h +++ b/JC_Display_Firmware/pins_config.h @@ -2,6 +2,13 @@ #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. Auf 0 setzen, wenn das Panel +// andersherum eingebaut wird. +// ------------------------------------------------------------------------------------- +#define WS7_ROTATE_180 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 @@ -19,9 +26,16 @@ #define EXAMPLE_LVGL_PORT_AVOID_TEAR_MODE 2 //range 1 to 3 #if JC_PANEL_TYPE == WS_PANEL_7H -// Waveshare 7" (H): Panel ist nativ 1280x720 Querformat -> keine Rotation, kein PPA noetig. -#define EXAMPLE_LVGL_PORT_ROTATION_DEGREE_ 0 // 0,90,180,270 +// 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 @@ -64,6 +78,10 @@ #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. Zeigt der Cursor spiegelverkehrt, hier die passende // Achse auf 1 setzen (die Spiegelung geschieht VOR dem Tausch, auf den Rohwerten).