Files
Dual-PID/JC_Display_Firmware/display_hal.cpp
T
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

86 lines
3.7 KiB
C++

// =====================================================================================
// display_hal.cpp - LVGL-Glue fuer JC4880P443C-I-W / JC1060P470C-I-W / Waveshare 7" (H)
// =====================================================================================
// Realer Modus: nutzt die Hersteller-Portierung. Der eigentliche esp_lcd-Bringup liegt
// bewusst in board_bringup.c (C). Hier nur die LVGL-/UI-Verdrahtung.
// =====================================================================================
#include <Arduino.h>
#include <lvgl.h>
#include "display_hal.h"
#include "ui.h"
#include "config.h"
// LVGL muss mit derselben Farbtiefe uebersetzt sein wie das Panel erwartet. Zieht der
// Build versehentlich eine fremde lv_conf.h (z.B. eine alte Datei neben dem lvgl-Ordner),
// faellt das hier auf - sonst erst am schwarzen oder farbverfaelschten Bild.
#if JC_PANEL_TYPE == WS_PANEL_7H
static_assert(LV_COLOR_DEPTH == 24, "Waveshare 7\" (H) braucht RGB888 - falsche lv_conf.h?");
#else
static_assert(LV_COLOR_DEPTH == 16, "JC-Panels brauchen RGB565 - falsche lv_conf.h?");
#endif
static ProtocolClient* g_client = nullptr;
// =====================================================================================
#if JC_USE_REAL_PANEL
// =====================================================================================
// ECHTE HARDWARE - Bringup in board_bringup.c, LVGL-Mutex im Hersteller-Port.
// =====================================================================================
extern "C" {
void jc_board_bringup(void); // board_bringup.c
void jc_backlight_set(int percent); // board_bringup.c
bool lvgl_port_lock(int timeout_ms); // lvgl_port_v9.c (Vendor-BSP)
void lvgl_port_unlock(void); // lvgl_port_v9.c (Vendor-BSP)
}
void hal_init(ProtocolClient* client) {
g_client = client;
jc_board_bringup(); // Panel + Touch + LVGL-Port (eigener Task)
jc_backlight_set(100);
if (lvgl_port_lock(-1)) { // UI im LVGL-Kontext aufbauen
ui_init(g_client);
lvgl_port_unlock();
}
}
void hal_loop() { /* LVGL laeuft im Port-Task - hier nichts zu tun. */ }
void hal_lock() { lvgl_port_lock(-1); }
void hal_unlock(){ lvgl_port_unlock(); }
void hal_backlight(int percent) { jc_backlight_set(percent); }
// =====================================================================================
#else // JC_USE_REAL_PANEL == 0
// =====================================================================================
// STUB-MODUS - minimales LVGL ohne Panel/Touch (zum Testen von Protokoll/Logik).
// =====================================================================================
#define HAL_BUF_LINES 40
#define HAL_BYTES_PER_PX (LV_COLOR_DEPTH / 8)
static uint8_t s_buf1[DISP_HOR_RES * HAL_BUF_LINES * HAL_BYTES_PER_PX];
static lv_display_t* s_disp = nullptr;
static uint32_t hal_tick_cb(void) { return (uint32_t)millis(); }
static void stub_flush_cb(lv_display_t* disp, const lv_area_t* area, uint8_t* px_map) {
(void)area; (void)px_map;
lv_display_flush_ready(disp); // Pixel werden verworfen (kein Panel)
}
void hal_init(ProtocolClient* client) {
g_client = client;
lv_init();
lv_tick_set_cb(hal_tick_cb);
s_disp = lv_display_create(DISP_HOR_RES, DISP_VER_RES);
lv_display_set_flush_cb(s_disp, stub_flush_cb);
lv_display_set_buffers(s_disp, s_buf1, nullptr, sizeof(s_buf1),
LV_DISPLAY_RENDER_MODE_PARTIAL);
ui_init(g_client);
}
void hal_loop() { lv_timer_handler(); }
void hal_lock() { /* kein Port-Task -> kein Lock noetig */ }
void hal_unlock(){ }
void hal_backlight(int percent) { (void)percent; /* kein Panel im Stub-Modus */ }
#endif // JC_USE_REAL_PANEL