2.5 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–222 (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.