Initial commit: 펌웨어 플래시 도구 (WPF) + 기존 PowerShell 키트

- DB720Flasher: WPF .NET 9 GUI 플래셔
  - 멀티모델 프로파일(flash.json + 빌트인 DB720/DB402S/DB400S/DB400Q/DB300eM)
  - 포트 자동감지(JTAG 우선, 유령 포트 자동 회피), esptool v5 동봉
- flash_app.ps1 / flash_full.ps1 / list_ports.ps1: 기존 PowerShell 키트
- profiles/: 모델별 flash.json 템플릿
- firmware/flash.json: DB720 모델 설정 (서명 실펌웨어 .bin 은 repo 제외)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
insulee
2026-06-23 16:10:40 +09:00
commit 69f4d4754f
25 changed files with 2545 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
using System.IO;
namespace DB720Flasher;
public static class FirmwareCatalog
{
// 모델 무관하게 보조 파일명은 공통 — 앱 후보 = 이 4개를 뺀 .bin
static readonly HashSet<string> Support = new(StringComparer.OrdinalIgnoreCase)
{ "bootloader.bin", "partition-table.bin", "ota_data_initial.bin", "www_fs.bin" };
static string? KnownNote(string fileName) => fileName switch
{
"DIBD720Te_08C_04R020C.bin" => "320×64 (4단20열, 8색) · 부팅 검증됨",
"DIBD720Ue_08B_08R040C.bin" => "640×128 (8단40열, 256색) · 미검증",
_ => null,
};
/// <summary>폴더의 앱 후보(.bin 중 보조 4종 제외)를 나열.</summary>
public static List<FirmwareItem> LoadApps(string folder)
{
var apps = new List<FirmwareItem>();
if (!Directory.Exists(folder)) return apps;
foreach (var path in Directory.EnumerateFiles(folder, "*.bin"))
{
var name = Path.GetFileName(path);
if (Support.Contains(name)) continue;
apps.Add(new FirmwareItem
{
FileName = name,
FullPath = path,
Size = SafeLen(path),
Note = KnownNote(name),
});
}
apps.Sort((a, b) => string.Compare(a.FileName, b.FileName, StringComparison.OrdinalIgnoreCase));
return apps;
}
/// <summary>선택한 모드+프로파일에 필요한 보조 파일이 폴더에 다 있는지. 없으면 빠진 목록.</summary>
public static string? MissingFor(string folder, FlashProfile p, FlashMode mode)
{
if (mode == FlashMode.AppOnly) return null;
bool includeBoot = mode == FlashMode.Full;
var miss = new List<string>();
foreach (var rg in p.SupportRegions)
{
if (rg.Kind == "bootloader" && !includeBoot) continue;
if (!File.Exists(Path.Combine(folder, rg.File!))) miss.Add(rg.File!);
}
return miss.Count == 0 ? null : string.Join(", ", miss);
}
/// <summary>exe 위치에서 위로 올라가며 firmware\ (bin 포함) 폴더를 찾는다.</summary>
public static string? AutoLocate(string startDir)
{
var dir = new DirectoryInfo(startDir);
for (int i = 0; i < 6 && dir is not null; i++)
{
var candidate = Path.Combine(dir.FullName, "firmware");
if (Directory.Exists(candidate) && Directory.EnumerateFiles(candidate, "*.bin").Any())
return candidate;
dir = dir.Parent;
}
return null;
}
static long SafeLen(string p) { try { return new FileInfo(p).Length; } catch { return 0; } }
}