VersaMCU/README.md

168 lines
3.9 KiB
Markdown

# 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)