Compare commits
11 Commits
04d2c71d01
...
pairing
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31e0e3a148 | ||
|
|
a272a15bcf | ||
|
|
8a1966ea90 | ||
|
|
b8a3a09e9f | ||
|
|
115105c032 | ||
|
|
19e8ca30c3 | ||
|
|
de7041c1f5 | ||
|
|
fe69dc6f19 | ||
|
|
bca2f6ea9c | ||
|
|
5a893a034c | ||
| 2513a9e7fb |
@@ -6,7 +6,26 @@
|
|||||||
"Bash(git add:*)",
|
"Bash(git add:*)",
|
||||||
"Bash(git commit:*)",
|
"Bash(git commit:*)",
|
||||||
"Bash(pip install:*)",
|
"Bash(pip install:*)",
|
||||||
"Bash(build_from_spec.bat)"
|
"Bash(build_from_spec.bat)",
|
||||||
|
"mcp__ide__getDiagnostics",
|
||||||
|
"Bash(source:*)",
|
||||||
|
"Bash(chmod:*)",
|
||||||
|
"Bash(python3:*)",
|
||||||
|
"Bash(pyinstaller:*)",
|
||||||
|
"Bash(open:*)",
|
||||||
|
"Bash(dos2unix:*)",
|
||||||
|
"Bash(./build_macos.sh:*)",
|
||||||
|
"Bash(brew install:*)",
|
||||||
|
"Bash(python:*)",
|
||||||
|
"Bash(./dist/ESP32_Flasher:*)",
|
||||||
|
"Bash(pkill:*)",
|
||||||
|
"Bash(curl -s http://127.0.0.1:5000/)",
|
||||||
|
"Bash(./build_web_macos.sh:*)",
|
||||||
|
"Bash(./dist/ESP32_Flasher.app/Contents/MacOS/ESP32_Flasher:*)",
|
||||||
|
"Bash(where:*)",
|
||||||
|
"Bash(idf.py size-components:*)",
|
||||||
|
"Bash(find:*)",
|
||||||
|
"Bash(git log:*)"
|
||||||
],
|
],
|
||||||
"deny": []
|
"deny": []
|
||||||
}
|
}
|
||||||
|
|||||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -1,6 +1,22 @@
|
|||||||
.pytest_cache/
|
.pytest_cache/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Python virtual environments
|
||||||
|
venv/
|
||||||
|
env/
|
||||||
|
ENV/
|
||||||
|
.venv/
|
||||||
|
|
||||||
|
# PyInstaller build artifacts
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
*.spec
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
|
||||||
# esp-idf built binaries
|
# esp-idf built binaries
|
||||||
build/
|
build/
|
||||||
build_*_*/
|
build_*_*/
|
||||||
@@ -21,3 +37,4 @@ dependencies.lock
|
|||||||
|
|
||||||
managed_components
|
managed_components
|
||||||
components
|
components
|
||||||
|
output
|
||||||
37
.vscode/c_cpp_properties.json
vendored
37
.vscode/c_cpp_properties.json
vendored
@@ -1,15 +1,38 @@
|
|||||||
{
|
{
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "Linux",
|
"name": "Win32",
|
||||||
"includePath": [
|
"includePath": [
|
||||||
"${workspaceFolder}/**"
|
"${workspaceFolder}/**",
|
||||||
|
"${env:USERPROFILE}/esp/v5.4.1/esp-idf/components/**",
|
||||||
|
"${env:USERPROFILE}/.espressif/tools/xtensa-esp-elf/**",
|
||||||
|
"${workspaceFolder}/build/config",
|
||||||
|
"${workspaceFolder}/managed_components/**"
|
||||||
],
|
],
|
||||||
"defines": [],
|
"defines": [
|
||||||
"compilerPath": "/usr/bin/gcc",
|
"ESP_PLATFORM"
|
||||||
"cStandard": "c17",
|
],
|
||||||
"cppStandard": "gnu++17",
|
"compilerPath": "${env:USERPROFILE}/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20241113/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc.exe",
|
||||||
"intelliSenseMode": "linux-gcc-x64"
|
"cStandard": "c11",
|
||||||
|
"cppStandard": "c++20",
|
||||||
|
"intelliSenseMode": "gcc-x64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mac",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**",
|
||||||
|
"/Users/brent/esp/v5.5.1/esp-idf/components/**",
|
||||||
|
"/Users/brent/.espressif/tools/xtensa-esp-elf/**",
|
||||||
|
"${workspaceFolder}/build/config",
|
||||||
|
"${workspaceFolder}/managed_components/**"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"ESP_PLATFORM"
|
||||||
|
],
|
||||||
|
"compilerPath": "/Users/brent/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20240530/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc",
|
||||||
|
"cStandard": "c11",
|
||||||
|
"cppStandard": "c++20",
|
||||||
|
"intelliSenseMode": "gcc-x64"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version": 4
|
"version": 4
|
||||||
|
|||||||
50
.vscode/launch.json
vendored
Normal file
50
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Build ESP32 Firmware (Windows)",
|
||||||
|
"type": "process",
|
||||||
|
"request": "launch",
|
||||||
|
"command": "idf.py",
|
||||||
|
"args": ["build"],
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"windows": {
|
||||||
|
"command": "idf.py"
|
||||||
|
},
|
||||||
|
"problemMatcher": ["$gcc"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Build ESP32 Firmware (macOS)",
|
||||||
|
"type": "process",
|
||||||
|
"request": "launch",
|
||||||
|
"command": "bash",
|
||||||
|
"args": ["-lc", "source ${IDF_PATH:-/opt/esp/idf}/export.sh && idf.py build"],
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"osx": {
|
||||||
|
"command": "bash"
|
||||||
|
},
|
||||||
|
"problemMatcher": ["$gcc"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Build Windows Flasher",
|
||||||
|
"type": "process",
|
||||||
|
"request": "launch",
|
||||||
|
"command": "${workspaceFolder}/flash_tool/build_from_spec.bat",
|
||||||
|
"cwd": "${workspaceFolder}/flash_tool",
|
||||||
|
"windows": {
|
||||||
|
"command": "${workspaceFolder}/flash_tool/build_from_spec.bat"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Build macOS Flasher",
|
||||||
|
"type": "process",
|
||||||
|
"request": "launch",
|
||||||
|
"command": "${workspaceFolder}/flash_tool/build_macos.sh",
|
||||||
|
"cwd": "${workspaceFolder}/flash_tool",
|
||||||
|
"osx": {
|
||||||
|
"command": "bash",
|
||||||
|
"args": ["${workspaceFolder}/flash_tool/build_macos.sh"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
10
.vscode/settings.json
vendored
10
.vscode/settings.json
vendored
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"C_Cpp.intelliSenseEngine": "default",
|
"C_Cpp.intelliSenseEngine": "default",
|
||||||
"idf.espIdfPathWin": "C:\\esp\\frameworks\\esp-idf-v5.3.3",
|
"idf.espIdfPathWin": "C:\\Users\\Brent.Perteet\\esp\\v5.4.1\\esp-idf",
|
||||||
"idf.openOcdConfigs": [
|
"idf.openOcdConfigs": [
|
||||||
"board/esp32-wrover-kit-3.3v.cfg"
|
"board/esp32-wrover-kit-3.3v.cfg"
|
||||||
],
|
],
|
||||||
"idf.portWin": "COM4",
|
"idf.portWin": "COM14",
|
||||||
"idf.toolsPathWin": "C:\\esp\\frameworks\\esp-idf-v5.3.3\\tools\\tools",
|
"idf.toolsPathWin": "C:\\Users\\Brent.Perteet\\.espressif",
|
||||||
"idf.flashType": "UART",
|
"idf.flashType": "UART",
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"esp_system.h": "c",
|
"esp_system.h": "c",
|
||||||
@@ -40,5 +40,7 @@
|
|||||||
"random": "c"
|
"random": "c"
|
||||||
},
|
},
|
||||||
"git.ignoreLimitWarning": true,
|
"git.ignoreLimitWarning": true,
|
||||||
"idf.pythonInstallPath": "/usr/bin/python"
|
"idf.pythonInstallPath": "C:\\Users\\Brent.Perteet\\.espressif\\tools\\idf-python\\3.11.2\\python.exe",
|
||||||
|
"idf.espIdfPath": "/Users/brent/esp/v5.5.1/esp-idf",
|
||||||
|
"idf.toolsPath": "/Users/brent/.espressif"
|
||||||
}
|
}
|
||||||
|
|||||||
26
.vscode/tasks.json
vendored
26
.vscode/tasks.json
vendored
@@ -1,11 +1,35 @@
|
|||||||
{
|
{
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"tasks": [
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "adapter",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "idf.py",
|
||||||
|
"args": ["build"],
|
||||||
|
"windows": {
|
||||||
|
"command": "cmd.exe",
|
||||||
|
"args": ["/c", "${env:USERPROFILE}\\esp\\v5.4.1\\esp-idf\\export.bat", "&&", "idf.py", "build"]
|
||||||
|
},
|
||||||
|
"osx": {
|
||||||
|
"command": "bash",
|
||||||
|
"args": ["-lc", "source ${IDF_PATH:-/opt/esp/idf}/export.sh && idf.py build"]
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"command": "bash",
|
||||||
|
"args": ["-lc", "source ${IDF_PATH:-/opt/esp/idf}/export.sh && idf.py build"]
|
||||||
|
},
|
||||||
|
"group": { "kind": "build", "isDefault": true },
|
||||||
|
"problemMatcher": ["${config:idf.cmakeCompilerArgs}"],
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always",
|
||||||
|
"panel": "dedicated"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "ESP-IDF: Build (RAM) + Sync to Host",
|
"label": "ESP-IDF: Build (RAM) + Sync to Host",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "bash -lc 'source ${IDF_PATH:-/opt/esp/idf}/export.sh && idf.py build && rsync -a --delete \"$PWD/build/\" /host_build/'",
|
"command": "bash -lc 'source ${IDF_PATH:-/opt/esp/idf}/export.sh && idf.py build && rsync -a --delete \"$PWD/build/\" /host_build/'",
|
||||||
"group": { "kind": "build", "isDefault": true },
|
"group": "build",
|
||||||
"problemMatcher": "$gcc"
|
"problemMatcher": "$gcc"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
9
flash_tool/.claude/settings.local.json
Normal file
9
flash_tool/.claude/settings.local.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"Bash(python:*)"
|
||||||
|
],
|
||||||
|
"deny": [],
|
||||||
|
"ask": []
|
||||||
|
}
|
||||||
|
}
|
||||||
110
flash_tool/BUILD_NOTES.md
Normal file
110
flash_tool/BUILD_NOTES.md
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
# Build Notes
|
||||||
|
|
||||||
|
## Build Status
|
||||||
|
|
||||||
|
✅ **macOS Build: SUCCESS**
|
||||||
|
- Built on: macOS 15.6 (arm64)
|
||||||
|
- Python Version: 3.9.6 (Xcode system Python with tkinter support)
|
||||||
|
- Output: `dist/ESP32_Flasher.app`
|
||||||
|
- Size: ~7.0 MB
|
||||||
|
- Tested: ✅ Application launches and runs successfully
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
**Important:** Homebrew's Python 3.13 does NOT include tkinter support by default.
|
||||||
|
|
||||||
|
**Solution:** Install python-tk package:
|
||||||
|
```bash
|
||||||
|
brew install python-tk@3.13
|
||||||
|
```
|
||||||
|
|
||||||
|
However, the build system will automatically use the system Python (3.9.6 from Xcode) which has tkinter built-in. This is the recommended approach.
|
||||||
|
|
||||||
|
## Known Issues
|
||||||
|
|
||||||
|
### ~~macOS tkinter Warning~~ - RESOLVED
|
||||||
|
**Previous Issue:** Homebrew Python 3.13 doesn't include tkinter
|
||||||
|
**Solution:** Build system now uses Xcode's Python 3.9.6 which has native tkinter support
|
||||||
|
**Status:** ✅ Fixed - no warnings, app works perfectly
|
||||||
|
|
||||||
|
### Virtual Environment Required (macOS)
|
||||||
|
Due to PEP 668 (externally-managed environments), macOS requires using a virtual environment for pip installations. The build scripts automatically handle this.
|
||||||
|
|
||||||
|
## Build Commands
|
||||||
|
|
||||||
|
### Quick Build (Any Platform)
|
||||||
|
```bash
|
||||||
|
python3 build.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### macOS Specific
|
||||||
|
```bash
|
||||||
|
./build_macos.sh
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```bash
|
||||||
|
source venv/bin/activate
|
||||||
|
pyinstaller ESP32_Flasher_macOS.spec
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows Specific
|
||||||
|
```batch
|
||||||
|
build_from_spec.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
## Distribution
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
- Distribute the entire `ESP32_Flasher.app` folder (it's a bundle)
|
||||||
|
- Users may need to run: `xattr -cr ESP32_Flasher.app` if macOS blocks it
|
||||||
|
- Consider creating a DMG for easier distribution
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
- Distribute the single `ESP32_Flasher.exe` file
|
||||||
|
- No installation required
|
||||||
|
- May trigger Windows SmartScreen (normal for unsigned apps)
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
flash_tool/
|
||||||
|
├── dist/ # Build output
|
||||||
|
│ ├── ESP32_Flasher.app # macOS bundle
|
||||||
|
│ └── ESP32_Flasher # Standalone binary
|
||||||
|
├── build/ # Build artifacts
|
||||||
|
├── venv/ # Python virtual environment (macOS)
|
||||||
|
├── gui_flasher.py # Source code
|
||||||
|
├── ESP32_Flasher_macOS.spec # macOS build config
|
||||||
|
├── ESP32_Flasher_Windows.spec # Windows build config
|
||||||
|
├── build.py # Universal build script
|
||||||
|
├── build_macos.sh # macOS build script
|
||||||
|
└── build_from_spec.bat # Windows build script
|
||||||
|
```
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
1. **Testing**: Test the app with actual ESP32 hardware and firmware
|
||||||
|
2. **Icons**: Add custom icons (.icns for macOS, .ico for Windows)
|
||||||
|
3. **Code Signing**: Sign the executables for production distribution
|
||||||
|
4. **DMG Creation**: Package macOS app in a DMG for easier distribution
|
||||||
|
5. **Windows Installer**: Consider creating an NSIS or WiX installer
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### "App is damaged" on macOS
|
||||||
|
```bash
|
||||||
|
xattr -cr dist/ESP32_Flasher.app
|
||||||
|
```
|
||||||
|
|
||||||
|
### Port permission issues on Linux
|
||||||
|
```bash
|
||||||
|
sudo usermod -a -G dialout $USER
|
||||||
|
```
|
||||||
|
(Logout/login required)
|
||||||
|
|
||||||
|
### Build fails on macOS
|
||||||
|
Make sure virtual environment is active:
|
||||||
|
```bash
|
||||||
|
source venv/bin/activate
|
||||||
|
```
|
||||||
45
flash_tool/ESP32_Flasher_Windows.spec
Normal file
45
flash_tool/ESP32_Flasher_Windows.spec
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
# PyInstaller spec file for Windows executable
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
|
||||||
|
a = Analysis(
|
||||||
|
['gui_flasher.py'],
|
||||||
|
pathex=[],
|
||||||
|
binaries=[],
|
||||||
|
datas=[('requirements.txt', '.')],
|
||||||
|
hiddenimports=['serial.tools.list_ports'],
|
||||||
|
hookspath=[],
|
||||||
|
hooksconfig={},
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
win_no_prefer_redirects=False,
|
||||||
|
win_private_assemblies=False,
|
||||||
|
cipher=block_cipher,
|
||||||
|
noarchive=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||||
|
|
||||||
|
exe = EXE(
|
||||||
|
pyz,
|
||||||
|
a.scripts,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
[],
|
||||||
|
name='ESP32_Flasher',
|
||||||
|
debug=False,
|
||||||
|
bootloader_ignore_signals=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
upx_exclude=[],
|
||||||
|
runtime_tmpdir=None,
|
||||||
|
console=False, # Set to False for windowed mode (no console)
|
||||||
|
disable_windowed_traceback=False,
|
||||||
|
argv_emulation=False,
|
||||||
|
target_arch=None,
|
||||||
|
codesign_identity=None,
|
||||||
|
entitlements_file=None,
|
||||||
|
icon=None, # Add path to .ico file if you have one
|
||||||
|
)
|
||||||
56
flash_tool/ESP32_Flasher_macOS.spec
Normal file
56
flash_tool/ESP32_Flasher_macOS.spec
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
# PyInstaller spec file for macOS executable
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
|
||||||
|
a = Analysis(
|
||||||
|
['gui_flasher.py'],
|
||||||
|
pathex=[],
|
||||||
|
binaries=[],
|
||||||
|
datas=[('requirements.txt', '.')],
|
||||||
|
hiddenimports=['serial.tools.list_ports'],
|
||||||
|
hookspath=[],
|
||||||
|
hooksconfig={},
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
win_no_prefer_redirects=False,
|
||||||
|
win_private_assemblies=False,
|
||||||
|
cipher=block_cipher,
|
||||||
|
noarchive=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||||
|
|
||||||
|
exe = EXE(
|
||||||
|
pyz,
|
||||||
|
a.scripts,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
[],
|
||||||
|
name='ESP32_Flasher',
|
||||||
|
debug=False,
|
||||||
|
bootloader_ignore_signals=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
upx_exclude=[],
|
||||||
|
runtime_tmpdir=None,
|
||||||
|
console=False, # macOS app bundle (no console window)
|
||||||
|
disable_windowed_traceback=False,
|
||||||
|
argv_emulation=False,
|
||||||
|
target_arch=None,
|
||||||
|
codesign_identity=None,
|
||||||
|
entitlements_file=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create macOS app bundle
|
||||||
|
app = BUNDLE(
|
||||||
|
exe,
|
||||||
|
name='ESP32_Flasher.app',
|
||||||
|
icon=None, # Add path to .icns file if you have one
|
||||||
|
bundle_identifier='com.soundshot.esp32flasher',
|
||||||
|
info_plist={
|
||||||
|
'NSPrincipalClass': 'NSApplication',
|
||||||
|
'NSHighResolutionCapable': 'True',
|
||||||
|
},
|
||||||
|
)
|
||||||
81
flash_tool/ESP32_WebFlasher_Windows.spec
Normal file
81
flash_tool/ESP32_WebFlasher_Windows.spec
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
# PyInstaller spec file for Windows executable (Web-based UI)
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Find esptool installation dynamically
|
||||||
|
try:
|
||||||
|
import esptool
|
||||||
|
esptool_dir = os.path.dirname(esptool.__file__)
|
||||||
|
print(f"Found esptool at: {esptool_dir}")
|
||||||
|
except ImportError:
|
||||||
|
print("Warning: esptool not found, stub files will not be included")
|
||||||
|
esptool_dir = None
|
||||||
|
|
||||||
|
# Build datas list - include all esptool data files
|
||||||
|
datas_list = [
|
||||||
|
('templates', 'templates'),
|
||||||
|
('static', 'static'),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add esptool targets directory (includes stub_flasher JSON files)
|
||||||
|
if esptool_dir and os.path.exists(os.path.join(esptool_dir, 'targets')):
|
||||||
|
targets_dir = os.path.join(esptool_dir, 'targets')
|
||||||
|
datas_list.append((targets_dir, 'esptool/targets'))
|
||||||
|
print(f"Including esptool targets from: {targets_dir}")
|
||||||
|
|
||||||
|
a = Analysis(
|
||||||
|
['web_flasher.py'],
|
||||||
|
pathex=[],
|
||||||
|
binaries=[],
|
||||||
|
datas=datas_list,
|
||||||
|
hiddenimports=[
|
||||||
|
'serial.tools.list_ports',
|
||||||
|
'flask',
|
||||||
|
'jinja2',
|
||||||
|
'werkzeug',
|
||||||
|
'flask_socketio',
|
||||||
|
'socketio',
|
||||||
|
'engineio.async_drivers.threading',
|
||||||
|
'esptool',
|
||||||
|
'esptool.cmds',
|
||||||
|
'esptool.loader',
|
||||||
|
'esptool.util',
|
||||||
|
],
|
||||||
|
hookspath=[],
|
||||||
|
hooksconfig={},
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
win_no_prefer_redirects=False,
|
||||||
|
win_private_assemblies=False,
|
||||||
|
cipher=block_cipher,
|
||||||
|
noarchive=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||||
|
|
||||||
|
exe = EXE(
|
||||||
|
pyz,
|
||||||
|
a.scripts,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
[],
|
||||||
|
name='ESP32_Flasher',
|
||||||
|
debug=False,
|
||||||
|
bootloader_ignore_signals=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
upx_exclude=[],
|
||||||
|
runtime_tmpdir=None,
|
||||||
|
console=False, # No console window
|
||||||
|
disable_windowed_traceback=False,
|
||||||
|
argv_emulation=False,
|
||||||
|
target_arch=None,
|
||||||
|
codesign_identity=None,
|
||||||
|
entitlements_file=None,
|
||||||
|
icon=None, # Add path to .ico file if you have one
|
||||||
|
)
|
||||||
69
flash_tool/ESP32_WebFlasher_macOS.spec
Normal file
69
flash_tool/ESP32_WebFlasher_macOS.spec
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
# PyInstaller spec file for macOS executable (Web-based UI)
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
|
||||||
|
a = Analysis(
|
||||||
|
['web_flasher.py'],
|
||||||
|
pathex=[],
|
||||||
|
binaries=[],
|
||||||
|
datas=[
|
||||||
|
('templates', 'templates'),
|
||||||
|
('static', 'static'),
|
||||||
|
],
|
||||||
|
hiddenimports=[
|
||||||
|
'serial.tools.list_ports',
|
||||||
|
'flask',
|
||||||
|
'jinja2',
|
||||||
|
'werkzeug',
|
||||||
|
'flask_socketio',
|
||||||
|
'socketio',
|
||||||
|
'engineio.async_drivers.threading',
|
||||||
|
],
|
||||||
|
hookspath=[],
|
||||||
|
hooksconfig={},
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
win_no_prefer_redirects=False,
|
||||||
|
win_private_assemblies=False,
|
||||||
|
cipher=block_cipher,
|
||||||
|
noarchive=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||||
|
|
||||||
|
exe = EXE(
|
||||||
|
pyz,
|
||||||
|
a.scripts,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
[],
|
||||||
|
name='ESP32_Flasher',
|
||||||
|
debug=False,
|
||||||
|
bootloader_ignore_signals=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
upx_exclude=[],
|
||||||
|
runtime_tmpdir=None,
|
||||||
|
console=False, # macOS app bundle (no console window)
|
||||||
|
disable_windowed_traceback=False,
|
||||||
|
argv_emulation=False,
|
||||||
|
target_arch=None,
|
||||||
|
codesign_identity=None,
|
||||||
|
entitlements_file=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create macOS app bundle
|
||||||
|
app = BUNDLE(
|
||||||
|
exe,
|
||||||
|
name='ESP32_Flasher.app',
|
||||||
|
icon=None, # Add path to .icns file if you have one
|
||||||
|
bundle_identifier='com.soundshot.esp32flasher',
|
||||||
|
info_plist={
|
||||||
|
'NSPrincipalClass': 'NSApplication',
|
||||||
|
'NSHighResolutionCapable': 'True',
|
||||||
|
'CFBundleShortVersionString': '1.0.0',
|
||||||
|
'CFBundleDisplayName': 'ESP32 Flasher',
|
||||||
|
},
|
||||||
|
)
|
||||||
148
flash_tool/README.md
Normal file
148
flash_tool/README.md
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
# ESP32 Firmware Flasher GUI
|
||||||
|
|
||||||
|
A cross-platform GUI tool for flashing ESP32 firmware packages.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Simple, user-friendly graphical interface
|
||||||
|
- Cross-platform support (Windows, macOS, Linux)
|
||||||
|
- Automatic serial port detection
|
||||||
|
- Firmware package validation (.zip files)
|
||||||
|
- Real-time flashing progress output
|
||||||
|
- Configurable flash parameters
|
||||||
|
|
||||||
|
## Building Executables
|
||||||
|
|
||||||
|
### Universal Build (Recommended)
|
||||||
|
|
||||||
|
The easiest way to build for your current platform:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python build.py
|
||||||
|
```
|
||||||
|
|
||||||
|
This script will:
|
||||||
|
1. Detect your platform automatically
|
||||||
|
2. Install required dependencies
|
||||||
|
3. Build the appropriate executable
|
||||||
|
|
||||||
|
### Platform-Specific Builds
|
||||||
|
|
||||||
|
#### macOS
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./build_macos.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates an application bundle at `dist/ESP32_Flasher.app`
|
||||||
|
|
||||||
|
To run:
|
||||||
|
```bash
|
||||||
|
open dist/ESP32_Flasher.app
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
|
||||||
|
```batch
|
||||||
|
build_from_spec.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates an executable at `dist\ESP32_Flasher.exe`
|
||||||
|
|
||||||
|
#### Linux
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python build.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Creates an executable at `dist/ESP32_Flasher`
|
||||||
|
|
||||||
|
## Running Without Building
|
||||||
|
|
||||||
|
You can run the GUI directly with Python:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python gui_flasher.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Firmware Package Format
|
||||||
|
|
||||||
|
The flasher expects a `.zip` file containing these files:
|
||||||
|
- `bootloader.bin` - ESP32 bootloader
|
||||||
|
- `partition-table.bin` - Partition table
|
||||||
|
- `ota_data_initial.bin` - OTA data
|
||||||
|
- `soundshot.bin` - Main application firmware
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
1. Launch the ESP32_Flasher application
|
||||||
|
2. Select your ESP32's serial port (or click Refresh)
|
||||||
|
3. Browse and select your firmware `.zip` package
|
||||||
|
4. (Optional) Adjust flash settings if needed
|
||||||
|
5. Click "Flash Firmware"
|
||||||
|
6. Wait for the process to complete
|
||||||
|
|
||||||
|
## Flash Settings
|
||||||
|
|
||||||
|
Default settings work for most ESP32 boards:
|
||||||
|
- **Chip**: esp32
|
||||||
|
- **Baud Rate**: 460800 (faster) or 115200 (more reliable)
|
||||||
|
- **Flash Mode**: dio
|
||||||
|
- **Flash Freq**: 40m
|
||||||
|
- **Flash Size**: 2MB (adjust based on your board)
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Port Not Detected
|
||||||
|
- Ensure ESP32 is connected via USB
|
||||||
|
- Install CH340/CP2102 drivers if needed (Windows/macOS)
|
||||||
|
- On Linux, add user to `dialout` group: `sudo usermod -a -G dialout $USER`
|
||||||
|
|
||||||
|
### Flash Failed
|
||||||
|
- Try lower baud rate (115200)
|
||||||
|
- Press and hold BOOT button during flash
|
||||||
|
- Check USB cable quality
|
||||||
|
- Verify firmware package integrity
|
||||||
|
|
||||||
|
### macOS: "App is damaged"
|
||||||
|
Run this command to allow the app:
|
||||||
|
```bash
|
||||||
|
xattr -cr dist/ESP32_Flasher.app
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
flash_tool/
|
||||||
|
├── gui_flasher.py # Main GUI application
|
||||||
|
├── ESP32_Flasher_macOS.spec # PyInstaller spec for macOS
|
||||||
|
├── ESP32_Flasher_Windows.spec # PyInstaller spec for Windows
|
||||||
|
├── build.py # Universal build script
|
||||||
|
├── build_macos.sh # macOS build script
|
||||||
|
├── build_from_spec.bat # Windows build script
|
||||||
|
├── requirements.txt # Python dependencies
|
||||||
|
└── README.md # This file
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- **tkinter**: GUI framework (included with Python)
|
||||||
|
- **pyserial**: Serial port communication
|
||||||
|
- **esptool**: ESP32 flashing utility
|
||||||
|
- **pyinstaller**: Executable builder
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[Your license here]
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
For issues and questions, please contact [your contact info].
|
||||||
BIN
flash_tool/SoundShot.png
Normal file
BIN
flash_tool/SoundShot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 105 KiB |
171
flash_tool/build.py
Executable file
171
flash_tool/build.py
Executable file
@@ -0,0 +1,171 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Universal build script for ESP32 Flasher GUI
|
||||||
|
Automatically detects platform and builds the appropriate executable
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import platform
|
||||||
|
import os
|
||||||
|
|
||||||
|
def get_platform():
|
||||||
|
"""Detect the current platform"""
|
||||||
|
system = platform.system()
|
||||||
|
if system == "Darwin":
|
||||||
|
return "macos"
|
||||||
|
elif system == "Windows":
|
||||||
|
return "windows"
|
||||||
|
elif system == "Linux":
|
||||||
|
return "linux"
|
||||||
|
else:
|
||||||
|
return "unknown"
|
||||||
|
|
||||||
|
def setup_venv():
|
||||||
|
"""Create and setup virtual environment if on macOS"""
|
||||||
|
if platform.system() == "Darwin":
|
||||||
|
if not os.path.exists("venv"):
|
||||||
|
print("Creating virtual environment (required on macOS)...")
|
||||||
|
try:
|
||||||
|
subprocess.run([sys.executable, "-m", "venv", "venv"], check=True)
|
||||||
|
print("✓ Virtual environment created")
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"✗ Failed to create virtual environment: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Use venv Python for the rest of the script
|
||||||
|
venv_python = os.path.join("venv", "bin", "python3")
|
||||||
|
if os.path.exists(venv_python):
|
||||||
|
return venv_python
|
||||||
|
|
||||||
|
return sys.executable
|
||||||
|
|
||||||
|
def install_dependencies(python_exe=None):
|
||||||
|
"""Install required Python packages"""
|
||||||
|
if python_exe is None:
|
||||||
|
python_exe = sys.executable
|
||||||
|
|
||||||
|
print("Installing dependencies...")
|
||||||
|
packages = ["pyinstaller", "esptool", "pyserial"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.run([python_exe, "-m", "pip", "install"] + packages, check=True)
|
||||||
|
print("✓ Dependencies installed successfully")
|
||||||
|
return True
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"✗ Failed to install dependencies: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def build_macos():
|
||||||
|
"""Build macOS application bundle"""
|
||||||
|
print("\n=== Building for macOS ===")
|
||||||
|
spec_file = "ESP32_Flasher_macOS.spec"
|
||||||
|
|
||||||
|
if not os.path.exists(spec_file):
|
||||||
|
print(f"✗ Error: {spec_file} not found")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.run(["pyinstaller", spec_file], check=True)
|
||||||
|
|
||||||
|
if os.path.exists("dist/ESP32_Flasher.app"):
|
||||||
|
print("\n✓ Build complete!")
|
||||||
|
print(f"\nApplication created at: dist/ESP32_Flasher.app")
|
||||||
|
print("\nTo run the application:")
|
||||||
|
print(" open dist/ESP32_Flasher.app")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print("\n✗ Build failed - application not found in dist folder")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"\n✗ Build failed: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def build_windows():
|
||||||
|
"""Build Windows executable"""
|
||||||
|
print("\n=== Building for Windows ===")
|
||||||
|
spec_file = "ESP32_Flasher_Windows.spec"
|
||||||
|
|
||||||
|
if not os.path.exists(spec_file):
|
||||||
|
print(f"✗ Error: {spec_file} not found")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.run(["pyinstaller", spec_file], check=True)
|
||||||
|
|
||||||
|
if os.path.exists("dist/ESP32_Flasher.exe"):
|
||||||
|
print("\n✓ Build complete!")
|
||||||
|
print(f"\nExecutable created at: dist\\ESP32_Flasher.exe")
|
||||||
|
print("\nYou can now distribute ESP32_Flasher.exe to users.")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print("\n✗ Build failed - executable not found in dist folder")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"\n✗ Build failed: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def build_linux():
|
||||||
|
"""Build Linux executable"""
|
||||||
|
print("\n=== Building for Linux ===")
|
||||||
|
print("Note: Linux users typically prefer to run Python scripts directly.")
|
||||||
|
print("Creating standalone executable anyway...")
|
||||||
|
|
||||||
|
# Use macOS spec as template for Linux (both use ELF format)
|
||||||
|
spec_file = "ESP32_Flasher_macOS.spec"
|
||||||
|
|
||||||
|
if not os.path.exists(spec_file):
|
||||||
|
print(f"✗ Error: {spec_file} not found")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.run(["pyinstaller", spec_file], check=True)
|
||||||
|
|
||||||
|
if os.path.exists("dist/ESP32_Flasher"):
|
||||||
|
print("\n✓ Build complete!")
|
||||||
|
print(f"\nExecutable created at: dist/ESP32_Flasher")
|
||||||
|
print("\nTo run:")
|
||||||
|
print(" ./dist/ESP32_Flasher")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print("\n✗ Build failed - executable not found in dist folder")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"\n✗ Build failed: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main build function"""
|
||||||
|
print("=== ESP32 Flasher - Universal Build Script ===\n")
|
||||||
|
|
||||||
|
# Detect platform
|
||||||
|
current_platform = get_platform()
|
||||||
|
print(f"Detected platform: {current_platform}")
|
||||||
|
|
||||||
|
if current_platform == "unknown":
|
||||||
|
print("✗ Unsupported platform")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Setup virtual environment if needed (macOS)
|
||||||
|
python_exe = setup_venv()
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
if not install_dependencies(python_exe):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Build for detected platform
|
||||||
|
success = False
|
||||||
|
if current_platform == "macos":
|
||||||
|
success = build_macos()
|
||||||
|
elif current_platform == "windows":
|
||||||
|
success = build_windows()
|
||||||
|
elif current_platform == "linux":
|
||||||
|
success = build_linux()
|
||||||
|
|
||||||
|
return 0 if success else 1
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
@@ -1,11 +1,24 @@
|
|||||||
@echo off
|
@echo off
|
||||||
|
echo === ESP32 Flasher - Windows Build Script ===
|
||||||
|
echo.
|
||||||
|
|
||||||
echo Installing dependencies...
|
echo Installing dependencies...
|
||||||
pip install pyinstaller esptool pyserial
|
pip install pyinstaller esptool pyserial
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo Building executable from spec file...
|
echo Building Windows executable...
|
||||||
pyinstaller ESP32_Flasher.spec
|
pyinstaller ESP32_Flasher_Windows.spec
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo Build complete! Find ESP32_Flasher.exe in the dist folder.
|
if exist "dist\ESP32_Flasher.exe" (
|
||||||
|
echo Build complete!
|
||||||
|
echo.
|
||||||
|
echo Executable created at: dist\ESP32_Flasher.exe
|
||||||
|
echo.
|
||||||
|
echo You can now distribute ESP32_Flasher.exe to users.
|
||||||
|
) else (
|
||||||
|
echo Build failed - executable not found in dist folder
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
pause
|
pause
|
||||||
45
flash_tool/build_macos.sh
Executable file
45
flash_tool/build_macos.sh
Executable file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Build script for macOS executable
|
||||||
|
|
||||||
|
echo "=== ESP32 Flasher - macOS Build Script ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check if running on macOS
|
||||||
|
if [[ "$OSTYPE" != "darwin"* ]]; then
|
||||||
|
echo "❌ Error: This script is for macOS only."
|
||||||
|
echo " Use build_from_spec.bat on Windows."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create virtual environment if it doesn't exist
|
||||||
|
if [ ! -d "venv" ]; then
|
||||||
|
echo "Creating virtual environment..."
|
||||||
|
python3 -m venv venv
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Activating virtual environment..."
|
||||||
|
source venv/bin/activate
|
||||||
|
|
||||||
|
echo "Installing dependencies..."
|
||||||
|
pip install pyinstaller esptool pyserial
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Building macOS application bundle..."
|
||||||
|
pyinstaller ESP32_Flasher_macOS.spec
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
if [ -d "dist/ESP32_Flasher.app" ]; then
|
||||||
|
echo "✓ Build complete!"
|
||||||
|
echo ""
|
||||||
|
echo "Application created at: dist/ESP32_Flasher.app"
|
||||||
|
echo ""
|
||||||
|
echo "To run the application:"
|
||||||
|
echo " open dist/ESP32_Flasher.app"
|
||||||
|
echo ""
|
||||||
|
echo "To distribute, you can:"
|
||||||
|
echo " 1. Zip the .app bundle"
|
||||||
|
echo " 2. Create a DMG installer (requires additional tools)"
|
||||||
|
else
|
||||||
|
echo "❌ Build failed - application not found in dist folder"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
43
flash_tool/build_web_macos.sh
Executable file
43
flash_tool/build_web_macos.sh
Executable file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Build script for macOS executable (Web-based UI)
|
||||||
|
|
||||||
|
echo "=== ESP32 Flasher (Web UI) - macOS Build Script ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check if running on macOS
|
||||||
|
if [[ "$OSTYPE" != "darwin"* ]]; then
|
||||||
|
echo "❌ Error: This script is for macOS only."
|
||||||
|
echo " Use build_web_windows.bat on Windows."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create virtual environment if it doesn't exist
|
||||||
|
if [ ! -d "venv" ]; then
|
||||||
|
echo "Creating virtual environment..."
|
||||||
|
python3 -m venv venv
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Activating virtual environment..."
|
||||||
|
source venv/bin/activate
|
||||||
|
|
||||||
|
echo "Installing dependencies..."
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Building macOS application bundle..."
|
||||||
|
pyinstaller ESP32_WebFlasher_macOS.spec
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
if [ -d "dist/ESP32_Flasher.app" ]; then
|
||||||
|
echo "✓ Build complete!"
|
||||||
|
echo ""
|
||||||
|
echo "Application created at: dist/ESP32_Flasher.app"
|
||||||
|
echo ""
|
||||||
|
echo "To run the application:"
|
||||||
|
echo " open dist/ESP32_Flasher.app"
|
||||||
|
echo ""
|
||||||
|
echo "The app will open in your default web browser!"
|
||||||
|
else
|
||||||
|
echo "❌ Build failed - application not found in dist folder"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
32
flash_tool/build_web_windows.bat
Normal file
32
flash_tool/build_web_windows.bat
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
@echo off
|
||||||
|
echo === ESP32 Flasher (Web UI) - Windows Build Script ===
|
||||||
|
echo.
|
||||||
|
|
||||||
|
REM Check if running on Windows
|
||||||
|
if not "%OS%"=="Windows_NT" (
|
||||||
|
echo Error: This script is for Windows only.
|
||||||
|
echo Use build_web_macos.sh on macOS.
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo Installing dependencies...
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Building Windows executable...
|
||||||
|
pyinstaller ESP32_WebFlasher_Windows.spec
|
||||||
|
|
||||||
|
echo.
|
||||||
|
if exist "dist\ESP32_Flasher.exe" (
|
||||||
|
echo Build complete!
|
||||||
|
echo.
|
||||||
|
echo Executable created at: dist\ESP32_Flasher.exe
|
||||||
|
echo.
|
||||||
|
echo The app will open in your default web browser!
|
||||||
|
echo You can now distribute ESP32_Flasher.exe to users.
|
||||||
|
) else (
|
||||||
|
echo Build failed - executable not found in dist folder
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
pause
|
||||||
@@ -21,6 +21,9 @@ class ESP32FlasherGUI:
|
|||||||
self.root.title("ESP32 Firmware Flasher")
|
self.root.title("ESP32 Firmware Flasher")
|
||||||
self.root.geometry("600x500")
|
self.root.geometry("600x500")
|
||||||
|
|
||||||
|
# Configure colors for dark mode compatibility
|
||||||
|
self.setup_colors()
|
||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
self.port_var = tk.StringVar()
|
self.port_var = tk.StringVar()
|
||||||
self.firmware_path_var = tk.StringVar()
|
self.firmware_path_var = tk.StringVar()
|
||||||
@@ -29,9 +32,41 @@ class ESP32FlasherGUI:
|
|||||||
self.setup_ui()
|
self.setup_ui()
|
||||||
self.refresh_ports()
|
self.refresh_ports()
|
||||||
|
|
||||||
|
def setup_colors(self):
|
||||||
|
"""Configure colors that work in both light and dark mode"""
|
||||||
|
# Try to detect dark mode on macOS
|
||||||
|
try:
|
||||||
|
import subprocess
|
||||||
|
result = subprocess.run(
|
||||||
|
['defaults', 'read', '-g', 'AppleInterfaceStyle'],
|
||||||
|
capture_output=True,
|
||||||
|
text=True
|
||||||
|
)
|
||||||
|
is_dark_mode = (result.returncode == 0 and 'Dark' in result.stdout)
|
||||||
|
except:
|
||||||
|
is_dark_mode = False
|
||||||
|
|
||||||
|
if is_dark_mode:
|
||||||
|
# Dark mode colors
|
||||||
|
self.bg_color = '#2b2b2b'
|
||||||
|
self.fg_color = '#ffffff'
|
||||||
|
self.text_bg = '#1e1e1e'
|
||||||
|
self.text_fg = '#d4d4d4'
|
||||||
|
self.button_bg = '#3c3c3c'
|
||||||
|
else:
|
||||||
|
# Light mode colors
|
||||||
|
self.bg_color = '#f0f0f0'
|
||||||
|
self.fg_color = '#000000'
|
||||||
|
self.text_bg = '#ffffff'
|
||||||
|
self.text_fg = '#000000'
|
||||||
|
self.button_bg = '#e0e0e0'
|
||||||
|
|
||||||
|
# Configure root window
|
||||||
|
self.root.configure(bg=self.bg_color)
|
||||||
|
|
||||||
def setup_ui(self):
|
def setup_ui(self):
|
||||||
# Main frame
|
# Main frame
|
||||||
main_frame = ttk.Frame(self.root, padding="10")
|
main_frame = tk.Frame(self.root, bg=self.bg_color, padx=10, pady=10)
|
||||||
main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||||
|
|
||||||
# Configure grid weights
|
# Configure grid weights
|
||||||
@@ -40,55 +75,76 @@ class ESP32FlasherGUI:
|
|||||||
main_frame.columnconfigure(1, weight=1)
|
main_frame.columnconfigure(1, weight=1)
|
||||||
|
|
||||||
# Port selection
|
# Port selection
|
||||||
ttk.Label(main_frame, text="Serial Port:").grid(row=0, column=0, sticky=tk.W, pady=5)
|
tk.Label(main_frame, text="Serial Port:", bg=self.bg_color, fg=self.fg_color).grid(
|
||||||
port_frame = ttk.Frame(main_frame)
|
row=0, column=0, sticky=tk.W, pady=5)
|
||||||
|
port_frame = tk.Frame(main_frame, bg=self.bg_color)
|
||||||
port_frame.grid(row=0, column=1, sticky=(tk.W, tk.E), pady=5)
|
port_frame.grid(row=0, column=1, sticky=(tk.W, tk.E), pady=5)
|
||||||
port_frame.columnconfigure(0, weight=1)
|
port_frame.columnconfigure(0, weight=1)
|
||||||
|
|
||||||
self.port_combo = ttk.Combobox(port_frame, textvariable=self.port_var, state="readonly")
|
self.port_combo = ttk.Combobox(port_frame, textvariable=self.port_var, state="readonly")
|
||||||
self.port_combo.grid(row=0, column=0, sticky=(tk.W, tk.E), padx=(0, 5))
|
self.port_combo.grid(row=0, column=0, sticky=(tk.W, tk.E), padx=(0, 5))
|
||||||
|
|
||||||
ttk.Button(port_frame, text="Refresh", command=self.refresh_ports).grid(row=0, column=1)
|
tk.Button(port_frame, text="Refresh", command=self.refresh_ports,
|
||||||
|
bg=self.button_bg, fg=self.fg_color, relief=tk.RAISED).grid(row=0, column=1)
|
||||||
|
|
||||||
# Firmware package selection
|
# Firmware package selection
|
||||||
ttk.Label(main_frame, text="Firmware Package:").grid(row=1, column=0, sticky=tk.W, pady=5)
|
tk.Label(main_frame, text="Firmware Package:", bg=self.bg_color, fg=self.fg_color).grid(
|
||||||
firmware_frame = ttk.Frame(main_frame)
|
row=1, column=0, sticky=tk.W, pady=5)
|
||||||
|
firmware_frame = tk.Frame(main_frame, bg=self.bg_color)
|
||||||
firmware_frame.grid(row=1, column=1, sticky=(tk.W, tk.E), pady=5)
|
firmware_frame.grid(row=1, column=1, sticky=(tk.W, tk.E), pady=5)
|
||||||
firmware_frame.columnconfigure(0, weight=1)
|
firmware_frame.columnconfigure(0, weight=1)
|
||||||
|
|
||||||
self.firmware_entry = ttk.Entry(firmware_frame, textvariable=self.firmware_path_var, state="readonly")
|
self.firmware_entry = tk.Entry(firmware_frame, textvariable=self.firmware_path_var,
|
||||||
|
state="readonly", bg=self.text_bg, fg=self.text_fg,
|
||||||
|
relief=tk.SUNKEN, borderwidth=2)
|
||||||
self.firmware_entry.grid(row=0, column=0, sticky=(tk.W, tk.E), padx=(0, 5))
|
self.firmware_entry.grid(row=0, column=0, sticky=(tk.W, tk.E), padx=(0, 5))
|
||||||
|
|
||||||
ttk.Button(firmware_frame, text="Browse", command=self.browse_firmware).grid(row=0, column=1)
|
tk.Button(firmware_frame, text="Browse", command=self.browse_firmware,
|
||||||
|
bg=self.button_bg, fg=self.fg_color, relief=tk.RAISED).grid(row=0, column=1)
|
||||||
|
|
||||||
# Flash settings frame
|
# Flash settings frame
|
||||||
settings_frame = ttk.LabelFrame(main_frame, text="Flash Settings", padding="5")
|
settings_frame = tk.LabelFrame(main_frame, text="Flash Settings",
|
||||||
|
bg=self.bg_color, fg=self.fg_color,
|
||||||
|
relief=tk.GROOVE, borderwidth=2, padx=5, pady=5)
|
||||||
settings_frame.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=10)
|
settings_frame.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=10)
|
||||||
settings_frame.columnconfigure(1, weight=1)
|
settings_frame.columnconfigure(1, weight=1)
|
||||||
|
|
||||||
# Flash settings
|
# Flash settings
|
||||||
ttk.Label(settings_frame, text="Chip:").grid(row=0, column=0, sticky=tk.W, pady=2)
|
tk.Label(settings_frame, text="Chip:", bg=self.bg_color, fg=self.fg_color).grid(
|
||||||
|
row=0, column=0, sticky=tk.W, pady=2, padx=(0, 10))
|
||||||
self.chip_var = tk.StringVar(value="esp32")
|
self.chip_var = tk.StringVar(value="esp32")
|
||||||
ttk.Entry(settings_frame, textvariable=self.chip_var, width=15).grid(row=0, column=1, sticky=tk.W, pady=2)
|
tk.Entry(settings_frame, textvariable=self.chip_var, width=15,
|
||||||
|
bg=self.text_bg, fg=self.text_fg, relief=tk.SUNKEN).grid(row=0, column=1, sticky=tk.W, pady=2)
|
||||||
|
|
||||||
ttk.Label(settings_frame, text="Baud Rate:").grid(row=1, column=0, sticky=tk.W, pady=2)
|
tk.Label(settings_frame, text="Baud Rate:", bg=self.bg_color, fg=self.fg_color).grid(
|
||||||
|
row=1, column=0, sticky=tk.W, pady=2, padx=(0, 10))
|
||||||
self.baud_var = tk.StringVar(value="460800")
|
self.baud_var = tk.StringVar(value="460800")
|
||||||
ttk.Entry(settings_frame, textvariable=self.baud_var, width=15).grid(row=1, column=1, sticky=tk.W, pady=2)
|
tk.Entry(settings_frame, textvariable=self.baud_var, width=15,
|
||||||
|
bg=self.text_bg, fg=self.text_fg, relief=tk.SUNKEN).grid(row=1, column=1, sticky=tk.W, pady=2)
|
||||||
|
|
||||||
ttk.Label(settings_frame, text="Flash Mode:").grid(row=2, column=0, sticky=tk.W, pady=2)
|
tk.Label(settings_frame, text="Flash Mode:", bg=self.bg_color, fg=self.fg_color).grid(
|
||||||
|
row=2, column=0, sticky=tk.W, pady=2, padx=(0, 10))
|
||||||
self.flash_mode_var = tk.StringVar(value="dio")
|
self.flash_mode_var = tk.StringVar(value="dio")
|
||||||
ttk.Entry(settings_frame, textvariable=self.flash_mode_var, width=15).grid(row=2, column=1, sticky=tk.W, pady=2)
|
tk.Entry(settings_frame, textvariable=self.flash_mode_var, width=15,
|
||||||
|
bg=self.text_bg, fg=self.text_fg, relief=tk.SUNKEN).grid(row=2, column=1, sticky=tk.W, pady=2)
|
||||||
|
|
||||||
ttk.Label(settings_frame, text="Flash Freq:").grid(row=3, column=0, sticky=tk.W, pady=2)
|
tk.Label(settings_frame, text="Flash Freq:", bg=self.bg_color, fg=self.fg_color).grid(
|
||||||
|
row=3, column=0, sticky=tk.W, pady=2, padx=(0, 10))
|
||||||
self.flash_freq_var = tk.StringVar(value="40m")
|
self.flash_freq_var = tk.StringVar(value="40m")
|
||||||
ttk.Entry(settings_frame, textvariable=self.flash_freq_var, width=15).grid(row=3, column=1, sticky=tk.W, pady=2)
|
tk.Entry(settings_frame, textvariable=self.flash_freq_var, width=15,
|
||||||
|
bg=self.text_bg, fg=self.text_fg, relief=tk.SUNKEN).grid(row=3, column=1, sticky=tk.W, pady=2)
|
||||||
|
|
||||||
ttk.Label(settings_frame, text="Flash Size:").grid(row=4, column=0, sticky=tk.W, pady=2)
|
tk.Label(settings_frame, text="Flash Size:", bg=self.bg_color, fg=self.fg_color).grid(
|
||||||
|
row=4, column=0, sticky=tk.W, pady=2, padx=(0, 10))
|
||||||
self.flash_size_var = tk.StringVar(value="2MB")
|
self.flash_size_var = tk.StringVar(value="2MB")
|
||||||
ttk.Entry(settings_frame, textvariable=self.flash_size_var, width=15).grid(row=4, column=1, sticky=tk.W, pady=2)
|
tk.Entry(settings_frame, textvariable=self.flash_size_var, width=15,
|
||||||
|
bg=self.text_bg, fg=self.text_fg, relief=tk.SUNKEN).grid(row=4, column=1, sticky=tk.W, pady=2)
|
||||||
|
|
||||||
# Flash button
|
# Flash button
|
||||||
self.flash_button = ttk.Button(main_frame, text="Flash Firmware", command=self.flash_firmware)
|
self.flash_button = tk.Button(main_frame, text="Flash Firmware", command=self.flash_firmware,
|
||||||
|
bg=self.button_bg, fg=self.fg_color,
|
||||||
|
relief=tk.RAISED, padx=20, pady=5,
|
||||||
|
font=('TkDefaultFont', 10, 'bold'))
|
||||||
self.flash_button.grid(row=3, column=0, columnspan=2, pady=10)
|
self.flash_button.grid(row=3, column=0, columnspan=2, pady=10)
|
||||||
|
|
||||||
# Progress bar
|
# Progress bar
|
||||||
@@ -96,8 +152,18 @@ class ESP32FlasherGUI:
|
|||||||
self.progress.grid(row=4, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=5)
|
self.progress.grid(row=4, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=5)
|
||||||
|
|
||||||
# Log output
|
# Log output
|
||||||
ttk.Label(main_frame, text="Output:").grid(row=5, column=0, sticky=tk.W, pady=(10, 0))
|
tk.Label(main_frame, text="Output:", bg=self.bg_color, fg=self.fg_color).grid(
|
||||||
self.log_text = scrolledtext.ScrolledText(main_frame, height=15, width=70)
|
row=5, column=0, sticky=tk.W, pady=(10, 0))
|
||||||
|
self.log_text = scrolledtext.ScrolledText(
|
||||||
|
main_frame,
|
||||||
|
height=15,
|
||||||
|
width=70,
|
||||||
|
bg=self.text_bg,
|
||||||
|
fg=self.text_fg,
|
||||||
|
insertbackground=self.text_fg, # Cursor color
|
||||||
|
relief=tk.SUNKEN,
|
||||||
|
borderwidth=2
|
||||||
|
)
|
||||||
self.log_text.grid(row=6, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=5)
|
self.log_text.grid(row=6, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=5)
|
||||||
main_frame.rowconfigure(6, weight=1)
|
main_frame.rowconfigure(6, weight=1)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
esptool>=4.0
|
esptool>=4.0
|
||||||
pyserial>=3.5
|
pyserial>=3.5
|
||||||
pyinstaller>=5.0
|
pyinstaller>=5.0
|
||||||
|
flask>=2.3.0
|
||||||
|
flask-socketio>=5.3.0
|
||||||
|
python-socketio>=5.11.0
|
||||||
BIN
flash_tool/static/SoundShot.png
Normal file
BIN
flash_tool/static/SoundShot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 105 KiB |
570
flash_tool/templates/index.html
Normal file
570
flash_tool/templates/index.html
Normal file
@@ -0,0 +1,570 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>SoundShot Firmware Flasher</title>
|
||||||
|
<script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||||
|
background: linear-gradient(135deg, #d94125 0%, #a33318 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
||||||
|
max-width: 700px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
background: linear-gradient(135deg, #2c2c2c 0%, #1a1a1a 100%);
|
||||||
|
padding: 40px 20px 30px 20px;
|
||||||
|
margin: -40px -40px 30px -40px;
|
||||||
|
border-radius: 12px 12px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
max-width: 450px;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #c04026;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
color: #d0d0d0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"],
|
||||||
|
select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
border: 2px solid #e0e0e0;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: border-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"]:focus,
|
||||||
|
select:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #c04026;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-input-wrapper {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-input-wrapper input[type="file"] {
|
||||||
|
position: absolute;
|
||||||
|
left: -9999px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-input-label {
|
||||||
|
display: block;
|
||||||
|
padding: 12px;
|
||||||
|
border: 2px dashed #e0e0e0;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-input-label:hover {
|
||||||
|
border-color: #c04026;
|
||||||
|
background: #fef6f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-selected {
|
||||||
|
border-color: #c04026;
|
||||||
|
border-style: solid;
|
||||||
|
background: #fef6f4;
|
||||||
|
color: #c04026;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 100%;
|
||||||
|
padding: 14px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background: linear-gradient(135deg, #d94125 0%, #a33318 100%);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover:not(:disabled) {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 10px 20px rgba(217, 65, 37, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-section {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-toggle {
|
||||||
|
background: #f0f0f0;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #333;
|
||||||
|
transition: background 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-toggle:hover {
|
||||||
|
background: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-box {
|
||||||
|
background: #1e1e1e;
|
||||||
|
color: #d4d4d4;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
max-height: 400px;
|
||||||
|
overflow-y: auto;
|
||||||
|
line-height: 1.6;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-box.expanded {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-box:empty::before {
|
||||||
|
content: 'Output will appear here...';
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar {
|
||||||
|
width: 100%;
|
||||||
|
height: 8px;
|
||||||
|
background: #e0e0e0;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 20px 0;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar-fill {
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, #d94125, #a33318);
|
||||||
|
width: 0%;
|
||||||
|
transition: width 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar-fill.indeterminate {
|
||||||
|
animation: progress 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes progress {
|
||||||
|
0% { width: 0%; }
|
||||||
|
50% { width: 100%; }
|
||||||
|
100% { width: 0%; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-text {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #c04026;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 5px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-text.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-message {
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin: 15px 0;
|
||||||
|
font-weight: 500;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-message.success {
|
||||||
|
background: #d4edda;
|
||||||
|
color: #155724;
|
||||||
|
border: 1px solid #c3e6cb;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-message.error {
|
||||||
|
background: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
border: 1px solid #f5c6cb;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh-btn {
|
||||||
|
padding: 8px 16px;
|
||||||
|
background: #f0f0f0;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #333;
|
||||||
|
margin-left: 10px;
|
||||||
|
transition: background 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh-btn:hover {
|
||||||
|
background: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.port-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.port-section .form-group {
|
||||||
|
flex: 1;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<img src="/static/SoundShot.png" alt="SoundShot" class="logo">
|
||||||
|
<p class="subtitle">Firmware Flasher</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form id="flashForm" onsubmit="return false;">
|
||||||
|
<div class="port-section">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="port">Serial Port</label>
|
||||||
|
<select id="port" name="port" required>
|
||||||
|
<option value="">Select a port...</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="refresh-btn" onclick="refreshPorts()">🔄 Refresh</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="firmware">Firmware Package (.zip)</label>
|
||||||
|
<div class="file-input-wrapper">
|
||||||
|
<input type="file" id="firmware" name="firmware" accept=".zip" required>
|
||||||
|
<label for="firmware" class="file-input-label" id="fileLabel">
|
||||||
|
📦 Click to select firmware package
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Hidden fields with default values -->
|
||||||
|
<input type="hidden" id="chip" name="chip" value="esp32">
|
||||||
|
<input type="hidden" id="baud" name="baud" value="460800">
|
||||||
|
<input type="hidden" id="flash_mode" name="flash_mode" value="dio">
|
||||||
|
<input type="hidden" id="flash_freq" name="flash_freq" value="40m">
|
||||||
|
<input type="hidden" id="flash_size" name="flash_size" value="2MB">
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary" id="flashBtn">
|
||||||
|
⚡ Flash Firmware
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="progress-bar" id="progressBar">
|
||||||
|
<div class="progress-bar-fill" id="progressBarFill"></div>
|
||||||
|
</div>
|
||||||
|
<div class="progress-text" id="progressText">0%</div>
|
||||||
|
|
||||||
|
<div class="status-message" id="statusMessage"></div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="output-section">
|
||||||
|
<div class="output-header">
|
||||||
|
<label>Output Log</label>
|
||||||
|
<button type="button" class="output-toggle" id="outputToggle" onclick="toggleOutput()">▼ Show Details</button>
|
||||||
|
</div>
|
||||||
|
<div class="output-box" id="output"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let statusCheckInterval = null;
|
||||||
|
let socket = null;
|
||||||
|
let heartbeatInterval = null;
|
||||||
|
|
||||||
|
// Toggle output visibility
|
||||||
|
function toggleOutput() {
|
||||||
|
const output = document.getElementById('output');
|
||||||
|
const toggle = document.getElementById('outputToggle');
|
||||||
|
|
||||||
|
if (output.classList.contains('expanded')) {
|
||||||
|
output.classList.remove('expanded');
|
||||||
|
toggle.textContent = '▼ Show Details';
|
||||||
|
} else {
|
||||||
|
output.classList.add('expanded');
|
||||||
|
toggle.textContent = '▲ Hide Details';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize Socket.IO connection
|
||||||
|
function initWebSocket() {
|
||||||
|
socket = io();
|
||||||
|
|
||||||
|
socket.on('connect', () => {
|
||||||
|
console.log('WebSocket connected');
|
||||||
|
|
||||||
|
// Start sending heartbeats every 2 seconds
|
||||||
|
heartbeatInterval = setInterval(() => {
|
||||||
|
socket.emit('heartbeat');
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('disconnect', () => {
|
||||||
|
console.log('WebSocket disconnected');
|
||||||
|
if (heartbeatInterval) {
|
||||||
|
clearInterval(heartbeatInterval);
|
||||||
|
heartbeatInterval = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('heartbeat_ack', (data) => {
|
||||||
|
// Heartbeat acknowledged
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load ports on page load
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
initWebSocket();
|
||||||
|
refreshPorts();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clean up on page unload
|
||||||
|
window.addEventListener('beforeunload', () => {
|
||||||
|
if (socket) {
|
||||||
|
socket.disconnect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle file selection
|
||||||
|
document.getElementById('firmware').addEventListener('change', function(e) {
|
||||||
|
const fileLabel = document.getElementById('fileLabel');
|
||||||
|
if (e.target.files.length > 0) {
|
||||||
|
fileLabel.textContent = '✓ ' + e.target.files[0].name;
|
||||||
|
fileLabel.classList.add('file-selected');
|
||||||
|
} else {
|
||||||
|
fileLabel.textContent = '📦 Click to select firmware package';
|
||||||
|
fileLabel.classList.remove('file-selected');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function refreshPorts() {
|
||||||
|
const portSelect = document.getElementById('port');
|
||||||
|
portSelect.innerHTML = '<option value="">Loading ports...</option>';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/ports');
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.success) {
|
||||||
|
portSelect.innerHTML = '<option value="">Select a port...</option>';
|
||||||
|
data.ports.forEach(port => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = port.device;
|
||||||
|
option.textContent = `${port.device} - ${port.description}`;
|
||||||
|
portSelect.appendChild(option);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
portSelect.innerHTML = '<option value="">Error loading ports</option>';
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
portSelect.innerHTML = '<option value="">Error loading ports</option>';
|
||||||
|
console.error('Error:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('flashForm').addEventListener('submit', async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
|
||||||
|
const flashBtn = document.getElementById('flashBtn');
|
||||||
|
const progressBar = document.getElementById('progressBar');
|
||||||
|
const progressBarFill = document.getElementById('progressBarFill');
|
||||||
|
const progressText = document.getElementById('progressText');
|
||||||
|
const output = document.getElementById('output');
|
||||||
|
const outputToggle = document.getElementById('outputToggle');
|
||||||
|
const statusMessage = document.getElementById('statusMessage');
|
||||||
|
|
||||||
|
// Disable form
|
||||||
|
flashBtn.disabled = true;
|
||||||
|
flashBtn.textContent = '⚡ Flashing...';
|
||||||
|
progressBar.classList.add('active');
|
||||||
|
progressBarFill.classList.add('indeterminate');
|
||||||
|
progressBarFill.style.width = '0%';
|
||||||
|
progressText.classList.add('active');
|
||||||
|
progressText.textContent = '0%';
|
||||||
|
output.textContent = '';
|
||||||
|
output.classList.remove('expanded');
|
||||||
|
outputToggle.textContent = '▼ Show Details';
|
||||||
|
statusMessage.style.display = 'none';
|
||||||
|
statusMessage.className = 'status-message';
|
||||||
|
|
||||||
|
// Create FormData
|
||||||
|
const formData = new FormData(e.target);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/flash', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.success) {
|
||||||
|
// Start checking status
|
||||||
|
statusCheckInterval = setInterval(checkStatus, 500);
|
||||||
|
} else {
|
||||||
|
showError(data.error);
|
||||||
|
resetForm();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
showError('Failed to start flash: ' + error.message);
|
||||||
|
resetForm();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function checkStatus() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/status');
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
// Update output
|
||||||
|
const output = document.getElementById('output');
|
||||||
|
output.textContent = data.output.join('\n');
|
||||||
|
output.scrollTop = output.scrollHeight;
|
||||||
|
|
||||||
|
// Update progress bar
|
||||||
|
const progressBarFill = document.getElementById('progressBarFill');
|
||||||
|
const progressText = document.getElementById('progressText');
|
||||||
|
if (data.progress !== undefined && data.progress > 0) {
|
||||||
|
// Switch from indeterminate to determinate
|
||||||
|
progressBarFill.classList.remove('indeterminate');
|
||||||
|
progressBarFill.style.width = data.progress + '%';
|
||||||
|
progressText.textContent = data.progress.toFixed(1) + '%';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if complete
|
||||||
|
if (!data.running && statusCheckInterval) {
|
||||||
|
clearInterval(statusCheckInterval);
|
||||||
|
statusCheckInterval = null;
|
||||||
|
|
||||||
|
const statusMessage = document.getElementById('statusMessage');
|
||||||
|
if (data.success === true) {
|
||||||
|
progressBarFill.style.width = '100%';
|
||||||
|
progressText.textContent = '100%';
|
||||||
|
statusMessage.textContent = '✓ Flash completed successfully!';
|
||||||
|
statusMessage.className = 'status-message success';
|
||||||
|
statusMessage.style.display = 'block';
|
||||||
|
} else if (data.success === false) {
|
||||||
|
statusMessage.textContent = '✗ Flash operation failed. Check the output log for details.';
|
||||||
|
statusMessage.className = 'status-message error';
|
||||||
|
statusMessage.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
resetForm();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error checking status:', error);
|
||||||
|
clearInterval(statusCheckInterval);
|
||||||
|
statusCheckInterval = null;
|
||||||
|
resetForm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showError(message) {
|
||||||
|
const statusMessage = document.getElementById('statusMessage');
|
||||||
|
statusMessage.textContent = '✗ ' + message;
|
||||||
|
statusMessage.className = 'status-message error';
|
||||||
|
statusMessage.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetForm() {
|
||||||
|
const flashBtn = document.getElementById('flashBtn');
|
||||||
|
const progressBar = document.getElementById('progressBar');
|
||||||
|
const progressBarFill = document.getElementById('progressBarFill');
|
||||||
|
const progressText = document.getElementById('progressText');
|
||||||
|
|
||||||
|
flashBtn.disabled = false;
|
||||||
|
flashBtn.textContent = '⚡ Flash Firmware';
|
||||||
|
|
||||||
|
// Delay hiding progress to let user see completion
|
||||||
|
setTimeout(() => {
|
||||||
|
progressBar.classList.remove('active');
|
||||||
|
progressText.classList.remove('active');
|
||||||
|
progressBarFill.classList.remove('indeterminate');
|
||||||
|
progressBarFill.style.width = '0%';
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
343
flash_tool/web_flasher.py
Normal file
343
flash_tool/web_flasher.py
Normal file
@@ -0,0 +1,343 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
ESP32 Firmware Flash Web Server
|
||||||
|
Web-based GUI interface for flashing firmware packages to ESP32 devices
|
||||||
|
"""
|
||||||
|
|
||||||
|
from flask import Flask, render_template, request, jsonify, send_from_directory
|
||||||
|
from flask_socketio import SocketIO, emit
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
import zipfile
|
||||||
|
import tempfile
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from pathlib import Path
|
||||||
|
import serial.tools.list_ports
|
||||||
|
import webbrowser
|
||||||
|
import socket
|
||||||
|
import time
|
||||||
|
import signal
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024 # 100MB max file size
|
||||||
|
app.config['SECRET_KEY'] = 'esp32-flasher-secret-key'
|
||||||
|
socketio = SocketIO(app, cors_allowed_origins="*")
|
||||||
|
|
||||||
|
# Global state
|
||||||
|
flash_status = {
|
||||||
|
'running': False,
|
||||||
|
'output': [],
|
||||||
|
'success': None,
|
||||||
|
'progress': 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Client connection tracking
|
||||||
|
client_connected = False
|
||||||
|
last_heartbeat = time.time()
|
||||||
|
shutdown_timer = None
|
||||||
|
|
||||||
|
def get_free_port():
|
||||||
|
"""Find a free port to run the server on"""
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
s.bind(('', 0))
|
||||||
|
s.listen(1)
|
||||||
|
port = s.getsockname()[1]
|
||||||
|
return port
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
"""Serve the main page"""
|
||||||
|
return render_template('index.html')
|
||||||
|
|
||||||
|
@app.route('/static/<path:filename>')
|
||||||
|
def serve_static(filename):
|
||||||
|
"""Serve static files"""
|
||||||
|
static_dir = os.path.join(os.path.dirname(__file__), 'static')
|
||||||
|
return send_from_directory(static_dir, filename)
|
||||||
|
|
||||||
|
@app.route('/api/ports')
|
||||||
|
def get_ports():
|
||||||
|
"""Get list of available serial ports"""
|
||||||
|
try:
|
||||||
|
ports = [{'device': port.device, 'description': port.description}
|
||||||
|
for port in serial.tools.list_ports.comports()]
|
||||||
|
return jsonify({'success': True, 'ports': ports})
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'success': False, 'error': str(e)})
|
||||||
|
|
||||||
|
@app.route('/api/flash', methods=['POST'])
|
||||||
|
def flash_firmware():
|
||||||
|
"""Flash firmware to ESP32"""
|
||||||
|
global flash_status
|
||||||
|
|
||||||
|
if flash_status['running']:
|
||||||
|
return jsonify({'success': False, 'error': 'Flash operation already in progress'})
|
||||||
|
|
||||||
|
# Get form data
|
||||||
|
port = request.form.get('port')
|
||||||
|
chip = request.form.get('chip', 'esp32')
|
||||||
|
baud = request.form.get('baud', '460800')
|
||||||
|
flash_mode = request.form.get('flash_mode', 'dio')
|
||||||
|
flash_freq = request.form.get('flash_freq', '40m')
|
||||||
|
flash_size = request.form.get('flash_size', '2MB')
|
||||||
|
|
||||||
|
# Get uploaded file
|
||||||
|
if 'firmware' not in request.files:
|
||||||
|
return jsonify({'success': False, 'error': 'No firmware file uploaded'})
|
||||||
|
|
||||||
|
firmware_file = request.files['firmware']
|
||||||
|
if firmware_file.filename == '':
|
||||||
|
return jsonify({'success': False, 'error': 'No firmware file selected'})
|
||||||
|
|
||||||
|
# Save and extract firmware
|
||||||
|
try:
|
||||||
|
# Create temp directory
|
||||||
|
temp_dir = tempfile.mkdtemp(prefix="esp32_flash_")
|
||||||
|
zip_path = os.path.join(temp_dir, 'firmware.zip')
|
||||||
|
firmware_file.save(zip_path)
|
||||||
|
|
||||||
|
# Extract firmware
|
||||||
|
with zipfile.ZipFile(zip_path, 'r') as zip_file:
|
||||||
|
zip_file.extractall(temp_dir)
|
||||||
|
|
||||||
|
# Start flash in background thread
|
||||||
|
flash_status = {'running': True, 'output': [], 'success': None, 'progress': 0}
|
||||||
|
thread = threading.Thread(
|
||||||
|
target=flash_worker,
|
||||||
|
args=(temp_dir, port, chip, baud, flash_mode, flash_freq, flash_size)
|
||||||
|
)
|
||||||
|
thread.daemon = True
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
return jsonify({'success': True, 'message': 'Flash started'})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'success': False, 'error': str(e)})
|
||||||
|
|
||||||
|
@app.route('/api/status')
|
||||||
|
def get_status():
|
||||||
|
"""Get current flash status"""
|
||||||
|
return jsonify(flash_status)
|
||||||
|
|
||||||
|
@socketio.on('connect')
|
||||||
|
def handle_connect():
|
||||||
|
"""Handle client connection"""
|
||||||
|
global client_connected, last_heartbeat, shutdown_timer
|
||||||
|
client_connected = True
|
||||||
|
last_heartbeat = time.time()
|
||||||
|
|
||||||
|
# Cancel any pending shutdown
|
||||||
|
if shutdown_timer:
|
||||||
|
shutdown_timer.cancel()
|
||||||
|
shutdown_timer = None
|
||||||
|
|
||||||
|
print('Client connected')
|
||||||
|
|
||||||
|
@socketio.on('disconnect')
|
||||||
|
def handle_disconnect():
|
||||||
|
"""Handle client disconnection"""
|
||||||
|
global client_connected, shutdown_timer
|
||||||
|
client_connected = False
|
||||||
|
print('Client disconnected - scheduling shutdown in 1 second...')
|
||||||
|
|
||||||
|
# Schedule shutdown after 5 seconds
|
||||||
|
shutdown_timer = threading.Timer(1.0, shutdown_server)
|
||||||
|
shutdown_timer.daemon = True
|
||||||
|
shutdown_timer.start()
|
||||||
|
|
||||||
|
@socketio.on('heartbeat')
|
||||||
|
def handle_heartbeat():
|
||||||
|
"""Handle heartbeat from client"""
|
||||||
|
global last_heartbeat
|
||||||
|
last_heartbeat = time.time()
|
||||||
|
emit('heartbeat_ack', {'timestamp': last_heartbeat})
|
||||||
|
|
||||||
|
def shutdown_server():
|
||||||
|
"""Gracefully shutdown the server"""
|
||||||
|
print('\nNo clients connected. Shutting down server...')
|
||||||
|
|
||||||
|
# Give a moment for any pending operations
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Shutdown Flask
|
||||||
|
try:
|
||||||
|
func = request.environ.get('werkzeug.server.shutdown')
|
||||||
|
if func is None:
|
||||||
|
# Alternative shutdown method
|
||||||
|
os.kill(os.getpid(), signal.SIGTERM)
|
||||||
|
else:
|
||||||
|
func()
|
||||||
|
except:
|
||||||
|
# Force exit as last resort
|
||||||
|
os._exit(0)
|
||||||
|
|
||||||
|
def flash_worker(temp_dir, port, chip, baud, flash_mode, flash_freq, flash_size):
|
||||||
|
"""Background worker for flashing firmware"""
|
||||||
|
global flash_status
|
||||||
|
import re
|
||||||
|
import io
|
||||||
|
from contextlib import redirect_stdout, redirect_stderr
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Define file paths
|
||||||
|
bootloader = os.path.join(temp_dir, "bootloader.bin")
|
||||||
|
firmware = os.path.join(temp_dir, "soundshot.bin")
|
||||||
|
ota_initial = os.path.join(temp_dir, "ota_data_initial.bin")
|
||||||
|
partition = os.path.join(temp_dir, "partition-table.bin")
|
||||||
|
|
||||||
|
# Verify files exist
|
||||||
|
required_files = [bootloader, firmware, ota_initial, partition]
|
||||||
|
for file_path in required_files:
|
||||||
|
if not os.path.exists(file_path):
|
||||||
|
flash_status['output'].append(f"ERROR: Missing file {os.path.basename(file_path)}")
|
||||||
|
flash_status['success'] = False
|
||||||
|
flash_status['running'] = False
|
||||||
|
return
|
||||||
|
|
||||||
|
# Build esptool command arguments
|
||||||
|
esptool_args = [
|
||||||
|
"--chip", chip,
|
||||||
|
"--port", port,
|
||||||
|
"--baud", baud,
|
||||||
|
"--before", "default_reset",
|
||||||
|
"--after", "hard_reset",
|
||||||
|
"write-flash",
|
||||||
|
"--flash-mode", flash_mode,
|
||||||
|
"--flash-freq", flash_freq,
|
||||||
|
"--flash-size", flash_size,
|
||||||
|
"0x1000", bootloader,
|
||||||
|
"0x20000", firmware,
|
||||||
|
"0x11000", ota_initial,
|
||||||
|
"0x8000", partition
|
||||||
|
]
|
||||||
|
|
||||||
|
flash_status['output'].append(f"Running esptool with args: {' '.join(esptool_args)}")
|
||||||
|
flash_status['output'].append("")
|
||||||
|
|
||||||
|
# Import and run esptool directly (works in both script and EXE)
|
||||||
|
import esptool
|
||||||
|
|
||||||
|
# Fix esptool data path for PyInstaller
|
||||||
|
if getattr(sys, 'frozen', False):
|
||||||
|
# Running as compiled executable
|
||||||
|
bundle_dir = sys._MEIPASS
|
||||||
|
esptool_targets = os.path.join(bundle_dir, 'esptool', 'targets')
|
||||||
|
if os.path.exists(esptool_targets):
|
||||||
|
# Override esptool's resource path
|
||||||
|
esptool.RESOURCES_DIR = bundle_dir
|
||||||
|
|
||||||
|
# Capture stdout/stderr
|
||||||
|
output_buffer = io.StringIO()
|
||||||
|
|
||||||
|
# Backup original sys.argv and replace with our arguments
|
||||||
|
original_argv = sys.argv
|
||||||
|
sys.argv = ['esptool.py'] + esptool_args
|
||||||
|
|
||||||
|
# Run esptool and capture output
|
||||||
|
return_code = 0
|
||||||
|
|
||||||
|
# Regex to parse progress lines
|
||||||
|
# Example: "Writing at 0x0011325c... (85 %)"
|
||||||
|
# or "Writing at 0x0011325c [========================> ] 85.3% 622592/730050 bytes..."
|
||||||
|
progress_pattern = re.compile(r'(\d+(?:\.\d+)?)\s*%')
|
||||||
|
|
||||||
|
# Save original stdout/stderr
|
||||||
|
original_stdout = sys.stdout
|
||||||
|
original_stderr = sys.stderr
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Custom output class to capture and stream esptool output
|
||||||
|
class OutputCapture:
|
||||||
|
def __init__(self):
|
||||||
|
self.buffer = []
|
||||||
|
|
||||||
|
def write(self, text):
|
||||||
|
if text and text.strip():
|
||||||
|
lines = text.rstrip().split('\n')
|
||||||
|
for line in lines:
|
||||||
|
flash_status['output'].append(line)
|
||||||
|
self.buffer.append(line)
|
||||||
|
|
||||||
|
# Try to extract progress percentage
|
||||||
|
match = progress_pattern.search(line)
|
||||||
|
if match:
|
||||||
|
try:
|
||||||
|
percent = float(match.group(1))
|
||||||
|
flash_status['progress'] = percent
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
return len(text)
|
||||||
|
|
||||||
|
def flush(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
capture = OutputCapture()
|
||||||
|
|
||||||
|
# Redirect stdout/stderr to our capture object
|
||||||
|
with redirect_stdout(capture), redirect_stderr(capture):
|
||||||
|
esptool.main()
|
||||||
|
|
||||||
|
except SystemExit as e:
|
||||||
|
return_code = e.code if e.code is not None else 0
|
||||||
|
finally:
|
||||||
|
# Restore original sys.argv and stdout/stderr
|
||||||
|
sys.argv = original_argv
|
||||||
|
sys.stdout = original_stdout
|
||||||
|
sys.stderr = original_stderr
|
||||||
|
|
||||||
|
if return_code == 0:
|
||||||
|
flash_status['output'].append("")
|
||||||
|
flash_status['output'].append("✓ Flash completed successfully!")
|
||||||
|
flash_status['success'] = True
|
||||||
|
flash_status['progress'] = 100
|
||||||
|
else:
|
||||||
|
flash_status['output'].append("")
|
||||||
|
flash_status['output'].append(f"✗ Flash failed with return code {return_code}")
|
||||||
|
flash_status['success'] = False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
flash_status['output'].append(f"✗ Error: {str(e)}")
|
||||||
|
flash_status['success'] = False
|
||||||
|
finally:
|
||||||
|
flash_status['running'] = False
|
||||||
|
# Clean up temp directory
|
||||||
|
try:
|
||||||
|
shutil.rmtree(temp_dir, ignore_errors=True)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def open_browser(port):
|
||||||
|
"""Open browser to the application"""
|
||||||
|
url = f'http://127.0.0.1:{port}'
|
||||||
|
webbrowser.open(url)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Run the web server"""
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# Disable Flask request logging to avoid colorama issues with stdout redirection
|
||||||
|
log = logging.getLogger('werkzeug')
|
||||||
|
log.setLevel(logging.ERROR)
|
||||||
|
|
||||||
|
port = get_free_port()
|
||||||
|
print(f"Starting ESP32 Flasher on port {port}...")
|
||||||
|
print(f"Open your browser to: http://127.0.0.1:{port}")
|
||||||
|
print(f"Server will automatically shut down when browser is closed.\n")
|
||||||
|
|
||||||
|
# Open browser after short delay
|
||||||
|
timer = threading.Timer(1.5, open_browser, args=[port])
|
||||||
|
timer.daemon = True
|
||||||
|
timer.start()
|
||||||
|
|
||||||
|
# Run Flask server with SocketIO
|
||||||
|
try:
|
||||||
|
socketio.run(app, host='127.0.0.1', port=port, debug=False, allow_unsafe_werkzeug=True, log_output=False)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print('\nShutting down...')
|
||||||
|
except SystemExit:
|
||||||
|
print('Server stopped.')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
173
main/bt_app.c
173
main/bt_app.c
@@ -107,7 +107,7 @@ static void bt_app_a2d_heart_beat(TimerHandle_t arg);
|
|||||||
static void bt_app_av_sm_hdlr(uint16_t event, void *param);
|
static void bt_app_av_sm_hdlr(uint16_t event, void *param);
|
||||||
|
|
||||||
/* utils for transfer BLuetooth Deveice Address into string form */
|
/* utils for transfer BLuetooth Deveice Address into string form */
|
||||||
static char *bda2str(esp_bd_addr_t bda, char *str, size_t size);
|
static char *bda2str(const uint8_t *bda, char *str, size_t size);
|
||||||
|
|
||||||
static esp_err_t bt_try_connect_known_devices(void);
|
static esp_err_t bt_try_connect_known_devices(void);
|
||||||
static void bt_debug_print_known_devices(void);
|
static void bt_debug_print_known_devices(void);
|
||||||
@@ -328,34 +328,16 @@ static esp_err_t bt_add_discovered_device(esp_bd_addr_t bda, const char *name)
|
|||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if device is already known
|
// Don't save discovered devices to NVS - they're not paired yet!
|
||||||
if (system_isDeviceKnown(bda)) {
|
// They will only be saved to NVS when successfully connected.
|
||||||
|
// Just log that we discovered this device.
|
||||||
char bda_str[18];
|
char bda_str[18];
|
||||||
ESP_LOGD(BT_AV_TAG, "Device %s (%s) already known, skipping",
|
ESP_LOGI(BT_AV_TAG, "Discovered device: %s (%s)",
|
||||||
name, bda2str(bda, bda_str, sizeof(bda_str)));
|
name, bda2str(bda, bda_str, sizeof(bda_str)));
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create paired_device_t structure for discovered device
|
|
||||||
paired_device_t device;
|
|
||||||
memcpy(device.bda, bda, ESP_BD_ADDR_LEN);
|
|
||||||
strncpy(device.name, name, DEVICE_NAME_MAX_LEN - 1);
|
|
||||||
device.name[DEVICE_NAME_MAX_LEN - 1] = '\0';
|
|
||||||
device.last_connected = 0; // Never connected, set to 0
|
|
||||||
|
|
||||||
// Save to NVS
|
|
||||||
esp_err_t ret = system_savePairedDevice(&device);
|
|
||||||
if (ret == ESP_OK) {
|
|
||||||
char bda_str[18];
|
|
||||||
ESP_LOGI(BT_AV_TAG, "Added discovered device to NVS: %s (%s)",
|
|
||||||
device.name, bda2str(device.bda, bda_str, sizeof(bda_str)));
|
|
||||||
} else {
|
|
||||||
ESP_LOGE(BT_AV_TAG, "Failed to save discovered device: %s", esp_err_to_name(ret));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static esp_err_t __attribute__((unused)) nvs_update_connection_timestamp(esp_bd_addr_t bda)
|
static esp_err_t __attribute__((unused)) nvs_update_connection_timestamp(esp_bd_addr_t bda)
|
||||||
{
|
{
|
||||||
if (!bda) {
|
if (!bda) {
|
||||||
@@ -485,7 +467,7 @@ static esp_err_t bt_try_next_known_device(void)
|
|||||||
/*********************************
|
/*********************************
|
||||||
* STATIC FUNCTION DEFINITIONS
|
* STATIC FUNCTION DEFINITIONS
|
||||||
********************************/
|
********************************/
|
||||||
static char *bda2str(esp_bd_addr_t bda, char *str, size_t size)
|
static char *bda2str(const uint8_t *bda, char *str, size_t size)
|
||||||
{
|
{
|
||||||
if (bda == NULL || str == NULL || size < 18) {
|
if (bda == NULL || str == NULL || size < 18) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -559,9 +541,14 @@ static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log device details for debugging
|
||||||
|
ESP_LOGI(BT_AV_TAG, " CoD: 0x%"PRIx32", Valid: %d, RSSI: %"PRId32", EIR: %p",
|
||||||
|
cod, esp_bt_gap_is_valid_cod(cod), rssi, eir);
|
||||||
|
|
||||||
/* search for device with MAJOR service class as "rendering" in COD */
|
/* search for device with MAJOR service class as "rendering" in COD */
|
||||||
if (!esp_bt_gap_is_valid_cod(cod) ||
|
if (!esp_bt_gap_is_valid_cod(cod) ||
|
||||||
!(esp_bt_gap_get_cod_srvc(cod) & ESP_BT_COD_SRVC_RENDERING)) {
|
!(esp_bt_gap_get_cod_srvc(cod) & ESP_BT_COD_SRVC_RENDERING)) {
|
||||||
|
ESP_LOGI(BT_AV_TAG, " Device filtered out - not an audio rendering device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,16 +566,11 @@ static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param)
|
|||||||
// Add to device list for GUI
|
// Add to device list for GUI
|
||||||
add_device_to_list(param->disc_res.bda, (char *)s_peer_bdname, false, rssi);
|
add_device_to_list(param->disc_res.bda, (char *)s_peer_bdname, false, rssi);
|
||||||
|
|
||||||
ESP_LOGI(BT_AV_TAG, "Found audio device, address %s, name %s (saved to NVS, not connecting)",
|
ESP_LOGI(BT_AV_TAG, "Found audio device, address %s, name %s (added to list)",
|
||||||
bda_str, s_peer_bdname);
|
bda_str, s_peer_bdname);
|
||||||
|
|
||||||
// Don't automatically connect to discovered devices - just save them to NVS
|
// Don't automatically connect - just continue discovering more devices
|
||||||
// The old code would set s_a2d_state = APP_AV_STATE_DISCOVERED and connect
|
// User will manually select a device from the menu to connect
|
||||||
// Now we just continue discovery to find more devices
|
|
||||||
s_a2d_state = APP_AV_STATE_DISCOVERED;
|
|
||||||
memcpy(s_peer_bda, param->disc_res.bda, ESP_BD_ADDR_LEN);
|
|
||||||
ESP_LOGI(BT_AV_TAG, "Cancel device discovery ...");
|
|
||||||
esp_bt_gap_cancel_discovery();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,28 +579,34 @@ static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
|
|||||||
switch (event) {
|
switch (event) {
|
||||||
/* when device discovered a result, this event comes */
|
/* when device discovered a result, this event comes */
|
||||||
case ESP_BT_GAP_DISC_RES_EVT: {
|
case ESP_BT_GAP_DISC_RES_EVT: {
|
||||||
if (s_a2d_state == APP_AV_STATE_DISCOVERING) {
|
// Log ALL discovered devices for debugging
|
||||||
|
char bda_str[18];
|
||||||
|
ESP_LOGI(BT_AV_TAG, "*** Device discovered: %s (A2DP state: %d)",
|
||||||
|
bda2str(param->disc_res.bda, bda_str, 18), s_a2d_state);
|
||||||
|
|
||||||
|
// Process the result regardless of A2DP state
|
||||||
filter_inquiry_scan_result(param);
|
filter_inquiry_scan_result(param);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* when discovery state changed, this event comes */
|
/* when discovery state changed, this event comes */
|
||||||
case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: {
|
case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: {
|
||||||
if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) {
|
if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) {
|
||||||
|
ESP_LOGI(BT_AV_TAG, "Device discovery stopped.");
|
||||||
|
s_device_list.discovery_active = false;
|
||||||
|
|
||||||
|
// Notify GUI that discovery is complete so it can refresh the display
|
||||||
|
system_notifyAll(EM_EVENT_BT_DISCOVERY_COMPLETE);
|
||||||
|
|
||||||
|
// Don't automatically connect - wait for user selection
|
||||||
|
// Only connect if we're in DISCOVERED state (manually triggered by bt_connect_device)
|
||||||
if (s_a2d_state == APP_AV_STATE_DISCOVERED) {
|
if (s_a2d_state == APP_AV_STATE_DISCOVERED) {
|
||||||
s_a2d_state = APP_AV_STATE_CONNECTING;
|
s_a2d_state = APP_AV_STATE_CONNECTING;
|
||||||
ESP_LOGI(BT_AV_TAG, "Device discovery stopped.");
|
|
||||||
ESP_LOGI(BT_AV_TAG, "a2dp connecting to peer: %s", s_peer_bdname);
|
ESP_LOGI(BT_AV_TAG, "a2dp connecting to peer: %s", s_peer_bdname);
|
||||||
/* connect source to peer device specified by Bluetooth Device Address */
|
|
||||||
esp_a2d_source_connect(s_peer_bda);
|
esp_a2d_source_connect(s_peer_bda);
|
||||||
} else {
|
|
||||||
/* not discovered, continue to discover */
|
|
||||||
ESP_LOGI(BT_AV_TAG, "Device discovery failed, continue to discover...");
|
|
||||||
s_a2d_state = APP_AV_STATE_UNCONNECTED;
|
|
||||||
//esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0);
|
|
||||||
}
|
}
|
||||||
} else if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) {
|
} else if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) {
|
||||||
ESP_LOGI(BT_AV_TAG, "Discovery started.");
|
ESP_LOGI(BT_AV_TAG, "Discovery started.");
|
||||||
|
s_device_list.discovery_active = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -717,15 +705,15 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
|
|||||||
// Print list of saved devices from NVS
|
// Print list of saved devices from NVS
|
||||||
bt_debug_print_known_devices();
|
bt_debug_print_known_devices();
|
||||||
|
|
||||||
// Try to connect to all known devices sequentially
|
// Try to connect to known devices automatically (those we've connected to before)
|
||||||
esp_err_t connect_ret = bt_try_connect_all_known_devices();
|
esp_err_t connect_ret = bt_try_connect_known_devices();
|
||||||
if (connect_ret != ESP_OK) {
|
if (connect_ret != ESP_OK) {
|
||||||
// No known devices found, start discovery to find new devices
|
// No known devices found - stay in unconnected state
|
||||||
ESP_LOGI(BT_AV_TAG, "No known devices found, starting discovery...");
|
// Don't start discovery automatically - user must do it from menu
|
||||||
s_a2d_state = APP_AV_STATE_DISCOVERING;
|
ESP_LOGI(BT_AV_TAG, "No previously connected devices found. User can discover devices from menu.");
|
||||||
esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0);
|
s_a2d_state = APP_AV_STATE_UNCONNECTED;
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(BT_AV_TAG, "Attempting to connect to known devices...");
|
ESP_LOGI(BT_AV_TAG, "Attempting to connect to previously connected device...");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create and start heart beat timer */
|
/* create and start heart beat timer */
|
||||||
@@ -1082,15 +1070,8 @@ static void bt_app_av_state_unconnected_hdlr(uint16_t event, void *param)
|
|||||||
case ESP_A2D_MEDIA_CTRL_ACK_EVT:
|
case ESP_A2D_MEDIA_CTRL_ACK_EVT:
|
||||||
break;
|
break;
|
||||||
case BT_APP_HEART_BEAT_EVT: {
|
case BT_APP_HEART_BEAT_EVT: {
|
||||||
// Try to connect to known devices, or start discovery if none available
|
// Don't automatically try to reconnect - wait for user to select device
|
||||||
esp_err_t connect_ret = bt_try_connect_all_known_devices();
|
// from the menu
|
||||||
|
|
||||||
if (connect_ret != ESP_OK) {
|
|
||||||
// No known devices, start discovery
|
|
||||||
ESP_LOGI(BT_AV_TAG, "No known devices available, starting discovery...");
|
|
||||||
s_a2d_state = APP_AV_STATE_DISCOVERING;
|
|
||||||
esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT: {
|
case ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT: {
|
||||||
@@ -1118,19 +1099,33 @@ static void bt_app_av_state_connecting_hdlr(uint16_t event, void *param)
|
|||||||
s_a2d_state = APP_AV_STATE_CONNECTED;
|
s_a2d_state = APP_AV_STATE_CONNECTED;
|
||||||
s_media_state = APP_AV_MEDIA_STATE_IDLE;
|
s_media_state = APP_AV_MEDIA_STATE_IDLE;
|
||||||
|
|
||||||
|
// Check if device is already paired, if not, add it as paired
|
||||||
|
if (!system_isDeviceKnown(s_peer_bda)) {
|
||||||
|
ESP_LOGI(BT_AV_TAG, "Device not in paired list, adding: %s", s_peer_bdname);
|
||||||
|
paired_device_t new_device;
|
||||||
|
memcpy(new_device.bda, s_peer_bda, ESP_BD_ADDR_LEN);
|
||||||
|
strncpy(new_device.name, (char*)s_peer_bdname, DEVICE_NAME_MAX_LEN - 1);
|
||||||
|
new_device.name[DEVICE_NAME_MAX_LEN - 1] = '\0';
|
||||||
|
new_device.last_connected = (uint32_t)(esp_timer_get_time() / 1000000);
|
||||||
|
system_savePairedDevice(&new_device);
|
||||||
|
|
||||||
|
// Update the device in the GUI list to show it as paired
|
||||||
|
for (int i = 0; i < s_device_list.count; i++) {
|
||||||
|
if (memcmp(s_device_list.devices[i].bda, s_peer_bda, ESP_BD_ADDR_LEN) == 0) {
|
||||||
|
s_device_list.devices[i].is_paired = true;
|
||||||
|
ESP_LOGI(BT_AV_TAG, "Marked device as paired in GUI list: %s", s_peer_bdname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// Update connection timestamp for this device
|
// Update connection timestamp for this device
|
||||||
system_updateConnectionTimestamp(s_peer_bda);
|
system_updateConnectionTimestamp(s_peer_bda);
|
||||||
} else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) {
|
|
||||||
ESP_LOGI(BT_AV_TAG, "Connection failed, trying next device...");
|
|
||||||
// Try next known device before giving up
|
|
||||||
esp_err_t next_ret = bt_try_next_known_device();
|
|
||||||
if (next_ret != ESP_OK) {
|
|
||||||
// No more devices to try, go to unconnected state
|
|
||||||
//s_a2d_state = APP_AV_STATE_UNCONNECTED;
|
|
||||||
ESP_LOGI(BT_AV_TAG, "No known devices available, starting discovery...");
|
|
||||||
s_a2d_state = APP_AV_STATE_DISCOVERING;
|
|
||||||
esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0);
|
|
||||||
}
|
}
|
||||||
|
} else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) {
|
||||||
|
ESP_LOGI(BT_AV_TAG, "Connection failed.");
|
||||||
|
// If device was previously connected (known device), don't retry automatically
|
||||||
|
// User can manually reconnect from menu
|
||||||
|
s_a2d_state = APP_AV_STATE_UNCONNECTED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1144,13 +1139,10 @@ static void bt_app_av_state_connecting_hdlr(uint16_t event, void *param)
|
|||||||
* when connecting lasts more than 2 heart beat intervals.
|
* when connecting lasts more than 2 heart beat intervals.
|
||||||
*/
|
*/
|
||||||
if (++s_connecting_intv >= 2) {
|
if (++s_connecting_intv >= 2) {
|
||||||
ESP_LOGI(BT_AV_TAG, "Connection timeout, trying next device...");
|
ESP_LOGI(BT_AV_TAG, "Connection timeout.");
|
||||||
// Try next known device before giving up
|
// Return to unconnected state - don't retry automatically
|
||||||
esp_err_t next_ret = bt_try_next_known_device();
|
// User can manually reconnect from menu
|
||||||
if (next_ret != ESP_OK) {
|
|
||||||
// No more devices to try, go to unconnected state
|
|
||||||
s_a2d_state = APP_AV_STATE_UNCONNECTED;
|
s_a2d_state = APP_AV_STATE_UNCONNECTED;
|
||||||
}
|
|
||||||
s_connecting_intv = 0;
|
s_connecting_intv = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1468,6 +1460,7 @@ static void bt_app_task_handler(void *arg)
|
|||||||
if (notifiedBits & EM_EVENT_BT_REFRESH) {
|
if (notifiedBits & EM_EVENT_BT_REFRESH) {
|
||||||
ESP_LOGI(BT_AV_TAG, "BT Refresh event received");
|
ESP_LOGI(BT_AV_TAG, "BT Refresh event received");
|
||||||
bt_clear_discovered_devices();
|
bt_clear_discovered_devices();
|
||||||
|
bt_start_discovery(); // Start new discovery after clearing
|
||||||
// Notify GUI that refresh is done - could add completion event if needed
|
// Notify GUI that refresh is done - could add completion event if needed
|
||||||
}
|
}
|
||||||
if (notifiedBits & EM_EVENT_BT_CONNECT) {
|
if (notifiedBits & EM_EVENT_BT_CONNECT) {
|
||||||
@@ -1826,6 +1819,33 @@ void bt_clear_discovered_devices(void) {
|
|||||||
ESP_LOGI(BT_AV_TAG, "Cleared discovered devices, kept %d paired devices", new_count);
|
ESP_LOGI(BT_AV_TAG, "Cleared discovered devices, kept %d paired devices", new_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bt_clear_all_devices(void) {
|
||||||
|
s_device_list.count = 0;
|
||||||
|
ESP_LOGI(BT_AV_TAG, "Cleared all devices from device list");
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_disconnect_current_device(void) {
|
||||||
|
if (s_a2d_state == APP_AV_STATE_CONNECTED) {
|
||||||
|
ESP_LOGI(BT_AV_TAG, "Disconnecting from current device");
|
||||||
|
|
||||||
|
// Stop media first if playing
|
||||||
|
if (s_media_state == APP_AV_MEDIA_STATE_STARTED) {
|
||||||
|
esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_SUSPEND);
|
||||||
|
s_media_state = APP_AV_MEDIA_STATE_STOPPING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disconnect A2DP
|
||||||
|
esp_a2d_source_disconnect(s_peer_bda);
|
||||||
|
s_a2d_state = APP_AV_STATE_DISCONNECTING;
|
||||||
|
} else if (s_a2d_state == APP_AV_STATE_CONNECTING) {
|
||||||
|
ESP_LOGI(BT_AV_TAG, "Cancelling connection attempt");
|
||||||
|
// Cancel connection attempt
|
||||||
|
s_a2d_state = APP_AV_STATE_UNCONNECTED;
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(BT_AV_TAG, "No device connected (state: %d)", s_a2d_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void bt_volume_up(void) {
|
void bt_volume_up(void) {
|
||||||
if (!s_volume_control_available) {
|
if (!s_volume_control_available) {
|
||||||
ESP_LOGW(BT_AV_TAG, "Volume control not available");
|
ESP_LOGW(BT_AV_TAG, "Volume control not available");
|
||||||
@@ -1848,8 +1868,11 @@ void bt_volume_down(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (s_volume_level > 0) {
|
if (s_volume_level > 0) {
|
||||||
|
if (s_volume_level < 10) {
|
||||||
|
s_volume_level = 0;
|
||||||
|
} else {
|
||||||
s_volume_level -= 10; // Decrease by ~8%
|
s_volume_level -= 10; // Decrease by ~8%
|
||||||
if (s_volume_level < 0) s_volume_level = 0;
|
}
|
||||||
|
|
||||||
ESP_LOGI(BT_AV_TAG, "Setting volume to %d", s_volume_level);
|
ESP_LOGI(BT_AV_TAG, "Setting volume to %d", s_volume_level);
|
||||||
esp_avrc_ct_send_set_absolute_volume_cmd(APP_RC_CT_TL_RN_VOLUME_CHANGE, s_volume_level);
|
esp_avrc_ct_send_set_absolute_volume_cmd(APP_RC_CT_TL_RN_VOLUME_CHANGE, s_volume_level);
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ void bt_app_task_shut_down(void);
|
|||||||
void bt_app_init(void);
|
void bt_app_init(void);
|
||||||
|
|
||||||
/* Bluetooth device management for GUI */
|
/* Bluetooth device management for GUI */
|
||||||
#define MAX_BT_DEVICES 20
|
#define MAX_BT_DEVICES 8 // Reduced from 20 to save memory
|
||||||
#define MAX_BT_NAME_LEN 32
|
#define MAX_BT_NAME_LEN 32
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -100,6 +100,12 @@ bool bt_connect_device(int device_index);
|
|||||||
/* Clear discovered devices (keep paired devices) */
|
/* Clear discovered devices (keep paired devices) */
|
||||||
void bt_clear_discovered_devices(void);
|
void bt_clear_discovered_devices(void);
|
||||||
|
|
||||||
|
/* Clear all devices from the device list (paired and discovered) */
|
||||||
|
void bt_clear_all_devices(void);
|
||||||
|
|
||||||
|
/* Disconnect from currently connected device */
|
||||||
|
void bt_disconnect_current_device(void);
|
||||||
|
|
||||||
/* Volume control functions */
|
/* Volume control functions */
|
||||||
void bt_volume_up(void);
|
void bt_volume_up(void);
|
||||||
void bt_volume_down(void);
|
void bt_volume_down(void);
|
||||||
|
|||||||
@@ -4,9 +4,11 @@
|
|||||||
// Define keypad buttons
|
// Define keypad buttons
|
||||||
#define PIN_NUM_BUTTON_0 36
|
#define PIN_NUM_BUTTON_0 36
|
||||||
#define PIN_NUM_BUTTON_1 39
|
#define PIN_NUM_BUTTON_1 39
|
||||||
#define PIN_NUM_LED_1 32
|
#define PIN_NUM_LED_0 32
|
||||||
#define PIN_NUM_LED_2 33
|
#define PIN_NUM_LED_1 33
|
||||||
|
#define PIN_NUM_LED_2 25
|
||||||
#define PIN_NUM_nON 26
|
#define PIN_NUM_nON 26
|
||||||
|
#define PIN_NUM_CHARGE_STATUS 2
|
||||||
|
|
||||||
|
|
||||||
// Define GPIO pins
|
// Define GPIO pins
|
||||||
|
|||||||
865
main/gui.c
865
main/gui.c
File diff suppressed because it is too large
Load Diff
55
main/main.c
55
main/main.c
@@ -104,20 +104,47 @@ static inline float LPF_Update(LowPassFilter *f, float input) {
|
|||||||
* STATIC FUNCTION DEFINITIONS
|
* STATIC FUNCTION DEFINITIONS
|
||||||
********************************/
|
********************************/
|
||||||
|
|
||||||
|
// Helper function to set LED with verification
|
||||||
|
static void set_led_level(gpio_num_t pin, uint32_t level)
|
||||||
|
{
|
||||||
|
esp_err_t err = gpio_set_level(pin, level);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to set GPIO %d to %lu: %s", pin, level, esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void init_gpio(void)
|
static void init_gpio(void)
|
||||||
{
|
{
|
||||||
gpio_config_t io_conf;
|
gpio_config_t io_conf;
|
||||||
|
|
||||||
|
// Reset GPIO peripheral to clear any SPI/peripheral configurations
|
||||||
|
gpio_reset_pin(PIN_NUM_LED_0);
|
||||||
|
gpio_reset_pin(PIN_NUM_LED_1);
|
||||||
|
gpio_reset_pin(PIN_NUM_LED_2);
|
||||||
|
|
||||||
// Configure output GPIO
|
// Configure output GPIO
|
||||||
io_conf.pin_bit_mask = (1ULL << PIN_NUM_LED_1) | (1ULL << PIN_NUM_LED_2);
|
io_conf.pin_bit_mask = (1ULL << PIN_NUM_LED_0) | (1ULL << PIN_NUM_LED_1) | (1ULL << PIN_NUM_LED_2);
|
||||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||||
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||||
gpio_config(&io_conf);
|
gpio_config(&io_conf);
|
||||||
|
|
||||||
|
// Set initial state
|
||||||
|
gpio_set_level(PIN_NUM_LED_0, 0);
|
||||||
|
gpio_set_level(PIN_NUM_LED_1, 0);
|
||||||
|
gpio_set_level(PIN_NUM_LED_2, 0);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "LED pins configured: %d, %d, %d", PIN_NUM_LED_0, PIN_NUM_LED_1, PIN_NUM_LED_2);
|
||||||
|
|
||||||
|
|
||||||
|
// Configure charge status input GPIO
|
||||||
|
io_conf.pin_bit_mask = (1ULL << PIN_NUM_CHARGE_STATUS);
|
||||||
|
io_conf.mode = GPIO_MODE_INPUT;
|
||||||
|
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||||
|
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||||
|
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||||
|
gpio_config(&io_conf);
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
@@ -275,16 +302,21 @@ void app_main(void)
|
|||||||
print_heap_info("POST_SYSTEM");
|
print_heap_info("POST_SYSTEM");
|
||||||
|
|
||||||
// Initialize IMU
|
// Initialize IMU
|
||||||
ESP_ERROR_CHECK(lsm6dsv_init(22, 21)); // SCL = IO14, SDA = IO15
|
ESP_ERROR_CHECK(lsm6dsv_init(22, 21)); // SCL = IO14, SDA = IO15`
|
||||||
print_heap_info("POST_IMU");
|
print_heap_info("POST_IMU");
|
||||||
|
|
||||||
// Create IMU task
|
// Create IMU task
|
||||||
TaskHandle_t h = xTaskCreate(imu_task, "imu_task", 2048, NULL, 5, NULL);
|
TaskHandle_t h = NULL;
|
||||||
|
xTaskCreate(imu_task, "imu_task", 2048, NULL, 5, &h);
|
||||||
print_heap_info("POST_IMU_TASK");
|
print_heap_info("POST_IMU_TASK");
|
||||||
|
|
||||||
bt_app_init();
|
bt_app_init();
|
||||||
print_heap_info("POST_BLUETOOTH");
|
print_heap_info("POST_BLUETOOTH");
|
||||||
|
|
||||||
|
gpio_set_level(PIN_NUM_LED_0, 1);
|
||||||
|
gpio_set_level(PIN_NUM_LED_1, 1);
|
||||||
|
gpio_set_level(PIN_NUM_LED_2, 1);
|
||||||
|
|
||||||
gui_start();
|
gui_start();
|
||||||
print_heap_info("POST_GUI");
|
print_heap_info("POST_GUI");
|
||||||
gpio_set_level(PIN_NUM_LED_2, 1);
|
gpio_set_level(PIN_NUM_LED_2, 1);
|
||||||
@@ -325,6 +357,23 @@ void app_main(void)
|
|||||||
#else
|
#else
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
// Read charge status and update system
|
||||||
|
bool is_charging = gpio_get_level(PIN_NUM_CHARGE_STATUS);
|
||||||
|
system_setChargeStatus(is_charging);
|
||||||
|
|
||||||
|
if (is_charging)
|
||||||
|
{
|
||||||
|
gpio_set_level(PIN_NUM_LED_0, 0);
|
||||||
|
gpio_set_level(PIN_NUM_LED_1, 1);
|
||||||
|
gpio_set_level(PIN_NUM_LED_2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gpio_set_level(PIN_NUM_LED_0, 1);
|
||||||
|
gpio_set_level(PIN_NUM_LED_1, 0);
|
||||||
|
gpio_set_level(PIN_NUM_LED_2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
system_processNvsRequests();
|
system_processNvsRequests();
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ void system_init(void)
|
|||||||
_systemState.zeroAngle = 0.0f;
|
_systemState.zeroAngle = 0.0f;
|
||||||
_systemState.primaryAxis = PRIMARY_AXIS;
|
_systemState.primaryAxis = PRIMARY_AXIS;
|
||||||
_systemState.pairedDeviceCount = 0;
|
_systemState.pairedDeviceCount = 0;
|
||||||
|
_systemState.isCharging = false;
|
||||||
|
|
||||||
_systemEvent = xEventGroupCreate();
|
_systemEvent = xEventGroupCreate();
|
||||||
|
|
||||||
@@ -57,6 +58,22 @@ float system_getAngle(void)
|
|||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void system_setChargeStatus(bool charging)
|
||||||
|
{
|
||||||
|
xSemaphoreTake(_eventManager.mutex, portMAX_DELAY);
|
||||||
|
_systemState.isCharging = charging;
|
||||||
|
xSemaphoreGive(_eventManager.mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool system_getChargeStatus(void)
|
||||||
|
{
|
||||||
|
bool charging;
|
||||||
|
xSemaphoreTake(_eventManager.mutex, portMAX_DELAY);
|
||||||
|
charging = _systemState.isCharging;
|
||||||
|
xSemaphoreGive(_eventManager.mutex);
|
||||||
|
return charging;
|
||||||
|
}
|
||||||
|
|
||||||
void system_setZeroAngle(void)
|
void system_setZeroAngle(void)
|
||||||
{
|
{
|
||||||
xSemaphoreTake(_eventManager.mutex, portMAX_DELAY);
|
xSemaphoreTake(_eventManager.mutex, portMAX_DELAY);
|
||||||
@@ -356,9 +373,9 @@ void system_processNvsRequests(void) {
|
|||||||
}
|
}
|
||||||
xSemaphoreGive(_eventManager.mutex);
|
xSemaphoreGive(_eventManager.mutex);
|
||||||
|
|
||||||
request.response_ready = true;
|
// Send the result directly as the notification value (not a pointer)
|
||||||
if (request.requestor) {
|
if (request.requestor) {
|
||||||
xTaskNotify(request.requestor, (uint32_t)&request, eSetValueWithOverwrite);
|
xTaskNotify(request.requestor, (uint32_t)request.result, eSetValueWithOverwrite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,8 +413,8 @@ esp_err_t system_savePairedDevice(const paired_device_t *device) {
|
|||||||
if (xQueueSend(_nvsRequestQueue, &request, pdMS_TO_TICKS(NVS_TIMEOUT_MS)) == pdTRUE) {
|
if (xQueueSend(_nvsRequestQueue, &request, pdMS_TO_TICKS(NVS_TIMEOUT_MS)) == pdTRUE) {
|
||||||
uint32_t notification;
|
uint32_t notification;
|
||||||
if (xTaskNotifyWait(0, UINT32_MAX, ¬ification, pdMS_TO_TICKS(NVS_TIMEOUT_MS)) == pdTRUE) {
|
if (xTaskNotifyWait(0, UINT32_MAX, ¬ification, pdMS_TO_TICKS(NVS_TIMEOUT_MS)) == pdTRUE) {
|
||||||
nvs_request_t *response = (nvs_request_t*)notification;
|
// notification contains the result directly (not a pointer)
|
||||||
return response->result;
|
return (esp_err_t)notification;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ESP_ERR_TIMEOUT;
|
return ESP_ERR_TIMEOUT;
|
||||||
@@ -425,8 +442,8 @@ esp_err_t system_removePairedDevice(esp_bd_addr_t bda) {
|
|||||||
if (xQueueSend(_nvsRequestQueue, &request, pdMS_TO_TICKS(NVS_TIMEOUT_MS)) == pdTRUE) {
|
if (xQueueSend(_nvsRequestQueue, &request, pdMS_TO_TICKS(NVS_TIMEOUT_MS)) == pdTRUE) {
|
||||||
uint32_t notification;
|
uint32_t notification;
|
||||||
if (xTaskNotifyWait(0, UINT32_MAX, ¬ification, pdMS_TO_TICKS(NVS_TIMEOUT_MS)) == pdTRUE) {
|
if (xTaskNotifyWait(0, UINT32_MAX, ¬ification, pdMS_TO_TICKS(NVS_TIMEOUT_MS)) == pdTRUE) {
|
||||||
nvs_request_t *response = (nvs_request_t*)notification;
|
// notification contains the result directly (not a pointer)
|
||||||
return response->result;
|
return (esp_err_t)notification;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ESP_ERR_TIMEOUT;
|
return ESP_ERR_TIMEOUT;
|
||||||
@@ -464,8 +481,8 @@ esp_err_t system_updateConnectionTimestamp(esp_bd_addr_t bda) {
|
|||||||
if (xQueueSend(_nvsRequestQueue, &request, pdMS_TO_TICKS(NVS_TIMEOUT_MS)) == pdTRUE) {
|
if (xQueueSend(_nvsRequestQueue, &request, pdMS_TO_TICKS(NVS_TIMEOUT_MS)) == pdTRUE) {
|
||||||
uint32_t notification;
|
uint32_t notification;
|
||||||
if (xTaskNotifyWait(0, UINT32_MAX, ¬ification, pdMS_TO_TICKS(NVS_TIMEOUT_MS)) == pdTRUE) {
|
if (xTaskNotifyWait(0, UINT32_MAX, ¬ification, pdMS_TO_TICKS(NVS_TIMEOUT_MS)) == pdTRUE) {
|
||||||
nvs_request_t *response = (nvs_request_t*)notification;
|
// notification contains the result directly (not a pointer)
|
||||||
return response->result;
|
return (esp_err_t)notification;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ESP_ERR_TIMEOUT;
|
return ESP_ERR_TIMEOUT;
|
||||||
@@ -480,3 +497,19 @@ const paired_device_t* system_getPairedDevices(size_t *count) {
|
|||||||
|
|
||||||
return (const paired_device_t*)_systemState.pairedDevices;
|
return (const paired_device_t*)_systemState.pairedDevices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t system_clearAllPairedDevices(void) {
|
||||||
|
// Directly clear in-memory state and save to NVS
|
||||||
|
xSemaphoreTake(_eventManager.mutex, portMAX_DELAY);
|
||||||
|
_systemState.pairedDeviceCount = 0;
|
||||||
|
esp_err_t ret = nvs_save_devices_internal(_systemState.pairedDevices, 0);
|
||||||
|
xSemaphoreGive(_eventManager.mutex);
|
||||||
|
|
||||||
|
if (ret == ESP_OK) {
|
||||||
|
ESP_LOGI("system", "Cleared all paired devices from NVS");
|
||||||
|
} else {
|
||||||
|
ESP_LOGE("system", "Failed to clear paired devices: %s", esp_err_to_name(ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -52,6 +52,9 @@ typedef struct SystemState_s
|
|||||||
paired_device_t pairedDevices[MAX_PAIRED_DEVICES];
|
paired_device_t pairedDevices[MAX_PAIRED_DEVICES];
|
||||||
size_t pairedDeviceCount;
|
size_t pairedDeviceCount;
|
||||||
|
|
||||||
|
// Charge status
|
||||||
|
bool isCharging;
|
||||||
|
|
||||||
} SystemState_t;
|
} SystemState_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -67,6 +70,7 @@ typedef struct SystemState_s
|
|||||||
#define EM_EVENT_BT_CONNECT (1UL<<3)
|
#define EM_EVENT_BT_CONNECT (1UL<<3)
|
||||||
#define EM_EVENT_VOLUME_UP (1UL<<4)
|
#define EM_EVENT_VOLUME_UP (1UL<<4)
|
||||||
#define EM_EVENT_VOLUME_DOWN (1UL<<5)
|
#define EM_EVENT_VOLUME_DOWN (1UL<<5)
|
||||||
|
#define EM_EVENT_BT_DISCOVERY_COMPLETE (1UL<<6)
|
||||||
// …add more event bit-masks here…
|
// …add more event bit-masks here…
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -83,6 +87,9 @@ ImuData_t system_getImuData(void);
|
|||||||
int system_getPrimaryAxis(void);
|
int system_getPrimaryAxis(void);
|
||||||
float system_getAngle(void);
|
float system_getAngle(void);
|
||||||
|
|
||||||
|
void system_setChargeStatus(bool charging);
|
||||||
|
bool system_getChargeStatus(void);
|
||||||
|
|
||||||
void system_setZeroAngle(void);
|
void system_setZeroAngle(void);
|
||||||
void system_clearZeroAngle(void);
|
void system_clearZeroAngle(void);
|
||||||
float system_getZeroAngle(void);
|
float system_getZeroAngle(void);
|
||||||
@@ -133,6 +140,7 @@ bool system_isDeviceKnown(esp_bd_addr_t bda);
|
|||||||
esp_err_t system_getKnownDeviceCount(size_t *count);
|
esp_err_t system_getKnownDeviceCount(size_t *count);
|
||||||
esp_err_t system_updateConnectionTimestamp(esp_bd_addr_t bda);
|
esp_err_t system_updateConnectionTimestamp(esp_bd_addr_t bda);
|
||||||
const paired_device_t* system_getPairedDevices(size_t *count);
|
const paired_device_t* system_getPairedDevices(size_t *count);
|
||||||
|
esp_err_t system_clearAllPairedDevices(void);
|
||||||
|
|
||||||
|
|
||||||
#define NVS_TIMEOUT_MS 5000
|
#define NVS_TIMEOUT_MS 5000
|
||||||
|
|||||||
196
sdkconfig
196
sdkconfig
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Automatically generated file. DO NOT EDIT.
|
# Automatically generated file. DO NOT EDIT.
|
||||||
# Espressif IoT Development Framework (ESP-IDF) 5.3.1 Project Configuration
|
# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Configuration
|
||||||
#
|
#
|
||||||
CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined"
|
CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined"
|
||||||
CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined"
|
CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined"
|
||||||
@@ -91,12 +91,14 @@ CONFIG_SOC_GPIO_OUT_RANGE_MAX=33
|
|||||||
CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA
|
CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA
|
||||||
CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y
|
CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y
|
||||||
CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3
|
CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3
|
||||||
|
CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y
|
||||||
CONFIG_SOC_I2C_NUM=2
|
CONFIG_SOC_I2C_NUM=2
|
||||||
CONFIG_SOC_HP_I2C_NUM=2
|
CONFIG_SOC_HP_I2C_NUM=2
|
||||||
CONFIG_SOC_I2C_FIFO_LEN=32
|
CONFIG_SOC_I2C_FIFO_LEN=32
|
||||||
CONFIG_SOC_I2C_CMD_REG_NUM=16
|
CONFIG_SOC_I2C_CMD_REG_NUM=16
|
||||||
CONFIG_SOC_I2C_SUPPORT_SLAVE=y
|
CONFIG_SOC_I2C_SUPPORT_SLAVE=y
|
||||||
CONFIG_SOC_I2C_SUPPORT_APB=y
|
CONFIG_SOC_I2C_SUPPORT_APB=y
|
||||||
|
CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y
|
||||||
CONFIG_SOC_I2C_STOP_INDEPENDENT=y
|
CONFIG_SOC_I2C_STOP_INDEPENDENT=y
|
||||||
CONFIG_SOC_I2S_NUM=2
|
CONFIG_SOC_I2S_NUM=2
|
||||||
CONFIG_SOC_I2S_HW_VERSION_1=y
|
CONFIG_SOC_I2S_HW_VERSION_1=y
|
||||||
@@ -111,6 +113,7 @@ CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y
|
|||||||
CONFIG_SOC_I2S_SUPPORTS_ADC=y
|
CONFIG_SOC_I2S_SUPPORTS_ADC=y
|
||||||
CONFIG_SOC_I2S_SUPPORTS_DAC=y
|
CONFIG_SOC_I2S_SUPPORTS_DAC=y
|
||||||
CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y
|
CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y
|
||||||
|
CONFIG_SOC_I2S_MAX_DATA_WIDTH=24
|
||||||
CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y
|
CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y
|
||||||
CONFIG_SOC_I2S_LCD_I80_VARIANT=y
|
CONFIG_SOC_I2S_LCD_I80_VARIANT=y
|
||||||
CONFIG_SOC_LCD_I80_SUPPORTED=y
|
CONFIG_SOC_LCD_I80_SUPPORTED=y
|
||||||
@@ -120,6 +123,7 @@ CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y
|
|||||||
CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y
|
CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y
|
||||||
CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y
|
CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y
|
||||||
CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y
|
CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y
|
||||||
|
CONFIG_SOC_LEDC_TIMER_NUM=4
|
||||||
CONFIG_SOC_LEDC_CHANNEL_NUM=8
|
CONFIG_SOC_LEDC_CHANNEL_NUM=8
|
||||||
CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20
|
CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20
|
||||||
CONFIG_SOC_MCPWM_GROUPS=2
|
CONFIG_SOC_MCPWM_GROUPS=2
|
||||||
@@ -172,6 +176,8 @@ CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2
|
|||||||
CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64
|
CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64
|
||||||
CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4
|
CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4
|
||||||
CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y
|
CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y
|
||||||
|
CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32
|
||||||
|
CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16
|
||||||
CONFIG_SOC_TOUCH_SENSOR_VERSION=1
|
CONFIG_SOC_TOUCH_SENSOR_VERSION=1
|
||||||
CONFIG_SOC_TOUCH_SENSOR_NUM=10
|
CONFIG_SOC_TOUCH_SENSOR_NUM=10
|
||||||
CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1
|
CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1
|
||||||
@@ -214,6 +220,7 @@ CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y
|
|||||||
CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y
|
CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y
|
||||||
CONFIG_SOC_PM_SUPPORT_MODEM_PD=y
|
CONFIG_SOC_PM_SUPPORT_MODEM_PD=y
|
||||||
CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y
|
CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y
|
||||||
|
CONFIG_SOC_PM_MODEM_PD_BY_SW=y
|
||||||
CONFIG_SOC_CLK_APLL_SUPPORTED=y
|
CONFIG_SOC_CLK_APLL_SUPPORTED=y
|
||||||
CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y
|
CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y
|
||||||
CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y
|
CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y
|
||||||
@@ -236,10 +243,11 @@ CONFIG_SOC_PHY_COMBO_MODULE=y
|
|||||||
CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y
|
CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y
|
||||||
CONFIG_IDF_CMAKE=y
|
CONFIG_IDF_CMAKE=y
|
||||||
CONFIG_IDF_TOOLCHAIN="gcc"
|
CONFIG_IDF_TOOLCHAIN="gcc"
|
||||||
|
CONFIG_IDF_TOOLCHAIN_GCC=y
|
||||||
CONFIG_IDF_TARGET_ARCH_XTENSA=y
|
CONFIG_IDF_TARGET_ARCH_XTENSA=y
|
||||||
CONFIG_IDF_TARGET_ARCH="xtensa"
|
CONFIG_IDF_TARGET_ARCH="xtensa"
|
||||||
CONFIG_IDF_TARGET="esp32"
|
CONFIG_IDF_TARGET="esp32"
|
||||||
CONFIG_IDF_INIT_VERSION="5.3.1"
|
CONFIG_IDF_INIT_VERSION="5.4.1"
|
||||||
CONFIG_IDF_TARGET_ESP32=y
|
CONFIG_IDF_TARGET_ESP32=y
|
||||||
CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000
|
CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000
|
||||||
|
|
||||||
@@ -273,6 +281,10 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
|||||||
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set
|
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set
|
||||||
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set
|
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set
|
||||||
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set
|
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Log
|
||||||
|
#
|
||||||
# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set
|
# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set
|
||||||
# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
|
# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
|
||||||
# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set
|
# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set
|
||||||
@@ -281,6 +293,14 @@ CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y
|
|||||||
# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
|
# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
|
||||||
CONFIG_BOOTLOADER_LOG_LEVEL=3
|
CONFIG_BOOTLOADER_LOG_LEVEL=3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Format
|
||||||
|
#
|
||||||
|
# CONFIG_BOOTLOADER_LOG_COLORS is not set
|
||||||
|
CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y
|
||||||
|
# end of Format
|
||||||
|
# end of Log
|
||||||
|
|
||||||
#
|
#
|
||||||
# Serial Flash Configurations
|
# Serial Flash Configurations
|
||||||
#
|
#
|
||||||
@@ -336,6 +356,7 @@ CONFIG_ESP_ROM_HAS_SW_FLOAT=y
|
|||||||
CONFIG_ESP_ROM_USB_OTG_NUM=-1
|
CONFIG_ESP_ROM_USB_OTG_NUM=-1
|
||||||
CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1
|
CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1
|
||||||
CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y
|
CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y
|
||||||
|
CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# Serial flasher config
|
# Serial flasher config
|
||||||
@@ -377,6 +398,7 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
|
|||||||
# CONFIG_PARTITION_TABLE_SINGLE_APP is not set
|
# CONFIG_PARTITION_TABLE_SINGLE_APP is not set
|
||||||
# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set
|
# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set
|
||||||
# CONFIG_PARTITION_TABLE_TWO_OTA is not set
|
# CONFIG_PARTITION_TABLE_TWO_OTA is not set
|
||||||
|
# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
@@ -400,6 +422,7 @@ CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
|||||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
|
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
|
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
|
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
|
||||||
|
# CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE is not set
|
||||||
CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y
|
CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y
|
||||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2
|
CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set
|
# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set
|
||||||
@@ -410,14 +433,18 @@ CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
|
|||||||
# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
|
# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
|
||||||
# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set
|
# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set
|
||||||
# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set
|
# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set
|
||||||
|
# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set
|
||||||
# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set
|
# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set
|
||||||
|
# CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS is not set
|
||||||
# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set
|
# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set
|
||||||
# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set
|
# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set
|
||||||
|
# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set
|
||||||
# CONFIG_COMPILER_DUMP_RTL_FILES is not set
|
# CONFIG_COMPILER_DUMP_RTL_FILES is not set
|
||||||
CONFIG_COMPILER_RT_LIB_GCCLIB=y
|
CONFIG_COMPILER_RT_LIB_GCCLIB=y
|
||||||
CONFIG_COMPILER_RT_LIB_NAME="gcc"
|
CONFIG_COMPILER_RT_LIB_NAME="gcc"
|
||||||
# CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set
|
# CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set
|
||||||
CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y
|
CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y
|
||||||
|
# CONFIG_COMPILER_STATIC_ANALYZER is not set
|
||||||
# end of Compiler options
|
# end of Compiler options
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -461,10 +488,20 @@ CONFIG_BT_ENC_KEY_SIZE_CTRL_VSC=y
|
|||||||
# CONFIG_BT_ENC_KEY_SIZE_CTRL_NONE is not set
|
# CONFIG_BT_ENC_KEY_SIZE_CTRL_NONE is not set
|
||||||
# CONFIG_BT_CLASSIC_BQB_ENABLED is not set
|
# CONFIG_BT_CLASSIC_BQB_ENABLED is not set
|
||||||
CONFIG_BT_A2DP_ENABLE=y
|
CONFIG_BT_A2DP_ENABLE=y
|
||||||
|
CONFIG_BT_AVRCP_ENABLED=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# AVRCP Features
|
||||||
|
#
|
||||||
|
CONFIG_BT_AVRCP_CT_COVER_ART_ENABLED=y
|
||||||
|
# end of AVRCP Features
|
||||||
|
|
||||||
# CONFIG_BT_SPP_ENABLED is not set
|
# CONFIG_BT_SPP_ENABLED is not set
|
||||||
# CONFIG_BT_L2CAP_ENABLED is not set
|
# CONFIG_BT_L2CAP_ENABLED is not set
|
||||||
|
# CONFIG_BT_SDP_COMMON_ENABLED is not set
|
||||||
# CONFIG_BT_HFP_ENABLE is not set
|
# CONFIG_BT_HFP_ENABLE is not set
|
||||||
# CONFIG_BT_HID_ENABLED is not set
|
# CONFIG_BT_HID_ENABLED is not set
|
||||||
|
CONFIG_BT_GOEPC_ENABLED=y
|
||||||
CONFIG_BT_BLE_ENABLED=y
|
CONFIG_BT_BLE_ENABLED=y
|
||||||
CONFIG_BT_GATTS_ENABLE=y
|
CONFIG_BT_GATTS_ENABLE=y
|
||||||
# CONFIG_BT_GATTS_PPCP_CHAR_GAP is not set
|
# CONFIG_BT_GATTS_PPCP_CHAR_GAP is not set
|
||||||
@@ -485,6 +522,7 @@ CONFIG_BT_GATTC_CONNECT_RETRY_COUNT=3
|
|||||||
CONFIG_BT_BLE_SMP_ENABLE=y
|
CONFIG_BT_BLE_SMP_ENABLE=y
|
||||||
# CONFIG_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set
|
# CONFIG_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set
|
||||||
# CONFIG_BT_BLE_SMP_ID_RESET_ENABLE is not set
|
# CONFIG_BT_BLE_SMP_ID_RESET_ENABLE is not set
|
||||||
|
CONFIG_BT_BLE_SMP_BOND_NVS_FLASH=y
|
||||||
# CONFIG_BT_STACK_NO_LOG is not set
|
# CONFIG_BT_STACK_NO_LOG is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -672,8 +710,8 @@ CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30
|
|||||||
CONFIG_BT_MAX_DEVICE_NAME_LEN=32
|
CONFIG_BT_MAX_DEVICE_NAME_LEN=32
|
||||||
# CONFIG_BT_BLE_RPA_SUPPORTED is not set
|
# CONFIG_BT_BLE_RPA_SUPPORTED is not set
|
||||||
CONFIG_BT_BLE_RPA_TIMEOUT=900
|
CONFIG_BT_BLE_RPA_TIMEOUT=900
|
||||||
# CONFIG_BT_BLE_42_FEATURES_SUPPORTED is not set
|
|
||||||
# CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL is not set
|
# CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL is not set
|
||||||
|
# CONFIG_BT_ABORT_WHEN_ALLOCATION_FAILS is not set
|
||||||
# end of Bluedroid Options
|
# end of Bluedroid Options
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -682,6 +720,7 @@ CONFIG_BT_BLE_RPA_TIMEOUT=900
|
|||||||
# CONFIG_BTDM_CTRL_MODE_BLE_ONLY is not set
|
# CONFIG_BTDM_CTRL_MODE_BLE_ONLY is not set
|
||||||
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y
|
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y
|
||||||
# CONFIG_BTDM_CTRL_MODE_BTDM is not set
|
# CONFIG_BTDM_CTRL_MODE_BTDM is not set
|
||||||
|
CONFIG_BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT=7
|
||||||
CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN=2
|
CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN=2
|
||||||
CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN=0
|
CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN=0
|
||||||
# CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI is not set
|
# CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI is not set
|
||||||
@@ -692,11 +731,16 @@ CONFIG_BTDM_CTRL_PCM_ROLE_MASTER=y
|
|||||||
# CONFIG_BTDM_CTRL_PCM_ROLE_SLAVE is not set
|
# CONFIG_BTDM_CTRL_PCM_ROLE_SLAVE is not set
|
||||||
CONFIG_BTDM_CTRL_PCM_POLAR_FALLING_EDGE=y
|
CONFIG_BTDM_CTRL_PCM_POLAR_FALLING_EDGE=y
|
||||||
# CONFIG_BTDM_CTRL_PCM_POLAR_RISING_EDGE is not set
|
# CONFIG_BTDM_CTRL_PCM_POLAR_RISING_EDGE is not set
|
||||||
|
CONFIG_BTDM_CTRL_PCM_FSYNCSHP_STEREO_MODE=y
|
||||||
|
# CONFIG_BTDM_CTRL_PCM_FSYNCSHP_MONO_MODE_LF is not set
|
||||||
|
# CONFIG_BTDM_CTRL_PCM_FSYNCSHP_MONO_MODE_FF is not set
|
||||||
CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0
|
CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0
|
||||||
CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0
|
CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0
|
||||||
|
CONFIG_BTDM_CTRL_PCM_FSYNCSHP_EFF=0
|
||||||
CONFIG_BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT=y
|
CONFIG_BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT=y
|
||||||
CONFIG_BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT_EFF=y
|
CONFIG_BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT_EFF=y
|
||||||
CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0
|
CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0
|
||||||
|
CONFIG_BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT_EFF=7
|
||||||
CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=2
|
CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=2
|
||||||
CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0
|
CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0
|
||||||
CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y
|
CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y
|
||||||
@@ -716,6 +760,14 @@ CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=y
|
|||||||
|
|
||||||
CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1
|
CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1
|
||||||
# CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set
|
# CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set
|
||||||
|
# CONFIG_BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# BLE disconnects when Instant Passed (0x28) occurs
|
||||||
|
#
|
||||||
|
# end of BLE disconnects when Instant Passed (0x28) occurs
|
||||||
|
|
||||||
|
# CONFIG_BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 is not set
|
||||||
CONFIG_BTDM_RESERVE_DRAM=0xdb5c
|
CONFIG_BTDM_RESERVE_DRAM=0xdb5c
|
||||||
CONFIG_BTDM_CTRL_HLI=y
|
CONFIG_BTDM_CTRL_HLI=y
|
||||||
# end of Controller Options
|
# end of Controller Options
|
||||||
@@ -724,6 +776,7 @@ CONFIG_BTDM_CTRL_HLI=y
|
|||||||
# Common Options
|
# Common Options
|
||||||
#
|
#
|
||||||
CONFIG_BT_ALARM_MAX_NUM=50
|
CONFIG_BT_ALARM_MAX_NUM=50
|
||||||
|
# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set
|
||||||
# end of Common Options
|
# end of Common Options
|
||||||
|
|
||||||
# CONFIG_BT_HCI_LOG_DEBUG_EN is not set
|
# CONFIG_BT_HCI_LOG_DEBUG_EN is not set
|
||||||
@@ -757,6 +810,7 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y
|
|||||||
#
|
#
|
||||||
CONFIG_ADC_DISABLE_DAC=y
|
CONFIG_ADC_DISABLE_DAC=y
|
||||||
# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy ADC Calibration Configuration
|
# Legacy ADC Calibration Configuration
|
||||||
@@ -772,42 +826,49 @@ CONFIG_ADC_CAL_LUT_ENABLE=y
|
|||||||
# Legacy DAC Driver Configurations
|
# Legacy DAC Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy DAC Driver Configurations
|
# end of Legacy DAC Driver Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy MCPWM Driver Configurations
|
# Legacy MCPWM Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy MCPWM Driver Configurations
|
# end of Legacy MCPWM Driver Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy Timer Group Driver Configurations
|
# Legacy Timer Group Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy Timer Group Driver Configurations
|
# end of Legacy Timer Group Driver Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy RMT Driver Configurations
|
# Legacy RMT Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy RMT Driver Configurations
|
# end of Legacy RMT Driver Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy I2S Driver Configurations
|
# Legacy I2S Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy I2S Driver Configurations
|
# end of Legacy I2S Driver Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy PCNT Driver Configurations
|
# Legacy PCNT Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy PCNT Driver Configurations
|
# end of Legacy PCNT Driver Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy SDM Driver Configurations
|
# Legacy SDM Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy SDM Driver Configurations
|
# end of Legacy SDM Driver Configurations
|
||||||
# end of Driver Configurations
|
# end of Driver Configurations
|
||||||
|
|
||||||
@@ -859,6 +920,7 @@ CONFIG_ADC_DISABLE_DAC_OUTPUT=y
|
|||||||
CONFIG_ESP_COEX_ENABLED=y
|
CONFIG_ESP_COEX_ENABLED=y
|
||||||
CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y
|
CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y
|
||||||
# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set
|
# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set
|
||||||
|
# CONFIG_ESP_COEX_GPIO_DEBUG is not set
|
||||||
# end of Wireless Coexistence
|
# end of Wireless Coexistence
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -897,6 +959,7 @@ CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y
|
|||||||
#
|
#
|
||||||
# CONFIG_I2C_ISR_IRAM_SAFE is not set
|
# CONFIG_I2C_ISR_IRAM_SAFE is not set
|
||||||
# CONFIG_I2C_ENABLE_DEBUG_LOG is not set
|
# CONFIG_I2C_ENABLE_DEBUG_LOG is not set
|
||||||
|
# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set
|
||||||
# end of ESP-Driver:I2C Configurations
|
# end of ESP-Driver:I2C Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1004,6 +1067,13 @@ CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y
|
|||||||
CONFIG_ESP_GDBSTUB_MAX_TASKS=32
|
CONFIG_ESP_GDBSTUB_MAX_TASKS=32
|
||||||
# end of GDB Stub
|
# end of GDB Stub
|
||||||
|
|
||||||
|
#
|
||||||
|
# ESP HID
|
||||||
|
#
|
||||||
|
CONFIG_ESPHID_TASK_SIZE_BT=2048
|
||||||
|
CONFIG_ESPHID_TASK_SIZE_BLE=4096
|
||||||
|
# end of ESP HID
|
||||||
|
|
||||||
#
|
#
|
||||||
# ESP HTTP client
|
# ESP HTTP client
|
||||||
#
|
#
|
||||||
@@ -1011,6 +1081,7 @@ CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y
|
|||||||
# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set
|
# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set
|
||||||
# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set
|
# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set
|
||||||
# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set
|
# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set
|
||||||
|
CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000
|
||||||
# end of ESP HTTP client
|
# end of ESP HTTP client
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1023,6 +1094,7 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32
|
|||||||
# CONFIG_HTTPD_LOG_PURGE_DATA is not set
|
# CONFIG_HTTPD_LOG_PURGE_DATA is not set
|
||||||
# CONFIG_HTTPD_WS_SUPPORT is not set
|
# CONFIG_HTTPD_WS_SUPPORT is not set
|
||||||
# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set
|
# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set
|
||||||
|
CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000
|
||||||
# end of HTTP Server
|
# end of HTTP Server
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1030,12 +1102,14 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32
|
|||||||
#
|
#
|
||||||
# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set
|
# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set
|
||||||
# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set
|
# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set
|
||||||
|
CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000
|
||||||
# end of ESP HTTPS OTA
|
# end of ESP HTTPS OTA
|
||||||
|
|
||||||
#
|
#
|
||||||
# ESP HTTPS server
|
# ESP HTTPS server
|
||||||
#
|
#
|
||||||
# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set
|
# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set
|
||||||
|
CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000
|
||||||
# end of ESP HTTPS server
|
# end of ESP HTTPS server
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1060,6 +1134,12 @@ CONFIG_ESP_REV_MIN_FULL=0
|
|||||||
#
|
#
|
||||||
CONFIG_ESP32_REV_MAX_FULL=399
|
CONFIG_ESP32_REV_MAX_FULL=399
|
||||||
CONFIG_ESP_REV_MAX_FULL=399
|
CONFIG_ESP_REV_MAX_FULL=399
|
||||||
|
CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0
|
||||||
|
CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=99
|
||||||
|
|
||||||
|
#
|
||||||
|
# Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99)
|
||||||
|
#
|
||||||
# end of Chip revision
|
# end of Chip revision
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1112,6 +1192,7 @@ CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y
|
|||||||
# Main XTAL Config
|
# Main XTAL Config
|
||||||
#
|
#
|
||||||
# CONFIG_XTAL_FREQ_26 is not set
|
# CONFIG_XTAL_FREQ_26 is not set
|
||||||
|
# CONFIG_XTAL_FREQ_32 is not set
|
||||||
CONFIG_XTAL_FREQ_40=y
|
CONFIG_XTAL_FREQ_40=y
|
||||||
# CONFIG_XTAL_FREQ_AUTO is not set
|
# CONFIG_XTAL_FREQ_AUTO is not set
|
||||||
CONFIG_XTAL_FREQ=40
|
CONFIG_XTAL_FREQ=40
|
||||||
@@ -1121,31 +1202,29 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y
|
|||||||
# end of Hardware Settings
|
# end of Hardware Settings
|
||||||
|
|
||||||
#
|
#
|
||||||
# LCD and Touch Panel
|
# ESP-Driver:LCD Controller Configurations
|
||||||
#
|
#
|
||||||
|
|
||||||
#
|
|
||||||
# LCD Touch Drivers are maintained in the IDF Component Registry
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# LCD Peripheral Configuration
|
|
||||||
#
|
|
||||||
CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32
|
|
||||||
# CONFIG_LCD_ENABLE_DEBUG_LOG is not set
|
# CONFIG_LCD_ENABLE_DEBUG_LOG is not set
|
||||||
# end of LCD Peripheral Configuration
|
# end of ESP-Driver:LCD Controller Configurations
|
||||||
# end of LCD and Touch Panel
|
|
||||||
|
#
|
||||||
|
# ESP-MM: Memory Management Configurations
|
||||||
|
#
|
||||||
|
# end of ESP-MM: Memory Management Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# ESP NETIF Adapter
|
# ESP NETIF Adapter
|
||||||
#
|
#
|
||||||
CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120
|
CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120
|
||||||
|
# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set
|
||||||
CONFIG_ESP_NETIF_TCPIP_LWIP=y
|
CONFIG_ESP_NETIF_TCPIP_LWIP=y
|
||||||
# CONFIG_ESP_NETIF_LOOPBACK is not set
|
# CONFIG_ESP_NETIF_LOOPBACK is not set
|
||||||
CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y
|
CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y
|
||||||
|
CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y
|
||||||
# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set
|
# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set
|
||||||
# CONFIG_ESP_NETIF_L2_TAP is not set
|
# CONFIG_ESP_NETIF_L2_TAP is not set
|
||||||
# CONFIG_ESP_NETIF_BRIDGE_EN is not set
|
# CONFIG_ESP_NETIF_BRIDGE_EN is not set
|
||||||
|
# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set
|
||||||
# end of ESP NETIF Adapter
|
# end of ESP NETIF Adapter
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1162,17 +1241,20 @@ CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y
|
|||||||
CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20
|
CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20
|
||||||
CONFIG_ESP_PHY_MAX_TX_POWER=20
|
CONFIG_ESP_PHY_MAX_TX_POWER=20
|
||||||
# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set
|
# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set
|
||||||
|
# CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set
|
||||||
CONFIG_ESP_PHY_RF_CAL_PARTIAL=y
|
CONFIG_ESP_PHY_RF_CAL_PARTIAL=y
|
||||||
# CONFIG_ESP_PHY_RF_CAL_NONE is not set
|
# CONFIG_ESP_PHY_RF_CAL_NONE is not set
|
||||||
# CONFIG_ESP_PHY_RF_CAL_FULL is not set
|
# CONFIG_ESP_PHY_RF_CAL_FULL is not set
|
||||||
CONFIG_ESP_PHY_CALIBRATION_MODE=0
|
CONFIG_ESP_PHY_CALIBRATION_MODE=0
|
||||||
# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set
|
# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set
|
||||||
|
# CONFIG_ESP_PHY_RECORD_USED_TIME is not set
|
||||||
# end of PHY
|
# end of PHY
|
||||||
|
|
||||||
#
|
#
|
||||||
# Power Management
|
# Power Management
|
||||||
#
|
#
|
||||||
# CONFIG_PM_ENABLE is not set
|
# CONFIG_PM_ENABLE is not set
|
||||||
|
CONFIG_PM_SLP_IRAM_OPT=y
|
||||||
# end of Power Management
|
# end of Power Management
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1187,6 +1269,11 @@ CONFIG_ESP_PHY_CALIBRATION_MODE=0
|
|||||||
# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set
|
# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set
|
||||||
# end of ESP Ringbuf
|
# end of ESP Ringbuf
|
||||||
|
|
||||||
|
#
|
||||||
|
# ESP Security Specific
|
||||||
|
#
|
||||||
|
# end of ESP Security Specific
|
||||||
|
|
||||||
#
|
#
|
||||||
# ESP System Settings
|
# ESP System Settings
|
||||||
#
|
#
|
||||||
@@ -1404,6 +1491,9 @@ CONFIG_FATFS_FS_LOCK=0
|
|||||||
CONFIG_FATFS_TIMEOUT_MS=10000
|
CONFIG_FATFS_TIMEOUT_MS=10000
|
||||||
CONFIG_FATFS_PER_FILE_CACHE=y
|
CONFIG_FATFS_PER_FILE_CACHE=y
|
||||||
# CONFIG_FATFS_USE_FASTSEEK is not set
|
# CONFIG_FATFS_USE_FASTSEEK is not set
|
||||||
|
CONFIG_FATFS_USE_STRFUNC_NONE=y
|
||||||
|
# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set
|
||||||
|
# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set
|
||||||
CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0
|
CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0
|
||||||
# CONFIG_FATFS_IMMEDIATE_FSYNC is not set
|
# CONFIG_FATFS_IMMEDIATE_FSYNC is not set
|
||||||
# CONFIG_FATFS_USE_LABEL is not set
|
# CONFIG_FATFS_USE_LABEL is not set
|
||||||
@@ -1429,6 +1519,7 @@ CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536
|
|||||||
# CONFIG_FREERTOS_USE_TICK_HOOK is not set
|
# CONFIG_FREERTOS_USE_TICK_HOOK is not set
|
||||||
CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
|
CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
|
||||||
# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set
|
# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set
|
||||||
|
CONFIG_FREERTOS_USE_TIMERS=y
|
||||||
CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc"
|
CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc"
|
||||||
# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set
|
# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set
|
||||||
# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set
|
# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set
|
||||||
@@ -1464,6 +1555,11 @@ CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y
|
|||||||
# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set
|
# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set
|
||||||
# end of Port
|
# end of Port
|
||||||
|
|
||||||
|
#
|
||||||
|
# Extra
|
||||||
|
#
|
||||||
|
# end of Extra
|
||||||
|
|
||||||
CONFIG_FREERTOS_PORT=y
|
CONFIG_FREERTOS_PORT=y
|
||||||
CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF
|
CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF
|
||||||
CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y
|
CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y
|
||||||
@@ -1501,7 +1597,11 @@ CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS=y
|
|||||||
# end of Heap memory debugging
|
# end of Heap memory debugging
|
||||||
|
|
||||||
#
|
#
|
||||||
# Log output
|
# Log
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Log Level
|
||||||
#
|
#
|
||||||
# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
|
# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
|
||||||
# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
|
# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
|
||||||
@@ -1514,11 +1614,29 @@ CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y
|
|||||||
# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set
|
# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set
|
||||||
# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set
|
# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set
|
||||||
CONFIG_LOG_MAXIMUM_LEVEL=3
|
CONFIG_LOG_MAXIMUM_LEVEL=3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Level Settings
|
||||||
|
#
|
||||||
# CONFIG_LOG_MASTER_LEVEL is not set
|
# CONFIG_LOG_MASTER_LEVEL is not set
|
||||||
|
CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y
|
||||||
|
# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set
|
||||||
|
# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set
|
||||||
|
CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y
|
||||||
|
# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set
|
||||||
|
CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y
|
||||||
|
CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31
|
||||||
|
# end of Level Settings
|
||||||
|
# end of Log Level
|
||||||
|
|
||||||
|
#
|
||||||
|
# Format
|
||||||
|
#
|
||||||
CONFIG_LOG_COLORS=y
|
CONFIG_LOG_COLORS=y
|
||||||
CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y
|
CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y
|
||||||
# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set
|
# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set
|
||||||
# end of Log output
|
# end of Format
|
||||||
|
# end of Log
|
||||||
|
|
||||||
#
|
#
|
||||||
# LWIP
|
# LWIP
|
||||||
@@ -1557,6 +1675,8 @@ CONFIG_LWIP_ESP_MLDV6_REPORT=y
|
|||||||
CONFIG_LWIP_MLDV6_TMR_INTERVAL=40
|
CONFIG_LWIP_MLDV6_TMR_INTERVAL=40
|
||||||
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
|
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
|
||||||
CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y
|
CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y
|
||||||
|
# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set
|
||||||
|
# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set
|
||||||
# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set
|
# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set
|
||||||
CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y
|
CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y
|
||||||
# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set
|
# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set
|
||||||
@@ -1571,6 +1691,7 @@ CONFIG_LWIP_DHCPS=y
|
|||||||
CONFIG_LWIP_DHCPS_LEASE_UNIT=60
|
CONFIG_LWIP_DHCPS_LEASE_UNIT=60
|
||||||
CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8
|
CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8
|
||||||
CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y
|
CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y
|
||||||
|
CONFIG_LWIP_DHCPS_ADD_DNS=y
|
||||||
# end of DHCP server
|
# end of DHCP server
|
||||||
|
|
||||||
# CONFIG_LWIP_AUTOIP is not set
|
# CONFIG_LWIP_AUTOIP is not set
|
||||||
@@ -1629,9 +1750,12 @@ CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y
|
|||||||
# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set
|
# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set
|
||||||
# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set
|
# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set
|
||||||
CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF
|
CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF
|
||||||
# CONFIG_LWIP_PPP_SUPPORT is not set
|
|
||||||
CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3
|
CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3
|
||||||
CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5
|
CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5
|
||||||
|
CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5
|
||||||
|
CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3
|
||||||
|
CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10
|
||||||
|
# CONFIG_LWIP_PPP_SUPPORT is not set
|
||||||
# CONFIG_LWIP_SLIP_SUPPORT is not set
|
# CONFIG_LWIP_SLIP_SUPPORT is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1661,8 +1785,10 @@ CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000
|
|||||||
#
|
#
|
||||||
# DNS
|
# DNS
|
||||||
#
|
#
|
||||||
|
CONFIG_LWIP_DNS_MAX_HOST_IP=1
|
||||||
CONFIG_LWIP_DNS_MAX_SERVERS=3
|
CONFIG_LWIP_DNS_MAX_SERVERS=3
|
||||||
# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set
|
# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set
|
||||||
|
# CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set
|
||||||
# end of DNS
|
# end of DNS
|
||||||
|
|
||||||
CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7
|
CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7
|
||||||
@@ -1686,6 +1812,8 @@ CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y
|
|||||||
CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y
|
CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y
|
||||||
# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set
|
# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set
|
||||||
# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set
|
# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set
|
||||||
|
CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_NONE=y
|
||||||
|
# CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM is not set
|
||||||
CONFIG_LWIP_HOOK_IP6_INPUT_NONE=y
|
CONFIG_LWIP_HOOK_IP6_INPUT_NONE=y
|
||||||
# CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT is not set
|
# CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT is not set
|
||||||
# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set
|
# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set
|
||||||
@@ -1744,6 +1872,7 @@ CONFIG_MBEDTLS_HAVE_TIME=y
|
|||||||
# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set
|
# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set
|
||||||
CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y
|
CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y
|
||||||
CONFIG_MBEDTLS_SHA512_C=y
|
CONFIG_MBEDTLS_SHA512_C=y
|
||||||
|
CONFIG_MBEDTLS_SHA3_C=y
|
||||||
CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y
|
CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y
|
||||||
# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set
|
# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set
|
||||||
# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set
|
# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set
|
||||||
@@ -1797,6 +1926,8 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y
|
|||||||
# end of Certificates
|
# end of Certificates
|
||||||
|
|
||||||
CONFIG_MBEDTLS_ECP_C=y
|
CONFIG_MBEDTLS_ECP_C=y
|
||||||
|
CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y
|
||||||
|
CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y
|
||||||
# CONFIG_MBEDTLS_DHM_C is not set
|
# CONFIG_MBEDTLS_DHM_C is not set
|
||||||
CONFIG_MBEDTLS_ECDH_C=y
|
CONFIG_MBEDTLS_ECDH_C=y
|
||||||
CONFIG_MBEDTLS_ECDSA_C=y
|
CONFIG_MBEDTLS_ECDSA_C=y
|
||||||
@@ -1820,6 +1951,7 @@ CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y
|
|||||||
# CONFIG_MBEDTLS_HKDF_C is not set
|
# CONFIG_MBEDTLS_HKDF_C is not set
|
||||||
# CONFIG_MBEDTLS_THREADING_C is not set
|
# CONFIG_MBEDTLS_THREADING_C is not set
|
||||||
CONFIG_MBEDTLS_ERROR_STRINGS=y
|
CONFIG_MBEDTLS_ERROR_STRINGS=y
|
||||||
|
CONFIG_MBEDTLS_FS_IO=y
|
||||||
# end of mbedTLS
|
# end of mbedTLS
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1867,25 +1999,10 @@ CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y
|
|||||||
# CONFIG_OPENTHREAD_ENABLED is not set
|
# CONFIG_OPENTHREAD_ENABLED is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Thread Operational Dataset
|
# OpenThread Spinel
|
||||||
#
|
#
|
||||||
CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP"
|
|
||||||
CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64"
|
|
||||||
CONFIG_OPENTHREAD_NETWORK_CHANNEL=15
|
|
||||||
CONFIG_OPENTHREAD_NETWORK_PANID=0x1234
|
|
||||||
CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe"
|
|
||||||
CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff"
|
|
||||||
CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53"
|
|
||||||
# end of Thread Operational Dataset
|
|
||||||
|
|
||||||
CONFIG_OPENTHREAD_XTAL_ACCURACY=130
|
|
||||||
# CONFIG_OPENTHREAD_SPINEL_ONLY is not set
|
# CONFIG_OPENTHREAD_SPINEL_ONLY is not set
|
||||||
# CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE is not set
|
# end of OpenThread Spinel
|
||||||
|
|
||||||
#
|
|
||||||
# Thread Address Query Config
|
|
||||||
#
|
|
||||||
# end of Thread Address Query Config
|
|
||||||
# end of OpenThread
|
# end of OpenThread
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1894,6 +2011,7 @@ CONFIG_OPENTHREAD_XTAL_ACCURACY=130
|
|||||||
CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y
|
CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y
|
||||||
CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y
|
CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y
|
||||||
CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y
|
CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y
|
||||||
|
CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y
|
||||||
# end of Protocomm
|
# end of Protocomm
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1936,6 +2054,7 @@ CONFIG_SPI_FLASH_BROWNOUT_RESET=y
|
|||||||
# Features here require specific hardware (READ DOCS FIRST!)
|
# Features here require specific hardware (READ DOCS FIRST!)
|
||||||
#
|
#
|
||||||
CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50
|
CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50
|
||||||
|
# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set
|
||||||
# end of Optional and Experimental Features (READ DOCS FIRST)
|
# end of Optional and Experimental Features (READ DOCS FIRST)
|
||||||
# end of Main Flash configuration
|
# end of Main Flash configuration
|
||||||
|
|
||||||
@@ -2065,6 +2184,8 @@ CONFIG_VFS_MAX_COUNT=8
|
|||||||
#
|
#
|
||||||
CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1
|
CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1
|
||||||
# end of Host File System I/O (Semihosting)
|
# end of Host File System I/O (Semihosting)
|
||||||
|
|
||||||
|
CONFIG_VFS_INITIALIZE_DEV_NULL=y
|
||||||
# end of Virtual file system
|
# end of Virtual file system
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -2082,6 +2203,7 @@ CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16
|
|||||||
CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
|
CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
|
||||||
# CONFIG_WIFI_PROV_BLE_BONDING is not set
|
# CONFIG_WIFI_PROV_BLE_BONDING is not set
|
||||||
# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set
|
# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set
|
||||||
|
# CONFIG_WIFI_PROV_BLE_NOTIFY is not set
|
||||||
# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set
|
# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set
|
||||||
CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y
|
CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y
|
||||||
# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set
|
# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set
|
||||||
@@ -2247,7 +2369,7 @@ CONFIG_LV_ATTRIBUTE_MEM_ALIGN_SIZE=1
|
|||||||
# Enable built-in fonts
|
# Enable built-in fonts
|
||||||
#
|
#
|
||||||
CONFIG_LV_FONT_MONTSERRAT_8=y
|
CONFIG_LV_FONT_MONTSERRAT_8=y
|
||||||
# CONFIG_LV_FONT_MONTSERRAT_10 is not set
|
CONFIG_LV_FONT_MONTSERRAT_10=y
|
||||||
CONFIG_LV_FONT_MONTSERRAT_12=y
|
CONFIG_LV_FONT_MONTSERRAT_12=y
|
||||||
CONFIG_LV_FONT_MONTSERRAT_14=y
|
CONFIG_LV_FONT_MONTSERRAT_14=y
|
||||||
# CONFIG_LV_FONT_MONTSERRAT_16 is not set
|
# CONFIG_LV_FONT_MONTSERRAT_16 is not set
|
||||||
@@ -2811,8 +2933,6 @@ CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32
|
|||||||
CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
|
CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_TX_BA_WIN=6
|
CONFIG_ESP32_WIFI_TX_BA_WIN=6
|
||||||
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
|
||||||
CONFIG_ESP32_WIFI_RX_BA_WIN=6
|
|
||||||
CONFIG_ESP32_WIFI_RX_BA_WIN=6
|
CONFIG_ESP32_WIFI_RX_BA_WIN=6
|
||||||
CONFIG_ESP32_WIFI_NVS_ENABLED=y
|
CONFIG_ESP32_WIFI_NVS_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y
|
CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y
|
||||||
|
|||||||
3008
sdkconfig.old
Normal file
3008
sdkconfig.old
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user