VersaMCU/doc/04_macro_system.md

67 lines
2.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Makro-System
**Dateien:** `config/macro_config.h`, `config/macro_config.cpp`, `CMainController.cpp`
## Datenstruktur
```cpp
struct __attribute__((packed)) SMacroStep {
uint8_t keycode; // HID Keyboard Usage (0x00 = leer → Step überspringen)
uint8_t modifier; // HID Modifier: Ctrl=0x01, Shift=0x02, Alt=0x04, GUI=0x08
};
#define MACRO_SLOTS 32
#define MACRO_MAX_STEPS 8
struct __attribute__((packed)) SMacroTable {
SMacroStep steps[MACRO_SLOTS][MACRO_MAX_STEPS]; // 32 × 8 × 2 = 512 Byte
};
```
Beide Structs sind `packed` (kein Padding). `sizeof(SMacroTable) == 512 == zwei NVM-Rows`.
## NVM-Speicherort
| Row | Adresse | Inhalt |
|---|---|---|
| Macro Row 0 | `0x1FB00` | SMacroTable Bytes 0255 |
| Macro Row 1 | `0x1FC00` | SMacroTable Bytes 256511 |
Beide Rows sind im Linkerscript reserviert. Gelöschter Flash (`0xFF`-Bytes) → `macro_config_load()` gibt `false` zurück → leere Tabelle (alle Keycodes 0).
## Slot-Zuweisung (Konvention, Board speichert blind)
| Slots | Verwendung |
|---|---|
| 019 | MX-Button `mx_idx` (entspricht key_id 5) |
| 2031 | Encoder-Aktionen (`enc * 3 + act_idx`, 0=SW / 1=CW / 2=CCW) |
## Laden und Speichern
**Laden** (`macro_config_load`):
- `memcpy` direkt aus Flash-Adresse in RAM-Struct
- Kein Magic/CRC — leere Tabelle (alle 0xFF) ist ein akzeptabler Zustand
**Speichern** (`macro_config_save`) — gibt `bool` zurück:
- SMacroTable in `uint8_t aligned_buf[512] __attribute__((aligned(4)))` kopieren (Pflicht!)
- `NVMCTRL->CTRLB.bit.MANW = 1` (manueller Schreib-Modus)
- Beide Rows löschen (`nvm_erase_row`) — bei NVM-Timeout: `return false`
- 8 Pages à 64 Byte schreiben (`nvm_write_page`) — bei NVM-Timeout: `return false`
- `return true`
> **Warum aligned_buf?** `nvm_write_page` castet den Pointer zu `volatile uint32_t*`. Wenn `&tbl` nicht 4-Byte-aligned ist (möglich bei packed struct), entsteht ein HardFault auf Cortex-M0+ (kein unaligned 32-Bit-Zugriff auf Peripherie-Adressen).
## Ausführung (in execute_action_down, ActionType::MACRO)
```
slot = action.data (031)
für Step 07:
if step.keycode == 0: abbrechen
HID Key-Down (keycode, modifier)
delay(10 ms)
HID Key-Up
delay(20 ms)
```
Die Makro-Tabelle liegt nach `setup()` im RAM (`m_macros` in CMainController). Kein NVM-Zugriff während der Ausführung.