Added doc

This commit is contained in:
2026-03-30 19:52:37 +02:00
parent 0b3c5f3217
commit 9079fefad8
9 changed files with 567 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
# 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 7222 |
| 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 7222 (ab `mx_actions`, nach dem `crc`-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:
1. `NVMCTRL->CTRLB.bit.MANW = 1` (manueller Schreib-Modus, kein Auto-Write)
2. Row löschen (`NVMCTRL_CTRLA_CMD_ER`)
3. Page-Buffer löschen (`NVMCTRL_CTRLA_CMD_PBC`)
4. 64 B als `uint32_t*` in Page-Buffer schreiben
5. Page programmieren (`NVMCTRL_CTRLA_CMD_WP`)
6. Schritte 35 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_page` castet `data` zu `const uint32_t*`. Der Puffer muss `__attribute__((aligned(4)))` sein. Packed Structs sind nicht garantiert aligned → immer via lokalen `uint8_t buf[256] __attribute__((aligned(4)))` + `memcpy` übergeben.