/** * @file buttons.h * @brief Button-Handler für ESP32-S3 GameBoy Emulator * * Dieser Header definiert die Button-Verwaltung für: * - 8× GameBoy-Buttons (D-Pad, A, B, Select, Start) * - 1× Power-Button für Sleep/Wake-Modus * * Hardware-Details: * - Alle Buttons sind Active-LOW (Pull-Up mit GND beim Drücken) * - Debouncing: 50ms pro Button * - Power-Button: GPIO 0 (Hardware-Schalter) * - GameBoy-Buttons: GPIO 8-14, 21 * * Integration: * - Direkter Callback zu Peanut-GB Emulator * - FreeRTOS Task für kontinuierliches Polling * - ESP32 Deep Sleep bei Power-Off */ #pragma once #include #include #include "esp_err.h" #ifdef __cplusplus extern "C" { #endif // ============================================ // BUTTON DEFINITIONEN // ============================================ /** * @brief GameBoy Button-Bits (kompatibel mit Peanut-GB Joypad) * * Diese Bit-Flags entsprechen dem GameBoy Joypad-Register (0xFF00) * Bit gesetzt (1) = Button gedrückt */ typedef enum { BTN_FLAG_A = (1 << 0), // A-Button (Aktions-Taste) BTN_FLAG_B = (1 << 1), // B-Button (Aktions-Taste) BTN_FLAG_SELECT = (1 << 2), // Select-Button (System-Taste) BTN_FLAG_START = (1 << 3), // Start-Button (System-Taste) BTN_FLAG_RIGHT = (1 << 4), // D-Pad Rechts BTN_FLAG_LEFT = (1 << 5), // D-Pad Links BTN_FLAG_UP = (1 << 6), // D-Pad Oben BTN_FLAG_DOWN = (1 << 7), // D-Pad Unten } button_flags_t; // ============================================ // ÖFFENTLICHE FUNKTIONEN // ============================================ /** * @brief Button-System initialisieren * @return ESP_OK bei Erfolg, Fehlercode sonst * * Diese Funktion: * - Konfiguriert alle GPIO-Pins als Eingänge mit Pull-Up * - Initialisiert Debouncing-State für alle Buttons * - Erstellt Button-Polling-Task (Core 1, Priorität 5) * - Konfiguriert GPIO 0 als RTC-Wakeup-Source für Deep Sleep * * WICHTIG: Muss vor buttons_start() aufgerufen werden! */ esp_err_t buttons_init(void); /** * @brief Button-Polling Task starten * * Startet den FreeRTOS Task, der kontinuierlich die Buttons abfragt. * Der Task läuft auf Core 1 mit Priorität 5 und aktualisiert * den Joypad-State alle 10ms. * * WICHTIG: buttons_init() muss vorher aufgerufen worden sein! */ void buttons_start(void); /** * @brief Aktuellen Button-State abrufen * @return 8-Bit Bitmaske mit gedrückten Buttons (1 = gedrückt) * * Gibt die aktuelle Button-Kombination zurück. * Mehrere Buttons können gleichzeitig gedrückt sein (z.B. A+B). * * Beispiel: * uint8_t state = buttons_get_state(); * if (state & BTN_FLAG_A) { * printf("A-Button ist gedrückt\n"); * } */ uint8_t buttons_get_state(void); /** * @brief Power-Button Status prüfen * @return true wenn Power-Schalter auf ON, false wenn auf OFF * * Diese Funktion liest den Hardware-Schalter auf GPIO 0. * - ON (true): Schalter geschlossen, GPIO 0 = LOW (GND) * - OFF (false): Schalter offen, GPIO 0 = HIGH (Pull-Up) * * Der Button-Task überwacht diesen Status automatisch und * aktiviert Deep Sleep wenn der Schalter auf OFF steht. */ bool buttons_is_power_on(void); /** * @brief Manuell in Deep Sleep wechseln * * Aktiviert ESP32 Deep Sleep Modus sofort. * Das System wacht nur auf, wenn: * - Power-Button (GPIO 0) auf ON geschaltet wird (LOW) * * Beim Aufwachen führt der ESP32 einen vollständigen Neustart durch. * Der Emulator-State geht verloren (außer wenn vorher gespeichert). * * WICHTIG: Diese Funktion kehrt nicht zurück! */ void buttons_enter_sleep(void); #ifdef __cplusplus } #endif