VersaMCU/src/CMainController.h

90 lines
3.8 KiB
C++
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.

// CMainController.h
// Zentraler Orchestrator des VersaPad v2.
// Kennt alle Subsysteme und koordiniert den Datenfluss zwischen ihnen.
// Einzige Instanz wird in main.cpp angelegt.
#pragma once
#include "CButton.h"
#include "CEventQueue.h"
#include "SEvent.h"
#include "hal/matrix.h"
#include "hal/encoder.h"
#include "hal/usb_hid.h"
#include "hal/usb_serial.h"
#include "config/action.h"
#include "config/nvm_config.h"
#include "config/macro_config.h"
class CMainController
{
public:
CMainController();
void setup(); // Einmalig in Arduino setup() aufrufen
void work(); // Jeden Loop-Durchlauf aufrufen
private:
// m_queue muss vor m_buttons deklariert sein: C++ initialisiert Member in
// Deklarationsreihenfolge. Die static-Bridge-Funktion (matrix_cb) erhält
// einen Pointer auf m_queue der muss zum Zeitpunkt der Nutzung gültig sein.
CEventQueue m_queue;
// Alle 25 Matrix-Keys (024) als CButton-Array.
// key_id 03: Encoder-SW (kein LED), key_id 4: NC, key_id 524: MX-Buttons mit LED.
CButton m_buttons[MATRIX_KEYS];
// Encoder CW/CCW-Aktionen aus NVM Encoder haben kein CButton-Objekt.
SAction m_enc_cw[4];
SAction m_enc_ccw[4];
void init_buttons(); // Buttons aus NVM-Config initialisieren
void poll_vendor(); // Eingehende Serial-Pakete (PC→Board) verarbeiten
void processEvents(); // Queue leeren, Aktionen ausführen
void execute_action_down(SAction action, uint8_t key_id); // Taste drücken (Hold-Start)
void execute_action_up(SAction action, uint8_t key_id); // Taste losgelassen (Hold-Ende)
void execute_encoder_action(SAction action, uint8_t enc_id, uint8_t host_event);
void updateLEDs(); // Dirty-LEDs in WS2812-Buffer schreiben
enum : uint8_t {
SERIAL_PAYLOAD_BYTES = 6,
CONFIG_CHUNKS = (sizeof(SDeviceConfig) + SERIAL_PAYLOAD_BYTES - 1) /
SERIAL_PAYLOAD_BYTES,
MACRO_CHUNKS = (sizeof(SMacroTable) + SERIAL_PAYLOAD_BYTES - 1) /
SERIAL_PAYLOAD_BYTES,
};
// ── Config-Empfangspuffer ─────────────────────────────────────────────────
uint8_t m_cfg_buf[sizeof(SDeviceConfig)]; // 740 Bytes
uint8_t m_cfg_received[CONFIG_CHUNKS];
uint8_t m_cfg_chunks_expected;
bool m_cfg_receiving;
bool m_cfg_transfer_valid;
// ── Makro-Empfangspuffer ──────────────────────────────────────────────────
uint8_t m_macro_buf[sizeof(SMacroTable)]; // 512 Bytes
uint8_t m_macro_received[MACRO_CHUNKS];
uint8_t m_macro_chunks_expected;
bool m_macro_receiving;
bool m_macro_transfer_valid;
static bool all_chunks_received(const uint8_t* received, uint8_t count);
// Geladene Makro-Tabelle (im RAM wird beim Start aus NVM geladen)
SMacroTable m_macros;
// Werksreset per Long-Press-Kombination:
// key_id 9 = unterster linker MX-Button (COL_1 / ROW_4)
// key_id 24 = unterster rechter MX-Button (COL_4 / ROW_4)
bool m_factory_left_held;
bool m_factory_right_held;
bool m_factory_reset_armed;
bool m_factory_reset_done;
uint32_t m_factory_hold_started_ms;
bool is_factory_reset_key(uint8_t key_id) const;
bool is_factory_reset_combo_active() const;
void update_factory_reset_led_feedback();
void update_factory_reset_hold(uint8_t key_id, bool pressed);
void check_factory_reset();
void perform_factory_reset();
void show_factory_reset_feedback();
};