VersaMCU/doc/07_serial_protocol.md

4.0 KiB
Raw Blame History

Serial-Protokoll (CDC USB)

Dateien: hal/usb_serial.h, hal/usb_serial.cpp

Grundprinzip

Board erscheint unter Windows als CDC Serial-Port (kein Treiber nötig). Alle Pakete haben feste Größe von 8 Byte kein Längen-Header, kein Framing, kein Escape.

Byte 0: Command / Event-ID
Byte 1: key_id (Button 024 oder Encoder 03) / Chunk-Index / Chunk-Count
Byte 2: r / Daten-Byte A
Byte 3: g / Daten-Byte B
Byte 4: b
Byte 57: reserviert (0x00)

Richtungen

Richtung ID-Bereich Verarbeitung
PC → Board (Commands) 0x010x7F poll_vendor() in CMainController
Board → PC (Events) 0x810xFF usb_serial_send() in processEvents

Command-Referenz (PC → Board)

ID Name Bedeutung
0x01 SET_LED_OVERRIDE key_id, r, g, b temporäre Override-Farbe setzen
0x02 CLEAR_LED_OVERRIDE key_id Override löschen, zurück zu base
0x03 SET_LED_BASE key_id, r, g, b base-Farbe dauerhaft ändern (kein NVM)
0x05 PING Board antwortet sofort mit PONG (0x85)
0x10 CONFIG_BEGIN Byte[1] = Chunk-Anzahl neuen Config-Empfang starten
0x11 CONFIG_DATA Byte[1] = Chunk-Index, Byte[27] = 6 B Nutzdaten
0x12 CONFIG_COMMIT CRC prüfen → NVM schreiben → Buttons neu laden → ACK/NACK
0x13 CONFIG_READ Board sendet aktuelle NVM-Config zurück (BEGIN/DATA/END)
0x20 MACRO_BEGIN Byte[1] = Chunk-Anzahl neuen Makro-Empfang starten
0x21 MACRO_DATA Byte[1] = Chunk-Index, Byte[27] = 6 B Nutzdaten
0x22 MACRO_COMMIT NVM schreiben → MACRO_ACK oder MACRO_NACK
0x23 MACRO_READ Board sendet aktuelle Makro-Tabelle zurück

Event-Referenz (Board → PC)

ID Name Bedeutung
0x81 KEY_DOWN key_id HOST_COMMAND-Button gedrückt
0x82 KEY_UP key_id (derzeit nicht gesendet)
0x83 ENC_CW enc_id Encoder-Schritt CW (HOST_COMMAND)
0x84 ENC_CCW enc_id Encoder-Schritt CCW (HOST_COMMAND)
0x85 PONG Antwort auf PING
0x90 CONFIG_ACK Config erfolgreich in NVM geschrieben
0x91 CONFIG_NACK Config CRC/Magic ungültig oder NVM-Timeout nicht geschrieben
0x92 CONFIG_BEGIN Byte[1] = Chunk-Anzahl (Config-Dump)
0x93 CONFIG_DATA Byte[1] = Index, Byte[27] = 6 B (Config-Dump)
0x94 CONFIG_END Config-Dump abgeschlossen
0x95 MACRO_ACK Makro-Tabelle erfolgreich gespeichert
0x96 MACRO_BEGIN Byte[1] = Chunk-Anzahl (Makro-Dump)
0x97 MACRO_DATA Byte[1] = Index, Byte[27] = 6 B (Makro-Dump)
0x98 MACRO_END Makro-Dump abgeschlossen
0x99 MACRO_NACK Makro-Tabelle: NVM-Timeout nicht geschrieben

Chunked Transfer

Config (740 B) und Makro-Tabelle (512 B) werden in 6-Byte-Chunks übertragen:

Config:  ceil(740 / 6) = 124 Chunks
Makros:  ceil(512 / 6) =  86 Chunks (letzter Chunk hat 2 Nutzbytes)

Ablauf (PC → Board):

BEGIN (chunk_count)
DATA chunk_0  (Bytes 05)
DATA chunk_1  (Bytes 611)
...
COMMIT

CONFIG_COMMIT: Board prüft Magic + Version + CRC. Bei Fehler → CONFIG_NACK. Bei NVM-Timeout während Erase/Write → CONFIG_NACK. Bei Erfolg → CONFIG_ACK.

MACRO_COMMIT: Kein CRC, Board schreibt direkt. Bei Erfolg → MACRO_ACK. Bei NVM-Timeout → MACRO_NACK.

ACK-Synchronisation (GUI-Seite)

VersaGUI wartet nach COMMIT auf das ACK/NACK via SemaphoreSlim (Timeout 3 s). Erst nach Freigabe des Gates startet der nächste Transfer. Dies verhindert, dass Makro-Chunks gesendet werden während das Board noch den Config-NVM schreibt (~750 ms für 3 Rows).

Implementierungsdetails

  • Ring-Buffer: 256 Byte Eingangspuffer (= 32 vollständige Pakete) in usb_serial.cpp
  • DTR-Check: usb_serial_send() sendet nur wenn SerialUSB aktiv ist (verhindert stilles Verwerfen wenn VersaGUI nicht verbunden)
  • SAMD21 CDC: Nach SWD-Flash braucht Windows eine physische USB-Reinitialisierung (Kabel abziehen/stecken) damit der CDC-Port neu enumeriert