diff --git a/index.html b/index.html
index ad2acdd..e6baed3 100644
--- a/index.html
+++ b/index.html
@@ -16,7 +16,7 @@
-
+
@@ -83,6 +83,9 @@
+
@@ -481,7 +484,7 @@
@@ -511,7 +514,7 @@
models: [
{
id: ROM.MODEL_FE,
- name: "433 MHz",
+ name: "470-510 MHz",
},
],
firmware_filename: "rnode_firmware_aethernode.zip",
@@ -527,6 +530,59 @@
},
},
},
+ {
+ name: "MeshAdventurer-S3 (Classic RNode)",
+ id: ROM.PRODUCT_HMBRW,
+ platform: ROM.PLATFORM_ESP32,
+ models: [
+ {
+ id: ROM.MODEL_FE,
+ name: "470-510 MHz",
+ },
+ {
+ id: ROM.MODEL_FE,
+ name: "863-928 MHz",
+ },
+ ],
+ firmware_filename: "rnode_firmware_meshadventurer_s3.zip",
+ firmware_repo: "https://github.com/chrismyers2000/MeshAdventurer",
+ flash_config: {
+ flash_size: "16MB",
+ flash_files: {
+ "0xe000": "rnode_firmware_meshadventurer_s3.boot_app0",
+ "0x1000": "rnode_firmware_meshadventurer_s3.bootloader",
+ "0x10000": "rnode_firmware_meshadventurer_s3.bin",
+ "0x210000": "console_image.bin",
+ "0x8000": "rnode_firmware_meshadventurer_s3.partitions",
+ },
+ },
+ },
+ {
+ name: "MeshAdventurer-S3 (Boundary Node)",
+ id: ROM.PRODUCT_HMBRW,
+ platform: ROM.PLATFORM_ESP32,
+ models: [
+ {
+ id: ROM.MODEL_FE,
+ name: "470-510 MHz",
+ },
+ {
+ id: ROM.MODEL_FE,
+ name: "863-928 MHz",
+ },
+ ],
+ firmware_filename: "rtnode_meshadventurer_s3.zip",
+ firmware_repo: "https://github.com/jrl290/RTNode-HeltecV4",
+ flash_config: {
+ flash_size: "16MB",
+ flash_files: {
+ "0xe000": "boot_app0.bin",
+ "0x0": "bootloader.bin",
+ "0x10000": "firmware.bin",
+ "0x8000": "partitions.bin",
+ },
+ },
+ },
{
name: "MeshAdventurer",
id: ROM.PRODUCT_HMBRW,
@@ -534,7 +590,11 @@
models: [
{
id: ROM.MODEL_FE,
- name: "868 MHz",
+ name: "470-510 MHz",
+ },
+ {
+ id: ROM.MODEL_FE,
+ name: "863-928 MHz",
},
],
firmware_filename: "rnode_firmware_meshadventurer.zip",
@@ -550,6 +610,33 @@
},
},
},
+ {
+ name: "DIY-V1",
+ id: ROM.PRODUCT_HMBRW,
+ platform: ROM.PLATFORM_ESP32,
+ models: [
+ {
+ id: ROM.MODEL_FE,
+ name: "470-510 MHz",
+ },
+ {
+ id: ROM.MODEL_FE,
+ name: "863-928 MHz",
+ },
+ ],
+ firmware_filename: "rnode_firmware_diy_v1.zip",
+ firmware_repo: "https://github.com/NanoVHF/Meshtastic-DIY",
+ flash_config: {
+ flash_size: "4MB",
+ flash_files: {
+ "0xe000": "rnode_firmware_diy_v1.boot_app0",
+ "0x1000": "rnode_firmware_diy_v1.bootloader",
+ "0x10000": "rnode_firmware_diy_v1.bin",
+ "0x210000": "console_image.bin",
+ "0x8000": "rnode_firmware_diy_v1.partitions",
+ },
+ },
+ },
{
name: "FakeTec (Promicro)",
id: ROM.PRODUCT_HMBRW,
@@ -563,6 +650,100 @@
firmware_filename: "rnode_firmware_promicro.zip",
firmware_repo: "https://github.com/gargomoma/fakeTec_pcb",
},
+ {
+ name: "Heltec V3 (Classic RNode)",
+ id: ROM.PRODUCT_H32_V3,
+ platform: ROM.PLATFORM_ESP32,
+ models: [
+ {
+ id: ROM.MODEL_C5,
+ name: "433 MHz",
+ },
+ {
+ id: ROM.MODEL_CA,
+ name: "868 MHz / 915 MHz / 923 MHz",
+ },
+ ],
+ firmware_filename: "rnode_firmware_heltec32v3.zip",
+ firmware_repo: "https://heltec.org/project/wifi-lora-32-v3/",
+ flash_config: {
+ flash_size: "8MB",
+ flash_files: {
+ "0xe000": "rnode_firmware_heltec32v3.boot_app0",
+ "0x0": "rnode_firmware_heltec32v3.bootloader",
+ "0x10000": "rnode_firmware_heltec32v3.bin",
+ "0x210000": "console_image.bin",
+ "0x8000": "rnode_firmware_heltec32v3.partitions",
+ },
+ },
+ },
+ {
+ name: "Heltec V3 (Boundary Node)",
+ id: ROM.PRODUCT_H32_V3,
+ platform: ROM.PLATFORM_ESP32,
+ models: [
+ {
+ id: ROM.MODEL_C8,
+ name: "868 MHz / 915 MHz / 923 MHz with PA",
+ },
+ ],
+ firmware_filename: "rtnode_heltec_V3.zip",
+ firmware_repo: "https://github.com/jrl290/RTNode-HeltecV4",
+ flash_config: {
+ flash_size: "16MB",
+ flash_files: {
+ "0xe000": "boot_app0.bin",
+ "0x0": "bootloader.bin",
+ "0x10000": "firmware.bin",
+ "0x8000": "partitions.bin",
+ },
+ },
+ },
+ {
+ name: "Heltec V4 (Classic RNode)",
+ id: ROM.PRODUCT_H32_V4,
+ platform: ROM.PLATFORM_ESP32,
+ models: [
+ {
+ id: ROM.MODEL_C8,
+ name: "868 MHz / 915 MHz / 923 MHz with PA",
+ },
+ ],
+ firmware_filename: "rnode_firmware_heltec32v4pa.zip",
+ firmware_repo: "https://heltec.org/project/wifi-lora-32-v4/",
+ flash_config: {
+ flash_size: "16MB",
+ flash_files: {
+ "0xe000": "rnode_firmware_heltec32v4pa.boot_app0",
+ "0x0": "rnode_firmware_heltec32v4pa.bootloader",
+ "0x10000": "rnode_firmware_heltec32v4pa.bin",
+ "0x210000": "console_image.bin",
+ "0x8000": "rnode_firmware_heltec32v4pa.partitions",
+ },
+ },
+ },
+ {
+ name: "Heltec V4 (Boundary Node)",
+ id: ROM.PRODUCT_H32_V4,
+ platform: ROM.PLATFORM_ESP32,
+ models: [
+ {
+ id: ROM.MODEL_C8,
+ name: "868 MHz / 915 MHz / 923 MHz with PA",
+ },
+ ],
+ firmware_filename: "rtnode_heltec_V4.zip",
+ firmware_repo: "https://github.com/jrl290/RTNode-HeltecV4",
+ flash_config: {
+ flash_size: "16MB",
+ flash_files: {
+ "0xe000": "boot_app0.bin",
+ "0x0": "bootloader.bin",
+ "0x10000": "firmware.bin",
+ "0x8000": "partitions.bin",
+ },
+ },
+ },
{
name: "Heltec T114",
id: ROM.PRODUCT_HELTEC_T114,
@@ -579,6 +760,73 @@
],
firmware_filename: "rnode_firmware_heltec_t114.zip",
firmware_repo: "https://heltec.org/project/mesh-node-t114/",
+ },
+ {
+ name: "LilyGO T-Beam",
+ id: ROM.PRODUCT_TBEAM,
+ platform: ROM.PLATFORM_ESP32,
+ models: [
+ {
+ id: ROM.MODEL_E4,
+ name: "433 MHz (with SX1278 chip)",
+ firmware_filename: "rnode_firmware_tbeam.zip",
+ flash_config: {
+ flash_size: "4MB",
+ flash_files: {
+ "0xe000": "rnode_firmware_tbeam.boot_app0",
+ "0x1000": "rnode_firmware_tbeam.bootloader",
+ "0x10000": "rnode_firmware_tbeam.bin",
+ "0x210000": "console_image.bin",
+ "0x8000": "rnode_firmware_tbeam.partitions",
+ },
+ },
+ },
+ {
+ id: ROM.MODEL_E9,
+ name: "868/915/923 MHz (with SX1276 chip)",
+ firmware_filename: "rnode_firmware_tbeam.zip",
+ flash_config: {
+ flash_size: "4MB",
+ flash_files: {
+ "0xe000": "rnode_firmware_tbeam.boot_app0",
+ "0x1000": "rnode_firmware_tbeam.bootloader",
+ "0x10000": "rnode_firmware_tbeam.bin",
+ "0x210000": "console_image.bin",
+ "0x8000": "rnode_firmware_tbeam.partitions",
+ },
+ },
+ },
+ {
+ id: ROM.MODEL_E3,
+ name: "433 MHz (with SX1268 chip)",
+ firmware_filename: "rnode_firmware_tbeam_sx1262.zip",
+ flash_config: {
+ flash_size: "4MB",
+ flash_files: {
+ "0xe000": "rnode_firmware_tbeam_sx1262.boot_app0",
+ "0x1000": "rnode_firmware_tbeam_sx1262.bootloader",
+ "0x10000": "rnode_firmware_tbeam_sx1262.bin",
+ "0x210000": "console_image.bin",
+ "0x8000": "rnode_firmware_tbeam_sx1262.partitions",
+ },
+ },
+ },
+ {
+ id: ROM.MODEL_E8,
+ name: "868/915/923 MHz (with SX1262 chip)",
+ firmware_filename: "rnode_firmware_tbeam_sx1262.zip",
+ flash_config: {
+ flash_size: "4MB",
+ flash_files: {
+ "0xe000": "rnode_firmware_tbeam_sx1262.boot_app0",
+ "0x1000": "rnode_firmware_tbeam_sx1262.bootloader",
+ "0x10000": "rnode_firmware_tbeam_sx1262.bin",
+ "0x210000": "console_image.bin",
+ "0x8000": "rnode_firmware_tbeam_sx1262.partitions",
+ },
+ },
+ },
+ ],
},
],
@@ -747,7 +995,7 @@
}
// close port
- console.log("Closing serial port");
+ console.log("Closing serial port...");
try {
await serialPort.close();
} catch(e) {
@@ -764,7 +1012,7 @@
return;
}
- // ensure flash config is known, use from selected model, or fallback to selected product
+ // ensure flash config is known
const flashConfig = this.selectedModel?.flash_config ?? this.selectedProduct?.flash_config;
if(!flashConfig){
alert("Flash config is not available for the selected device.");
@@ -784,10 +1032,10 @@
return;
}
- // update progress
this.isFlashing = true;
this.flashingProgress = 0;
+ let transport;
try {
// read zip file
@@ -795,48 +1043,32 @@
const zipReader = new window.zip.ZipReader(blobReader);
const zipEntries = await zipReader.getEntries();
- // get files to flash
const filesToFlash = [];
for(const [address, filename] of Object.entries(flashConfig.flash_files)){
-
- // find file inside zip
- const file = zipEntries.find((zipEntry) => zipEntry.filename === filename);
- if(!file){
- throw filename + " not found in firmware file!";
- }
-
- // get file data as binary string
- const blob = await file.getData(new window.zip.BlobWriter());
- const data = await this.readAsBinaryString(blob); // fixme: deprecated, but works for now
-
- // add to files to flash
- filesToFlash.push({
- "address": parseInt(address),
- "data": data,
- });
-
+ const zipEntry = zipEntries.find(e => e.filename === filename);
+ if(!zipEntry) throw filename + " not found in firmware file!";
+ const blob = await zipEntry.getData(new window.zip.BlobWriter());
+ const data = await this.readAsBinaryString(blob); // deprecated, works for now
+ filesToFlash.push({ address: parseInt(address), data });
}
// init transport and esploader
- const transport = new window.Transport(serialPort, true);
+ transport = new window.Transport(serialPort, true);
const esploader = new window.ESPLoader({
- transport: transport,
+ transport,
baudrate: 921600,
debugLogging: false,
enableTracing: false,
terminal: {
- clean() {
-
- },
- writeLine(data) {
- console.log(data);
- },
- write(data) {
- console.log(data);
- },
+ clean() {},
+ writeLine(data) { console.log(data); },
+ write(data) { console.log(data); },
},
});
+ // completely disable TRACE logging
+ transport.trace = () => {};
+
// load device info
await esploader.main();
@@ -850,34 +1082,97 @@
compress: true,
calculateMD5Hash: (image) => CryptoJS.MD5(CryptoJS.enc.Latin1.parse(image)),
reportProgress: (fileIndex, written, total) => {
- const currentFilePercentage = (written / total) * 100;
- this.flashingProgress = Math.floor(currentFilePercentage);
+ const percent = (written / total) * 100;
+ this.flashingProgress = Math.floor(percent);
},
});
// reboot device
await transport.setDTR(false);
- await new Promise((resolve) => setTimeout(resolve, 100));
+ await new Promise(resolve => setTimeout(resolve, 100));
await transport.setDTR(true);
- // flashing successful
alert("Firmware has been flashed!");
} catch(e) {
alert("Firmware flashing failed: " + e);
+ console.error(e);
+ } finally {
+ this.isFlashing = false;
+
+ // release reader/writer locks before closing port
+ try {
+ if(transport?.reader){
+ await transport.reader.cancel();
+ transport.reader.releaseLock();
+ }
+ if(transport?.writer){
+ transport.writer.releaseLock();
+ }
+
+ console.log("Closing serial port...");
+ await serialPort.close();
+ } catch(e) {
+ console.warn("Failed to close serial port, ignoring...", e);
+ }
+ }
+ },
+ async eraseEsp32() {
+ if (!window.ESPLoader) {
+ alert("esptool-js could not be loaded.");
+ return;
+ }
+
+ // ask for serial port
+ const serialPort = await this.askForSerialPort();
+ if (!serialPort) return;
+
+ this.isFlashing = true;
+
+ let transport, esploader;
+
+ try {
+ transport = new window.Transport(serialPort, true);
+ esploader = new window.ESPLoader({
+ transport: transport,
+ baudrate: 921600,
+ debugLogging: false,
+ enableTracing: false,
+ terminal: {
+ clean() {},
+ writeLine(data) { console.log(data); },
+ write(data) { console.log(data); },
+ },
+ });
+
+ // completely disable TRACE logging
+ transport.trace = () => {};
+
+ await esploader.main();
+ await esploader.eraseFlash();
+ alert("Flash erase completed!");
+ } catch (e) {
+ alert("Flash erase failed: " + e);
console.log(e);
} finally {
this.isFlashing = false;
- }
- // close port
- console.log("Closing serial port");
- try {
- await serialPort.close();
- } catch(e) {
- console.log("failed to close serial port, ignoring...", e);
- }
+ // properly release streams before closing
+ try {
+ if (transport?.reader) {
+ await transport.reader.cancel();
+ transport.reader.releaseLock();
+ }
+ if (transport?.writer) {
+ transport.writer.releaseLock();
+ }
+ console.log("Closing serial port...");
+ await serialPort.close();
+ } catch (e) {
+ console.warn("Failed to close serial port, ignoring...", e);
+ }
+ }
},
async detect() {