VersaGUI/doc/01_serial_manager.md
2026-03-30 19:51:38 +02:00

77 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SerialManager
**Datei:** `SerialManager.cs`
## Verantwortung
- COM-Port-Erkennung per WMI (VID/PID)
- Verbindungsaufbau und automatischer Reconnect
- Hintergrund-Lese-Thread mit Paket-Assembler
- Sende-Methoden für alle Protokoll-Operationen
## COM-Port-Erkennung
```csharp
VidPid = "VID_239A&PID_0042" // muss mit platformio.ini übereinstimmen
SELECT Name, DeviceID FROM Win32_PnPEntity WHERE DeviceID LIKE '%VID_239A&PID_0042%'
// Name enthält z.B. "USB Serial Device (COM3)" → extrahiert "COM3"
```
Erkennt das Board auch bei wechselnder COM-Nummer. Funktioniert auch nach USB-Reinitialisierung (Kabel abziehen/stecken nach SWD-Flash).
## Verbindungsaufbau (TryConnect)
```
Monitor.TryEnter(_connectLock) nur ein gleichzeitiger Versuch
FindPort() per WMI
SerialPort erstellen:
ReadTimeout = 500 ms
WriteTimeout = 500 ms
DtrEnable = true ← VOR Open() setzen! (SAMD21 CDC-Constraint)
port.Open()
Thread.Sleep(200) CDC stabilisieren
ReadLoop-Thread starten
Connected-Event → UI-Thread
```
**Reconnect-Timer**: alle 3 s, Start nach 500 ms. 5 s Backoff (`_waitingAfterDisconnect`) nach Verbindungsverlust damit Board vollständig re-enumerieren kann.
## ReadLoop (Hintergrund-Thread)
```
while (port.IsOpen):
b = port.ReadByte() blockiert 500 ms (ReadTimeout)
buf[bufFill++] = b
if bufFill < 8: continue
→ SerialPacket fertig → SynchronizationContext.Post → PacketReceived auf UI-Thread
bufFill = 0
Bei IOException:
if port.IsOpen: ignorieren ← .NET 7: IOException = normaler Timeout (kein Fehler!)
else: break → Disconnect
```
## Sende-Methoden
| Methode | Funktion |
|---|---|
| `Send(pkt)` | Rohe 8-Byte-Übertragung (fire-and-forget, ignoriert Sendefehler) |
| `SetLedOverride(keyId, r, g, b)` | CMD 0x01 |
| `ClearLedOverride(keyId)` | CMD 0x02 |
| `SetLedBase(keyId, r, g, b)` | CMD 0x03 |
| `RequestConfig()` | CMD 0x13 Board antwortet mit Config-Dump |
| `RequestMacros()` | CMD 0x23 Board antwortet mit Makro-Dump |
| `SendConfig(cfg)` | BEGIN(0x10) → 38×DATA(0x11) → COMMIT(0x12), 5 ms zwischen Chunks |
| `SendMacros(macros)` | BEGIN(0x20) → 43×DATA(0x21) → COMMIT(0x22), 5 ms zwischen Chunks |
`SendConfig` und `SendMacros` blockieren ~400 ms → werden in `Task.Run()` aus `ConfigForm.OnSave()` aufgerufen.
## Events
| Event | Gefeuert wenn |
|---|---|
| `Connected` | Verbindung erfolgreich hergestellt (auf UI-Thread) |
| `Disconnected` | Verbindung verloren (auf UI-Thread) |
| `PacketReceived` | Vollständiges 8-Byte-Paket empfangen (auf UI-Thread) |