Files
VersaMCU/doc/00_architecture.md
T

126 lines
3.4 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.
# VersaMCU Architekturübersicht
## Zielplattform
| Merkmal | Wert |
|---|---|
| MCU | ATSAMD21G17D, Cortex-M0+, 48 MHz |
| Flash | 128 KB |
| RAM | 16 KB |
| FPU | keine; LED-/Timingpfade verwenden Integer-Arithmetik |
| USB | HID Keyboard + Consumer + CDC Serial |
| Toolchain | PlatformIO + Arduino Core |
## Setup und Loop
```text
Arduino setup()
delay(500)
ws2812_init()
rotes Startsignal für 1 s
CMainController::setup()
macro_config_load()
init_buttons() -> nvm_config_load()
Queue-Bridge setzen
usb_hid_init()
usb_serial_init()
matrix_init(cb)
encoder_init(cb)
Arduino loop()
matrix_scan()
poll_vendor()
processEvents()
check_factory_reset()
updateLEDs()
```
Die Reihenfolge ist absichtlich simpel:
- Eingaben einsammeln
- CDC-Kommandos vom Host verarbeiten
- Event-Queue leeren
- Sonderlogik fuer den Werksreset pruefen
- LED-Frame nur bei Bedarf rendern
Makros, Encoder-Taps, NVM-Schreiben sowie Start- und Reset-Feedback verwenden
blockierende Delays. Währenddessen werden Matrix und CDC nicht bearbeitet.
## Datenfluss
```text
matrix_scan / encoder ISR
-> EventQueue
-> processEvents()
-> execute_action_down / execute_action_up
-> usb_hid_*
-> usb_serial_send() fuer HOST_COMMAND
CDC Serial
-> poll_vendor()
-> Config/Makros einlesen oder dumpen
-> LED-Overrides setzen/loeschen
LED-Render
-> CButton.render_led()
-> ws2812_set()
-> ws2812_show() nur wenn dirty
```
## Zentrale Komponenten
| Datei | Aufgabe |
|---|---|
| `main.cpp` | startet den Controller |
| `CMainController.*` | Orchestrator fuer Inputs, Actions, Serial, LEDs |
| `CButton.*` | LED-Zustand, Animationen, Action-Referenz |
| `CEventQueue.*` | fester Ringbuffer mit 16 nutzbaren Slots |
| `config/nvm_config.*` | Config v3 laden, speichern, Defaults |
| `config/macro_config.*` | Makros laden, speichern |
| `hal/matrix.*` | 5x5-Matrixscan mit Debounce |
| `hal/encoder.*` | Encoder-ISR und Drehrichtung |
| `hal/usb_hid.*` | Keyboard- und Consumer-HID |
| `hal/usb_serial.*` | CDC-Paketpfad |
| `hal/ws2812.*` | WS2812-Treiber |
Die drei Fader sind nur im Variant und in `config/pins.h` definiert. Es gibt
aktuell keinen Fader-HAL und keine Verarbeitung im Controller.
## Key-ID-Schema
```text
0..3 = Encoder-SW
4 = unbenutzt
5..24 = MX-Buttons
```
Die beiden Werksreset-Tasten sind:
- `key_id 9` = unten links
- `key_id 24` = unten rechts
## Werksreset im Ablauf
Der Werksreset ist keine PC-Funktion, sondern Teil der Firmware:
- sobald beide Reset-Tasten gleichzeitig gehalten werden, werden ihre normalen Actions unterdrueckt
- falls bereits ein HID-Hold aktiv war, wird er sofort freigegeben
- nach 5 Sekunden gemeinsamer Haltezeit wird Default-Config + leere Makro-Tabelle in NVM geschrieben
- danach folgt ein kurzes rotes Feedback-Blinken
## Invarianten
- Projektcode vermeidet dynamische Allokation
- Integer-Arithmetik in zeitkritischen LED-/ISR-Pfaden
- `packed` fuer serielle und NVM-relevante Structs
- NVM-Schreibpuffer muessen 4-Byte-aligned sein
- `usb_serial_send()` sendet nur bei aktiver CDC-Verbindung
## Nebenläufigkeit
Encoder-Callbacks laufen im EIC-Interrupt, Matrixcallbacks im Loop. Beide
schreiben in dieselbe `CEventQueue`; `processEvents()` liest im Loop. Der
Matrixcallback maskiert Interrupts während seines Queue-Pushs, sodass Loop und
ISR den Tail-Index nicht gleichzeitig ändern. Bei Überlauf werden Events
weiterhin verworfen.