8.1.4. Firmware
Die Firmware macht aus dem ESP32-Touchdisplay ein konfigurierbares USB-Bedienpanel. Sie zeichnet die Seiten, verarbeitet Berührungen, sendet Eingaben an den Computer und speichert die Konfiguration für den nächsten Start.
Der beschriebene Entwicklungsstand vom 8. November 2026 verwendet ESP-IDF 5.5.2, LVGL 8.4.0 und esp_tinyusb 2.2.0. Die Touchanbindung erfolgt über den GT911-Treiber. Die konkreten Abhängigkeiten stehen in main/idf_component.yml.
| Datei | Aufgabe |
|---|---|
main/main.c |
Start, Oberfläche, Buttonaktionen, Navigation und Displaytimeout |
main/pad_config.c |
Konfigurationsprüfung, Migration, Speicherung und CDC-Protokoll |
main/media_hid.c |
USB-Deskriptoren und HID-Ausgabe |
main/pad_profiles.c |
Sichtbare Seiten und laufende Profilauswahl |
main/app_commands.c |
Geräterequests für Programmbefehle und deren Rückmeldungen |
main/key_editor.c |
Bearbeitung einer Tastaturbelegung direkt auf dem Gerät |
main/lvgl_port.c und main/pad_display.c |
LVGL-Anbindung, Bildrotation und Touchtransformation |
main/waveshare_rgb_lcd_port.c |
Boardbezogene Anbindung von Display und Touch |
Beim Start initialisiert die Firmware die Konfiguration, das Display und USB. LVGL läuft in einer eigenen FreeRTOS-Task. Ein Timer der Oberfläche verarbeitet alle 20 Millisekunden unter anderem das Konfigurationsprotokoll, ausstehende Profilwechsel und Fristen für Programmbefehle. HID-Tastendrücke werden über eine eigene Queue und Task ausgegeben.
Eine Seite enthält Buttons auf einem Koordinatenraster. Jeder Button besitzt eine Zeile, eine Spalte, eine Breite und eine Höhe. Die Koordinaten beginnen bei eins. Freie Flächen bleiben erhalten, und rechteckige Buttons können mehrere Rasterzellen belegen.
Die Validierung weist Überlappungen und Platzierungen außerhalb der Seitenkapazität zurück. Bis zu 16 Seiten mit jeweils höchstens 160 Buttons sind vorgesehen. Die logischen Grenzen reichen bis 100 Spalten und 1000 Zeilen. In der Praxis begrenzt außerdem das gemeinsame Konfigurationsbudget, wie viele Elemente zusammen gespeichert werden können.
Es gibt vier Aktionstypen. key sendet eine Tastaturtaste mit Modifiern, consumer eine Medienaktion, wiggle schaltet die periodische Mausbewegung und command fordert einen benannten Programmbefehl beim Desktop an.
Kurzes Tippen führt die Aktion aus. Langes Drücken öffnet bei Tastaturbuttons den Tasten- und Iconeditor. Medien- und Programmbuttons zeigen eine Beschreibung. Der Mausbewegungsbutton öffnet seine Einstellungen. Horizontales Wischen wechselt zwischen sichtbaren Seiten, vertikales Wischen scrollt überlange Seiteninhalte.
Jede Seite kann mit 0°, 90°, 180° oder 270° dargestellt werden. Die Rotation gilt auch für die zugehörigen Geräteeditoren und Touchziele. Ein begonnener Seitenwechsel verwendet bis zum Loslassen die Orientierung der Ausgangsseite. Anschließend übernimmt die Darstellung die Orientierung der Zielseite.
Die Umsetzung verwendet einen logischen Vollbildpuffer in PSRAM und zwei physische RGB-Ausgabepuffer. Die Firmware kopiert das Bild mit der gewünschten Rotation in den nächsten Ausgabepuffer und synchronisiert die Verwendung mit dem Displaytreiber. Für Touchereignisse berechnet sie die inverse Transformation.
Der zusätzliche logische RGB565-Puffer benötigt bei 800 × 480 Pixeln 768.000 Byte. Diese Umsetzung erklärt, warum PSRAM für die konkrete Firmware wesentlich ist. Framerate, Displayartefakte und die Genauigkeit der Touchbedienung müssen zusätzlich am Gerät erprobt werden.
Die Konfiguration wird als JSON im NVS-Speicher abgelegt. Die eingebettete main/default_config.json dient als Werkskonfiguration. Sie enthält unter anderem Mediensteuerung und eine Seite mit F13–F24.
Ein Schreibzugriff wird zunächst validiert und erst nach erfolgreichem Speichern aktiviert. Fehlerhafte oder zu große Konfigurationen ersetzen den aktiven Stand nicht. Änderungen direkt am Gerät können über eine bestehende Subscription an den Desktop gemeldet werden.
Die vollständige serialisierte Konfiguration muss kleiner als 48.896 Byte bleiben. Bilder sind RGB565-Ressourcen mit maximal 64 × 64 Pixeln. Bis zu 32 Ressourcen sind vorgesehen, sie teilen sich aber das Budget mit Seiten, Buttons und Profilen.
Ältere Konfigurationen mit gepackten Zeilen können beim Start in das aktuelle Rasterformat migriert werden. Vorhandene Konfigurationsidentität und gespeicherter Inhalt bleiben dabei zunächst erhalten. Die migrierte Darstellung wird erst durch eine ausdrückliche Übertragung oder eine normale lokale Änderung gespeichert. Der aktuelle Austausch mit dem Desktop verlangt Schema 3 und Protokoll 4.
Profile blenden ausgewählte Seiten aus. Der Wechsel verändert einen Laufzeitzustand und schreibt deshalb nicht bei jeder Auswahl den Flash. Während einer Berührung oder eines offenen Geräteeditors wartet eine angeforderte Auswahl. Beim Einschalten beginnt das Gerät mit dem festgelegten Standardprofil.
Der Displaytimeout schaltet die Hintergrundbeleuchtung aus und reduziert die CPU-Frequenz von 240 auf 80 MHz. USB, Touchabfrage und Mausbewegung bleiben aktiv. Die erste Berührung stellt 240 MHz und die Beleuchtung wieder her. Sie wird zum Aufwecken verwendet und löst keine Taste aus.
Für einen Build wird die zum Projekt passende ESP-IDF-Umgebung aktiviert. Danach werden die Befehle im Firmwareverzeichnis ausgeführt.
idf.py build
sh tests/run.sh
Die nativen C-Tests benötigen IDF_PATH für cJSON und verwenden AddressSanitizer sowie UndefinedBehaviorSanitizer. Sie behandeln unter anderem Konfiguration, Speicherfehler, Befehlsrückmeldungen, Profile, Rastermigration und Displaytransformation.
Zum Flashen wird der tatsächliche Geräteport eingesetzt.
DEVICE_PORT='<Geräteport>'
idf.py -p "$DEVICE_PORT" flash
Die eigene Partitionstabelle enthält 280 KiB NVS und eine 2-MiB-Anwendungspartition. Wegen des gegenüber dem Prototyp geänderten Anwendungsoffsets ist der vollständige Build einschließlich Partitionstabelle zu flashen. Die Desktop-Anwendung übernimmt diesen Schritt bislang nicht.
Zur Erprobung am Gerät gehören anschließend USB-Tasten, Mediensteuerung, Seitenwechsel, lange Berührungen, Profile, Rotation, Displaytimeout und die gespeicherte Konfiguration nach einem Neustart. Die Beschreibung des Quellstands ersetzt diese Hardwareprüfung nicht. Weitere Schritte stehen im Kapitel Nachbauen und Weiterentwickeln.