forked from jappel/VersaMCU
90 lines
3.8 KiB
C++
90 lines
3.8 KiB
C++
// 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 (0–24) als CButton-Array.
|
||
// key_id 0–3: Encoder-SW (kein LED), key_id 4: NC, key_id 5–24: 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();
|
||
};
|