buttons, power button pin 18, deep sleep implementation, dokumentaion, and decription. optimzed sd card and display init, remove bloink screens at start, added color screens for error notifications

This commit is contained in:
2025-12-01 22:44:18 +01:00
parent c4a0fd7769
commit 1675d59f54
10 changed files with 3259 additions and 672 deletions
+125
View File
@@ -0,0 +1,125 @@
/**
* @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 <stdint.h>
#include <stdbool.h>
#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
+20 -11
View File
@@ -128,7 +128,13 @@ extern "C" {
// ============================================
// POWER SWITCH (Hardware Toggle Switch)
// ============================================
#define POWER_SWITCH_PIN 0 // GPIO0 - Hardware power switch
// WICHTIG: Power-Button Enable/Disable Flag
// Setze auf 0 während der Entwicklung (kein Hardware-Schalter verbunden)
// Setze auf 1 wenn Hardware-Schalter angeschlossen ist
#define POWER_BUTTON_ENABLED 1 // 0=deaktiviert, 1=aktiviert
#define POWER_SWITCH_PIN 18 // GPIO18 - Hardware power switch (RTC-fähig, frei)
#define POWER_SWITCH_ON 0 // Switch closed = GND = Device ON
#define POWER_SWITCH_OFF 1 // Switch open = Pull-up = Device goes to sleep
@@ -136,12 +142,13 @@ extern "C" {
// - When switch is CLOSED (pin reads LOW): Device runs normally
// - When switch is OPENED (pin reads HIGH): Device enters deep-sleep
// - When switch is CLOSED again: ESP32 wakes up from deep-sleep
//
//
// Implementation:
// - Configure GPIO0 with internal pull-up
// - Configure GPIO18 with internal pull-up
// - Monitor pin state in main loop
// - On transition LOW->HIGH: Enter esp_deep_sleep_start()
// - ESP32 will wake on GPIO LOW (RTC_GPIO wakeup)
// - POWER_BUTTON_ENABLED muss auf 1 gesetzt werden wenn Schalter verbunden ist
#define POWER_SWITCH_CHECK_MS 100 // Check switch state every 100ms
@@ -177,7 +184,7 @@ extern "C" {
// ============================================
// STATUS LED - Optional
// ============================================
#define LED_STATUS_PIN 18 // Changed from 19 (USB conflict!)
#define LED_STATUS_PIN -1 // Deaktiviert (GPIO 18 wird für Power-Switch verwendet)
#define LED_ACTIVE_LEVEL 1
// ============================================
@@ -193,7 +200,7 @@ extern "C" {
// ============================================
/*
USED PINS - OPTIMIZED LAYOUT:
- GPIO 0: POWER_SWITCH (Hardware toggle switch)
- GPIO 0: FREI (war Power-Switch, aber Pin nicht erreichbar auf Board)
- GPIO 1: LCD Backlight PWM
- GPIO 3: Volume Potentiometer (ADC1_CH2)
- GPIO 4: Brightness Potentiometer (ADC1_CH3)
@@ -211,7 +218,7 @@ USED PINS - OPTIMIZED LAYOUT:
- GPIO 15: Link Cable SCLK (freed from NFC!)
- GPIO 16: I2S DIN (now conflict-free, NFC moved to shared I2C!)
- GPIO 17: Link Cable SIN
- GPIO 18: Status LED (was 19, USB conflict fixed!)
- GPIO 18: POWER_SWITCH (Hardware toggle switch - RTC-fähig!)
- GPIO 19: RESERVED (USB D-)
- GPIO 20: RESERVED (USB D+)
- GPIO 21: BTN_SELECT (native GPIO)
@@ -231,13 +238,15 @@ USED PINS - OPTIMIZED LAYOUT:
POWER SWITCH WIRING:
┌─────────┐
│ ESP32 │
│ GPIO 0 ├──────┬──────── Switch ──────┐
│ GPIO 18 ├──────┬──────── Switch ──────┐
│ │ │ │
│ (Pull-up) [Switch] GND
│ │ │
└─────────┘ │
└─ When closed: GPIO0 = LOW (ON)
When open: GPIO0 = HIGH (SLEEP)
│ │ │
└─────────┘ │
└─ When closed: GPIO18 = LOW (ON)
When open: GPIO18 = HIGH (SLEEP)
WICHTIG: POWER_BUTTON_ENABLED in diesem File auf 1 setzen wenn Schalter verbunden!
*/