esp32tool 1.3.2 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apple-touch-icon.png +0 -0
- package/css/style.css +47 -35
- package/dist/const.js +1 -1
- package/dist/esp_loader.d.ts +4 -0
- package/dist/esp_loader.js +47 -28
- package/dist/web/index.js +1 -1
- package/icons/icon-128.png +0 -0
- package/icons/icon-144.png +0 -0
- package/icons/icon-152.png +0 -0
- package/icons/icon-192.png +0 -0
- package/icons/icon-384.png +0 -0
- package/icons/icon-512.png +0 -0
- package/icons/icon-72.png +0 -0
- package/icons/icon-96.png +0 -0
- package/js/console.js +12 -2
- package/js/modules/esptool.js +1 -1
- package/js/script.js +93 -150
- package/js/util/console-color.js +2 -1
- package/js/webusb-serial.js +42 -7
- package/package.json +3 -3
- package/screenshots/desktop.png +0 -0
- package/screenshots/mobile.png +0 -0
- package/src/const.ts +1 -1
- package/src/esp_loader.ts +48 -29
- package/sw.js +1 -1
package/apple-touch-icon.png
CHANGED
|
Binary file
|
package/css/style.css
CHANGED
|
@@ -179,36 +179,7 @@ div.clear {
|
|
|
179
179
|
display: none;
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
/* Console Container */
|
|
183
|
-
.console-container {
|
|
184
|
-
height: 500px;
|
|
185
|
-
overflow: hidden;
|
|
186
|
-
transition: height 0.3s ease-in-out, visibility 0.3s ease-in-out;
|
|
187
|
-
margin: 0;
|
|
188
|
-
padding: 0;
|
|
189
|
-
visibility: visible;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
.console-container.hidden {
|
|
193
|
-
height: 0;
|
|
194
|
-
visibility: hidden;
|
|
195
|
-
max-height: 0;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/* Mobile console optimization */
|
|
199
|
-
@media (max-width: 768px) {
|
|
200
|
-
.console-container {
|
|
201
|
-
height: 350px;
|
|
202
|
-
font-size: 13px;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
@media (max-width: 480px) {
|
|
207
|
-
.console-container {
|
|
208
|
-
height: 300px;
|
|
209
|
-
font-size: 12px;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
182
|
+
/* Console Container - OLD DEFINITION REMOVED - See bottom of file for new fullscreen version */
|
|
212
183
|
|
|
213
184
|
.notSupported {
|
|
214
185
|
padding: 1em;
|
|
@@ -2189,11 +2160,7 @@ div.clear {
|
|
|
2189
2160
|
padding-right: 10px;
|
|
2190
2161
|
}
|
|
2191
2162
|
|
|
2192
|
-
/* Console optimization for small screens */
|
|
2193
|
-
.console-container {
|
|
2194
|
-
height: 300px;
|
|
2195
|
-
font-size: 12px;
|
|
2196
|
-
}
|
|
2163
|
+
/* Console optimization for small screens - REMOVED - Using fullscreen console now */
|
|
2197
2164
|
|
|
2198
2165
|
/* Filesystem manager for small screens */
|
|
2199
2166
|
.littlefs-manager {
|
|
@@ -2257,3 +2224,48 @@ div.clear {
|
|
|
2257
2224
|
-webkit-tap-highlight-color: transparent;
|
|
2258
2225
|
}
|
|
2259
2226
|
}
|
|
2227
|
+
|
|
2228
|
+
/* Console Container Styling */
|
|
2229
|
+
.console-container {
|
|
2230
|
+
position: fixed;
|
|
2231
|
+
top: 0;
|
|
2232
|
+
left: 0;
|
|
2233
|
+
right: 0;
|
|
2234
|
+
bottom: 0;
|
|
2235
|
+
z-index: 1001; /* Above header and main content */
|
|
2236
|
+
background-color: #1c1c1c;
|
|
2237
|
+
margin: 0;
|
|
2238
|
+
padding: 0;
|
|
2239
|
+
}
|
|
2240
|
+
|
|
2241
|
+
.console-container.hidden {
|
|
2242
|
+
display: none;
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2245
|
+
/* Ensure console wrapper fills the container */
|
|
2246
|
+
.console-container .esp32tool-console-wrapper {
|
|
2247
|
+
position: absolute;
|
|
2248
|
+
top: 0;
|
|
2249
|
+
left: 0;
|
|
2250
|
+
right: 0;
|
|
2251
|
+
bottom: 0;
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2254
|
+
/* Hide header and commands when console is active */
|
|
2255
|
+
body.console-active .header {
|
|
2256
|
+
display: none !important;
|
|
2257
|
+
}
|
|
2258
|
+
|
|
2259
|
+
body.console-active #commands {
|
|
2260
|
+
display: none !important;
|
|
2261
|
+
}
|
|
2262
|
+
|
|
2263
|
+
body.console-active #notSupported {
|
|
2264
|
+
display: none !important;
|
|
2265
|
+
}
|
|
2266
|
+
|
|
2267
|
+
/* Remove padding from main when console is active */
|
|
2268
|
+
body.console-active .main {
|
|
2269
|
+
padding-top: 0 !important;
|
|
2270
|
+
overflow: hidden !important;
|
|
2271
|
+
}
|
package/dist/const.js
CHANGED
|
@@ -128,7 +128,7 @@ export const ESP32S3_UARTDEV_BUF_NO_USB_OTG = 3; // The above var when USB-OTG i
|
|
|
128
128
|
export const ESP32S3_UARTDEV_BUF_NO_USB_JTAG_SERIAL = 4; // The above var when USB-JTAG/Serial is used
|
|
129
129
|
export const ESP32C2_SPI_REG_BASE = 0x60002000;
|
|
130
130
|
export const ESP32C2_BASEFUSEADDR = 0x60008800;
|
|
131
|
-
export const ESP32C2_MACFUSEADDR =
|
|
131
|
+
export const ESP32C2_MACFUSEADDR = ESP32C2_BASEFUSEADDR + 0x040;
|
|
132
132
|
export const ESP32C2_SPI_USR_OFFS = 0x18;
|
|
133
133
|
export const ESP32C2_SPI_USR1_OFFS = 0x1c;
|
|
134
134
|
export const ESP32C2_SPI_USR2_OFFS = 0x20;
|
package/dist/esp_loader.d.ts
CHANGED
|
@@ -19,6 +19,10 @@ export declare class ESPLoader extends EventTarget {
|
|
|
19
19
|
currentBaudRate: number;
|
|
20
20
|
private _maxUSBSerialBaudrate?;
|
|
21
21
|
private _reader?;
|
|
22
|
+
private SLIP_END;
|
|
23
|
+
private SLIP_ESC;
|
|
24
|
+
private SLIP_ESC_END;
|
|
25
|
+
private SLIP_ESC_ESC;
|
|
22
26
|
private _isESP32S2NativeUSB;
|
|
23
27
|
private _initializationSucceeded;
|
|
24
28
|
private __commandLock;
|
package/dist/esp_loader.js
CHANGED
|
@@ -27,6 +27,10 @@ export class ESPLoader extends EventTarget {
|
|
|
27
27
|
this.connected = true;
|
|
28
28
|
this.flashSize = null;
|
|
29
29
|
this.currentBaudRate = ESP_ROM_BAUD;
|
|
30
|
+
this.SLIP_END = 0xc0;
|
|
31
|
+
this.SLIP_ESC = 0xdb;
|
|
32
|
+
this.SLIP_ESC_END = 0xdc;
|
|
33
|
+
this.SLIP_ESC_ESC = 0xdd;
|
|
30
34
|
this._isESP32S2NativeUSB = false;
|
|
31
35
|
this._initializationSucceeded = false;
|
|
32
36
|
this.__commandLock = Promise.resolve([0, []]);
|
|
@@ -1720,44 +1724,44 @@ export class ESPLoader extends EventTarget {
|
|
|
1720
1724
|
const waitingFor = partialPacket === null ? "header" : "content";
|
|
1721
1725
|
throw new SlipReadError("Timed out waiting for packet " + waitingFor);
|
|
1722
1726
|
}
|
|
1723
|
-
const
|
|
1727
|
+
const byte = this._readByte();
|
|
1724
1728
|
if (partialPacket === null) {
|
|
1725
1729
|
// waiting for packet header
|
|
1726
|
-
if (
|
|
1730
|
+
if (byte == this.SLIP_END) {
|
|
1727
1731
|
partialPacket = [];
|
|
1728
1732
|
}
|
|
1729
1733
|
else {
|
|
1730
1734
|
if (this.debug) {
|
|
1731
|
-
this.logger.debug("Read invalid data: " + toHex(
|
|
1735
|
+
this.logger.debug("Read invalid data: " + toHex(byte));
|
|
1732
1736
|
this.logger.debug("Remaining data in serial buffer: " +
|
|
1733
1737
|
hexFormatter(this._inputBuffer));
|
|
1734
1738
|
}
|
|
1735
|
-
throw new SlipReadError("Invalid head of packet (" + toHex(
|
|
1739
|
+
throw new SlipReadError("Invalid head of packet (" + toHex(byte) + ")");
|
|
1736
1740
|
}
|
|
1737
1741
|
}
|
|
1738
1742
|
else if (inEscape) {
|
|
1739
1743
|
// part-way through escape sequence
|
|
1740
1744
|
inEscape = false;
|
|
1741
|
-
if (
|
|
1742
|
-
partialPacket.push(
|
|
1745
|
+
if (byte == this.SLIP_ESC_END) {
|
|
1746
|
+
partialPacket.push(this.SLIP_END);
|
|
1743
1747
|
}
|
|
1744
|
-
else if (
|
|
1745
|
-
partialPacket.push(
|
|
1748
|
+
else if (byte == this.SLIP_ESC_ESC) {
|
|
1749
|
+
partialPacket.push(this.SLIP_ESC);
|
|
1746
1750
|
}
|
|
1747
1751
|
else {
|
|
1748
1752
|
if (this.debug) {
|
|
1749
|
-
this.logger.debug("Read invalid data: " + toHex(
|
|
1753
|
+
this.logger.debug("Read invalid data: " + toHex(byte));
|
|
1750
1754
|
this.logger.debug("Remaining data in serial buffer: " +
|
|
1751
1755
|
hexFormatter(this._inputBuffer));
|
|
1752
1756
|
}
|
|
1753
|
-
throw new SlipReadError("Invalid SLIP escape (0xdb, " + toHex(
|
|
1757
|
+
throw new SlipReadError("Invalid SLIP escape (0xdb, " + toHex(byte) + ")");
|
|
1754
1758
|
}
|
|
1755
1759
|
}
|
|
1756
|
-
else if (
|
|
1760
|
+
else if (byte == this.SLIP_ESC) {
|
|
1757
1761
|
// start of escape sequence
|
|
1758
1762
|
inEscape = true;
|
|
1759
1763
|
}
|
|
1760
|
-
else if (
|
|
1764
|
+
else if (byte == this.SLIP_END) {
|
|
1761
1765
|
// end of packet
|
|
1762
1766
|
if (this.debug)
|
|
1763
1767
|
this.logger.debug("Received full packet: " + hexFormatter(partialPacket));
|
|
@@ -1767,7 +1771,7 @@ export class ESPLoader extends EventTarget {
|
|
|
1767
1771
|
}
|
|
1768
1772
|
else {
|
|
1769
1773
|
// normal byte in packet
|
|
1770
|
-
partialPacket.push(
|
|
1774
|
+
partialPacket.push(byte);
|
|
1771
1775
|
}
|
|
1772
1776
|
}
|
|
1773
1777
|
}
|
|
@@ -1798,44 +1802,44 @@ export class ESPLoader extends EventTarget {
|
|
|
1798
1802
|
}
|
|
1799
1803
|
if (this.debug)
|
|
1800
1804
|
this.logger.debug("Read " + readBytes.length + " bytes: " + hexFormatter(readBytes));
|
|
1801
|
-
for (const
|
|
1805
|
+
for (const byte of readBytes) {
|
|
1802
1806
|
if (partialPacket === null) {
|
|
1803
1807
|
// waiting for packet header
|
|
1804
|
-
if (
|
|
1808
|
+
if (byte == this.SLIP_END) {
|
|
1805
1809
|
partialPacket = [];
|
|
1806
1810
|
}
|
|
1807
1811
|
else {
|
|
1808
1812
|
if (this.debug) {
|
|
1809
|
-
this.logger.debug("Read invalid data: " + toHex(
|
|
1813
|
+
this.logger.debug("Read invalid data: " + toHex(byte));
|
|
1810
1814
|
this.logger.debug("Remaining data in serial buffer: " +
|
|
1811
1815
|
hexFormatter(this._inputBuffer));
|
|
1812
1816
|
}
|
|
1813
|
-
throw new SlipReadError("Invalid head of packet (" + toHex(
|
|
1817
|
+
throw new SlipReadError("Invalid head of packet (" + toHex(byte) + ")");
|
|
1814
1818
|
}
|
|
1815
1819
|
}
|
|
1816
1820
|
else if (inEscape) {
|
|
1817
1821
|
// part-way through escape sequence
|
|
1818
1822
|
inEscape = false;
|
|
1819
|
-
if (
|
|
1820
|
-
partialPacket.push(
|
|
1823
|
+
if (byte == this.SLIP_ESC_END) {
|
|
1824
|
+
partialPacket.push(this.SLIP_END);
|
|
1821
1825
|
}
|
|
1822
|
-
else if (
|
|
1823
|
-
partialPacket.push(
|
|
1826
|
+
else if (byte == this.SLIP_ESC_ESC) {
|
|
1827
|
+
partialPacket.push(this.SLIP_ESC);
|
|
1824
1828
|
}
|
|
1825
1829
|
else {
|
|
1826
1830
|
if (this.debug) {
|
|
1827
|
-
this.logger.debug("Read invalid data: " + toHex(
|
|
1831
|
+
this.logger.debug("Read invalid data: " + toHex(byte));
|
|
1828
1832
|
this.logger.debug("Remaining data in serial buffer: " +
|
|
1829
1833
|
hexFormatter(this._inputBuffer));
|
|
1830
1834
|
}
|
|
1831
|
-
throw new SlipReadError("Invalid SLIP escape (0xdb, " + toHex(
|
|
1835
|
+
throw new SlipReadError("Invalid SLIP escape (0xdb, " + toHex(byte) + ")");
|
|
1832
1836
|
}
|
|
1833
1837
|
}
|
|
1834
|
-
else if (
|
|
1838
|
+
else if (byte == this.SLIP_ESC) {
|
|
1835
1839
|
// start of escape sequence
|
|
1836
1840
|
inEscape = true;
|
|
1837
1841
|
}
|
|
1838
|
-
else if (
|
|
1842
|
+
else if (byte == this.SLIP_END) {
|
|
1839
1843
|
// end of packet
|
|
1840
1844
|
if (this.debug)
|
|
1841
1845
|
this.logger.debug("Received full packet: " + hexFormatter(partialPacket));
|
|
@@ -1845,7 +1849,7 @@ export class ESPLoader extends EventTarget {
|
|
|
1845
1849
|
}
|
|
1846
1850
|
else {
|
|
1847
1851
|
// normal byte in packet
|
|
1848
|
-
partialPacket.push(
|
|
1852
|
+
partialPacket.push(byte);
|
|
1849
1853
|
}
|
|
1850
1854
|
}
|
|
1851
1855
|
}
|
|
@@ -2770,6 +2774,8 @@ export class ESPLoader extends EventTarget {
|
|
|
2770
2774
|
this.logger.debug(`USB detection failed, using cached value: ${this.isUsbJtagOrOtg}`);
|
|
2771
2775
|
isUsbJtag = this.isUsbJtagOrOtg;
|
|
2772
2776
|
}
|
|
2777
|
+
// Release reader/writer so console can create new ones
|
|
2778
|
+
// This is needed for Desktop (Web Serial) to unlock streams
|
|
2773
2779
|
if (isUsbJtag) {
|
|
2774
2780
|
// USB-JTAG/OTG devices: Use watchdog reset which closes port
|
|
2775
2781
|
const wasReset = await this._resetToFirmwareIfNeeded();
|
|
@@ -2792,6 +2798,19 @@ export class ESPLoader extends EventTarget {
|
|
|
2792
2798
|
catch (err) {
|
|
2793
2799
|
this.logger.debug(`Could not reset device: ${err}`);
|
|
2794
2800
|
}
|
|
2801
|
+
// For WebUSB (Android), recreate streams after hardware reset
|
|
2802
|
+
const isWebUSB = this.port.isWebUSB === true;
|
|
2803
|
+
if (isWebUSB) {
|
|
2804
|
+
try {
|
|
2805
|
+
// Use the public recreateStreams() method to safely recreate streams
|
|
2806
|
+
// without closing the port (important after hardware reset)
|
|
2807
|
+
await this.port.recreateStreams();
|
|
2808
|
+
this.logger.debug("WebUSB streams recreated for console mode");
|
|
2809
|
+
}
|
|
2810
|
+
catch (err) {
|
|
2811
|
+
this.logger.debug(`Failed to recreate WebUSB streams: ${err}`);
|
|
2812
|
+
}
|
|
2813
|
+
}
|
|
2795
2814
|
return false; // Port stays open
|
|
2796
2815
|
}
|
|
2797
2816
|
}
|
|
@@ -3181,7 +3200,7 @@ export class ESPLoader extends EventTarget {
|
|
|
3181
3200
|
// Wait for the buffer to fill
|
|
3182
3201
|
await sleep(bufferingTime);
|
|
3183
3202
|
// Unsupported command response is sent 8 times and has
|
|
3184
|
-
// 14 bytes length including delimiter 0xC0 bytes.
|
|
3203
|
+
// 14 bytes length including delimiter SLIP_END (0xC0) bytes.
|
|
3185
3204
|
// At least part of it is read as a command response,
|
|
3186
3205
|
// but to be safe, read it all.
|
|
3187
3206
|
const bytesToDrain = 14 * 8;
|
|
@@ -3345,7 +3364,7 @@ export class ESPLoader extends EventTarget {
|
|
|
3345
3364
|
// The stub expects 4 bytes (ACK), if we send less it will break out
|
|
3346
3365
|
try {
|
|
3347
3366
|
// Send SLIP frame with no data (just delimiters)
|
|
3348
|
-
const abortFrame = [
|
|
3367
|
+
const abortFrame = [this.SLIP_END, this.SLIP_END]; // Empty SLIP frame
|
|
3349
3368
|
await this.writeToStream(abortFrame);
|
|
3350
3369
|
this.logger.debug(`Sent abort frame to stub`);
|
|
3351
3370
|
// Give stub time to process abort
|