@zixe/flash-esp32-web
Version:
Flash ESP32 utility for the web using esptool-js and Web Serial API.
60 lines (59 loc) • 2.51 kB
JavaScript
// @ts-ignore: ไม่มี types ของ esptool-js
import { ESPLoader } from "esptool-js";
/// <reference types="w3c-web-serial" />
export class ESPFlasher {
constructor(options) {
this.loader = null;
this.port = null;
this.options = options;
}
async connect(baudRate) {
this.options?.onLog?.("Requesting serial port...");
const serial = navigator.serial;
this.port = await serial.requestPort({ filters: [] });
if (!this.port)
throw new Error("SerialPort not available");
await this.port.open({ baudRate: baudRate ?? this.options?.baudRate ?? 115200 });
this.options?.onLog?.("Serial port opened");
const terminal = {
clean: () => this.options?.onLog?.("[terminal] cleaned"),
writeLine: (data) => this.options?.onLog?.(data),
write: (data) => this.options?.onLog?.(data)
};
this.loader = new ESPLoader(this.port, false, terminal);
// ปรับตรงนี้!
await this.loader.connect("no_reset"); // <-- ป้องกัน hardware reset
this.options?.onLog?.("Connected to ESP32 (no reset)!");
}
async flash(files) {
if (!this.loader)
throw new Error("ESP not connected");
this.options?.onLog?.("Preparing files for flashing...");
const flashArray = [];
for (const f of files) {
const arrayBuffer = await f.file.arrayBuffer();
flashArray.push([f.offset, new Uint8Array(arrayBuffer)]);
this.options?.onLog?.(`Added ${f.name ?? "bin"} (0x${f.offset.toString(16)}) [${(arrayBuffer.byteLength / 1024).toFixed(1)} KB]`);
}
this.options?.onLog?.("Flashing started");
await this.loader.write_flash(flashArray, "keep", (written, total) => {
const percent = Math.floor((written / total) * 100);
this.options?.onProgress?.("flashing", percent);
});
this.options?.onLog?.("Flash complete!");
this.options?.onProgress?.("success", 100);
}
async restart() {
if (!this.loader)
throw new Error("ESP not connected");
this.options?.onLog?.("Restarting ESP32...");
await this.loader.hard_reset();
this.options?.onLog?.("ESP32 Restarted!");
}
async disconnect() {
await this.port?.close();
this.options?.onLog?.("Serial port closed");
this.loader = null;
this.port = null;
}
}