# VersaMCU Firmware fuer das VersaPad v2 Macro-Pad. Laeuft auf einem ATSAMD21G17D mit PlatformIO und Arduino-Framework. ## Hardware | Eigenschaft | Detail | |---|---| | MCU | ATSAMD21G17D, Cortex-M0+, 48 MHz | | Flash / RAM | 128 KB / 16 KB | | USB | Composite: HID Keyboard + Consumer + CDC Serial | | Matrix | 5x5 logisch, davon 20 MX-Buttons + 4 Encoder-SW + 1 unbelegt | | Encoder | 4x Rotary Encoder mit Quadratur via EIC-Interrupt | | LEDs | 20x WS2812B an `PB22` | | Programmer | Atmel-ICE via SWD, kein Bootloader | ## Build und Flash ```bash pio run pio run --target upload ``` Der Upload laeuft per OpenOCD ueber SWD. ## Laufzeitmodell `main.cpp` startet genau einen `CMainController`. Die Hauptschleife in `work()` ist: ```text matrix_scan() poll_vendor() processEvents() check_factory_reset() updateLEDs() ``` Dabei gilt: - Matrix und Encoder erzeugen `SEvent`s. - `processEvents()` fuehrt daraus HID, Makros, Host-Commands oder Profilwechsel aus. - `poll_vendor()` verarbeitet das 8-Byte-CDC-Protokoll mit Config- und Makro-Transfers. - `updateLEDs()` rendert nur dann zu den WS2812, wenn sich etwas geaendert hat. ## Action-System Unterstuetzte `ActionType`s: | Typ | Verhalten | |---|---| | `NONE` | keine Aktion | | `HID_KEY` | Keyboard-Hold ueber USB HID | | `HID_CONSUMER` | Media/Consumer-Hold ueber USB HID | | `HOST_COMMAND` | Event an die GUI per CDC Serial | | `MACRO` | Firmware spielt Makro-Slot komplett ab | | `PROFILE_SWITCH` | aktives Profil in NVM wechseln | Wichtige Semantik: - normale Keys und Consumer folgen dem Hold-Modell - Encoder `CW` / `CCW` sind immer Tap-Events - Makros laufen komplett in der Firmware, ohne laufende App ## LED-System Jeder MX-Button hat: - eine Base-Farbe - optional eine temporaere Override-Farbe - eine Animation Aktuelle Animationsmodi: - `STATIC` - `BLINK` - `PULSE` - `FADE_IN` - `FADE_OUT` - `COLOR_CYCLE` - `COLOR_FADE` Die GUI nutzt derzeit vor allem `STATIC`, `BLINK`, `PULSE` und `COLOR_CYCLE`. ## Aktuelles NVM-Layout ### DeviceConfig - Version: `3` - Magic: `0x56503203` - Groesse: `740` Byte - CRC16-CCITT ueber Bytes `7..739` - 3 Profile - globale Helligkeit - per-LED-Helligkeit ### MacroTable - 32 Slots - 8 Steps pro Slot - 512 Byte gesamt ### Flash-Bereich | Bereich | Adresse | Groesse | |---|---|---| | Makros | `0x1FB00-0x1FCFF` | 512 B | | Config | `0x1FD00-0x1FFFF` | 768 B, davon 740 B genutzt | Config und Makros liegen in getrennten reservierten NVM-Bereichen. ## Werksreset Die Firmware hat einen eingebauten Recovery-Pfad: - unteren linken und unteren rechten MX-Button gleichzeitig 5 Sekunden halten - waehrend des Holds leuchten diese beiden Tasten rot - ihre normalen HID-Aktionen werden waehrenddessen unterdrueckt - bei Erfolg blinken alle LEDs kurz rot - danach werden Config und Makros auf Werkseinstellungen zurueckgesetzt und neu geladen Reset-Inhalt: - alle Aktionen `NONE` - alle Makro-Slots leer - Base-LEDs auf Defaultwerte - sichtbarer Idle-Zustand wieder Regenbogen Wichtig: - ein SWD-Reflash loescht diese NVM-Daten nicht automatisch - der Werksreset ist der vorgesehene Weg, um eine kaputte Konfiguration zu bereinigen ## Projektstruktur ```text VersaMCU/ |-- platformio.ini |-- boards/ |-- variants/versapad/ `-- src/ |-- main.cpp |-- CMainController.h/.cpp |-- CButton.h/.cpp |-- CEventQueue.h/.cpp |-- SEvent.h |-- config/ | |-- action.h | |-- macro_config.h/.cpp | `-- nvm_config.h/.cpp `-- hal/ |-- encoder.h/.cpp |-- matrix.h/.cpp |-- usb_hid.h/.cpp |-- usb_serial.h/.cpp `-- ws2812.h/.cpp ``` ## Weiterfuehrende Doku - [doc/INDEX.md](doc/INDEX.md) - [doc/00_architecture.md](doc/00_architecture.md) - [doc/03_action_engine.md](doc/03_action_engine.md) - [doc/04_macro_system.md](doc/04_macro_system.md) - [doc/06_nvm_config.md](doc/06_nvm_config.md) - [doc/07_serial_protocol.md](doc/07_serial_protocol.md)