Adds doc/10_usb_bootloader.md as the primary reference for the UF2 bootloader (memory layout, key-based boot entry, build/flash steps, hardware test findings, known limitations), following the existing numbered-doc convention. Updates doc/INDEX.md, doc/09_known_limitations.md (bootloader is no longer "not supported", just scoped), and doc/08_development.md accordingly. Removes bootloader/TESTING.md (its findings now live in doc/10_usb_bootloader.md) and trims bootloader/README.md down to what belongs with that subproject specifically: upstream attribution/license and local build/flash commands, plus the OpenOCD manual-flashing warning since that's implementation-specific detail that would clutter the higher-level doc. Updates the top-level README.md (feature table, hardware table, quickstart, project tree, doc links) to reflect USB flashing as a supported path alongside SWD. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|---|---|---|
| boards | ||
| bootloader | ||
| doc | ||
| src | ||
| variants/versapad | ||
| .gitignore | ||
| AGENTS.md | ||
| platformio.ini | ||
| README.md | ||
| uf2conv.py | ||
| upload_openocd.py | ||
| upload_uf2.py | ||
VersaMCU
Firmware für das VersaPad-v2-Makropad. Das Projekt läuft auf einem ATSAMD21G17D mit PlatformIO und dem Arduino-SAMD-Framework.
Aktueller Funktionsumfang
| Bereich | Stand |
|---|---|
| Eingaben | 20 MX-Tasten, 4 Encoder-Taster und 4 Quadratur-Encoder |
| USB | Keyboard-HID, Consumer-HID und CDC Serial |
| Aktionen | HID-Key, Consumer-Key, Host-Event, Makro, Profilwechsel |
| Makros | 32 Slots mit je bis zu 8 HID-Schritten |
| Profile | 3 Profile in Config v3 |
| LEDs | 20 WS2812B mit Base-/Override-Farbe und 7 Animationsmodi |
| Persistenz | Config und Makros im internen Flash |
| Recovery | Werksreset über zwei Tasten |
| Firmware-Update | SWD (Atmel-ICE) oder USB (UF2-Bootloader, bootloader/) |
Die drei Fader-Pins sind im Board-Variant definiert, werden von der aktuellen Firmware aber noch nicht eingelesen.
Hardware
| Eigenschaft | Detail |
|---|---|
| MCU | ATSAMD21G17D, Cortex-M0+, 48 MHz |
| Flash / RAM | 128 KiB / 16 KiB |
| Matrix | logisch 5×5: 20 MX, 4 Encoder-SW, 1 unbelegt |
| Encoder | 4× Quadratur über EIC-Interrupts |
| LEDs | 20× WS2812B an PB22 |
| USB | Native USB als HID + CDC Composite Device |
| Programmer | Atmel-ICE/CMSIS-DAP über SWD, oder USB über den UF2-Bootloader |
Schnellstart
Voraussetzungen sind PlatformIO Core oder die PlatformIO IDE sowie für den Upload ein angeschlossener Atmel-ICE beziehungsweise kompatibler CMSIS-DAP-Adapter.
pio run -e versapad
pio run -e versapad --target upload
Das Standard-Environment versapad baut für boards/versapad_nobl.json. Der
Upload wird durch upload_openocd.py über das von PlatformIO installierte
OpenOCD ausgeführt.
Alternativ lässt sich die App-Firmware nach einem einmaligen SWD-Bootloader-Flash auch über USB aktualisieren, ganz ohne Atmel-ICE:
cd bootloader && pio run -e versapad_bootloader --target upload # einmalig
pio run -e versapad_usb --target upload # danach jedes App-Update
Details, Speicherlayout und die Bootloader-Aktivierung (kein physischer Reset-Taster auf dieser Platine) stehen in 10_usb_bootloader.md.
Laufzeitmodell
main.cpp besitzt genau einen CMainController. Nach einem roten Startsignal
initialisiert er NVM, USB, Matrix und Encoder. Die Hauptschleife ist:
matrix_scan()
poll_vendor()
processEvents()
check_factory_reset()
updateLEDs()
- Matrix und Encoder legen
SEvents in eine feste Queue. - Der Controller setzt Events in HID-Aktionen, Makros, Host-Events oder Profilwechsel um.
poll_vendor()verarbeitet feste 8-Byte-Pakete über CDC.- LEDs werden nur neu übertragen, wenn ein Zustand dirty ist oder eine Animation läuft.
- Makros, Encoder-Taps, NVM-Zugriffe und visuelles Reset-Feedback blockieren den Loop kurzzeitig; es gibt keinen Scheduler.
Wichtige Datenverträge
Config v3
- Magic
0x56503203 SDeviceConfig: 740 Byte- CRC16-CCITT über Bytes
7..739 - 3 Profile
- globale und LED-spezifische Helligkeit
- 124 Chunks mit je 6 Nutzbytes beim CDC-Transfer
Makros
SMacroTable: 512 Byte- 32 Slots × 8 Schritte × 2 Byte
- 86 Chunks mit je 6 Nutzbytes beim CDC-Transfer
Flashzugriffe
| Bereich | Adresse | Größe |
|---|---|---|
| Makros | 0x1FB00..0x1FCFF |
512 B |
| Config | 0x1FD00..0x1FFFF |
768 B, davon 740 B genutzt |
Das aktive Linker-Skript und boards/versapad_nobl.json begrenzen das
Firmware-Image auf 0x00000..0x1FAFF. Damit sind alle fünf NVM-Rows gegen
Firmwarewachstum geschützt.
Werksreset
Unteren linken und unteren rechten MX-Button gleichzeitig fünf Sekunden halten:
- die Tasten werden während des Haltens rot markiert,
- ihre normalen Aktionen werden unterdrückt,
- bei Erfolg blinken alle LEDs kurz rot,
- Config und Makrotabelle werden auf Defaults zurückgesetzt.
Ein normaler SWD-Reflash löscht diese NVM-Daten nicht automatisch.
Projektstruktur
VersaMCU/
|-- AGENTS.md # Kontext und Richtlinien für Coding-LLMs
|-- README.md
|-- platformio.ini
|-- upload_openocd.py # SWD-Upload-Hook (env:versapad)
|-- uf2conv.py # .bin -> .uf2 Konverter (App-Firmware)
|-- upload_uf2.py # USB-Upload-Hook (env:versapad_usb)
|-- boards/ # PlatformIO-Boarddefinitionen
|-- variants/versapad/ # Pinmapping und Linker-Skripte
|-- doc/ # Architektur- und Protokolldokumentation
|-- bootloader/ # UF2-Bootloader (eigenes PlatformIO-Projekt)
`-- src/
|-- main.cpp
|-- CMainController.* # Orchestrierung
|-- CButton.* # Actions und LED-Zustand
|-- CEventQueue.* # feste Event-Queue
|-- config/ # Binärformate, NVM und Pins
`-- hal/ # Matrix, Encoder, HID, CDC, WS2812
Einstieg für Entwickler und LLMs
Für einen neuen Kollegen:
- Entwicklung und Einstieg
- Architektur
- die zum Task passende Fachdokumentation im Dokumentationsindex
- bekannte Einschränkungen
Für einen Coding-Agent zusätzlich AGENTS.md als
Repository-Anweisung mitgeben. Die Datei enthält Quellenhierarchie,
Binärverträge, Änderungsregeln und die minimale Verifikation.