# NVM-Konfiguration Dateien: - `config/nvm_config.h` - `config/nvm_config.cpp` ## Flash-Layout | Bereich | Adresse | Groesse | Inhalt | |---|---|---|---| | Macro Row 0 | `0x1FB00` | 256 B | `SMacroTable` Bytes `0..255` | | Macro Row 1 | `0x1FC00` | 256 B | `SMacroTable` Bytes `256..511` | | Config Row 0 | `0x1FD00` | 256 B | Header + Profil 0 Anfang | | Config Row 1 | `0x1FE00` | 256 B | Profil 0 Rest + Profil 1 Anfang | | Config Row 2 | `0x1FF00` | 256 B | Profil 1 Rest + Profil 2 + Reserve | Makros und Config sind komplett getrennt. Das aktive Linker-Skript reserviert `0x1FB00..0x1FFFF` als eigenen NVM-Memory-Bereich. Die Boarddefinition meldet entsprechend höchstens 129.792 Byte Firmware-Flash. Damit kann ein erfolgreich gelinktes Image die fünf NVM-Rows nicht überdecken. ## `SDeviceConfig` Aktueller Stand: - Magic: `0x56503203` - Version: `3` - Groesse: `740` Byte - auf 3 Config-Rows verteilt ### Header | Offset | Groesse | Feld | |---|---|---| | `0` | 4 | `magic` | | `4` | 1 | `version` | | `5` | 2 | `crc` | | `7` | 1 | `active_profile` | | `8` | 1 | `global_brightness` | | `9` | 4 | `enc_sensitivity[4]` | | `13` | 19 | Reserve | `enc_sensitivity` ist im Binärformat vorhanden und hat Default `1`, wird von der Encoderdekodierung derzeit aber nicht verwendet. ### Pro Profil Jedes Profil belegt 236 Byte: | Offset im Profil | Groesse | Feld | |---|---|---| | `0` | 60 | `mx_actions[20]` | | `60` | 36 | `enc_actions[4][3]` | | `96` | 20 | `led_r[20]` | | `116` | 20 | `led_g[20]` | | `136` | 20 | `led_b[20]` | | `156` | 20 | `led_brightness[20]` | | `176` | 20 | `led_anim[20]` | | `196` | 40 | `led_period_ms[20]` | Gesamtrechnung: ```text 32 Byte Header + 3 * 236 Byte Profile = 740 Byte ``` ## CRC CRC16-CCITT: - Polynom `0x1021` - Init `0xFFFF` - Bereich: Bytes `7..739` Damit sind auch `active_profile` und globale Helligkeit abgesichert. ## Defaults `nvm_config_defaults()` setzt: - `active_profile = 0` - `global_brightness = 255` - `enc_sensitivity[*] = 1` - alle Actions auf `NONE` - alle `led_brightness[*] = 255` - Base-Farbe `R=80, G=40, B=0` - `led_anim = COLOR_CYCLE` - `led_period_ms = 4000` Praktisch sichtbares Ergebnis: - alle MX-LEDs laufen wieder im Regenbogenmodus ## Laden `nvm_config_load()`: 1. 740 Byte aus NVM kopieren 2. Magic, Version und CRC prüfen 3. Profilindex, Actiontypen/-daten und LED-Enums prüfen 4. `PULSE`-Perioden auf mindestens 2 ms prüfen 5. bei Fehlern Defaults laden und `false` zurückgeben Die Firmware faellt also immer auf einen gueltigen Zustand zurueck. Die Defaults werden bei diesem Fallback nur in das übergebene RAM-Struct geschrieben und nicht automatisch in Flash persistiert. Dieselbe Validierung wird vor einem Config-Commit aus dem CDC-Protokoll verwendet. ## Speichern `nvm_config_save()`: 1. die vom Aufrufer bereits vorbereitete 740-Byte-Config in einen 768-Byte-Row-Puffer kopieren 2. Rest mit `0xFF` fuellen 3. `MANW = 1` 4. 3 Rows loeschen 5. 12 Pages zu je 64 Byte schreiben Rueckgabewert: - `true` bei Erfolg - `false` bei NVM-Timeout Wichtig: - der Schreibpuffer muss 4-Byte-aligned sein - `packed` allein reicht dafuer nicht - `nvm_config_save()` berechnet die CRC in einer lokalen Kopie immer neu - `static_assert` schützt die erwarteten Größen 3, 236 und 740 Byte beim Build ## Zusammenhang mit Werksreset Der Werksreset nutzt denselben Pfad: - `nvm_config_defaults(cfg)` - `nvm_config_save(cfg)` Dadurch werden auch kaputte, aber formal noch vorhandene Alt-Daten im NVM wirklich ueberschrieben.