# DeviceConfig & MacroTable **Datei:** `DeviceConfig.cs` ## Überblick C#-Spiegel der Firmware-Structs. Muss byte-kompatibel mit `SDeviceConfig` (nvm_config.h) und `SMacroTable` (macro_config.h) sein. --- ## DeviceConfig ### Felder | Feld | Typ | Inhalt | |---|---|---| | `ActiveProfileIndex` | `byte` | Aktives Profil (0–2) | | `GlobalBrightness` | `byte` | Globale LED-Helligkeit (0–255) | | `MxActions[20]` | `DeviceAction[]` | Aktionen für MX-Buttons 0–19 (aus aktivem Profil) | | `EncActions[4,3]` | `DeviceAction[,]` | Encoder [0–3][SW=0/CW=1/CCW=2] (aus aktivem Profil) | | `LedBase[20]` | `Color[]` | RGB-Basis-LED-Farbe je Button (aus aktivem Profil) | | `LedAnim[20]` | `LedAnimType[]` | Animation je Button (aus aktivem Profil) | | `LedPeriod[20]` | `ushort[]` | Animationsperiode in ms (aus aktivem Profil) | ### Serialisierungs-Layout (ToBytes / FromBytes, 740 B) ``` Offset 0 4B Magic 0x56503203 (little-endian) Offset 4 1B Version = 3 Offset 5 2B CRC16-CCITT über Bytes 7–739 (little-endian) Offset 7 1B active_profile (0–2) Offset 8 1B global_brightness Offset 9 4B enc_sensitivity[4] Offset 13 19B Reserve (_reserve) Profil 0 (Offset 32, 236 B): Offset 32 60B MxActions[20] je 3B: type(1) + data_lo(1) + data_hi(1) Offset 92 36B EncActions[4][3] je 3B Offset 128 20B LedBase[i].R Offset 148 20B LedBase[i].G Offset 168 20B LedBase[i].B Offset 188 20B LedBrightness[i] Offset 208 20B LedAnim[i] als byte Offset 228 40B LedPeriod[i] als uint16 little-endian Profil 1 (Offset 268, 236 B): identisches Layout Profil 2 (Offset 504, 236 B): identisches Layout ``` ### CRC16-CCITT Polynom `0x1021`, Init `0xFFFF`, über Bytes 7–739 (nach dem CRC-Feld selbst, einschließlich `active_profile`). Muss identisch mit Firmware-Implementierung sein. `DeviceConfig.Crc16()` ist statisch und direkt testbar. ### Defaults (entspricht Firmware-Defaults) - Alle Aktionen: `None` - LEDs: warm-weiß (R=80, G=40, B=0), Helligkeit 255 - Animation: `ColorCycle` (Regenbogen), Period 4000 ms - `active_profile = 0`, `global_brightness = 255` --- ## DeviceAction ```csharp public enum ActionType : byte { None=0, HidKey=1, HidConsumer=2, HostCommand=3, Macro=4, ProfileSwitch=5 } public class DeviceAction { public ActionType Type { get; set; } public ushort Data { get; set; } // HidKey: Low-Byte = HID Keycode, High-Byte = Modifier // HidConsumer: Consumer Usage ID // HostCommand: Command-ID // Macro: Slot-Index 0–31 // ProfileSwitch: 0–2 = Ziel-Profil, 0xFFFF = nächstes Profil (Zyklus) } ``` `DeviceAction.Display` gibt einen lesbaren String zurück (z.B. `"Strg+C"`, `"Play/Pause"`, `"→ Profil 2"`, `"→ Nächstes Profil"`). --- ## MacroTable ```csharp public class MacroTable { public const int Slots = 32; public const int MaxSteps = 8; public MacroStep[,] Steps { get; } // [slot][step] } public class MacroStep { public byte Keycode { get; set; } // 0 = leer public byte Modifier { get; set; } } ``` ### Slot-Konvention | Slots | Verwendung | |---|---| | 0–19 | MX-Button `mxIdx` (`MacroTable.SlotForMx(mxIdx)`) | | 20–31 | Encoder: `20 + enc * 3 + actIdx` (`MacroTable.SlotForEncoder(enc, actIdx)`) | ### Serialisierung (512 B) 32 Slots × 8 Steps × 2 B = 512 B. Keycode zuerst, dann Modifier. Kein Magic/CRC (Board akzeptiert jeden Inhalt). --- ## LedAnimType ```csharp public enum LedAnimType : byte { Static=0, Blink=1, Pulse=2, ColorCycle=5 } ``` Werte entsprechen `LEDAnim` in der Firmware. `FADE_IN` (3) und `FADE_OUT` (4) existieren in der Firmware aber nicht in der GUI (nicht konfigurierbar).