Added hold function and updated doc
This commit is contained in:
+45
-33
@@ -1,6 +1,6 @@
|
||||
# Aktions-Engine
|
||||
|
||||
**Dateien:** `config/action.h`, `CMainController.cpp` (`processEvents`, `execute_action`)
|
||||
**Dateien:** `config/action.h`, `CButton.h/.cpp`, `CMainController.cpp` (`processEvents`, `execute_action_down`, `execute_action_up`)
|
||||
|
||||
## SAction-Struct
|
||||
|
||||
@@ -24,47 +24,59 @@ struct __attribute__((packed)) SAction {
|
||||
| `HOST_COMMAND` | Event an VersaGUI senden, App führt aus | Command-ID (frei definiert) |
|
||||
| `MACRO` | Makro-Sequenz aus NVM-Tabelle | Slot-Index 0–31 |
|
||||
|
||||
## Ausführung (execute_action)
|
||||
## execute_action_down() — Taste gedrückt (Hold-Start)
|
||||
|
||||
**HID_KEY:**
|
||||
```
|
||||
usb_hid_send_key(keycode, modifier)
|
||||
delay(10 ms)
|
||||
usb_hid_release_key()
|
||||
```
|
||||
→ Tap-Only-Modell. Kein Hold-Support. KEY_UP löst kein HID-Release aus.
|
||||
| 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 |
|
||||
|
||||
**HID_CONSUMER:**
|
||||
```
|
||||
usb_hid_send_consumer(usage_id)
|
||||
usb_hid_release_consumer()
|
||||
```
|
||||
→ Kein Delay nötig (Consumer-Keys sind Edge-getriggert).
|
||||
## execute_action_up() — Taste losgelassen (Hold-Ende)
|
||||
|
||||
**HOST_COMMAND:**
|
||||
`execute_action()` macht nichts. `processEvents()` sendet zusätzlich `USB_EVT_KEY_DOWN` via CDC Serial an VersaGUI. Die App entscheidet was passiert (URL öffnen, Programm starten, …).
|
||||
| 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**:
|
||||
|
||||
**MACRO:**
|
||||
```
|
||||
für jeden Step [0–3] im Slot:
|
||||
if keycode == 0: abbrechen
|
||||
usb_hid_send_key(keycode, modifier)
|
||||
delay(10 ms)
|
||||
usb_hid_release_key()
|
||||
delay(20 ms) // Pause damit der Host den Step verarbeiten kann
|
||||
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
|
||||
```
|
||||
|
||||
## Event-Verarbeitung
|
||||
Das OS erkennt die gedrückte Taste und startet sein eigenes Key-Repeat nach ~500 ms — wie auf einer normalen Tastatur.
|
||||
|
||||
Events werden in `processEvents()` aus `CEventQueue` konsumiert (FIFO):
|
||||
## Tap-Modell (Encoder CW/CCW)
|
||||
|
||||
- `KEY_DOWN` → `CButton.on_press()` (aktuell leer, Erweiterungspunkt) + `execute_action()`
|
||||
- `KEY_UP` → `CButton.on_release()` (aktuell leer)
|
||||
- `ENC_CW/CCW` → `execute_action(m_enc_cw/ccw[enc_id])`
|
||||
Encoder-Bewegungen sind diskret (kein Halten möglich) und verwenden das **Tap-Modell**:
|
||||
|
||||
Encoder CW/CCW-Aktionen sind in `CMainController` direkt als `SAction`-Arrays gehalten (kein CButton-Objekt, da Encoder keine LED haben).
|
||||
```
|
||||
ENC_CW/ENC_CCW-Event → execute_action_down() + delay(10) + execute_action_up()
|
||||
```
|
||||
|
||||
## Bekannte Einschränkungen
|
||||
(Atomare Sequenz für jeden Encoder-Schritt.)
|
||||
|
||||
- **Kein Hold**: `execute_action` bei KEY_DOWN sendet sofort Key-Down + Key-Up. Halten der Taste löst keine Wiederholung aus.
|
||||
- **HOST_COMMAND KEY_UP**: Board sendet derzeit kein `USB_EVT_KEY_UP` für KEY_UP-Events (nur KEY_DOWN wird gemeldet).
|
||||
## 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()`
|
||||
|
||||
@@ -32,7 +32,7 @@ Beide Rows sind im Linkerscript vom Code-Bereich ausgeschlossen.
|
||||
## CRC16-CCITT
|
||||
|
||||
- Polynom: `0x1021`, Init: `0xFFFF`
|
||||
- Berechnet über Bytes 7–222 (ab `mx_actions`, nach dem `crc`-Feld selbst)
|
||||
- Berechnet über Bytes 7–248 (ab `mx_actions`, nach dem `crc`-Feld selbst)
|
||||
- Sichert Datenintegrität nach NVM-Schreiben und bei Versionswechsel
|
||||
|
||||
## Lese-Logik
|
||||
|
||||
Reference in New Issue
Block a user