170 lines
4.1 KiB
Markdown
170 lines
4.1 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.
|
|
|
|
Beim Serial-Dump der Config werden 124 Chunks zu je 6 Nutzbytes uebertragen. Implementierungen muessen den daraus berechneten Byte-Offset mindestens 16 Bit breit halten, weil Profil 2 und 3 hinter Byte 255 liegen.
|
|
|
|
## 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)
|