VersaMCU/doc/00_architecture.md

108 lines
2.5 KiB
Markdown

# VersaMCU - Architekturuebersicht
## Zielplattform
| Merkmal | Wert |
|---|---|
| MCU | ATSAMD21G17D, Cortex-M0+, 48 MHz |
| Flash | 128 KB |
| RAM | 16 KB |
| FPU | keine, deshalb Integer-Arithmetik |
| USB | HID Keyboard + Consumer + CDC Serial |
| Toolchain | PlatformIO + Arduino Core |
## Setup und Loop
```text
setup()
macro_config_load()
nvm_config_load()
init_buttons()
usb_hid_init()
usb_serial_init()
matrix_init(cb)
encoder_init(cb)
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
## 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.*` | ISR-sicherer Ringbuffer |
| `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 |
## 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
- kein Heap
- keine Floats
- `packed` fuer serielle und NVM-relevante Structs
- NVM-Schreibpuffer muessen 4-Byte-aligned sein
- `usb_serial_send()` sendet nur bei aktiver CDC-Verbindung