5.1 KiB
NVM-Konfiguration
Dateien: config/nvm_config.h, config/nvm_config.cpp
Flash-Layout
| Row | Adresse | Größe | Inhalt |
|---|---|---|---|
| Row 0 | 0x1FE00 |
256 B | SDeviceConfig (223 B genutzt, 33 B Padding) |
| Row 1 | 0x1FF00 |
256 B | SMacroTable (256 B, komplett genutzt) |
Beide Rows sind im Linkerscript vom Code-Bereich ausgeschlossen.
SDeviceConfig – Byte-Layout (223 Byte, packed)
| Offset | Größe | Feld |
|---|---|---|
| 0 | 4 | magic = 0x56503202 ('VP2\x02') |
| 4 | 1 | version = 2 |
| 5 | 2 | crc – CRC16-CCITT über Bytes 7–222 |
| 7 | 60 | mx_actions[20] – 20 × 3 B SAction |
| 67 | 36 | enc_actions[4][3] – 12 × 3 B SAction |
| 103 | 20 | led_r[20] |
| 123 | 20 | led_g[20] |
| 143 | 20 | led_b[20] |
| 163 | 20 | led_anim[20] – LEDAnim-Typ als uint8_t |
| 183 | 40 | led_period_ms[20] – uint16_t, little-endian |
| 223 | — | Ende des genutzten Bereichs |
__attribute__((packed)) ist zwingend. Ohne packed wäre SAction 4 B statt 3 B (Alignment-Padding), was sizeof(SDeviceConfig) um 32 B vergrößert und die C#-Deserialisierung in VersaGUI zerstört.
CRC16-CCITT
- Polynom:
0x1021, Init:0xFFFF - Berechnet über Bytes 7–248 (ab
mx_actions, nach demcrc-Feld selbst) - Sichert Datenintegrität nach NVM-Schreiben und bei Versionswechsel
Lese-Logik
memcpy aus Flash-Adresse 0x1FE00
if magic != 0x56503202: Defaults laden, return false
if version != 2: Defaults laden, return false
if crc != crc(cfg): Defaults laden, return false
return true
Kein Absturz bei ungültiger Config – Defaults greifen immer.
Defaults
- Alle Aktionen:
NONE - LEDs: warm-weiß (R=80, G=40, B=0)
- Animation:
COLOR_CYCLE(Typ 5), Period 4000 ms
Schreib-Logik (NVM-Mechanik)
SAMD21 NVM: Row = 256 B = 4 Pages à 64 B. Schreiben erfordert:
NVMCTRL->CTRLB.bit.MANW = 1(manueller Schreib-Modus, kein Auto-Write)- Row löschen (
NVMCTRL_CTRLA_CMD_ER) - Page-Buffer löschen (
NVMCTRL_CTRLA_CMD_PBC) - 64 B als
uint32_t*in Page-Buffer schreiben - Page programmieren (
NVMCTRL_CTRLA_CMD_WP) - Schritte 3–5 viermal (für alle 4 Pages)
NVMCTRL->ADDR.reg = addr / 2– NVMCTRL erwartet Wort-Adresse (16-Bit-Worte), nicht Byte-Adresse.
Aligned-Buffer-Pflicht:
nvm_write_pagecastetdatazuconst uint32_t*. Der Puffer muss__attribute__((aligned(4)))sein. Packed Structs sind nicht garantiert aligned → immer via lokalenuint8_t buf[256] __attribute__((aligned(4)))+memcpyübergeben.
Geplante Erweiterung: NVM v3
Motivation
Das bisherige Layout (2 Rows, 512 B) stößt an mehrere Grenzen:
- Makro-Steps zu kurz — 4 Steps reichen für komplexe Shortcuts (z.B. Excel-Ribbon-Navigation: Alt → Buchstabe → Buchstabe → ...) nicht aus. Ziel: 8 Steps.
- Keine Profile — Eine einzige Config erlaubt keine Umschaltung zwischen Layouts (z.B. Coding vs. Tabellenkalkulation). Ziel: 3 unabhängige Profile.
- Keine Helligkeitssteuerung — Weder global noch pro LED einstellbar. Beide Ebenen sollen konfigurierbar werden.
- Encoder-Sensitivity — Schrittweite pro Encoder soll konfigurierbar sein.
Das bisherige Layout hat außerdem Config und Macros in denselben Adressbereich gemischt (0x1FE00 Config, 0x1FF00 Macros). Das neue Layout trennt beide Bereiche sauber.
Neues Flash-Layout (5 Rows, 0x1FB00–0x1FFFF)
| Row | Adresse | Größe | 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 | Globaler Header + Profil 0 (Bytes 0–255) |
| Config Row 1 | 0x1FE00 |
256 B | Profil 0 (Rest) + Profil 1 (Bytes 256–511) |
| Config Row 2 | 0x1FF00 |
256 B | Profil 1 (Rest) + Profil 2 + Reserve (Bytes 512–767) |
Macros und Config liegen in vollständig getrennten, jeweils zusammenhängenden Row-Blöcken.
Config-Inhalt (768 B, davon 740 B genutzt, 28 B Reserve)
Globaler Header (32 B, Offset 0):
| Offset | Größe | Feld |
|---|---|---|
| 0 | 4 | magic = 0x56503203 ('VP2\x03') |
| 4 | 1 | version = 3 |
| 5 | 2 | crc – CRC16-CCITT über alle Nutzdaten (ab Byte 7) |
| 7 | 1 | active_profile (0–2) |
| 8 | 1 | global_brightness (0–255) |
| 9 | 4 | enc_sensitivity[4] (1 B pro Encoder) |
| 13 | 19 | Reserve |
Pro Profil (236 B, Offset 32 + idx × 236):
| Offset | Größe | Feld |
|---|---|---|
| 0 | 60 | mx_actions[20] – 20 × 3 B SAction |
| 60 | 36 | enc_actions[4][3] – 12 × 3 B SAction |
| 96 | 20 | led_r[20] |
| 116 | 20 | led_g[20] |
| 136 | 20 | led_b[20] |
| 156 | 20 | led_brightness[20] ← neu |
| 176 | 20 | led_anim[20] |
| 196 | 40 | led_period_ms[20] |
Makro-Tabelle (512 B)
32 Slots × 8 Steps × 2 B = 512 B. Gegenüber v2 doppelt so viele Steps (4 → 8), Slot-Anzahl und Struktur bleiben gleich. Siehe 04_macro_system.md.
Migration von v2
Beim Laden: wenn magic oder version nicht zu v3 passen, werden Defaults geladen (kein Migrations-Pfad von v2 → v3, da das Layout inkompatibel ist). Eine einmalige Neukonfiguration nach dem Firmware-Update ist nötig.