VersaMCU/doc/03_action_engine.md

83 lines
2.9 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.

# Aktions-Engine
**Dateien:** `config/action.h`, `CButton.h/.cpp`, `CMainController.cpp` (`processEvents`, `execute_action_down`, `execute_action_up`)
## SAction-Struct
```cpp
struct __attribute__((packed)) SAction {
ActionType type; // 1 Byte
uint16_t data; // 2 Bytes (Keycode, Consumer-Code, Command-ID oder Slot-Index)
};
// Gesamt: 3 Bytes (packed! ohne packed wären es 4 durch Alignment)
```
`packed` ist zwingend damit `sizeof(SDeviceConfig) == 223` mit der C#-Serialisierung in VersaGUI übereinstimmt.
## ActionType
| Typ | Bedeutung | data-Inhalt |
|---|---|---|
| `NONE` | Keine Aktion | — |
| `HID_KEY` | Tastendruck via USB HID Keyboard | Low-Byte = HID Keycode, High-Byte = Modifier |
| `HID_CONSUMER` | Consumer Control (Volume, Media, …) | Consumer Usage ID |
| `HOST_COMMAND` | Event an VersaGUI senden, App führt aus | Command-ID (frei definiert) |
| `MACRO` | Makro-Sequenz aus NVM-Tabelle | Slot-Index 031 |
## execute_action_down() — Taste gedrückt (Hold-Start)
| ActionType | Verhalten |
|---|---|
| `HID_KEY` | `usb_hid_send_key(keycode, modifier)` — Taste bleibt gedrückt bis `execute_action_up()` |
| `HID_CONSUMER` | `usb_hid_send_consumer(usage_id)` — bleibt aktiv bis `execute_action_up()` |
| `HOST_COMMAND` | `usb_serial_send(USB_EVT_KEY_DOWN, key_id)` |
| `MACRO` | Volle Sequenz ausführen (Steps[slot], keycode==0 = Ende, delay 10+20 ms) |
| `NONE` | nop |
## execute_action_up() — Taste losgelassen (Hold-Ende)
| ActionType | Verhalten |
|---|---|
| `HID_KEY` | `usb_hid_release_key()` |
| `HID_CONSUMER` | `usb_hid_release_consumer()` |
| `HOST_COMMAND` | — (optional: könnte `USB_EVT_KEY_UP` senden) |
| `MACRO`/`NONE` | nop |
## Hold-Modell (HID-Keys und Consumer Controls)
Normale Tasten- und Media-Aktionen folgen dem **Hold-Modell**:
```
KEY_DOWN-Event vom Board → execute_action_down() → HID Key-Down senden
[Taste bleibt physisch gedrückt...]
KEY_UP-Event vom Board → execute_action_up() → HID Key-Up senden
```
Das OS erkennt die gedrückte Taste und startet sein eigenes Key-Repeat nach ~500 ms — wie auf einer normalen Tastatur.
## Tap-Modell (Encoder CW/CCW)
Encoder-Bewegungen sind diskret (kein Halten möglich) und verwenden das **Tap-Modell**:
```
ENC_CW/ENC_CCW-Event → execute_action_down() + delay(10) + execute_action_up()
```
(Atomare Sequenz für jeden Encoder-Schritt.)
## Work-Loop-Reihenfolge
```cpp
void work() {
matrix_scan(); // → Events in Queue (KEY_DOWN, KEY_UP, ENC_CW, ENC_CCW)
poll_vendor(); // Serial-Pakete verarbeiten (PC↔Board Kommandos)
processEvents(); // → execute_action_down/up() aufrufen
updateLEDs(); // Dirty-LEDs aktualisieren
}
```
**processEvents() verarbeitet:**
- `KEY_DOWN``execute_action_down()`
- `KEY_UP``execute_action_up()`
- `ENC_CW` / `ENC_CCW``execute_action_down()` + `delay(10)` + `execute_action_up()`