PSRAM auf Oct geändert, POTI Funktionen geändert auf EDIF 4.4, sdkconfig angepasst für nfc manager und potis
This commit is contained in:
parent
2545bd45a2
commit
68c2f3bd35
362
README.md
362
README.md
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
## 📋 Projekt-Übersicht
|
## 📋 Projekt-Übersicht
|
||||||
|
|
||||||
Dieses Projekt ist ein **kompletter GameBoy Emulator** für das Waveshare ESP32-S3-Touch-LCD-2 Board.
|
Dieses Projekt ist ein kompletter GameBoy Emulator für das **Waveshare ESP32-S3-Touch-LCD-2** Board.
|
||||||
|
|
||||||
### ✨ Features
|
### ✨ Features
|
||||||
|
|
||||||
|
|
@ -21,6 +21,179 @@ Dieses Projekt ist ein **kompletter GameBoy Emulator** für das Waveshare ESP32-
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 🚀 Schnellstart - Build & Flash
|
||||||
|
|
||||||
|
### Voraussetzungen
|
||||||
|
|
||||||
|
- **ESP-IDF v4.4** installiert
|
||||||
|
- **Python 3.10** (NICHT 3.12!)
|
||||||
|
- **Git**
|
||||||
|
- **pyenv** (für Python-Version Management)
|
||||||
|
|
||||||
|
### ⚙️ Installation & Build
|
||||||
|
|
||||||
|
#### 1️⃣ Original GNUBoy Repository klonen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Erstelle Arbeitsverzeichnis
|
||||||
|
mkdir -p ~/Arduino/gameboy
|
||||||
|
cd ~/Arduino/gameboy
|
||||||
|
|
||||||
|
# Clone das Original MCH2022 GNUBoy Projekt
|
||||||
|
git clone -b v4.4 --recursive https://github.com/badgeteam/mch2022-esp32-app-gnuboy.git gnuboy
|
||||||
|
cd gnuboy
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2️⃣ Unser angepasstes Projekt darüber kopieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone unser LEGO GameBoy Projekt
|
||||||
|
cd ~/Arduino/gameboy
|
||||||
|
git clone https://git.hacker-net.de/Hacker-Software/lego-esp32s3-gameboy.git
|
||||||
|
|
||||||
|
# Kopiere alle Dateien über das Original-Projekt
|
||||||
|
cp -r lego-esp32s3-gameboy/* gnuboy/
|
||||||
|
cd gnuboy
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3️⃣ ESP-IDF v4.4 Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Abhängigkeiten installieren
|
||||||
|
sudo apt install python3-gevent python3-virtualenv git wget flex bison gperf python3 python3-pip python3-setuptools cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 curl
|
||||||
|
sudo apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
libssl-dev \
|
||||||
|
zlib1g-dev \
|
||||||
|
libbz2-dev \
|
||||||
|
libreadline-dev \
|
||||||
|
libsqlite3-dev \
|
||||||
|
wget \
|
||||||
|
curl \
|
||||||
|
llvm \
|
||||||
|
libncurses5-dev \
|
||||||
|
libncursesw5-dev \
|
||||||
|
xz-utils \
|
||||||
|
tk-dev \
|
||||||
|
libffi-dev \
|
||||||
|
liblzma-dev \
|
||||||
|
python3-openssl \
|
||||||
|
git
|
||||||
|
|
||||||
|
|
||||||
|
# pyenv installieren (falls noch nicht vorhanden)
|
||||||
|
curl https://pyenv.run | bash
|
||||||
|
|
||||||
|
# Zu ~/.bashrc hinzufügen:
|
||||||
|
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
|
||||||
|
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
|
||||||
|
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
|
||||||
|
source ~/.bashrc
|
||||||
|
|
||||||
|
# Python 3.10 installieren und aktivieren
|
||||||
|
pyenv install 3.10.13
|
||||||
|
pyenv local 3.10.13
|
||||||
|
|
||||||
|
# ESP-IDF v4.4 installieren
|
||||||
|
git clone -b v4.4 --recursive https://github.com/espressif/esp-idf.git ~/esp-idf
|
||||||
|
cd ~/esp-idf
|
||||||
|
./install.sh esp32s3
|
||||||
|
source ./export.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4️⃣ **WICHTIG: Fix-Scripts ausführen!**
|
||||||
|
|
||||||
|
⚠️ **Vor dem Kompilieren müssen zwingend diese beiden Scripts ausgeführt werden:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/Arduino/gameboy/gnuboy
|
||||||
|
|
||||||
|
# 1. PSRAM-Kompatibilität für ESP-IDF v4.4 herstellen
|
||||||
|
chmod +x fix_psram.sh
|
||||||
|
./fix_psram.sh
|
||||||
|
|
||||||
|
# 2. Komponenten-Abhängigkeiten fixen (Potentiometer, NFC, JSON)
|
||||||
|
chmod +x fix_poti_manager_nfc_json.sh
|
||||||
|
./fix_poti_manager_nfc_json.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Was machen diese Scripts?**
|
||||||
|
- `fix_psram.sh`: Ersetzt `esp_psram` mit `esp_hw_support` (ESP-IDF v4.4 API-Änderung)
|
||||||
|
- `fix_poti_manager_nfc_json.sh`:
|
||||||
|
- Fügt fehlende Komponenten-Abhängigkeiten hinzu (json, fatfs, st7789)
|
||||||
|
- Kopiert `hardware_config.h` an die richtigen Stellen
|
||||||
|
- Passt ADC-API für Potentiometer an (entfernt deprecated `esp_adc_cal`)
|
||||||
|
|
||||||
|
#### 5️⃣ Projekt konfigurieren & bauen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/Arduino/gameboy/gnuboy
|
||||||
|
|
||||||
|
# ESP-IDF Environment laden
|
||||||
|
source ~/esp-idf/export.sh
|
||||||
|
|
||||||
|
# Target setzen
|
||||||
|
idf.py set-target esp32s3
|
||||||
|
|
||||||
|
# (Optional) Konfiguration anpassen, wird schon durch script fix_psram.sh gemacht
|
||||||
|
idf.py menuconfig
|
||||||
|
# → Component config → ESP32S3-Specific → PSRAM auf "Octal Mode" setzen
|
||||||
|
|
||||||
|
# Projekt bauen
|
||||||
|
idf.py build
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 6️⃣ Flashen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# USB-Port finden (meist /dev/ttyUSB0 oder /dev/ttyACM0)
|
||||||
|
ls /dev/ttyUSB* /dev/ttyACM*
|
||||||
|
|
||||||
|
# Flashen (ggf. BOOT-Button beim Verbinden gedrückt halten)
|
||||||
|
idf.py -p /dev/ttyUSB0 flash
|
||||||
|
|
||||||
|
# Mit Monitor (zum Debuggen)
|
||||||
|
idf.py -p /dev/ttyUSB0 flash monitor
|
||||||
|
|
||||||
|
# Monitor beenden: Ctrl + ]
|
||||||
|
#Einfach nur monitor
|
||||||
|
#idf.py -p /dev/ttyUSB0 monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🐛 Troubleshooting
|
||||||
|
|
||||||
|
#### Python 3.12 Fehler?
|
||||||
|
```bash
|
||||||
|
# Python 3.10 installieren:
|
||||||
|
siehe anfang 3️⃣ ESP-IDF v4.4 Setup
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Build Fehler?
|
||||||
|
```bash
|
||||||
|
# Clean & rebuild:
|
||||||
|
idf.py fullclean
|
||||||
|
idf.py build
|
||||||
|
```
|
||||||
|
|
||||||
|
#### PSRAM nicht erkannt?
|
||||||
|
```bash
|
||||||
|
# Octal PSRAM aktivieren:
|
||||||
|
idf.py menuconfig
|
||||||
|
# → Component config → ESP32S3-Specific
|
||||||
|
# → [*] Support for external, SPI-connected RAM
|
||||||
|
# → SPI RAM config → Mode: Octal Mode PSRAM
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Board kommt nicht in Flash-Modus?
|
||||||
|
```
|
||||||
|
1. BOOT-Button gedrückt halten
|
||||||
|
2. RESET-Button kurz drücken
|
||||||
|
3. BOOT-Button loslassen
|
||||||
|
4. Flash-Befehl ausführen
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 🛠️ Hardware
|
## 🛠️ Hardware
|
||||||
|
|
||||||
### Hauptkomponenten
|
### Hauptkomponenten
|
||||||
|
|
@ -35,43 +208,37 @@ Dieses Projekt ist ein **kompletter GameBoy Emulator** für das Waveshare ESP32-
|
||||||
|
|
||||||
### Pin-Belegung
|
### Pin-Belegung
|
||||||
|
|
||||||
Siehe `main/hardware_config.h` für **alle** Pin-Definitionen!
|
> **Siehe `main/hardware_config.h` für alle Pin-Definitionen!**
|
||||||
|
|
||||||
**Wichtigste Pins:**
|
**Wichtigste Pins:**
|
||||||
|
|
||||||
```
|
**Display (ST7789):**
|
||||||
Display (ST7789):
|
|
||||||
- MOSI: GPIO 11
|
- MOSI: GPIO 11
|
||||||
- SCLK: GPIO 12
|
- SCLK: GPIO 12
|
||||||
- CS: GPIO 10
|
- CS: GPIO 10
|
||||||
- DC: GPIO 8
|
- DC: GPIO 8
|
||||||
- RST: GPIO 14
|
- RST: GPIO 14
|
||||||
- BL: GPIO 9
|
- BL: GPIO 9
|
||||||
|
|
||||||
Audio (I2S):
|
**Audio (I2S):**
|
||||||
- BCLK: GPIO 41
|
- BCLK: GPIO 35
|
||||||
- LRC: GPIO 42
|
- LRC: GPIO 36
|
||||||
- DIN: GPIO 40
|
- DIN: GPIO 37
|
||||||
|
|
||||||
NFC (PN532):
|
**NFC (PN532):**
|
||||||
- SCL: GPIO 16
|
- SCL: GPIO 16
|
||||||
- SDA: GPIO 15
|
- SDA: GPIO 15
|
||||||
|
|
||||||
Buttons:
|
**Buttons:**
|
||||||
- UP: GPIO 1
|
- UP: GPIO 1, DOWN: GPIO 2
|
||||||
- DOWN: GPIO 2
|
- LEFT: GPIO 42, RIGHT: GPIO 41
|
||||||
- LEFT: GPIO 42
|
- A: GPIO 21, B: GPIO 47
|
||||||
- RIGHT: GPIO 41
|
- START: GPIO 48, SELECT: GPIO 45
|
||||||
- A: GPIO 21
|
|
||||||
- B: GPIO 47
|
|
||||||
- START: GPIO 48
|
|
||||||
- SELECT:GPIO 45
|
|
||||||
|
|
||||||
Link Cable:
|
**Link Cable:**
|
||||||
- SCLK: GPIO 17
|
- SCLK: GPIO 17
|
||||||
- SOUT: GPIO 18
|
- SOUT: GPIO 18
|
||||||
- SIN: GPIO 38
|
- SIN: GPIO 38
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -79,89 +246,44 @@ Link Cable:
|
||||||
|
|
||||||
```
|
```
|
||||||
esp32-s3-gnuboy/
|
esp32-s3-gnuboy/
|
||||||
├── CMakeLists.txt # Root CMake
|
├── CMakeLists.txt # Root CMake
|
||||||
├── sdkconfig.defaults # ESP-IDF config
|
├── sdkconfig.defaults # ESP-IDF config
|
||||||
├── partitions.csv # Flash partitions
|
├── partitions.csv # Flash partitions
|
||||||
├── README.md # Diese Datei
|
├── README.md # Diese Datei
|
||||||
|
├── fix_psram.sh # ⚠️ WICHTIG: Vor Build ausführen!
|
||||||
|
├── fix_poti_manager_nfc_json.sh # ⚠️ WICHTIG: Vor Build ausführen!
|
||||||
│
|
│
|
||||||
├── main/
|
├── main/
|
||||||
│ ├── CMakeLists.txt
|
│ ├── CMakeLists.txt
|
||||||
│ ├── main.c # Hauptprogramm
|
│ ├── main.c # Hauptprogramm
|
||||||
│ └── hardware_config.h # Pin-Definitionen
|
│ └── include/
|
||||||
|
│ └── hardware_config.h # Pin-Definitionen
|
||||||
│
|
│
|
||||||
└── components/
|
└── components/
|
||||||
├── gnuboy/ # GNUBoy Emulator Core
|
├── gnuboy/ # GNUBoy Emulator Core
|
||||||
│ ├── CMakeLists.txt
|
│ ├── CMakeLists.txt
|
||||||
│ ├── include/gnuboy.h
|
│ ├── include/gnuboy.h
|
||||||
│ └── gnuboy_placeholder.c
|
│ └── gnuboy_placeholder.c
|
||||||
│
|
│
|
||||||
├── st7789/ # Display Driver
|
├── st7789/ # Display Driver
|
||||||
│ ├── CMakeLists.txt
|
│ ├── CMakeLists.txt
|
||||||
│ ├── include/st7789.h
|
│ ├── include/st7789.h
|
||||||
│ └── st7789.c
|
│ └── st7789.c
|
||||||
│
|
│
|
||||||
├── nfc_manager/ # NFC ROM Selection
|
├── nfc_manager/ # NFC ROM Selection
|
||||||
│ ├── CMakeLists.txt
|
│ ├── CMakeLists.txt
|
||||||
│ ├── include/nfc_manager.h
|
│ ├── include/nfc_manager.h
|
||||||
│ └── nfc_manager.c
|
│ └── nfc_manager.c
|
||||||
│
|
│
|
||||||
└── link_cable/ # 2-Player Support
|
├── link_cable/ # 2-Player Support
|
||||||
|
│ ├── CMakeLists.txt
|
||||||
|
│ ├── include/link_cable.h
|
||||||
|
│ └── link_cable.c
|
||||||
|
│
|
||||||
|
└── potentiometer_manager/ # Volume/Brightness Control
|
||||||
├── CMakeLists.txt
|
├── CMakeLists.txt
|
||||||
├── include/link_cable.h
|
├── include/potentiometer_manager.h
|
||||||
└── link_cable.c
|
└── potentiometer_manager.c
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Build & Flash
|
|
||||||
|
|
||||||
### Voraussetzungen
|
|
||||||
|
|
||||||
1. **ESP-IDF v4.4** installiert
|
|
||||||
2. **Python 3.10** (NICHT 3.12!)
|
|
||||||
3. **Git**
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Repository klonen
|
|
||||||
git clone <dein-repo>
|
|
||||||
cd esp32-s3-gnuboy
|
|
||||||
|
|
||||||
# 2. ESP-IDF aktivieren
|
|
||||||
source ~/esp-idf/export.sh
|
|
||||||
|
|
||||||
# 3. Target setzen
|
|
||||||
idf.py set-target esp32s3
|
|
||||||
|
|
||||||
# 4. (Optional) Konfiguration anpassen
|
|
||||||
idf.py menuconfig
|
|
||||||
|
|
||||||
# 5. Bauen
|
|
||||||
idf.py build
|
|
||||||
|
|
||||||
# 6. Flashen
|
|
||||||
idf.py -p /dev/ttyUSB0 flash
|
|
||||||
|
|
||||||
# 7. Monitor
|
|
||||||
idf.py monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
### Troubleshooting
|
|
||||||
|
|
||||||
**Python 3.12 Fehler?**
|
|
||||||
```bash
|
|
||||||
# Python 3.10 installieren:
|
|
||||||
sudo apt-get install python3.10 python3.10-venv
|
|
||||||
cd ~/esp-idf
|
|
||||||
python3.10 ./install.sh esp32s3
|
|
||||||
```
|
|
||||||
|
|
||||||
**Build Fehler?**
|
|
||||||
```bash
|
|
||||||
# Clean & rebuild:
|
|
||||||
idf.py fullclean
|
|
||||||
idf.py build
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -170,18 +292,18 @@ idf.py build
|
||||||
|
|
||||||
### ROMs laden
|
### ROMs laden
|
||||||
|
|
||||||
1. **SD-Karte formatieren** (FAT32)
|
1. SD-Karte formatieren (FAT32)
|
||||||
2. **Verzeichnis erstellen:** `/roms/gb/`
|
2. Verzeichnis erstellen: `/roms/gb/`
|
||||||
3. **ROMs kopieren** (.gb oder .gbc Dateien)
|
3. ROMs kopieren (.gb oder .gbc Dateien)
|
||||||
4. **SD-Karte einlegen**
|
4. SD-Karte einlegen
|
||||||
|
|
||||||
### NFC ROM-Auswahl
|
### NFC ROM-Auswahl
|
||||||
|
|
||||||
1. **NFC Tags programmieren** mit ROM-Namen
|
- NFC Tags programmieren mit ROM-Namen
|
||||||
2. **Tag scannen** → ROM startet automatisch!
|
- Tag scannen → ROM startet automatisch!
|
||||||
3. **Mapping-File:** `/sd/nfc_roms.json`
|
- Mapping-File: `/sd/nfc_roms.json`
|
||||||
|
|
||||||
Beispiel `nfc_roms.json`:
|
**Beispiel `nfc_roms.json`:**
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"mappings": [
|
"mappings": [
|
||||||
|
|
@ -199,23 +321,23 @@ Beispiel `nfc_roms.json`:
|
||||||
|
|
||||||
### Link Cable 2-Player
|
### Link Cable 2-Player
|
||||||
|
|
||||||
1. **Zwei GameBoys bauen**
|
- Zwei GameBoys bauen
|
||||||
2. **Link Cable verbinden:**
|
- Link Cable verbinden:
|
||||||
- SCLK ↔ SCLK
|
- SCLK ↔ SCLK
|
||||||
- SOUT ↔ SIN (gekreuzt!)
|
- SOUT ↔ SIN (gekreuzt!)
|
||||||
- SIN ↔ SOUT (gekreuzt!)
|
- SIN ↔ SOUT (gekreuzt!)
|
||||||
- GND ↔ GND
|
- GND ↔ GND
|
||||||
3. **Gleiches ROM laden** auf beiden
|
- Gleiches ROM laden auf beiden
|
||||||
4. **Im Spiel:** 2-Player Mode wählen
|
- Im Spiel: 2-Player Mode wählen
|
||||||
5. **Spielen!** 🎮🔗🎮
|
- Spielen! 🎮🔗🎮
|
||||||
|
|
||||||
### Buttons
|
### Buttons
|
||||||
|
|
||||||
```
|
|
||||||
GameBoy Layout:
|
GameBoy Layout:
|
||||||
|
```
|
||||||
┌─────┐
|
┌─────┐
|
||||||
←→↑↓ B A
|
←→↑↓ B A
|
||||||
SELECT START
|
SELECT START
|
||||||
```
|
```
|
||||||
|
|
||||||
- **D-Pad:** Bewegung
|
- **D-Pad:** Bewegung
|
||||||
|
|
@ -232,19 +354,20 @@ GameBoy Layout:
|
||||||
|
|
||||||
## 🔧 Entwicklung
|
## 🔧 Entwicklung
|
||||||
|
|
||||||
### Nächste Schritte
|
### Aktueller Status
|
||||||
|
|
||||||
**Aktueller Status:**
|
|
||||||
- ✅ Projekt-Struktur fertig
|
- ✅ Projekt-Struktur fertig
|
||||||
- ✅ CMake Build System
|
- ✅ CMake Build System
|
||||||
- ✅ Pin-Konfiguration
|
- ✅ Pin-Konfiguration
|
||||||
- ✅ Component-Grundstruktur
|
- ✅ Component-Grundstruktur
|
||||||
|
- ✅ ESP-IDF v4.4 Kompatibilität
|
||||||
|
- ✅ PSRAM Support (8MB Octal)
|
||||||
- ⏳ GNUBoy Core Integration
|
- ⏳ GNUBoy Core Integration
|
||||||
- ⏳ ST7789 Driver fertigstellen
|
- ⏳ ST7789 Driver fertigstellen
|
||||||
- ⏳ NFC Implementation
|
- ⏳ NFC Implementation
|
||||||
- ⏳ Link Cable Implementation
|
- ⏳ Link Cable Implementation
|
||||||
|
|
||||||
**TODO:**
|
### TODO
|
||||||
|
|
||||||
1. **GNUBoy Core integrieren:**
|
1. **GNUBoy Core integrieren:**
|
||||||
- Quellcode von esplay-gb portieren
|
- Quellcode von esplay-gb portieren
|
||||||
|
|
@ -274,8 +397,8 @@ GameBoy Layout:
|
||||||
### Code-Richtlinien
|
### Code-Richtlinien
|
||||||
|
|
||||||
- **Zentralisierte Konfiguration:** Alle Pins in `hardware_config.h`
|
- **Zentralisierte Konfiguration:** Alle Pins in `hardware_config.h`
|
||||||
- **ESP-IDF Stil:** ESP_LOG statt printf
|
- **ESP-IDF Stil:** `ESP_LOG` statt `printf`
|
||||||
- **Fehlerbehandlung:** Immer ESP_ERROR_CHECK nutzen
|
- **Fehlerbehandlung:** Immer `ESP_ERROR_CHECK` nutzen
|
||||||
- **Dokumentation:** Doxygen-Kommentare
|
- **Dokumentation:** Doxygen-Kommentare
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -291,6 +414,7 @@ GameBoy Layout:
|
||||||
|
|
||||||
- **GNUBoy:** Original GameBoy Emulator
|
- **GNUBoy:** Original GameBoy Emulator
|
||||||
- **esplay-gb:** ESP32 Port von pebri86
|
- **esplay-gb:** ESP32 Port von pebri86
|
||||||
|
- **MCH2022 Badge Team:** ESP32 GNUBoy App
|
||||||
- **Waveshare:** Hardware Board
|
- **Waveshare:** Hardware Board
|
||||||
- **Stefan:** LEGO GameBoy Projekt! 🎮
|
- **Stefan:** LEGO GameBoy Projekt! 🎮
|
||||||
|
|
||||||
|
|
@ -299,10 +423,12 @@ GameBoy Layout:
|
||||||
## 📞 Support
|
## 📞 Support
|
||||||
|
|
||||||
Bei Fragen oder Problemen:
|
Bei Fragen oder Problemen:
|
||||||
|
|
||||||
1. Hardware-Config prüfen (`hardware_config.h`)
|
1. Hardware-Config prüfen (`hardware_config.h`)
|
||||||
2. Serial Monitor checken (`idf.py monitor`)
|
2. Serial Monitor checken (`idf.py monitor`)
|
||||||
3. Build-Log lesen
|
3. Build-Log lesen
|
||||||
4. Pin-Konflikte überprüfen
|
4. Pin-Konflikte überprüfen
|
||||||
|
5. Fix-Scripts ausgeführt? (`fix_psram.sh` & `fix_poti_manager_nfc_json.sh`)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -316,7 +442,7 @@ Bei Fragen oder Problemen:
|
||||||
- Professionelle Qualität
|
- Professionelle Qualität
|
||||||
- Open Source
|
- Open Source
|
||||||
|
|
||||||
**Let's build it!** 🚀🎮
|
**Let's build it! 🚀🎮**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* @file potentiometer_manager.c
|
* @file potentiometer_manager.c
|
||||||
* @brief Potentiometer Manager Implementation - COMPLETE!
|
* @brief Potentiometer Manager Implementation - ESP-IDF v4.4 Compatible
|
||||||
*
|
*
|
||||||
* Features:
|
* Features:
|
||||||
* - Dual ADC reading (Volume + Brightness)
|
* - Dual ADC reading (Volume + Brightness)
|
||||||
|
|
@ -8,12 +8,13 @@
|
||||||
* - Automatic monitoring task
|
* - Automatic monitoring task
|
||||||
* - Callback on changes
|
* - Callback on changes
|
||||||
* - Direct ST7789 brightness control
|
* - Direct ST7789 brightness control
|
||||||
|
*
|
||||||
|
* NOTE: Simplified for ESP-IDF v4.4 - removed esp_adc_cal (not available in v4.4)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "driver/adc.h"
|
#include "driver/adc.h"
|
||||||
#include "esp_adc_cal.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "potentiometer_manager.h"
|
#include "potentiometer_manager.h"
|
||||||
|
|
@ -36,10 +37,6 @@ static TaskHandle_t poti_task_handle = NULL;
|
||||||
static bool poti_task_running = false;
|
static bool poti_task_running = false;
|
||||||
static poti_change_callback_t change_callback = NULL;
|
static poti_change_callback_t change_callback = NULL;
|
||||||
|
|
||||||
// ADC calibration
|
|
||||||
static esp_adc_cal_characteristics_t adc1_chars;
|
|
||||||
static esp_adc_cal_characteristics_t adc2_chars;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize ADC for potentiometers
|
* @brief Initialize ADC for potentiometers
|
||||||
*/
|
*/
|
||||||
|
|
@ -52,27 +49,23 @@ static esp_err_t poti_adc_init(void)
|
||||||
// Configure ADC2 (Brightness - GPIO 46)
|
// Configure ADC2 (Brightness - GPIO 46)
|
||||||
adc2_config_channel_atten(ADC2_CHANNEL_5, POTI_ADC_ATTEN); // GPIO 46 = ADC2_CH5
|
adc2_config_channel_atten(ADC2_CHANNEL_5, POTI_ADC_ATTEN); // GPIO 46 = ADC2_CH5
|
||||||
|
|
||||||
// Characterize ADC
|
ESP_LOGI(TAG, "ADC configured for potentiometers");
|
||||||
esp_adc_cal_characterize(ADC_UNIT_1, POTI_ADC_ATTEN, POTI_ADC_WIDTH,
|
|
||||||
1100, &adc1_chars);
|
|
||||||
esp_adc_cal_characterize(ADC_UNIT_2, POTI_ADC_ATTEN, POTI_ADC_WIDTH,
|
|
||||||
1100, &adc2_chars);
|
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read ADC with averaging
|
* @brief Read ADC with averaging (simplified - no calibration)
|
||||||
*/
|
*/
|
||||||
static uint32_t poti_read_adc1_averaged(void)
|
static uint32_t poti_read_adc1_averaged(void)
|
||||||
{
|
{
|
||||||
uint32_t sum = 0;
|
uint32_t sum = 0;
|
||||||
|
|
||||||
for (int i = 0; i < ADC_SAMPLES; i++) {
|
for (int i = 0; i < ADC_SAMPLES; i++) {
|
||||||
uint32_t voltage;
|
|
||||||
int raw = adc1_get_raw(ADC1_CHANNEL_2);
|
int raw = adc1_get_raw(ADC1_CHANNEL_2);
|
||||||
voltage = esp_adc_cal_raw_to_voltage(raw, &adc1_chars);
|
if (raw >= 0) {
|
||||||
sum += voltage;
|
sum += raw;
|
||||||
|
}
|
||||||
vTaskDelay(pdMS_TO_TICKS(1));
|
vTaskDelay(pdMS_TO_TICKS(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,34 +75,38 @@ static uint32_t poti_read_adc1_averaged(void)
|
||||||
static uint32_t poti_read_adc2_averaged(void)
|
static uint32_t poti_read_adc2_averaged(void)
|
||||||
{
|
{
|
||||||
uint32_t sum = 0;
|
uint32_t sum = 0;
|
||||||
|
int valid_samples = 0;
|
||||||
|
|
||||||
for (int i = 0; i < ADC_SAMPLES; i++) {
|
for (int i = 0; i < ADC_SAMPLES; i++) {
|
||||||
int raw;
|
int raw;
|
||||||
uint32_t voltage;
|
|
||||||
|
|
||||||
// ADC2 read (can fail if WiFi is active!)
|
// ADC2 read (can fail if WiFi is active!)
|
||||||
esp_err_t ret = adc2_get_raw(ADC2_CHANNEL_5, POTI_ADC_WIDTH, &raw);
|
esp_err_t ret = adc2_get_raw(ADC2_CHANNEL_5, POTI_ADC_WIDTH, &raw);
|
||||||
if (ret == ESP_OK) {
|
if (ret == ESP_OK && raw >= 0) {
|
||||||
voltage = esp_adc_cal_raw_to_voltage(raw, &adc2_chars);
|
sum += raw;
|
||||||
sum += voltage;
|
valid_samples++;
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(TAG, "ADC2 read failed (WiFi active?)");
|
ESP_LOGD(TAG, "ADC2 read failed (WiFi active?)");
|
||||||
return sum / (i > 0 ? i : 1); // Return partial average
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1));
|
vTaskDelay(pdMS_TO_TICKS(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sum / ADC_SAMPLES;
|
if (valid_samples == 0) {
|
||||||
|
return 0; // No valid readings
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum / valid_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convert voltage to percentage (0-100%)
|
* @brief Convert raw ADC value to percentage (0-100%)
|
||||||
|
* For 12-bit ADC: 0-4095 range
|
||||||
*/
|
*/
|
||||||
static uint8_t voltage_to_percent(uint32_t voltage_mv, uint32_t max_mv)
|
static uint8_t raw_to_percent(uint32_t raw_value, uint32_t max_value)
|
||||||
{
|
{
|
||||||
if (voltage_mv >= max_mv) return 100;
|
if (raw_value >= max_value) return 100;
|
||||||
return (voltage_mv * 100) / max_mv;
|
return (raw_value * 100) / max_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -120,13 +117,13 @@ static void poti_monitor_task(void *arg)
|
||||||
ESP_LOGI(TAG, "Potentiometer monitoring task started");
|
ESP_LOGI(TAG, "Potentiometer monitoring task started");
|
||||||
|
|
||||||
while (poti_task_running) {
|
while (poti_task_running) {
|
||||||
// Read potentiometers
|
// Read potentiometers (raw ADC values)
|
||||||
uint32_t volume_mv = poti_read_adc1_averaged();
|
uint32_t volume_raw = poti_read_adc1_averaged();
|
||||||
uint32_t brightness_mv = poti_read_adc2_averaged();
|
uint32_t brightness_raw = poti_read_adc2_averaged();
|
||||||
|
|
||||||
// Convert to percentage
|
// Convert to percentage (12-bit ADC: 0-4095)
|
||||||
uint8_t new_volume = voltage_to_percent(volume_mv, 3300);
|
uint8_t new_volume = raw_to_percent(volume_raw, 4095);
|
||||||
uint8_t new_brightness = voltage_to_percent(brightness_mv, 3300);
|
uint8_t new_brightness = raw_to_percent(brightness_raw, 4095);
|
||||||
|
|
||||||
// Clamp brightness to minimum (display shouldn't be completely off)
|
// Clamp brightness to minimum (display shouldn't be completely off)
|
||||||
if (new_brightness < LCD_BCKL_MIN) {
|
if (new_brightness < LCD_BCKL_MIN) {
|
||||||
|
|
@ -169,12 +166,16 @@ esp_err_t poti_manager_init(void)
|
||||||
ESP_LOGI(TAG, "Initializing Potentiometer Manager...");
|
ESP_LOGI(TAG, "Initializing Potentiometer Manager...");
|
||||||
|
|
||||||
// Initialize ADC
|
// Initialize ADC
|
||||||
ESP_ERROR_CHECK(poti_adc_init());
|
esp_err_t ret = poti_adc_init();
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to initialize ADC");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// Read initial values
|
// Read initial values
|
||||||
poti_update();
|
poti_update();
|
||||||
|
|
||||||
ESP_LOGI(TAG, "✓ Potentiometer Manager initialized");
|
ESP_LOGI(TAG, "Potentiometer Manager initialized");
|
||||||
ESP_LOGI(TAG, " Volume: %d%%, Brightness: %d%%",
|
ESP_LOGI(TAG, " Volume: %d%%, Brightness: %d%%",
|
||||||
current_volume, current_brightness);
|
current_volume, current_brightness);
|
||||||
|
|
||||||
|
|
@ -206,7 +207,7 @@ esp_err_t poti_manager_start(poti_change_callback_t callback)
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGI(TAG, "✓ Potentiometer monitoring started");
|
ESP_LOGI(TAG, "Potentiometer monitoring started");
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -236,11 +237,11 @@ uint8_t poti_get_brightness(void)
|
||||||
esp_err_t poti_update(void)
|
esp_err_t poti_update(void)
|
||||||
{
|
{
|
||||||
// Manual single update (without task)
|
// Manual single update (without task)
|
||||||
uint32_t volume_mv = poti_read_adc1_averaged();
|
uint32_t volume_raw = poti_read_adc1_averaged();
|
||||||
uint32_t brightness_mv = poti_read_adc2_averaged();
|
uint32_t brightness_raw = poti_read_adc2_averaged();
|
||||||
|
|
||||||
current_volume = voltage_to_percent(volume_mv, 3300);
|
current_volume = raw_to_percent(volume_raw, 4095);
|
||||||
current_brightness = voltage_to_percent(brightness_mv, 3300);
|
current_brightness = raw_to_percent(brightness_raw, 4095);
|
||||||
|
|
||||||
if (current_brightness < LCD_BCKL_MIN) {
|
if (current_brightness < LCD_BCKL_MIN) {
|
||||||
current_brightness = LCD_BCKL_MIN;
|
current_brightness = LCD_BCKL_MIN;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Fix remaining compilation errors for gnuboy ESP32-S3
|
||||||
|
|
||||||
|
# Set your gnuboy project path here (adjust if needed!)
|
||||||
|
GNUBOY_DIR=~/Arduino/gameboy/gnuboy
|
||||||
|
|
||||||
|
echo "=== Fixing gnuboy compilation errors ==="
|
||||||
|
echo "Project directory: $GNUBOY_DIR"
|
||||||
|
|
||||||
|
if [ ! -d "$GNUBOY_DIR" ]; then
|
||||||
|
echo "ERROR: Project directory not found!"
|
||||||
|
echo "Please edit this script and set GNUBOY_DIR to your gnuboy path"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$GNUBOY_DIR"
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 1. Copy hardware_config.h to main/include if comes from an old build, else error file not found. Zhis was okay in newer version. If you are on newer version comment it out to supress copy error
|
||||||
|
# ============================================
|
||||||
|
echo ""
|
||||||
|
echo "1. Installing hardware_config.h..."
|
||||||
|
mkdir -p main/include
|
||||||
|
cp main/hardware_config.h main/include/
|
||||||
|
echo " ✓ hardware_config.h installed"
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 2. Fix potentiometer_manager - ADC calibration
|
||||||
|
# ============================================
|
||||||
|
echo ""
|
||||||
|
echo "2. Fixing potentiometer_manager (esp_adc_cal.h issue)..."
|
||||||
|
|
||||||
|
# Check if component exists
|
||||||
|
if [ -f "components/potentiometer_manager/potentiometer_manager.c" ]; then
|
||||||
|
# Replace esp_adc_cal.h with esp_adc/adc_cali.h (ESP-IDF v4.4)
|
||||||
|
sed -i 's/#include "esp_adc_cal.h"/#include "driver\/adc.h"/g' \
|
||||||
|
components/potentiometer_manager/potentiometer_manager.c
|
||||||
|
|
||||||
|
# Also need to fix ADC calibration API calls if present
|
||||||
|
# In ESP-IDF v4.4, ADC calibration is optional/different
|
||||||
|
echo " ✓ potentiometer_manager patched"
|
||||||
|
else
|
||||||
|
echo " ⚠ potentiometer_manager not found, skipping"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 3. Add cJSON dependency to nfc_manager
|
||||||
|
# ============================================
|
||||||
|
echo ""
|
||||||
|
echo "3. Fixing nfc_manager (cJSON dependency)..."
|
||||||
|
|
||||||
|
if [ -f "components/nfc_manager/CMakeLists.txt" ]; then
|
||||||
|
# Check if cJSON is already in REQUIRES
|
||||||
|
if ! grep -q "json" components/nfc_manager/CMakeLists.txt; then
|
||||||
|
# Add json to REQUIRES (cJSON is part of ESP-IDF as 'json' component)
|
||||||
|
sed -i 's/REQUIRES \(.*\)/REQUIRES \1 json/g' components/nfc_manager/CMakeLists.txt
|
||||||
|
echo " ✓ cJSON dependency added"
|
||||||
|
else
|
||||||
|
echo " ✓ cJSON dependency already present"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo " ⚠ nfc_manager/CMakeLists.txt not found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 4. Add hardware_config.h include path to components
|
||||||
|
# ============================================
|
||||||
|
echo ""
|
||||||
|
echo "4. Adding hardware_config.h include paths..."
|
||||||
|
|
||||||
|
# Components that need hardware_config.h
|
||||||
|
COMPONENTS="st7789 link_cable potentiometer_manager"
|
||||||
|
|
||||||
|
for comp in $COMPONENTS; do
|
||||||
|
if [ -f "components/$comp/CMakeLists.txt" ]; then
|
||||||
|
# Add main/include to include directories
|
||||||
|
if ! grep -q "\${CMAKE_SOURCE_DIR}/main/include" "components/$comp/CMakeLists.txt"; then
|
||||||
|
# Find PRIV_INCLUDE_DIRS or add after idf_component_register
|
||||||
|
if grep -q "PRIV_INCLUDE_DIRS" "components/$comp/CMakeLists.txt"; then
|
||||||
|
sed -i "s|PRIV_INCLUDE_DIRS|PRIV_INCLUDE_DIRS \"\${CMAKE_SOURCE_DIR}/main/include\"|g" \
|
||||||
|
"components/$comp/CMakeLists.txt"
|
||||||
|
elif grep -q "idf_component_register" "components/$comp/CMakeLists.txt"; then
|
||||||
|
# Add INCLUDE_DIRS line before closing parenthesis
|
||||||
|
sed -i '/idf_component_register(/a\ INCLUDE_DIRS "include" "${CMAKE_SOURCE_DIR}/main/include"' \
|
||||||
|
"components/$comp/CMakeLists.txt"
|
||||||
|
fi
|
||||||
|
echo " ✓ $comp: hardware_config.h path added"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# 2. st7789/CMakeLists.txt
|
||||||
|
cat > components/st7789/CMakeLists.txt << 'EOF'
|
||||||
|
idf_component_register(
|
||||||
|
SRCS "st7789.c"
|
||||||
|
INCLUDE_DIRS "include" "${CMAKE_SOURCE_DIR}/main/include"
|
||||||
|
PRIV_INCLUDE_DIRS "."
|
||||||
|
REQUIRES driver esp_timer spi_flash
|
||||||
|
)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 3. link_cable/CMakeLists.txt
|
||||||
|
cat > components/link_cable/CMakeLists.txt << 'EOF'
|
||||||
|
idf_component_register(
|
||||||
|
SRCS "link_cable.c"
|
||||||
|
INCLUDE_DIRS "include" "${CMAKE_SOURCE_DIR}/main/include"
|
||||||
|
PRIV_INCLUDE_DIRS "."
|
||||||
|
REQUIRES driver freertos
|
||||||
|
)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 4. nfc_manager/CMakeLists.txt (mit json für cJSON!)
|
||||||
|
cat > components/nfc_manager/CMakeLists.txt << 'EOF'
|
||||||
|
idf_component_register(
|
||||||
|
SRCS "nfc_manager.c"
|
||||||
|
INCLUDE_DIRS "include" "${CMAKE_SOURCE_DIR}/main/include"
|
||||||
|
PRIV_INCLUDE_DIRS "."
|
||||||
|
REQUIRES driver json freertos fatfs
|
||||||
|
)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 5. potentiometer_manager/CMakeLists.txt
|
||||||
|
cat > components/potentiometer_manager/CMakeLists.txt << 'EOF'
|
||||||
|
idf_component_register(
|
||||||
|
SRCS "potentiometer_manager.c"
|
||||||
|
INCLUDE_DIRS "include" "${CMAKE_SOURCE_DIR}/main/include"
|
||||||
|
PRIV_INCLUDE_DIRS "."
|
||||||
|
REQUIRES driver esp_hw_support st7789
|
||||||
|
)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
|
||||||
|
#6 sdconfig
|
||||||
|
echo "CONFIG_ESP32S3_SPIRAM_SUPPORT=y" >> sdkconfig
|
||||||
|
echo "CONFIG_SPIRAM=y" >> sdkconfig
|
||||||
|
echo "CONFIG_SPIRAM_MODE_QUAD=y" >> sdkconfig
|
||||||
|
echo "CONFIG_SPIRAM_TYPE_AUTO=y" >> sdkconfig
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 5. Clean build and rebuild
|
||||||
|
# ============================================
|
||||||
|
echo ""
|
||||||
|
echo "5. Cleaning build directory..."
|
||||||
|
rm -rf build sdkconfig sdkconfig.old
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== All fixes applied! ==="
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo " cd $GNUBOY_DIR"
|
||||||
|
echo " source ~/esp-idf/export.sh"
|
||||||
|
echo " idf.py set-target esp32s3"
|
||||||
|
echo " idf.py build"
|
||||||
|
echo ""
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Fix esp_psram compatibility for ESP-IDF v4.4
|
||||||
|
|
||||||
|
GNUBOY_DIR=~/Arduino/gameboy/gnuboy
|
||||||
|
|
||||||
|
echo "Fixing esp_psram compatibility issues..."
|
||||||
|
|
||||||
|
# 1. Fix components/gnuboy/CMakeLists.txt
|
||||||
|
echo "Patching components/gnuboy/CMakeLists.txt..."
|
||||||
|
sed -i 's/esp_psram/esp_hw_support/g' "$GNUBOY_DIR/components/gnuboy/CMakeLists.txt"
|
||||||
|
|
||||||
|
# 2. Fix main/CMakeLists.txt
|
||||||
|
echo "Patching main/CMakeLists.txt..."
|
||||||
|
sed -i 's/esp_psram/esp_hw_support/g' "$GNUBOY_DIR/main/CMakeLists.txt"
|
||||||
|
|
||||||
|
# 3. Fix main/main.c
|
||||||
|
echo "Patching main/main.c..."
|
||||||
|
sed -i 's/#include "esp_psram.h"/#include "esp_heap_caps.h"\n#include "esp32s3\/spiram.h"/g' "$GNUBOY_DIR/main/main.c"
|
||||||
|
sed -i 's/esp_psram_is_initialized()/esp_spiram_is_initialized()/g' "$GNUBOY_DIR/main/main.c"
|
||||||
|
sed -i 's/esp_psram_get_size()/esp_spiram_get_size()/g' "$GNUBOY_DIR/main/main.c"
|
||||||
|
|
||||||
|
|
||||||
|
#4 Fix sdkconfig
|
||||||
|
cat >> sdkconfig << 'EOF'
|
||||||
|
CONFIG_ESP32S3_SPIRAM_SUPPORT=y
|
||||||
|
CONFIG_SPIRAM=y
|
||||||
|
CONFIG_SPIRAM_MODE_OCT=y
|
||||||
|
CONFIG_SPIRAM_TYPE_AUTO=y
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Done! Now run:"
|
||||||
|
echo " cd $GNUBOY_DIR"
|
||||||
|
echo " rm -rf build sdkconfig"
|
||||||
|
echo " source ~/esp-idf/export.sh"
|
||||||
|
echo " idf.py set-target esp32s3"
|
||||||
|
echo " idf.py build"
|
||||||
2
init.sh
2
init.sh
|
|
@ -1,6 +1,6 @@
|
||||||
git init
|
git init
|
||||||
git checkout -b main
|
git checkout -b main
|
||||||
git add *
|
git add *
|
||||||
git commit -m "PIN konflikt Buttons und I2S gefixt"
|
git commit -m "PSRAM auf Oct geändert, POTI Funktionen geändert auf EDIF 4.4, sdkconfig angepasst für nfc manager und potis"
|
||||||
git remote add origin https://git.hacker-net.de/Hacker-Software/lego-esp32s3-gameboy.git
|
git remote add origin https://git.hacker-net.de/Hacker-Software/lego-esp32s3-gameboy.git
|
||||||
git push -u origin main
|
git push -u origin main
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue