# Serial-Protokoll (CDC USB) Dateien: - `hal/usb_serial.h` - `hal/usb_serial.cpp` - `CMainController.cpp` ## Paketformat Alle Pakete sind exakt 8 Byte lang: ```text Byte 0: command / event id Byte 1: key_id oder chunk-index oder chunk-count Byte 2: daten a Byte 3: daten b Byte 4: daten c Byte 5..7: reserviert ``` Es gibt kein Framing und keinen Laengenheader. ## Richtungen | Richtung | IDs | Verarbeitung | |---|---|---| | PC -> Board | `0x01..0x7F` | `poll_vendor()` | | Board -> PC | `0x81..0xFF` | `usb_serial_send()` | ## Commands | ID | Name | Zweck | |---|---|---| | `0x01` | `SET_LED_OVERRIDE` | temporaere LED-Override setzen | | `0x02` | `CLEAR_LED_OVERRIDE` | Override entfernen | | `0x03` | `SET_LED_BASE` | Base-Farbe im RAM setzen | | `0x05` | `PING` | Antwort: `PONG` | | `0x10` | `CONFIG_BEGIN` | Config-Transfer starten | | `0x11` | `CONFIG_DATA` | 6 Byte Config-Nutzdaten | | `0x12` | `CONFIG_COMMIT` | Config pruefen und speichern | | `0x13` | `CONFIG_READ` | Config-Dump an Host senden | | `0x20` | `MACRO_BEGIN` | Makro-Transfer starten | | `0x21` | `MACRO_DATA` | 6 Byte Makro-Nutzdaten | | `0x22` | `MACRO_COMMIT` | Makros speichern | | `0x23` | `MACRO_READ` | Makro-Dump an Host senden | ## Events | ID | Name | Zweck | |---|---|---| | `0x81` | `KEY_DOWN` | Host-Command-Button gedrueckt | | `0x82` | `KEY_UP` | Host-Command-Button losgelassen | | `0x83` | `ENC_CW` | Encoder Host-Command im Uhrzeigersinn | | `0x84` | `ENC_CCW` | Encoder Host-Command gegen Uhrzeigersinn | | `0x85` | `PONG` | Antwort auf Ping | | `0x90` | `CONFIG_ACK` | Config erfolgreich gespeichert | | `0x91` | `CONFIG_NACK` | Config ungueltig oder NVM-Timeout | | `0x92` | `CONFIG_BEGIN` | Config-Dump beginnt | | `0x93` | `CONFIG_DATA` | 6 Byte Config-Dump | | `0x94` | `CONFIG_END` | Config-Dump fertig | | `0x95` | `MACRO_ACK` | Makros erfolgreich gespeichert | | `0x96` | `MACRO_BEGIN` | Makro-Dump beginnt | | `0x97` | `MACRO_DATA` | 6 Byte Makro-Dump | | `0x98` | `MACRO_END` | Makro-Dump fertig | | `0x99` | `MACRO_NACK` | Makro-Speichern fehlgeschlagen | ## Chunk-Zahlen Aktuelle Blob-Groessen: - Config: `740` Byte - Makros: `512` Byte Bei 6 Nutzbytes pro Paket ergibt das: ```text Config: ceil(740 / 6) = 124 Chunks Makros: ceil(512 / 6) = 86 Chunks ``` Wichtig fuer Implementierungen: Der Byte-Offset eines Chunks muss mindestens 16 Bit breit sein. Bei der Config liegt der Offset ab Chunk 43 ueber 255 Byte; ein 8-Bit-Offset wuerde ueberlaufen und spaetere Profilbereiche falsch dumpen. ## Transferablauf ### PC -> Board ```text BEGIN(chunk_count) DATA 0 DATA 1 ... COMMIT ``` ### Board -> PC ```text BEGIN(chunk_count) DATA 0 DATA 1 ... END ``` ## Validierung `CONFIG_COMMIT` prueft: - Magic - Version - CRC Nur bei erfolgreicher Pruefung wird in NVM geschrieben. `MACRO_COMMIT` schreibt ohne CRC direkt nach NVM und signalisiert nur Erfolg oder Fehler. ## Praktische Hinweise fuer die GUI - nach `CONFIG_COMMIT` auf `CONFIG_ACK` oder `CONFIG_NACK` warten - danach erst `MACRO_*` senden - Dumps besser sequenziell lesen: zuerst Config, danach Makros - `DtrEnable` muss aktiv sein, sonst verwirft das Board CDC-Ausgaben ## Implementierungsdetails - RX-Ringbuffer: 256 Byte = 32 volle Pakete - feste 8-Byte-Pakete vereinfachen Firmware und GUI - nach einem reinen SWD-Reflash kann ein physischer USB-Reconnect noetig sein