tasmota-webserial-esptool 7.3.0 → 7.3.2

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.
Files changed (55) hide show
  1. package/dist/esp_loader.d.ts +13 -0
  2. package/dist/esp_loader.js +305 -138
  3. package/dist/stubs/esp32c3.json +3 -3
  4. package/dist/stubs/esp32c5.json +3 -3
  5. package/dist/stubs/esp32c6.json +3 -3
  6. package/dist/stubs/esp32c61.json +3 -3
  7. package/dist/stubs/esp32h2.json +3 -3
  8. package/dist/stubs/esp32p4.json +3 -3
  9. package/dist/stubs/esp32p4r3.json +3 -3
  10. package/dist/stubs/esp32s3.json +3 -3
  11. package/dist/web/esp32c3-CHKfoI8W.js +1 -0
  12. package/dist/web/esp32c5-BDW4KtLo.js +1 -0
  13. package/dist/web/esp32c6-il8tTxAG.js +1 -0
  14. package/dist/web/esp32c61-thKzxBGf.js +1 -0
  15. package/dist/web/esp32h2-CxoUHv_P.js +1 -0
  16. package/dist/web/esp32p4-D3jLP-jY.js +1 -0
  17. package/dist/web/esp32p4r3-CqI71ojR.js +1 -0
  18. package/dist/web/esp32s3-DGwDVIgz.js +1 -0
  19. package/dist/web/index.js +1 -1
  20. package/js/modules/esp32c3-CHKfoI8W.js +1 -0
  21. package/js/modules/esp32c5-BDW4KtLo.js +1 -0
  22. package/js/modules/esp32c6-il8tTxAG.js +1 -0
  23. package/js/modules/esp32c61-thKzxBGf.js +1 -0
  24. package/js/modules/esp32h2-CxoUHv_P.js +1 -0
  25. package/js/modules/esp32p4-D3jLP-jY.js +1 -0
  26. package/js/modules/esp32p4r3-CqI71ojR.js +1 -0
  27. package/js/modules/esp32s3-DGwDVIgz.js +1 -0
  28. package/js/modules/esptool.js +1 -1
  29. package/package.json +1 -1
  30. package/src/esp_loader.ts +326 -143
  31. package/src/stubs/README.md +1 -1
  32. package/src/stubs/esp32c3.json +3 -3
  33. package/src/stubs/esp32c5.json +3 -3
  34. package/src/stubs/esp32c6.json +3 -3
  35. package/src/stubs/esp32c61.json +3 -3
  36. package/src/stubs/esp32h2.json +3 -3
  37. package/src/stubs/esp32p4.json +3 -3
  38. package/src/stubs/esp32p4r3.json +3 -3
  39. package/src/stubs/esp32s3.json +3 -3
  40. package/dist/web/esp32c3-BGQu6Tl5.js +0 -1
  41. package/dist/web/esp32c5-0b050IXn.js +0 -1
  42. package/dist/web/esp32c6-D9SxtU9b.js +0 -1
  43. package/dist/web/esp32c61-B2dSOrao.js +0 -1
  44. package/dist/web/esp32h2-BBdaXb2C.js +0 -1
  45. package/dist/web/esp32p4-BLGlFHot.js +0 -1
  46. package/dist/web/esp32p4r3-CEI3EOJv.js +0 -1
  47. package/dist/web/esp32s3-BUw3lf0r.js +0 -1
  48. package/js/modules/esp32c3-BGQu6Tl5.js +0 -1
  49. package/js/modules/esp32c5-0b050IXn.js +0 -1
  50. package/js/modules/esp32c6-D9SxtU9b.js +0 -1
  51. package/js/modules/esp32c61-B2dSOrao.js +0 -1
  52. package/js/modules/esp32h2-BBdaXb2C.js +0 -1
  53. package/js/modules/esp32p4-BLGlFHot.js +0 -1
  54. package/js/modules/esp32p4r3-CEI3EOJv.js +0 -1
  55. package/js/modules/esp32s3-BUw3lf0r.js +0 -1
