From f99be6f238efa983e9348aa7f42dde1e8d409857 Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Mon, 18 May 2026 13:05:17 +0200 Subject: [PATCH 1/4] feature: reset esp --- CHANGELOG.md | 3 ++- src/serialPortManager.ts | 42 ++++++++++++++++++++++++++++++++++++++++ src/webviewPanel.ts | 19 ++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f86100..5eacabb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,10 @@ ## [0.26.5] - 2026-05-xx -### New Feature** +### New Feature - **Filter save** - operations now provide visual feedback to users, confirming successful saves with "Saved ✓" messages or displaying error details if an issue occurs. - Save button shows a disabled state while processing and displays timed feedback that clearly indicates whether the operation succeeded or failed. + - **Reset button** - new toolbar button performs a hard-reset of the connected ESP chip by toggling the RTS/EN line, mirroring `esptool reset_chip("hard-reset")`. Enabled while connected; disabled otherwise. ## [0.26.4] - 2026-05-18 diff --git a/src/serialPortManager.ts b/src/serialPortManager.ts index 1c0afdc..3622443 100644 --- a/src/serialPortManager.ts +++ b/src/serialPortManager.ts @@ -459,6 +459,48 @@ export class SerialPortManager extends vscode.Disposable { }); } + /** + * Perform a hard reset of the connected ESP chip by toggling the RTS line + * (which is wired to the chip's EN/RESET pin on the standard auto-reset + * circuit used by virtually every ESP dev-board). + * + * Mirrors esptool's `HardReset` strategy + * (https://github.com/espressif/esptool/blob/af0787da2cccaf68080d8032cfaf4ce918c3037d/esptool/reset.py) + * and is invoked by `esptool reset_chip("hard-reset")`: + * RTS = True → EN low (chip held in reset) + * sleep 100 ms + * RTS = False → EN high (chip released, boots normally) + * + * DTR is explicitly held LOW (false) the whole time so the two-transistor + * auto-reset circuit only pulls EN — pulling DTR high (the node-serialport + * default for unspecified flags is `dtr: true`) would assert IO0 LOW and + * drop the chip into the ROM bootloader instead of doing a normal boot. + * + * Note: on chips that talk via native USB-CDC (ESP32-S2/S3/C3/P4 when no + * USB-UART bridge is involved) RTS is not physically wired to EN and this + * call is effectively a no-op — esptool falls back to `watchdog_reset` in + * that case, which is not implementable from the host alone. + */ + async hardReset(): Promise { + if (!this.port || !this._isConnected) { + throw new Error('Serial port not connected'); + } + const port = this.port; + // Always pass BOTH dtr and rts: node-serialport's set() resets every + // unspecified flag to its default (dtr: true, rts: true). Letting dtr + // default to true would assert IO0 LOW via the auto-reset circuit and + // send the chip into download mode instead of resetting it. + const setSignals = (dtr: boolean, rts: boolean): Promise => + new Promise((resolve, reject) => { + port.set({ dtr, rts }, (err) => (err ? reject(err) : resolve())); + }); + this.log.appendLine('[ESP Decoder] hard-reset: RTS=1 DTR=0 (EN low, IO0 high)'); + await setSignals(false, true); + await new Promise((r) => setTimeout(r, 100)); + this.log.appendLine('[ESP Decoder] hard-reset: RTS=0 DTR=0 (EN high, IO0 high)'); + await setSignals(false, false); + } + async sendData(data: string): Promise { if (!this.port || !this._isConnected) { throw new Error('Serial port not connected'); diff --git a/src/webviewPanel.ts b/src/webviewPanel.ts index b030e78..e3438bc 100644 --- a/src/webviewPanel.ts +++ b/src/webviewPanel.ts @@ -433,6 +433,17 @@ export class EspDecoderWebviewPanel implements vscode.WebviewViewProvider { this.syncState(); break; } + case 'hardReset': { + try { + await this.serialManager.hardReset(); + } catch (err) { + this.postMessage({ + type: 'error', + message: `Reset error: ${err instanceof Error ? err.message : String(err)}`, + }); + } + break; + } case 'selectPort': { const port = await this.serialManager.selectPort(); this.syncState(); @@ -1669,6 +1680,7 @@ export class EspDecoderWebviewPanel implements vscode.WebviewViewProvider {
+
@@ -2103,6 +2115,10 @@ export class EspDecoderWebviewPanel implements vscode.WebviewViewProvider { vscode.postMessage({ type: 'disconnect' }); }); + document.getElementById('btn-reset').addEventListener('click', () => { + vscode.postMessage({ type: 'hardReset' }); + }); + document.getElementById('btn-elf').addEventListener('click', () => { vscode.postMessage({ type: 'selectElf' }); }); @@ -2584,6 +2600,7 @@ export class EspDecoderWebviewPanel implements vscode.WebviewViewProvider { const text = document.getElementById('status-text'); const btnConnect = document.getElementById('btn-connect'); const btnDisconnect = document.getElementById('btn-disconnect'); + const btnReset = document.getElementById('btn-reset'); if (isConnected) { dot.className = 'status-indicator connected'; @@ -2591,12 +2608,14 @@ export class EspDecoderWebviewPanel implements vscode.WebviewViewProvider { btnConnect.textContent = 'Connect'; btnConnect.disabled = true; btnDisconnect.disabled = false; + btnReset.disabled = false; } else { dot.className = 'status-indicator disconnected'; text.textContent = 'Disconnected'; btnConnect.textContent = 'Connect'; btnConnect.disabled = false; btnDisconnect.disabled = true; + btnReset.disabled = true; } if (port) { From 48899dd37c382d222b57ef26df7420ced5ea69e7 Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Mon, 18 May 2026 13:09:19 +0200 Subject: [PATCH 2/4] feedback reset --- src/webviewPanel.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/webviewPanel.ts b/src/webviewPanel.ts index e3438bc..8add8b7 100644 --- a/src/webviewPanel.ts +++ b/src/webviewPanel.ts @@ -2116,7 +2116,15 @@ export class EspDecoderWebviewPanel implements vscode.WebviewViewProvider { }); document.getElementById('btn-reset').addEventListener('click', () => { + const btn = document.getElementById('btn-reset'); vscode.postMessage({ type: 'hardReset' }); + const originalText = btn.textContent; + btn.classList.add('feedback-saved'); + btn.textContent = 'Reset \u2713'; + setTimeout(function() { + btn.classList.remove('feedback-saved'); + btn.textContent = originalText; + }, 600); }); document.getElementById('btn-elf').addEventListener('click', () => { From c16ab7007bddd2f8eb1640c3b5fc42145f2a7769 Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Mon, 18 May 2026 13:17:57 +0200 Subject: [PATCH 3/4] fix comment about reset --- src/serialPortManager.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/serialPortManager.ts b/src/serialPortManager.ts index 3622443..63a67ad 100644 --- a/src/serialPortManager.ts +++ b/src/serialPortManager.ts @@ -477,9 +477,8 @@ export class SerialPortManager extends vscode.Disposable { * drop the chip into the ROM bootloader instead of doing a normal boot. * * Note: on chips that talk via native USB-CDC (ESP32-S2/S3/C3/P4 when no - * USB-UART bridge is involved) RTS is not physically wired to EN and this - * call is effectively a no-op — esptool falls back to `watchdog_reset` in - * that case, which is not implementable from the host alone. + * USB-UART bridge is involved) the reset may not work. The port disappears when + * the chip resets, and ESP-Decoder tries to auto-reconnect to the same port before the reset. */ async hardReset(): Promise { if (!this.port || !this._isConnected) { From fa444cbe6a093390d74bb45d64e6e73cb344883f Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Mon, 18 May 2026 13:29:00 +0200 Subject: [PATCH 4/4] Bump v0.27.0 --- CHANGELOG.md | 5 ++--- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5eacabb..53ef092 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,10 @@ # Changelog -## [0.26.5] - 2026-05-xx +## [0.27.0] - 2026-05-18 ### New Feature - - **Filter save** - operations now provide visual feedback to users, confirming successful saves with "Saved ✓" messages or displaying error details if an issue occurs. - - Save button shows a disabled state while processing and displays timed feedback that clearly indicates whether the operation succeeded or failed. - **Reset button** - new toolbar button performs a hard-reset of the connected ESP chip by toggling the RTS/EN line, mirroring `esptool reset_chip("hard-reset")`. Enabled while connected; disabled otherwise. + - **Filter save** - operations now provide visual feedback to users, confirming successful saves with "Saved ✓" messages or displaying error details if an issue occurs. Save button shows a disabled state while processing and displays timed feedback that clearly indicates whether the operation succeeded or failed. ## [0.26.4] - 2026-05-18 diff --git a/package-lock.json b/package-lock.json index 35893dc..7e3b359 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "esp-decoder", - "version": "0.26.4", + "version": "0.27.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "esp-decoder", - "version": "0.26.4", + "version": "0.27.0", "license": "GPL-3.0", "dependencies": { "serialport": "^13.0.0" diff --git a/package.json b/package.json index 120aaa3..e8f2794 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "esp-decoder", "displayName": "ESP Crash Decoder", "description": "Decode ESP32 / ESP8266 crash dumps from serial port", - "version": "0.26.4", + "version": "0.27.0", "publisher": "Jason2866", "license": "GPL-3.0", "icon": "assets/icon_large.png",