# Bekannte Einschränkungen und Risiken Diese Liste beschreibt den aktuellen Implementierungsstand. Sie ist keine Liste bereits umgesetzter Features. ## Flash-Reservierung stimmt nicht vollständig mit dem NVM-Zugriff überein Die Firmware liest und schreibt: ```text 0x1FB00..0x1FCFF Makros (512 Byte) 0x1FD00..0x1FFFF Config (768 Byte, davon 740 Byte genutzt) ``` Das aktive Linker-Skript `flash_without_bootloader.ld` erlaubt Firmware jedoch bis einschließlich `0x1FDFF` und reserviert nur `0x1FE00..0x1FFFF`. Damit sind `0x1FB00..0x1FDFF` nicht gegen ein zukünftig wachsendes Firmware-Image geschützt. Das aktuelle Image liegt deutlich darunter, aber der Build prüft diese NVM-Grenze nicht. Das Bootloader-Linker-Skript reserviert aktuell gar keinen separaten NVM-Bereich. Das auskommentierte USB-Bootloader-Environment ist daher kein unterstütztes Ziel. Die aktive Boarddatei benennt die MCU als `samd21g17d`, setzt für den Arduino-Core aber weiterhin das Kompatibilitätsmakro `__SAMD21G18A__`. Der PlatformIO-Build meldet korrekt 128 KiB Flash und 16 KiB RAM; vor device-spezifischen Änderungen sollte diese historische Makro-Abweichung trotzdem geprüft werden. ## Event-Queue hat gemischte Producer Matrixevents werden im Loop erzeugt, Encoderevents in EIC-Interrupts. Beide rufen `CEventQueue::push()` auf und verändern denselben Tail-Index ohne Interruptschutz. Ein Encoderinterrupt kann einen Matrix-Push unterbrechen. Die bisherige Annahme eines reinen Single-Producer/Single-Consumer-Ringbuffers ist deshalb nicht vollständig erfüllt; seltene verlorene oder überschriebene Events sind theoretisch möglich. Zusätzlich werden Events bei voller Queue still verworfen. ## `HOST_COMMAND` nutzt seine `data` nicht `SAction.data` ist für `ActionType::HOST_COMMAND` vorhanden, wird in `execute_action_down()` aber nicht übertragen. Gesendet wird nur `USB_EVT_KEY_DOWN (0x81)` mit der Matrix-Key-ID beziehungsweise Encoder-ID. `USB_EVT_KEY_UP (0x82)`, `USB_EVT_ENC_CW (0x83)` und `USB_EVT_ENC_CCW (0x84)` sind definiert, werden vom aktuellen Controller aber nicht gesendet. Bei Encoder-Host-Actions geht dadurch die Richtung im gesendeten Paket verloren, sofern die Host-Anwendung sie nicht anderweitig aus der konfigurierten Action ableitet. ## HID-Holds sind global Der Keyboard-Report enthält zwar sechs Keycode-Felder, die Implementierung setzt aber nur das erste. Jeder neue `HID_KEY`-Down ersetzt den vorherigen Report; jedes Release sendet einen komplett leeren Report. Analog existiert nur ein globaler Consumer-Usage-Wert. Gleichzeitige unabhängige Holds werden daher nicht korrekt verwaltet. ## CDC-Transfers sind nur schwach validiert - `BEGIN` speichert die angekündigte Chunkzahl, `COMMIT` vergleicht sie aber nicht mit empfangenen Chunks. - Doppelte, fehlende oder ungeordnete Chunks werden nicht verfolgt. - Config-Commit prüft Magic, Version und CRC, aber keine Feldwerte oder Enum-Bereiche. - Makro-Commit hat weder CRC noch Vollständigkeitsprüfung. - Das 8-Byte-Protokoll besitzt kein Framing. Ein verlorenes oder zusätzliches Byte desynchronisiert alle folgenden Pakete. Insbesondere kann ein formal CRC-korrektes Profil ungültige Animationswerte enthalten. `PULSE` benötigt in der aktuellen Arithmetik eine Periode von mindestens 2 ms; dieser Mindestwert wird nicht validiert. ## Farbanimationen umgehen Teile der Helligkeits-/Override-Logik Globale und LED-spezifische Helligkeit werden beim Laden in die Base-Farbe eingerechnet. `COLOR_CYCLE` berechnet RGB dagegen direkt mit festen 40 % Helligkeit und ignoriert Base-Farbe sowie Override. `COLOR_FADE` benötigt den separaten Aufruf `set_color_fade()`; das reine Laden des Enum-Werts aus einer Config setzt keine Start- und Zielfarbe. ## Reservierte beziehungsweise noch ungenutzte Hardware und Felder - Die drei Fader-Pins sind im Variant und in `config/pins.h` definiert, werden von der Firmware aber nicht eingelesen. - `enc_sensitivity[4]` wird gespeichert und mit Default `1` befüllt, beeinflusst die Encoderdekodierung derzeit aber nicht. - `SET_LED_BASE` verändert nur den RAM-Zustand und wird nicht in NVM persistiert. ## Zeitverhalten Makros und Encoder-Taps verwenden blockierende `delay()`-Aufrufe. Startsignal, Werksreset-Feedback und NVM-Operationen blockieren ebenfalls den Loop. Während dessen werden Matrix und CDC nicht bearbeitet; Encoder-ISRs können weiter Events erzeugen, bis die Queue voll ist.