esp32tool 1.3.6 → 1.3.7

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/js/script.js CHANGED
@@ -736,7 +736,7 @@ async function clickConnect() {
736
736
  throw err;
737
737
  }
738
738
 
739
- logMsg("Connected to " + esploader.chipName);
739
+ // logMsg("Connected to " + esploader.chipName);
740
740
  logMsg("MAC Address: " + formatMacAddr(esploader.macAddr()));
741
741
 
742
742
  // Store chip info globally
@@ -934,7 +934,7 @@ async function initConsoleUI() {
934
934
  }
935
935
  consoleCloseHandler = async () => {
936
936
  if (!consoleSwitch.checked) return;
937
- debugMsg("Closing console...");
937
+ logMsg("Closing console");
938
938
  consoleSwitch.checked = false;
939
939
  saveSetting("console", false);
940
940
  await closeConsole();
@@ -1149,8 +1149,8 @@ async function closeConsole() {
1149
1149
  const needsManualReconnect = await espLoaderBeforeConsole.exitConsoleMode();
1150
1150
 
1151
1151
  if (needsManualReconnect) {
1152
- // ESP32-S2: Port has changed, need to select new port
1153
- logMsg("ESP32-S2: Port changed - please select the new port");
1152
+ // Port has changed, need to select new port
1153
+ // logMsg("Port changed - please select the new port");
1154
1154
  toggleUIConnected(false);
1155
1155
  espStub = undefined;
1156
1156
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esp32tool",
3
- "version": "1.3.6",
3
+ "version": "1.3.7",
4
4
  "type": "module",
5
5
  "description": "Flash & Read ESP devices using WebSerial, Electron, and also Android mobile via WebUSB",
6
6
  "main": "electron/main.cjs",
@@ -54,22 +54,22 @@
54
54
  "@rollup/plugin-node-resolve": "^16.0.0",
55
55
  "@rollup/plugin-terser": "^0.4.4",
56
56
  "@rollup/plugin-typescript": "^12.3.0",
57
- "@types/node": "^25.0.10",
57
+ "@types/node": "^25.2.3",
58
58
  "@types/pako": "^2.0.4",
59
59
  "@types/serialport": "^10.2.0",
60
60
  "@types/w3c-web-serial": "^1.0.7",
61
61
  "archiver": "^7.0.1",
62
- "electron": "^40.0.0",
62
+ "electron": "^40.2.1",
63
63
  "electron-squirrel-startup": "^1.0.1",
64
64
  "eslint": "^9.39.2",
65
65
  "eslint-config-prettier": "^10.1.8",
66
- "eslint-plugin-prettier": "^5.5.4",
66
+ "eslint-plugin-prettier": "^5.5.5",
67
67
  "npm-run-all": "^4.1.5",
68
68
  "prettier": "^3.8.1",
69
69
  "rollup": "^4.57.0",
70
70
  "serve": "^14.2.4",
71
71
  "typescript": "^5.7.3",
72
- "typescript-eslint": "^8.54.0"
72
+ "typescript-eslint": "^8.55.0"
73
73
  },
74
74
  "dependencies": {
75
75
  "pako": "^2.1.0",
Binary file
Binary file
package/src/const.ts CHANGED
@@ -93,9 +93,11 @@ export const ESP32_SPI_MISO_DLEN_OFFS = 0x2c;
93
93
  export const ESP32_SPI_W0_OFFS = 0x80;
94
94
  export const ESP32_UART_DATE_REG_ADDR = 0x60000078;
95
95
  export const ESP32_BOOTLOADER_FLASH_OFFSET = 0x1000;
96
+ export const ESP32_APB_CTL_DATE_ADDR = 0x3ff66000 + 0x7c;
96
97
 
97
98
  export const ESP32S2_SPI_REG_BASE = 0x3f402000;
98
99
  export const ESP32S2_BASEFUSEADDR = 0x3f41a000;
100
+ export const ESP32S2_EFUSE_BLOCK1_ADDR = ESP32S2_BASEFUSEADDR + 0x044;
99
101
  export const ESP32S2_MACFUSEADDR = 0x3f41a044;
100
102
  export const ESP32S2_SPI_USR_OFFS = 0x18;
101
103
  export const ESP32S2_SPI_USR1_OFFS = 0x1c;
@@ -125,6 +127,7 @@ export const ESP32S2_UARTDEV_BUF_NO_USB_OTG = 2; // Value of the above indicatin
125
127
 
126
128
  export const ESP32S3_SPI_REG_BASE = 0x60002000;
127
129
  export const ESP32S3_BASEFUSEADDR = 0x60007000;
130
+ export const ESP32S3_EFUSE_BLOCK1_ADDR = ESP32S3_BASEFUSEADDR + 0x044;
128
131
  export const ESP32S3_MACFUSEADDR = 0x60007000 + 0x044;
129
132
  export const ESP32S3_SPI_USR_OFFS = 0x18;
130
133
  export const ESP32S3_SPI_USR1_OFFS = 0x1c;
@@ -155,6 +158,7 @@ export const ESP32S3_UARTDEV_BUF_NO_USB_JTAG_SERIAL = 4; // The above var when U
155
158
 
156
159
  export const ESP32C2_SPI_REG_BASE = 0x60002000;
157
160
  export const ESP32C2_BASEFUSEADDR = 0x60008800;
161
+ export const ESP32C2_EFUSE_BLOCK2_ADDR = ESP32C2_BASEFUSEADDR + 0x040;
158
162
  export const ESP32C2_MACFUSEADDR = ESP32C2_BASEFUSEADDR + 0x040;
159
163
  export const ESP32C2_SPI_USR_OFFS = 0x18;
160
164
  export const ESP32C2_SPI_USR1_OFFS = 0x1c;
@@ -210,6 +214,7 @@ export const ESP32C3_EFUSE_RD_MAC_SPI_SYS_5_REG = 0x60008858;
210
214
 
211
215
  export const ESP32C5_SPI_REG_BASE = 0x60003000;
212
216
  export const ESP32C5_BASEFUSEADDR = 0x600b4800;
217
+ export const ESP32C5_EFUSE_BLOCK1_ADDR = ESP32C5_BASEFUSEADDR + 0x044;
213
218
  export const ESP32C5_MACFUSEADDR = 0x600b4800 + 0x044;
214
219
  export const ESP32C5_SPI_USR_OFFS = 0x18;
215
220
  export const ESP32C5_SPI_USR1_OFFS = 0x1c;
@@ -218,13 +223,19 @@ export const ESP32C5_SPI_MOSI_DLEN_OFFS = 0x24;
218
223
  export const ESP32C5_SPI_MISO_DLEN_OFFS = 0x28;
219
224
  export const ESP32C5_SPI_W0_OFFS = 0x58;
220
225
  export const ESP32C5_UART_DATE_REG_ADDR = 0x6000007c;
226
+ export const ESP32C5_UART_CLKDIV_REG = 0x60000014;
221
227
  export const ESP32C5_BOOTLOADER_FLASH_OFFSET = 0x2000;
228
+ // ESP32-C5 Crystal frequency detection registers
229
+ export const ESP32C5_PCR_SYSCLK_CONF_REG = 0x60096110;
230
+ export const ESP32C5_PCR_SYSCLK_XTAL_FREQ_V = 0x7f << 24;
231
+ export const ESP32C5_PCR_SYSCLK_XTAL_FREQ_S = 24;
222
232
  // ESP32-C5 USB-JTAG/Serial detection
223
233
  export const ESP32C5_UARTDEV_BUF_NO = 0x4085f514; // Variable in ROM .bss which indicates the port in use
224
234
  export const ESP32C5_UARTDEV_BUF_NO_USB_JTAG_SERIAL = 3; // The above var when USB-JTAG/Serial is used
225
235
 
226
236
  export const ESP32C6_SPI_REG_BASE = 0x60003000;
227
237
  export const ESP32C6_BASEFUSEADDR = 0x600b0800;
238
+ export const ESP32C6_EFUSE_BLOCK1_ADDR = ESP32C6_BASEFUSEADDR + 0x044;
228
239
  export const ESP32C6_MACFUSEADDR = 0x600b0800 + 0x044;
229
240
  export const ESP32C6_SPI_USR_OFFS = 0x18;
230
241
  export const ESP32C6_SPI_USR1_OFFS = 0x1c;
@@ -265,6 +276,7 @@ export const ESP32C5_C6_RTC_CNTL_SWD_WPROTECT_REG =
265
276
 
266
277
  export const ESP32C61_SPI_REG_BASE = 0x60003000;
267
278
  export const ESP32C61_BASEFUSEADDR = 0x600b4800;
279
+ export const ESP32C61_EFUSE_BLOCK1_ADDR = ESP32C61_BASEFUSEADDR + 0x044;
268
280
  export const ESP32C61_MACFUSEADDR = 0x600b4800 + 0x044;
269
281
  export const ESP32C61_SPI_USR_OFFS = 0x18;
270
282
  export const ESP32C61_SPI_USR1_OFFS = 0x1c;
@@ -277,6 +289,7 @@ export const ESP32C61_BOOTLOADER_FLASH_OFFSET = 0x0000;
277
289
 
278
290
  export const ESP32H2_SPI_REG_BASE = 0x60003000;
279
291
  export const ESP32H2_BASEFUSEADDR = 0x600b0800;
292
+ export const ESP32H2_EFUSE_BLOCK1_ADDR = ESP32H2_BASEFUSEADDR + 0x044;
280
293
  export const ESP32H2_MACFUSEADDR = 0x600b0800 + 0x044;
281
294
  export const ESP32H2_SPI_USR_OFFS = 0x18;
282
295
  export const ESP32H2_SPI_USR1_OFFS = 0x1c;
@@ -302,6 +315,7 @@ export const ESP32H2_UARTDEV_BUF_NO_USB_JTAG_SERIAL = 3; // The above var when U
302
315
 
303
316
  export const ESP32H4_SPI_REG_BASE = 0x60099000;
304
317
  export const ESP32H4_BASEFUSEADDR = 0x600b1800;
318
+ export const ESP32H4_EFUSE_BLOCK1_ADDR = ESP32H4_BASEFUSEADDR + 0x044;
305
319
  export const ESP32H4_MACFUSEADDR = 0x600b1800 + 0x044;
306
320
  export const ESP32H4_SPI_USR_OFFS = 0x18;
307
321
  export const ESP32H4_SPI_USR1_OFFS = 0x1c;
@@ -324,6 +338,7 @@ export const ESP32H4_RTC_CNTL_SWD_WKEY = 0x50d83aa1; // LP_WDT_SWD_WKEY, same as
324
338
 
325
339
  export const ESP32H21_SPI_REG_BASE = 0x60003000;
326
340
  export const ESP32H21_BASEFUSEADDR = 0x600b4000;
341
+ export const ESP32H21_EFUSE_BLOCK1_ADDR = ESP32H21_BASEFUSEADDR + 0x044;
327
342
  export const ESP32H21_MACFUSEADDR = 0x600b4000 + 0x044;
328
343
  export const ESP32H21_SPI_USR_OFFS = 0x18;
329
344
  export const ESP32H21_SPI_USR1_OFFS = 0x1c;
package/src/esp_loader.ts CHANGED
@@ -58,7 +58,17 @@ import {
58
58
  CHIP_DETECT_MAGIC_REG_ADDR,
59
59
  CHIP_DETECT_MAGIC_VALUES,
60
60
  CHIP_ID_TO_INFO,
61
+ ESP32_BASEFUSEADDR,
62
+ ESP32_APB_CTL_DATE_ADDR,
63
+ ESP32S2_EFUSE_BLOCK1_ADDR,
64
+ ESP32S3_EFUSE_BLOCK1_ADDR,
65
+ ESP32C2_EFUSE_BLOCK2_ADDR,
66
+ ESP32C5_EFUSE_BLOCK1_ADDR,
67
+ ESP32C6_EFUSE_BLOCK1_ADDR,
68
+ ESP32C61_EFUSE_BLOCK1_ADDR,
69
+ ESP32H2_EFUSE_BLOCK1_ADDR,
61
70
  ESP32P4_EFUSE_BLOCK1_ADDR,
71
+ ESP32S31_EFUSE_BLOCK1_ADDR,
62
72
  SlipReadError,
63
73
  ESP32S2_RTC_CNTL_WDTWPROTECT_REG,
64
74
  ESP32S2_RTC_CNTL_WDTCONFIG0_REG,
@@ -82,6 +92,10 @@ import {
82
92
  ESP32C5_C6_RTC_CNTL_WDTCONFIG0_REG,
83
93
  ESP32C5_C6_RTC_CNTL_WDTCONFIG1_REG,
84
94
  ESP32C5_C6_RTC_CNTL_WDT_WKEY,
95
+ ESP32C5_UART_CLKDIV_REG,
96
+ ESP32C5_PCR_SYSCLK_CONF_REG,
97
+ ESP32C5_PCR_SYSCLK_XTAL_FREQ_V,
98
+ ESP32C5_PCR_SYSCLK_XTAL_FREQ_S,
85
99
  ESP32P4_RTC_CNTL_WDTWPROTECT_REG,
86
100
  ESP32P4_RTC_CNTL_WDTCONFIG0_REG,
87
101
  ESP32P4_RTC_CNTL_WDTCONFIG1_REG,
@@ -98,6 +112,7 @@ import {
98
112
  } from "./const";
99
113
  import { getStubCode } from "./stubs";
100
114
  import { hexFormatter, sleep, slipEncode, toHex } from "./util";
115
+ import { FLASH_MANUFACTURERS, FLASH_DEVICES } from "./flash_jedec";
101
116
  import { deflate } from "pako";
102
117
  import { pack, unpack } from "./struct";
103
118
 
@@ -530,7 +545,11 @@ export class ESPLoader extends EventTarget {
530
545
  for (let i = 0; i < 4; i++) {
531
546
  this._efuses[i] = await this.readRegister(AddrMAC + 4 * i);
532
547
  }
533
- this.logger.log(`Chip type ${this.chipName}`);
548
+ const revisionInfo =
549
+ this.chipRevision !== null && this.chipRevision !== undefined
550
+ ? ` (revision ${this.chipRevision})`
551
+ : "";
552
+ this.logger.log(`Connected to ${this.chipName}${revisionInfo}`);
534
553
  this.logger.debug(
535
554
  `Bootloader flash offset: 0x${FlAddr.flashOffs.toString(16)}`,
536
555
  );
@@ -553,21 +572,16 @@ export class ESPLoader extends EventTarget {
553
572
  this.chipName = chipInfo.name;
554
573
  this.chipFamily = chipInfo.family;
555
574
 
556
- // Get chip revision for ESP32-P4 and ESP32-C3
557
- if (this.chipFamily === CHIP_FAMILY_ESP32P4) {
558
- this.chipRevision = await this.getChipRevision();
559
- this.logger.debug(`ESP32-P4 revision: ${this.chipRevision}`);
575
+ this.chipRevision = await this.getChipRevision();
576
+ this.logger.debug(`${this.chipName} revision: ${this.chipRevision}`);
560
577
 
561
- // Set chip variant based on revision
562
- if (this.chipRevision >= 300) {
563
- this.chipVariant = "rev300";
564
- } else {
565
- this.chipVariant = "rev0";
566
- }
567
- this.logger.debug(`ESP32-P4 variant: ${this.chipVariant}`);
568
- } else if (this.chipFamily === CHIP_FAMILY_ESP32C3) {
569
- this.chipRevision = await this.getChipRevision();
570
- this.logger.debug(`ESP32-C3 revision: ${this.chipRevision}`);
578
+ if (
579
+ this.chipFamily === CHIP_FAMILY_ESP32P4 &&
580
+ this.chipRevision >= 300
581
+ ) {
582
+ this.chipVariant = "rev300";
583
+ } else if (this.chipFamily === CHIP_FAMILY_ESP32P4) {
584
+ this.chipVariant = "rev0";
571
585
  }
572
586
 
573
587
  this.logger.debug(
@@ -617,17 +631,12 @@ export class ESPLoader extends EventTarget {
617
631
  this.chipName = chip.name;
618
632
  this.chipFamily = chip.family;
619
633
 
620
- if (this.chipFamily === CHIP_FAMILY_ESP32P4) {
621
- this.chipRevision = await this.getChipRevision();
634
+ this.chipRevision = await this.getChipRevision();
635
+ this.logger.debug(`${this.chipName} revision: ${this.chipRevision}`);
622
636
 
623
- if (this.chipRevision >= 300) {
624
- this.chipVariant = "rev300";
625
- } else {
626
- this.chipVariant = "rev0";
627
- }
637
+ if (this.chipFamily === CHIP_FAMILY_ESP32P4) {
638
+ this.chipVariant = this.chipRevision >= 300 ? "rev300" : "rev0";
628
639
  this.logger.debug(`ESP32-P4 variant: ${this.chipVariant}`);
629
- } else if (this.chipFamily === CHIP_FAMILY_ESP32C3) {
630
- this.chipRevision = await this.getChipRevision();
631
640
  }
632
641
 
633
642
  this.logger.debug(
@@ -635,28 +644,102 @@ export class ESPLoader extends EventTarget {
635
644
  );
636
645
  }
637
646
 
638
- /**
639
- * Get chip revision for ESP32-P4
640
- */
641
647
  async getChipRevision(): Promise<number> {
642
- if (this.chipFamily === CHIP_FAMILY_ESP32P4) {
643
- // Read from EFUSE_BLOCK1 to get chip revision
644
- // Word 2 contains revision info for ESP32-P4
645
- const word2 = await this.readRegister(ESP32P4_EFUSE_BLOCK1_ADDR + 8);
646
-
647
- // Minor revision: bits [3:0]
648
- const minorRev = word2 & 0x0f;
649
-
650
- // Major revision: bits [23] << 2 | bits [5:4]
651
- const majorRev = (((word2 >> 23) & 1) << 2) | ((word2 >> 4) & 0x03);
652
-
653
- // Revision is major * 100 + minor
654
- return majorRev * 100 + minorRev;
655
- } else if (this.chipFamily === CHIP_FAMILY_ESP32C3) {
656
- return await this.getChipRevisionC3();
648
+ let minor = 0;
649
+ let major = 0;
650
+
651
+ switch (this.chipFamily) {
652
+ case CHIP_FAMILY_ESP32: {
653
+ const efuse3 = await this.readRegister(ESP32_BASEFUSEADDR + 4 * 3);
654
+ const efuse5 = await this.readRegister(ESP32_BASEFUSEADDR + 4 * 5);
655
+ minor = (efuse5 >> 24) & 0x3;
656
+ const revBit0 = (efuse3 >> 15) & 0x1;
657
+ const revBit1 = (efuse5 >> 20) & 0x1;
658
+ const apb = await this.readRegister(ESP32_APB_CTL_DATE_ADDR);
659
+ const revBit2 = (apb >> 31) & 0x1;
660
+ const combined = (revBit2 << 2) | (revBit1 << 1) | revBit0;
661
+ major =
662
+ ({ 0: 0, 1: 1, 3: 2, 7: 3 } as Record<number, number>)[combined] ?? 0;
663
+ break;
664
+ }
665
+ case CHIP_FAMILY_ESP32S2: {
666
+ const w3 = await this.readRegister(ESP32S2_EFUSE_BLOCK1_ADDR + 4 * 3);
667
+ const w4 = await this.readRegister(ESP32S2_EFUSE_BLOCK1_ADDR + 4 * 4);
668
+ const hi = (w3 >> 20) & 0x01;
669
+ const lo = (w4 >> 4) & 0x07;
670
+ minor = (hi << 3) + lo;
671
+ major = (w3 >> 18) & 0x03;
672
+ break;
673
+ }
674
+ case CHIP_FAMILY_ESP32S3: {
675
+ const w3 = await this.readRegister(ESP32S3_EFUSE_BLOCK1_ADDR + 4 * 3);
676
+ const w5 = await this.readRegister(ESP32S3_EFUSE_BLOCK1_ADDR + 4 * 5);
677
+ const hi = (w5 >> 23) & 0x01;
678
+ const lo = (w3 >> 18) & 0x07;
679
+ minor = (hi << 3) + lo;
680
+ major = (w5 >> 24) & 0x03;
681
+ break;
682
+ }
683
+ case CHIP_FAMILY_ESP32C2: {
684
+ const w1 = await this.readRegister(ESP32C2_EFUSE_BLOCK2_ADDR + 4 * 1);
685
+ minor = (w1 >> 16) & 0x0f;
686
+ major = (w1 >> 20) & 0x03;
687
+ break;
688
+ }
689
+ case CHIP_FAMILY_ESP32C3: {
690
+ const w3 = await this.readRegister(ESP32C3_EFUSE_RD_MAC_SPI_SYS_3_REG);
691
+ const w5 = await this.readRegister(ESP32C3_EFUSE_RD_MAC_SPI_SYS_5_REG);
692
+ const hi = (w5 >> 23) & 0x01;
693
+ const lo = (w3 >> 18) & 0x07;
694
+ minor = (hi << 3) + lo;
695
+ major = (w5 >> 24) & 0x03;
696
+ break;
697
+ }
698
+ case CHIP_FAMILY_ESP32C5: {
699
+ const w2 = await this.readRegister(ESP32C5_EFUSE_BLOCK1_ADDR + 4 * 2);
700
+ minor = w2 & 0x0f;
701
+ major = (w2 >> 4) & 0x03;
702
+ break;
703
+ }
704
+ case CHIP_FAMILY_ESP32C6: {
705
+ const w3 = await this.readRegister(ESP32C6_EFUSE_BLOCK1_ADDR + 4 * 3);
706
+ minor = (w3 >> 18) & 0x0f;
707
+ major = (w3 >> 22) & 0x03;
708
+ break;
709
+ }
710
+ case CHIP_FAMILY_ESP32C61: {
711
+ const w2 = await this.readRegister(ESP32C61_EFUSE_BLOCK1_ADDR + 4 * 2);
712
+ minor = w2 & 0x0f;
713
+ major = (w2 >> 4) & 0x03;
714
+ break;
715
+ }
716
+ case CHIP_FAMILY_ESP32H2: {
717
+ const w3 = await this.readRegister(ESP32H2_EFUSE_BLOCK1_ADDR + 4 * 3);
718
+ minor = (w3 >> 18) & 0x07;
719
+ major = (w3 >> 21) & 0x03;
720
+ break;
721
+ }
722
+ case CHIP_FAMILY_ESP32H4: {
723
+ break;
724
+ }
725
+ case CHIP_FAMILY_ESP32H21: {
726
+ break;
727
+ }
728
+ case CHIP_FAMILY_ESP32P4: {
729
+ const w2 = await this.readRegister(ESP32P4_EFUSE_BLOCK1_ADDR + 4 * 2);
730
+ minor = w2 & 0x0f;
731
+ major = (((w2 >> 23) & 1) << 2) | ((w2 >> 4) & 0x03);
732
+ break;
733
+ }
734
+ case CHIP_FAMILY_ESP32S31: {
735
+ const w2 = await this.readRegister(ESP32S31_EFUSE_BLOCK1_ADDR + 4 * 2);
736
+ minor = w2 & 0x0f;
737
+ major = (w2 >> 4) & 0x03;
738
+ break;
739
+ }
657
740
  }
658
741
 
659
- return 0;
742
+ return major * 100 + minor;
660
743
  }
661
744
 
662
745
  /**
@@ -1511,7 +1594,7 @@ export class ESPLoader extends EventTarget {
1511
1594
  try {
1512
1595
  await Promise.race([syncPromise, timeoutPromise]);
1513
1596
  // Sync succeeded
1514
- this.logger.log(
1597
+ this.logger.debug(
1515
1598
  `Connected CDC/JTAG successfully with ${strategy.name} reset.`,
1516
1599
  );
1517
1600
  return;
@@ -1562,29 +1645,6 @@ export class ESPLoader extends EventTarget {
1562
1645
  await this.rtcWdtResetChipSpecific();
1563
1646
  }
1564
1647
 
1565
- /**
1566
- * Get chip revision for ESP32-C3
1567
- * Reads from EFUSE registers and calculates revision
1568
- */
1569
- async getChipRevisionC3(): Promise<number> {
1570
- if (this.chipFamily !== CHIP_FAMILY_ESP32C3) {
1571
- return 0;
1572
- }
1573
-
1574
- // Read EFUSE_RD_MAC_SPI_SYS_3_REG (bits [20:18] = lower 3 bits of revision)
1575
- const word3 = await this.readRegister(ESP32C3_EFUSE_RD_MAC_SPI_SYS_3_REG);
1576
- const low = (word3 >> 18) & 0x07;
1577
-
1578
- // Read EFUSE_RD_MAC_SPI_SYS_5_REG (bits [25:23] = upper 3 bits of revision)
1579
- const word5 = await this.readRegister(ESP32C3_EFUSE_RD_MAC_SPI_SYS_5_REG);
1580
- const hi = (word5 >> 23) & 0x07;
1581
-
1582
- // Combine: upper 3 bits from word5, lower 3 bits from word3
1583
- const revision = (hi << 3) | low;
1584
-
1585
- return revision;
1586
- }
1587
-
1588
1648
  /**
1589
1649
  * RTC watchdog timer reset for ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C5, ESP32-C6, and ESP32-P4
1590
1650
  * Uses specific registers for each chip family
@@ -2180,16 +2240,38 @@ export class ESPLoader extends EventTarget {
2180
2240
  return state;
2181
2241
  }
2182
2242
 
2243
+ async getC5CrystalFreqRomExpect(): Promise<number> {
2244
+ const reg = await this.readRegister(ESP32C5_PCR_SYSCLK_CONF_REG);
2245
+ return (
2246
+ (reg & ESP32C5_PCR_SYSCLK_XTAL_FREQ_V) >>> ESP32C5_PCR_SYSCLK_XTAL_FREQ_S
2247
+ );
2248
+ }
2249
+
2250
+ async getC5CrystalFreqDetected(): Promise<number> {
2251
+ const UART_CLKDIV_MASK = 0xfffff;
2252
+ const uartDiv =
2253
+ (await this.readRegister(ESP32C5_UART_CLKDIV_REG)) & UART_CLKDIV_MASK;
2254
+ const estXtal = (ESP_ROM_BAUD * uartDiv) / 1e6;
2255
+ if (estXtal > 45) return 48;
2256
+ if (estXtal > 33) return 40;
2257
+ return 26;
2258
+ }
2259
+
2183
2260
  async setBaudrate(baud: number) {
2184
- try {
2185
- // Send ESP_ROM_BAUD(115200) as the old one if running STUB otherwise 0
2186
- const buffer = pack("<II", baud, this.IS_STUB ? ESP_ROM_BAUD : 0);
2187
- await this.checkCommand(ESP_CHANGE_BAUDRATE, buffer);
2188
- } catch (e) {
2189
- this.logger.error(`Baudrate change error: ${e}`);
2190
- throw new Error(
2191
- `Unable to change the baud rate to ${baud}: No response from set baud rate command.`,
2192
- );
2261
+ const chipFamily = this._parent ? this._parent.chipFamily : this.chipFamily;
2262
+
2263
+ if (!this.IS_STUB && chipFamily === CHIP_FAMILY_ESP32C5) {
2264
+ await this.setBaudrateC5Rom(baud);
2265
+ } else {
2266
+ try {
2267
+ const buffer = pack("<II", baud, this.IS_STUB ? ESP_ROM_BAUD : 0);
2268
+ await this.checkCommand(ESP_CHANGE_BAUDRATE, buffer);
2269
+ } catch (e) {
2270
+ this.logger.error(`Baudrate change error: ${e}`);
2271
+ throw new Error(
2272
+ `Unable to change the baud rate to ${baud}: No response from set baud rate command.`,
2273
+ );
2274
+ }
2193
2275
  }
2194
2276
 
2195
2277
  if (this._parent) {
@@ -2221,7 +2303,34 @@ export class ESPLoader extends EventTarget {
2221
2303
  );
2222
2304
  }
2223
2305
 
2224
- this.logger.log(`Changed baud rate to ${baud}`);
2306
+ this.logger.debug(`Changed baud rate to ${baud}`);
2307
+ }
2308
+
2309
+ private async setBaudrateC5Rom(baud: number) {
2310
+ const crystalFreqRomExpect = await this.getC5CrystalFreqRomExpect();
2311
+ const crystalFreqDetect = await this.getC5CrystalFreqDetected();
2312
+ this.logger.log(
2313
+ `ROM expects crystal freq: ${crystalFreqRomExpect} MHz, detected ${crystalFreqDetect} MHz.`,
2314
+ );
2315
+
2316
+ let baudRate = baud;
2317
+ if (crystalFreqDetect === 48 && crystalFreqRomExpect === 40) {
2318
+ baudRate = Math.trunc((baud * 40) / 48);
2319
+ } else if (crystalFreqDetect === 40 && crystalFreqRomExpect === 48) {
2320
+ baudRate = Math.trunc((baud * 48) / 40);
2321
+ }
2322
+
2323
+ this.logger.log(`Changing baud rate to ${baudRate}...`);
2324
+ try {
2325
+ const buffer = pack("<II", baudRate, 0);
2326
+ await this.checkCommand(ESP_CHANGE_BAUDRATE, buffer);
2327
+ } catch (e) {
2328
+ this.logger.error(`Baudrate change error: ${e}`);
2329
+ throw new Error(
2330
+ `Unable to change the baud rate to ${baudRate}: No response from set baud rate command.`,
2331
+ );
2332
+ }
2333
+ this.logger.log("Changed.");
2225
2334
  }
2226
2335
 
2227
2336
  async reconfigurePort(baud: number) {
@@ -2823,18 +2932,23 @@ export class ESPLoader extends EventTarget {
2823
2932
  return status;
2824
2933
  }
2825
2934
  async detectFlashSize() {
2826
- this.logger.log("Detecting Flash Size");
2935
+ this.logger.debug("Detecting Flash Size");
2827
2936
 
2828
2937
  const flashId = await this.flashId();
2829
2938
  const manufacturer = flashId & 0xff;
2830
2939
  const flashIdLowbyte = (flashId >> 16) & 0xff;
2940
+ const deviceTypeByte = (flashId >> 8) & 0xff;
2941
+ const deviceId = (deviceTypeByte << 8) | flashIdLowbyte;
2942
+ const jedecId = (manufacturer << 16) | deviceId;
2943
+
2944
+ const mfrName = FLASH_MANUFACTURERS[manufacturer];
2945
+ const deviceName = FLASH_DEVICES[jedecId];
2831
2946
 
2832
- this.logger.log(`FlashId: ${toHex(flashId)}`);
2833
- this.logger.log(`Flash Manufacturer: ${manufacturer.toString(16)}`);
2834
2947
  this.logger.log(
2835
- `Flash Device: ${((flashId >> 8) & 0xff).toString(
2836
- 16,
2837
- )}${flashIdLowbyte.toString(16)}`,
2948
+ `Flash Manufacturer: ${mfrName || "Unknown"} (0x${manufacturer.toString(16)})`,
2949
+ );
2950
+ this.logger.log(
2951
+ `Flash Device: ${deviceName || `Unknown (0x${deviceId.toString(16)})`}`,
2838
2952
  );
2839
2953
 
2840
2954
  this.flashSize = DETECTED_FLASH_SIZES[flashIdLowbyte];
@@ -2925,7 +3039,7 @@ export class ESPLoader extends EventTarget {
2925
3039
  const ramBlock = USB_RAM_BLOCK;
2926
3040
 
2927
3041
  // Upload
2928
- this.logger.log("Uploading stub...");
3042
+ this.logger.debug("Uploading stub...");
2929
3043
  for (const field of ["text", "data"] as const) {
2930
3044
  const fieldData = stub[field];
2931
3045
  const offset = stub[`${field}_start` as "text_start" | "data_start"];
@@ -2949,7 +3063,7 @@ export class ESPLoader extends EventTarget {
2949
3063
  if (pChar != "OHAI") {
2950
3064
  throw new Error("Failed to start stub. Unexpected response: " + pChar);
2951
3065
  }
2952
- this.logger.log("Stub is now running...");
3066
+ this.logger.debug("Stub is now running...");
2953
3067
  const espStubLoader = new EspStubLoader(this.port, this.logger, this);
2954
3068
 
2955
3069
  // Try to autodetect the flash size.
@@ -3479,10 +3593,9 @@ export class ESPLoader extends EventTarget {
3479
3593
  // Port will change - release reader/writer and let the port become invalid
3480
3594
  await this.releaseReaderWriter();
3481
3595
 
3482
- this.logger.log(
3596
+ this.logger.debug(
3483
3597
  `${this.chipName} USB-OTG: Port will change after WDT reset`,
3484
3598
  );
3485
- this.logger.log("Please select the new port for console mode");
3486
3599
 
3487
3600
  // Dispatch event to signal port change
3488
3601
  this.dispatchEvent(
@@ -3760,7 +3873,7 @@ export class ESPLoader extends EventTarget {
3760
3873
  // Detect chip type
3761
3874
  await this.detectChip();
3762
3875
 
3763
- this.logger.log(`Reconnected to bootloader: ${this.chipName}`);
3876
+ this.logger.debug(`Reconnected to bootloader: ${this.chipName}`);
3764
3877
  } catch (err) {
3765
3878
  // Ensure flag is reset on error
3766
3879
  this._isReconfiguring = false;
@@ -3803,7 +3916,7 @@ export class ESPLoader extends EventTarget {
3803
3916
 
3804
3917
  if (isUsbOtgChip && isUsbJtagOrOtg) {
3805
3918
  // USB-OTG devices: Need to reset to bootloader, which will cause port change
3806
- this.logger.log(`${this.chipName} USB: Resetting to bootloader mode`);
3919
+ this.logger.debug(`${this.chipName} USB: Resetting to bootloader mode`);
3807
3920
 
3808
3921
  // Perform hardware reset to bootloader (GPIO0=LOW)
3809
3922
  // This will cause the port to change from CDC (firmware) to JTAG (bootloader)
@@ -3821,7 +3934,7 @@ export class ESPLoader extends EventTarget {
3821
3934
  // Wait for reset to complete and port to change
3822
3935
  await sleep(500);
3823
3936
 
3824
- this.logger.log(
3937
+ this.logger.debug(
3825
3938
  `${this.chipName}: Port changed. Please select the bootloader port.`,
3826
3939
  );
3827
3940