@@ -20,10 +20,14 @@ export declare class ESPLoader extends EventTarget {
20
20
  private _reader?;
21
21
  private _isESP32S2NativeUSB;
22
22
  private _initializationSucceeded;
23
+ private __commandLock;
24
+ private _isReconfiguring;
23
25
  constructor(port: SerialPort, logger: Logger, _parent?: ESPLoader | undefined);
24
26
  private get _inputBuffer();
25
27
  private get _totalBytesRead();
26
28
  private set _totalBytesRead(value);
29
+ private get _commandLock();
30
+ private set _commandLock(value);
27
31
  private detectUSBSerialChip;
28
32
  initialize(): Promise<void>;
29
33
  /**
@@ -65,6 +69,9 @@ export declare class ESPLoader extends EventTarget {
65
69
  * Send a command packet, check that the command succeeded and
66
70
  * return a tuple with the value and data.
67
71
  * See the ESP Serial Protocol for more details on what value/data are
72
+ *
73
+ * Commands are serialized to prevent concurrent execution which can cause
74
+ * WritableStream lock contention on CP210x adapters under Windows
68
75
  */
69
76
  checkCommand(opcode: number, buffer: number[], checksum?: number, timeout?: number): Promise<[number, number[]]>;
70
77
  /**
@@ -188,6 +195,12 @@ export declare class ESPLoader extends EventTarget {
188
195
  */
189
196
  memFinish(entrypoint?: number): Promise<[number, number[]]>;
190
197
  runStub(skipFlashDetection?: boolean): Promise<EspStubLoader>;
198
+ __writer?: WritableStreamDefaultWriter<Uint8Array>;
199
+ __writeChain: Promise<void>;
200
+ private get _writer();
201
+ private set _writer(value);
202
+ private get _writeChain();
203
+ private set _writeChain(value);
191
204
  writeToStream(data: number[]): Promise<void>;
192
205
  disconnect(): Promise<void>;
193
206
  /**
@@ -23,7 +23,10 @@ export class ESPLoader extends EventTarget {
23
23
  this._currentBaudRate = ESP_ROM_BAUD;
24
24
  this._isESP32S2NativeUSB = false;
25
25
  this._initializationSucceeded = false;
26
+ this.__commandLock = Promise.resolve([0, []]);
27
+ this._isReconfiguring = false;
26
28
  this.state_DTR = false;
29
+ this.__writeChain = Promise.resolve();
27
30
  }
28
31
  get _inputBuffer() {
29
32
  return this._parent ? this._parent._inputBuffer : this.__inputBuffer;
@@ -41,6 +44,17 @@ export class ESPLoader extends EventTarget {
41
44
  this.__totalBytesRead = value;
42
45
  }
43
46
  }
47
+ get _commandLock() {
48
+ return this._parent ? this._parent._commandLock : this.__commandLock;
49
+ }
50
+ set _commandLock(value) {
51
+ if (this._parent) {
52
+ this._parent._commandLock = value;
53
+ }
54
+ else {
55
+ this.__commandLock = value;
56
+ }
57
+ }
44
58
  detectUSBSerialChip(vendorId, productId) {
45
59
  // Common USB-Serial chip vendors and their products
46
60
  const chips = {
@@ -393,68 +407,78 @@ export class ESPLoader extends EventTarget {
393
407
  * Send a command packet, check that the command succeeded and
394
408
  * return a tuple with the value and data.
395
409
  * See the ESP Serial Protocol for more details on what value/data are
410
+ *
411
+ * Commands are serialized to prevent concurrent execution which can cause
412
+ * WritableStream lock contention on CP210x adapters under Windows
396
413
  */
397
414
  async checkCommand(opcode, buffer, checksum = 0, timeout = DEFAULT_TIMEOUT) {
398
- timeout = Math.min(timeout, MAX_TIMEOUT);
399
- await this.sendCommand(opcode, buffer, checksum);
400
- const [value, responseData] = await this.getResponse(opcode, timeout);
401
- if (responseData === null) {
402
- throw new Error("Didn't get enough status bytes");
403
- }
404
- let data = responseData;
405
- let statusLen = 0;
406
- if (this.IS_STUB || this.chipFamily == CHIP_FAMILY_ESP8266) {
407
- statusLen = 2;
408
- }
409
- else if ([
410
- CHIP_FAMILY_ESP32,
411
- CHIP_FAMILY_ESP32S2,
412
- CHIP_FAMILY_ESP32S3,
413
- CHIP_FAMILY_ESP32C2,
414
- CHIP_FAMILY_ESP32C3,
415
- CHIP_FAMILY_ESP32C5,
416
- CHIP_FAMILY_ESP32C6,
417
- CHIP_FAMILY_ESP32C61,
418
- CHIP_FAMILY_ESP32H2,
419
- CHIP_FAMILY_ESP32H4,
420
- CHIP_FAMILY_ESP32H21,
421
- CHIP_FAMILY_ESP32P4,
422
- CHIP_FAMILY_ESP32S31,
423
- ].includes(this.chipFamily)) {
424
- statusLen = 4;
425
- }
426
- else {
427
- // When chipFamily is not yet set (e.g., during GET_SECURITY_INFO in detectChip),
428
- // assume modern chips use 4-byte status
429
- if (opcode === ESP_GET_SECURITY_INFO) {
430
- statusLen = 4;
415
+ // Serialize command execution to prevent lock contention
416
+ const executeCommand = async () => {
417
+ timeout = Math.min(timeout, MAX_TIMEOUT);
418
+ await this.sendCommand(opcode, buffer, checksum);
419
+ const [value, responseData] = await this.getResponse(opcode, timeout);
420
+ if (responseData === null) {
421
+ throw new Error("Didn't get enough status bytes");
431
422
  }
432
- else if ([2, 4].includes(data.length)) {
433
- statusLen = data.length;
423
+ let data = responseData;
424
+ let statusLen = 0;
425
+ if (this.IS_STUB || this.chipFamily == CHIP_FAMILY_ESP8266) {
426
+ statusLen = 2;
434
427
  }
435
- }
436
- if (data.length < statusLen) {
437
- throw new Error("Didn't get enough status bytes");
438
- }
439
- const status = data.slice(-statusLen, data.length);
440
- data = data.slice(0, -statusLen);
441
- if (this.debug) {
442
- this.logger.debug("status", status);
443
- this.logger.debug("value", value);
444
- this.logger.debug("data", data);
445
- }
446
- if (status[0] == 1) {
447
- if (status[1] == ROM_INVALID_RECV_MSG) {
448
- // Unsupported command can result in more than one error response
449
- // Use drainInputBuffer for CP210x compatibility on Windows
450
- await this.drainInputBuffer(200);
451
- throw new Error("Invalid (unsupported) command " + toHex(opcode));
428
+ else if ([
429
+ CHIP_FAMILY_ESP32,
430
+ CHIP_FAMILY_ESP32S2,
431
+ CHIP_FAMILY_ESP32S3,
432
+ CHIP_FAMILY_ESP32C2,
433
+ CHIP_FAMILY_ESP32C3,
434
+ CHIP_FAMILY_ESP32C5,
435
+ CHIP_FAMILY_ESP32C6,
436
+ CHIP_FAMILY_ESP32C61,
437
+ CHIP_FAMILY_ESP32H2,
438
+ CHIP_FAMILY_ESP32H4,
439
+ CHIP_FAMILY_ESP32H21,
440
+ CHIP_FAMILY_ESP32P4,
441
+ CHIP_FAMILY_ESP32S31,
442
+ ].includes(this.chipFamily)) {
443
+ statusLen = 4;
452
444
  }
453
445
  else {
454
- throw new Error("Command failure error code " + toHex(status[1]));
446
+ // When chipFamily is not yet set (e.g., during GET_SECURITY_INFO in detectChip),
447
+ // assume modern chips use 4-byte status
448
+ if (opcode === ESP_GET_SECURITY_INFO) {
449
+ statusLen = 4;
450
+ }
451
+ else if ([2, 4].includes(data.length)) {
452
+ statusLen = data.length;
453
+ }
455
454
  }
456
- }
457
- return [value, data];
455
+ if (data.length < statusLen) {
456
+ throw new Error("Didn't get enough status bytes");
457
+ }
458
+ const status = data.slice(-statusLen, data.length);
459
+ data = data.slice(0, -statusLen);
460
+ if (this.debug) {
461
+ this.logger.debug("status", status);
462
+ this.logger.debug("value", value);
463
+ this.logger.debug("data", data);
464
+ }
465
+ if (status[0] == 1) {
466
+ if (status[1] == ROM_INVALID_RECV_MSG) {
467
+ // Unsupported command can result in more than one error response
468
+ // Use drainInputBuffer for CP210x compatibility on Windows
469
+ await this.drainInputBuffer(200);
470
+ throw new Error("Invalid (unsupported) command " + toHex(opcode));
471
+ }
472
+ else {
473
+ throw new Error("Command failure error code " + toHex(status[1]));
474
+ }
475
+ }
476
+ return [value, data];
477
+ };
478
+ // Chain command execution through the lock
479
+ // Use both .then() handlers to ensure lock continues even on error
480
+ this._commandLock = this._commandLock.then(executeCommand, executeCommand);
481
+ return this._commandLock;
458
482
  }
459
483
  /**
460
484
  * @name sendCommand
@@ -624,6 +648,24 @@ export class ESPLoader extends EventTarget {
624
648
  async reconfigurePort(baud) {
625
649
  var _a;
626
650
  try {
651
+ this._isReconfiguring = true;
652
+ // Wait for pending writes to complete
653
+ try {
654
+ await this._writeChain;
655
+ }
656
+ catch (err) {
657
+ this.logger.debug(`Pending write error during reconfigure: ${err}`);
658
+ }
659
+ // Release persistent writer before closing
660
+ if (this._writer) {
661
+ try {
662
+ this._writer.releaseLock();
663
+ }
664
+ catch (err) {
665
+ this.logger.debug(`Writer release error during reconfigure: ${err}`);
666
+ }
667
+ this._writer = undefined;
668
+ }
627
669
  // SerialPort does not allow to be reconfigured while open so we close and re-open
628
670
  // reader.cancel() causes the Promise returned by the read() operation running on
629
671
  // the readLoop to return immediately with { value: undefined, done: true } and thus
@@ -641,6 +683,9 @@ export class ESPLoader extends EventTarget {
641
683
  this.logger.error(`Reconfigure port error: ${e}`);
642
684
  throw new Error(`Unable to change the baud rate to ${baud}: ${e}`);
643
685
  }
686
+ finally {
687
+ this._isReconfiguring = false;
688
+ }
644
689
  }
645
690
  /**
646
691
  * @name connectWithResetStrategies
@@ -1200,19 +1245,83 @@ export class ESPLoader extends EventTarget {
1200
1245
  }
1201
1246
  return espStubLoader;
1202
1247
  }
1248
+ get _writer() {
1249
+ return this._parent ? this._parent._writer : this.__writer;
1250
+ }
1251
+ set _writer(value) {
1252
+ if (this._parent) {
1253
+ this._parent._writer = value;
1254
+ }
1255
+ else {
1256
+ this.__writer = value;
1257
+ }
1258
+ }
1259
+ get _writeChain() {
1260
+ return this._parent ? this._parent._writeChain : this.__writeChain;
1261
+ }
1262
+ set _writeChain(value) {
1263
+ if (this._parent) {
1264
+ this._parent._writeChain = value;
1265
+ }
1266
+ else {
1267
+ this.__writeChain = value;
1268
+ }
1269
+ }
1203
1270
  async writeToStream(data) {
1204
1271
  if (!this.port.writable) {
1205
1272
  this.logger.debug("Port writable stream not available, skipping write");
1206
1273
  return;
1207
1274
  }
1208
- const writer = this.port.writable.getWriter();
1209
- await writer.write(new Uint8Array(data));
1210
- try {
1211
- writer.releaseLock();
1212
- }
1213
- catch (err) {
1214
- this.logger.error(`Ignoring release lock error: ${err}`);
1275
+ if (this._isReconfiguring) {
1276
+ throw new Error("Cannot write during port reconfiguration");
1215
1277
  }
1278
+ // Queue writes to prevent lock contention (critical for CP2102 on Windows)
1279
+ this._writeChain = this._writeChain
1280
+ .then(async () => {
1281
+ // Check if port is still writable before attempting write
1282
+ if (!this.port.writable) {
1283
+ throw new Error("Port became unavailable during write");
1284
+ }
1285
+ // Get or create persistent writer
1286
+ if (!this._writer) {
1287
+ try {
1288
+ this._writer = this.port.writable.getWriter();
1289
+ }
1290
+ catch (err) {
1291
+ this.logger.error(`Failed to get writer: ${err}`);
1292
+ throw err;
1293
+ }
1294
+ }
1295
+ // Perform the write
1296
+ await this._writer.write(new Uint8Array(data));
1297
+ }, async () => {
1298
+ // Previous write failed, but still attempt this write
1299
+ if (!this.port.writable) {
1300
+ throw new Error("Port became unavailable during write");
1301
+ }
1302
+ // Writer was likely cleaned up by previous error, create new one
1303
+ if (!this._writer) {
1304
+ this._writer = this.port.writable.getWriter();
1305
+ }
1306
+ await this._writer.write(new Uint8Array(data));
1307
+ })
1308
+ .catch((err) => {
1309
+ this.logger.error(`Write error: ${err}`);
1310
+ // Ensure writer is cleaned up on any error
1311
+ if (this._writer) {
1312
+ try {
1313
+ this._writer.releaseLock();
1314
+ }
1315
+ catch (e) {
1316
+ // Ignore release errors
1317
+ }
1318
+ this._writer = undefined;
1319
+ }
1320
+ // Re-throw to propagate error
1321
+ throw err;
1322
+ });
1323
+ // Always await the write chain to ensure errors are caught
1324
+ await this._writeChain;
1216
1325
  }
1217
1326
  async disconnect() {
1218
1327
  if (this._parent) {
@@ -1223,15 +1332,50 @@ export class ESPLoader extends EventTarget {
1223
1332
  this.logger.debug("Port already closed, skipping disconnect");
1224
1333
  return;
1225
1334
  }
1226
- await this.port.writable.getWriter().close();
1227
- await new Promise((resolve) => {
1228
- if (!this._reader) {
1229
- resolve(undefined);
1335
+ try {
1336
+ this._isReconfiguring = true;
1337
+ // Wait for pending writes to complete
1338
+ try {
1339
+ await this._writeChain;
1230
1340
  }
1231
- this.addEventListener("disconnect", resolve, { once: true });
1232
- this._reader.cancel();
1233
- });
1234
- this.connected = false;
1341
+ catch (err) {
1342
+ this.logger.debug(`Pending write error during disconnect: ${err}`);
1343
+ }
1344
+ // Release persistent writer before closing
1345
+ if (this._writer) {
1346
+ try {
1347
+ await this._writer.close();
1348
+ this._writer.releaseLock();
1349
+ }
1350
+ catch (err) {
1351
+ this.logger.debug(`Writer close/release error: ${err}`);
1352
+ }
1353
+ this._writer = undefined;
1354
+ }
1355
+ else {
1356
+ // No persistent writer exists, close stream directly
1357
+ // This path is taken when no writes have been queued
1358
+ try {
1359
+ const writer = this.port.writable.getWriter();
1360
+ await writer.close();
1361
+ writer.releaseLock();
1362
+ }
1363
+ catch (err) {
1364
+ this.logger.debug(`Direct writer close error: ${err}`);
1365
+ }
1366
+ }
1367
+ await new Promise((resolve) => {
1368
+ if (!this._reader) {
1369
+ resolve(undefined);
1370
+ }
1371
+ this.addEventListener("disconnect", resolve, { once: true });
1372
+ this._reader.cancel();
1373
+ });
1374
+ this.connected = false;
1375
+ }
1376
+ finally {
1377
+ this._isReconfiguring = false;
1378
+ }
1235
1379
  }
1236
1380
  /**
1237
1381
  * @name reconnectAndResume
@@ -1242,82 +1386,105 @@ export class ESPLoader extends EventTarget {
1242
1386
  await this._parent.reconnect();
1243
1387
  return;
1244
1388
  }
1245
- this.logger.log("Reconnecting serial port...");
1246
- this.connected = false;
1247
- this.__inputBuffer = [];
1248
- // Cancel reader
1249
- if (this._reader) {
1389
+ try {
1390
+ this._isReconfiguring = true;
1391
+ this.logger.log("Reconnecting serial port...");
1392
+ this.connected = false;
1393
+ this.__inputBuffer = [];
1394
+ // Wait for pending writes to complete
1250
1395
  try {
1251
- await this._reader.cancel();
1396
+ await this._writeChain;
1252
1397
  }
1253
1398
  catch (err) {
1254
- this.logger.debug(`Reader cancel error: ${err}`);
1399
+ this.logger.debug(`Pending write error during reconnect: ${err}`);
1255
1400
  }
1256
- this._reader = undefined;
1257
- }
1258
- // Close port
1259
- try {
1260
- await this.port.close();
1261
- this.logger.log("Port closed");
1262
- }
1263
- catch (err) {
1264
- this.logger.debug(`Port close error: ${err}`);
1265
- }
1266
- // Open the port
1267
- this.logger.debug("Opening port...");
1268
- try {
1269
- await this.port.open({ baudRate: ESP_ROM_BAUD });
1270
- this.connected = true;
1271
- }
1272
- catch (err) {
1273
- throw new Error(`Failed to open port: ${err}`);
1274
- }
1275
- // Verify port streams are available
1276
- if (!this.port.readable || !this.port.writable) {
1277
- throw new Error(`Port streams not available after open (readable: ${!!this.port.readable}, writable: ${!!this.port.writable})`);
1278
- }
1279
- // Save chip info and flash size (no need to detect again)
1280
- const savedChipFamily = this.chipFamily;
1281
- const savedChipName = this.chipName;
1282
- const savedChipRevision = this.chipRevision;
1283
- const savedChipVariant = this.chipVariant;
1284
- const savedFlashSize = this.flashSize;
1285
- // Reinitialize
1286
- await this.hardReset(true);
1287
- if (!this._parent) {
1288
- this.__inputBuffer = [];
1289
- this.__totalBytesRead = 0;
1290
- this.readLoop();
1291
- }
1292
- await this.flushSerialBuffers();
1293
- await this.sync();
1294
- // Restore chip info
1295
- this.chipFamily = savedChipFamily;
1296
- this.chipName = savedChipName;
1297
- this.chipRevision = savedChipRevision;
1298
- this.chipVariant = savedChipVariant;
1299
- this.flashSize = savedFlashSize;
1300
- this.logger.debug(`Reconnect complete (chip: ${this.chipName})`);
1301
- // Verify port is ready
1302
- if (!this.port.writable || !this.port.readable) {
1303
- throw new Error("Port not ready after reconnect");
1304
- }
1305
- // Load stub
1306
- const stubLoader = await this.runStub(true);
1307
- this.logger.debug("Stub loaded");
1308
- // Restore baudrate if it was changed
1309
- if (this._currentBaudRate !== ESP_ROM_BAUD) {
1310
- await stubLoader.setBaudrate(this._currentBaudRate);
1311
- // Verify port is still ready after baudrate change
1401
+ // Release persistent writer
1402
+ if (this._writer) {
1403
+ try {
1404
+ this._writer.releaseLock();
1405
+ }
1406
+ catch (err) {
1407
+ this.logger.debug(`Writer release error during reconnect: ${err}`);
1408
+ }
1409
+ this._writer = undefined;
1410
+ }
1411
+ // Cancel reader
1412
+ if (this._reader) {
1413
+ try {
1414
+ await this._reader.cancel();
1415
+ }
1416
+ catch (err) {
1417
+ this.logger.debug(`Reader cancel error: ${err}`);
1418
+ }
1419
+ this._reader = undefined;
1420
+ }
1421
+ // Close port
1422
+ try {
1423
+ await this.port.close();
1424
+ this.logger.log("Port closed");
1425
+ }
1426
+ catch (err) {
1427
+ this.logger.debug(`Port close error: ${err}`);
1428
+ }
1429
+ // Open the port
1430
+ this.logger.debug("Opening port...");
1431
+ try {
1432
+ await this.port.open({ baudRate: ESP_ROM_BAUD });
1433
+ this.connected = true;
1434
+ }
1435
+ catch (err) {
1436
+ throw new Error(`Failed to open port: ${err}`);
1437
+ }
1438
+ // Verify port streams are available
1439
+ if (!this.port.readable || !this.port.writable) {
1440
+ throw new Error(`Port streams not available after open (readable: ${!!this.port.readable}, writable: ${!!this.port.writable})`);
1441
+ }
1442
+ // Save chip info and flash size (no need to detect again)
1443
+ const savedChipFamily = this.chipFamily;
1444
+ const savedChipName = this.chipName;
1445
+ const savedChipRevision = this.chipRevision;
1446
+ const savedChipVariant = this.chipVariant;
1447
+ const savedFlashSize = this.flashSize;
1448
+ // Reinitialize
1449
+ await this.hardReset(true);
1450
+ if (!this._parent) {
1451
+ this.__inputBuffer = [];
1452
+ this.__totalBytesRead = 0;
1453
+ this.readLoop();
1454
+ }
1455
+ await this.flushSerialBuffers();
1456
+ await this.sync();
1457
+ // Restore chip info
1458
+ this.chipFamily = savedChipFamily;
1459
+ this.chipName = savedChipName;
1460
+ this.chipRevision = savedChipRevision;
1461
+ this.chipVariant = savedChipVariant;
1462
+ this.flashSize = savedFlashSize;
1463
+ this.logger.debug(`Reconnect complete (chip: ${this.chipName})`);
1464
+ // Verify port is ready
1312
1465
  if (!this.port.writable || !this.port.readable) {
1313
- throw new Error(`Port not ready after baudrate change (readable: ${!!this.port.readable}, writable: ${!!this.port.writable})`);
1466
+ throw new Error("Port not ready after reconnect");
1314
1467
  }
1468
+ // Load stub
1469
+ const stubLoader = await this.runStub(true);
1470
+ this.logger.debug("Stub loaded");
1471
+ // Restore baudrate if it was changed
1472
+ if (this._currentBaudRate !== ESP_ROM_BAUD) {
1473
+ await stubLoader.setBaudrate(this._currentBaudRate);
1474
+ // Verify port is still ready after baudrate change
1475
+ if (!this.port.writable || !this.port.readable) {
1476
+ throw new Error(`Port not ready after baudrate change (readable: ${!!this.port.readable}, writable: ${!!this.port.writable})`);
1477
+ }
1478
+ }
1479
+ // Copy stub state to this instance if we're a stub loader
1480
+ if (this.IS_STUB) {
1481
+ Object.assign(this, stubLoader);
1482
+ }
1483
+ this.logger.debug("Reconnection successful");
1315
1484
  }
1316
- // Copy stub state to this instance if we're a stub loader
1317
- if (this.IS_STUB) {
1318
- Object.assign(this, stubLoader);
1485
+ finally {
1486
+ this._isReconfiguring = false;
1319
1487
  }
1320
- this.logger.debug("Reconnection successful");
1321
1488
  }
1322
1489
  /**
1323
1490
  * @name drainInputBuffer
@@ -1,8 +1,8 @@
1
1
  {
2
- "entry": 1077413608,
3
- "text": "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",
2
+ "entry": 1077413654,
3
+ "text": "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",
4
4
  "text_start": 1077411840,
5
- "data": "FEDIP6wKOEAWCzhAqAs4QHwMOEDkDDhAkgw4QIYJOEA4DDhAeAw4QMQLOEA2CThA7As4QDYJOECKCjhA1Ao4QBYLOECoCzhAnAo4QK4JOED6CThAmAo4QN4OOEAWCzhAoA04QJoOOED0CDhAwA44QPQIOED0CDhA9Ag4QPQIOED0CDhA9Ag4QPQIOED0CDhARg04QPQIOEC4DThAmg44QA==",
5
+ "data": "FEDIP9oKOEBECzhA1gs4QKoMOEASDThAwAw4QLQJOEBmDDhApgw4QPILOEBkCThAGgw4QGQJOEC4CjhAAgs4QEQLOEDWCzhAygo4QNwJOEAoCjhAxgo4QAwPOEBECzhAzg04QMgOOEAiCThA7g44QCIJOEAiCThAIgk4QCIJOEAiCThAIgk4QCIJOEAiCThAdA04QCIJOEDmDThAyA44QA==",
6
6
  "data_start": 1070164916,
7
7
  "bss_start": 1070088192
8
8
  }
@@ -1,8 +1,8 @@
1
1
  {
2
- "entry": 1082133142,
3
- "text": "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",
2
+ "entry": 1082133196,
3
+ "text": "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",
4
4
  "text_start": 1082130432,
5
- "data": "FACEQPoOgEBkD4BA+A+AQMwQgEA0EYBA4hCAQFQNgECIEIBAyBCAQBQQgEAEDYBAPBCAQAQNgEDWDoBAIg+AQGQPgED4D4BA6A6AQHwNgECqDYBA5A6AQC4TgEBkD4BA8BGAQOoSgEC+DIBAEBOAQL4MgEC+DIBAvgyAQL4MgEC+DIBAvgyAQL4MgEC+DIBAlhGAQL4MgEAIEoBA6hKAQA==",
5
+ "data": "FACEQDAPgECaD4BALhCAQAIRgEBqEYBAGBGAQIoNgEC+EIBA/hCAQEoQgEA6DYBAchCAQDoNgEAMD4BAWA+AQJoPgEAuEIBAHg+AQLINgEDgDYBAGg+AQGQTgECaD4BAJhKAQCATgED0DIBARhOAQPQMgED0DIBA9AyAQPQMgED0DIBA9AyAQPQMgED0DIBAzBGAQPQMgEA+EoBAIBOAQA==",
6
6
  "data_start": 1082469300,
7
7
  "bss_start": 1082392576
8
8
  }