8 Step macro and profile switching fully working

This commit is contained in:
2026-04-13 22:34:54 +02:00
parent 098a166a9f
commit 433d61c29f
10 changed files with 204 additions and 193 deletions
+19 -40
View File
@@ -10,18 +10,24 @@ struct __attribute__((packed)) SMacroStep {
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[32][4]; // 32 Slots × 4 Steps × 2 Byte = 256 Byte
SMacroStep steps[MACRO_SLOTS][MACRO_MAX_STEPS]; // 32 × 8 × 2 = 512 Byte
};
```
Beide Structs sind `packed` (kein Padding). `sizeof(SMacroTable) == 256 == eine NVM-Row`.
Beide Structs sind `packed` (kein Padding). `sizeof(SMacroTable) == 512 == zwei NVM-Rows`.
## NVM-Speicherort
- **Row 1**: Adresse `0x1FF00`, 256 Byte
- Vom Linkerscript reserviert (nicht überschreibbar durch Code)
- Gelöschter Flash (`0xFF`-Bytes) → `macro_config_load()` gibt false zurück → leere Tabelle (alle Keycodes 0)
| 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)
@@ -34,21 +40,22 @@ Beide Structs sind `packed` (kein Padding). `sizeof(SMacroTable) == 256 == eine
**Laden** (`macro_config_load`):
- `memcpy` direkt aus Flash-Adresse in RAM-Struct
- Kein Magic/CRC (leere Tabelle bei 0xFF ist akzeptabler Zustand)
- Kein Magic/CRC leere Tabelle (alle 0xFF) ist ein akzeptabler Zustand
**Speichern** (`macro_config_save`):
- SMacroTable in `uint8_t aligned_buf[256] __attribute__((aligned(4)))` kopieren (Pflicht!)
**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)
- Row 1 löschen (`nvm_erase_row`)
- 4 Pages à 64 Byte schreiben (`nvm_write_page`)
- 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, ActionType::MACRO)
## Ausführung (in execute_action_down, ActionType::MACRO)
```
slot = action.data (031)
für Step 03:
für Step 07:
if step.keycode == 0: abbrechen
HID Key-Down (keycode, modifier)
delay(10 ms)
@@ -57,31 +64,3 @@ für Step 03:
```
Die Makro-Tabelle liegt nach `setup()` im RAM (`m_macros` in CMainController). Kein NVM-Zugriff während der Ausführung.
---
## Geplante Erweiterung: 8 Steps (NVM v3)
### Motivation
4 Steps reichen für einfache Shortcuts, aber nicht für Excel-Ribbon-Navigation oder andere Sequenzen mit 5+ Tasten. Mit dem NVM-v3-Umbau (siehe [06_nvm_config.md](06_nvm_config.md)) stehen zwei vollständige Rows für die Makro-Tabelle zur Verfügung.
### Neues Layout
```cpp
#define MACRO_SLOTS 32
#define MACRO_MAX_STEPS 8 // war: 4
struct __attribute__((packed)) SMacroTable {
SMacroStep steps[32][8]; // 32 × 8 × 2 = 512 Bytes = 2 NVM-Rows
};
```
### Neuer NVM-Speicherort
| Row | Adresse | Inhalt |
|---|---|---|
| Macro Row 0 | `0x1FB00` | SMacroTable Bytes 0255 |
| Macro Row 1 | `0x1FC00` | SMacroTable Bytes 256511 |
`macro_config_save` muss entsprechend beide Rows löschen und 8 Pages schreiben (statt bisher 4).