VersaMCU/doc/06_nvm_config.md
2026-03-30 19:52:37 +02:00

2.5 KiB
Raw Blame History

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.