tasmota-webserial-esptool 6.4.1 → 6.5.1

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.
@@ -0,0 +1,232 @@
1
+ # Implementation Summary: ESP32-P4 Chip Variant Support
2
+
3
+ ## ✅ Erfolgreich implementiert
4
+
5
+ ### Ziel
6
+ Unterscheidung zwischen ESP32-P4 Revision 0 und Revision 300, damit esp-web-tools separate Manifeste für beide Varianten bereitstellen kann.
7
+
8
+ ## Implementierte Änderungen
9
+
10
+ ### 1. WebSerial_ESPTool
11
+
12
+ **Datei: `src/esp_loader.ts`**
13
+
14
+ #### Neues Feld:
15
+ ```typescript
16
+ chipVariant: string | null = null;
17
+ ```
18
+
19
+ #### Erweiterte Chip-Erkennung:
20
+ - Bei IMAGE_CHIP_ID Erkennung (Rev. 300+):
21
+ - Revision wird aus eFuses gelesen
22
+ - `chipVariant` wird auf `"rev300"` oder `"rev0"` gesetzt
23
+
24
+ - Bei Magic Value Erkennung (Rev. < 300):
25
+ - Revision wird aus eFuses gelesen
26
+ - `chipVariant` wird auf `"rev300"` oder `"rev0"` gesetzt
27
+
28
+ #### Revision-Berechnung:
29
+ ```typescript
30
+ // Aus EFUSE_BLOCK1 (Word 2):
31
+ const minorRev = word2 & 0x0f;
32
+ const majorRev = (((word2 >> 23) & 1) << 2) | ((word2 >> 4) & 0x03);
33
+ const revision = majorRev * 100 + minorRev;
34
+
35
+ // Variante setzen:
36
+ if (revision >= 300) {
37
+ chipVariant = "rev300";
38
+ } else {
39
+ chipVariant = "rev0";
40
+ }
41
+ ```
42
+
43
+ ### 2. esp-web-tools
44
+
45
+ **Datei: `src/const.ts`**
46
+
47
+ #### Erweitertes Build Interface:
48
+ ```typescript
49
+ export interface Build {
50
+ chipFamily: "ESP32-P4" | ...;
51
+ chipVariant?: string; // NEU - optional
52
+ parts: { path: string; offset: number; }[];
53
+ }
54
+ ```
55
+
56
+ #### Erweitertes FlashState Interface:
57
+ ```typescript
58
+ export interface BaseFlashState {
59
+ chipFamily?: Build["chipFamily"] | "Unknown Chip";
60
+ chipVariant?: string | null; // NEU
61
+ // ...
62
+ }
63
+ ```
64
+
65
+ **Datei: `src/flash.ts`**
66
+
67
+ #### Erweiterte Build-Auswahl:
68
+ ```typescript
69
+ build = manifest.builds.find((b) => {
70
+ // Match chipFamily
71
+ if (b.chipFamily !== chipFamily) {
72
+ return false;
73
+ }
74
+ // Wenn Build chipVariant spezifiziert, muss es matchen
75
+ if (b.chipVariant !== undefined) {
76
+ return b.chipVariant === chipVariant;
77
+ }
78
+ // Ohne chipVariant: Match für alle Varianten
79
+ return true;
80
+ });
81
+ ```
82
+
83
+ #### Verbesserte Meldungen:
84
+ - Initialisierung zeigt chipVariant an
85
+ - Fehlermeldungen enthalten chipVariant-Info
86
+
87
+ **Datei: `README.md`**
88
+ - Dokumentation für Chip Variant Support hinzugefügt
89
+ - Beispiel für P4-Varianten
90
+
91
+ ## Verwendung
92
+
93
+ ### Manifest mit spezifischen Builds:
94
+ ```json
95
+ {
96
+ "name": "My Firmware",
97
+ "version": "1.0.0",
98
+ "builds": [
99
+ {
100
+ "chipFamily": "ESP32-P4",
101
+ "chipVariant": "rev0",
102
+ "parts": [
103
+ { "path": "firmware_p4_old.bin", "offset": 0 }
104
+ ]
105
+ },
106
+ {
107
+ "chipFamily": "ESP32-P4",
108
+ "chipVariant": "rev300",
109
+ "parts": [
110
+ { "path": "firmware_p4_new.bin", "offset": 0 }
111
+ ]
112
+ }
113
+ ]
114
+ }
115
+ ```
116
+
117
+ ### Manifest mit Fallback:
118
+ ```json
119
+ {
120
+ "builds": [
121
+ {
122
+ "chipFamily": "ESP32-P4",
123
+ "chipVariant": "rev300",
124
+ "parts": [...]
125
+ },
126
+ {
127
+ "chipFamily": "ESP32-P4",
128
+ "parts": [...] // Fallback für rev0
129
+ }
130
+ ]
131
+ }
132
+ ```
133
+
134
+ ## Build-Status
135
+
136
+ ✅ **WebSerial_ESPTool**: Kompiliert erfolgreich
137
+ ✅ **esp-web-tools**: Kompiliert erfolgreich
138
+ ✅ **TypeScript**: Keine Fehler
139
+ ✅ **Abwärtskompatibilität**: Vollständig gewährleistet
140
+
141
+ ## Nächste Schritte
142
+
143
+ ### Für Deployment:
144
+
145
+ 1. **WebSerial_ESPTool**:
146
+ ```bash
147
+ cd WebSerial_ESPTool
148
+ # Version in package.json erhöhen (z.B. 6.5.0)
149
+ npm run prepublishOnly
150
+ npm publish
151
+ ```
152
+
153
+ 2. **esp-web-tools**:
154
+ ```bash
155
+ cd esp-web-tools
156
+ # package.json aktualisieren: "tasmota-webserial-esptool": "^6.5.0"
157
+ npm install
158
+ # Version in package.json erhöhen (z.B. 8.2.0)
159
+ npm run prepublishOnly
160
+ npm publish
161
+ ```
162
+
163
+ ### Für Testing:
164
+
165
+ 1. **Hardware-Tests**:
166
+ - Test mit ESP32-P4 Rev. 0 Hardware
167
+ - Test mit ESP32-P4 Rev. 300 Hardware
168
+ - Verifizierung der korrekten Varianten-Erkennung
169
+
170
+ 2. **Manifest-Tests**:
171
+ - Test mit chipVariant-spezifischen Builds
172
+ - Test mit Fallback-Builds
173
+ - Test mit gemischten Manifesten
174
+
175
+ ## Dokumentation
176
+
177
+ Erstellt:
178
+ - ✅ `CHIP_VARIANT_SUPPORT.md` - Vollständige technische Dokumentation
179
+ - ✅ `CHANGELOG_CHIP_VARIANT.md` - Detaillierte Änderungsliste
180
+ - ✅ `IMPLEMENTATION_SUMMARY.md` - Diese Datei
181
+ - ✅ `manifest-example-p4-variants.json` - Beispiel-Manifest
182
+ - ✅ README.md Update in esp-web-tools
183
+
184
+ ## Technische Details
185
+
186
+ ### Chip-Erkennung Flow:
187
+
188
+ ```
189
+ 1. ESPLoader.initialize()
190
+
191
+ 2. detectChip()
192
+
193
+ 3a. Versuche GET_SECURITY_INFO (IMAGE_CHIP_ID)
194
+ → Erfolg: chipId = 18 (ESP32-P4)
195
+ → getChipRevision() → chipVariant setzen
196
+
197
+ 3b. Fallback: Magic Value Detection
198
+ → chipMagicValue = 0x0, 0x7039ad9, oder 0x0addbad0
199
+ → getChipRevision() → chipVariant setzen
200
+
201
+ 4. chipVariant ist nun "rev0" oder "rev300"
202
+ ```
203
+
204
+ ### Manifest Matching Flow:
205
+
206
+ ```
207
+ 1. Chip erkannt: chipFamily = "ESP32-P4", chipVariant = "rev300"
208
+
209
+ 2. Durchsuche manifest.builds[]
210
+
211
+ 3. Für jeden Build:
212
+ - chipFamily muss matchen
213
+ - Wenn Build.chipVariant definiert: muss exakt matchen
214
+ - Wenn Build.chipVariant undefined: immer Match
215
+
216
+ 4. Ersten passenden Build verwenden
217
+ ```
218
+
219
+ ## Vorteile
220
+
221
+ 1. **Flexibilität**: Manifeste können spezifische oder generische Builds anbieten
222
+ 2. **Abwärtskompatibilität**: Bestehende Manifeste funktionieren unverändert
223
+ 3. **Zukunftssicher**: Erweiterbar für weitere Chip-Varianten
224
+ 4. **Transparent**: Variante wird dem Benutzer angezeigt
225
+ 5. **Robust**: Fallback-Mechanismus verhindert Fehler
226
+
227
+ ## Getestet
228
+
229
+ - ✅ TypeScript Kompilierung
230
+ - ✅ Build-Prozess
231
+ - ✅ Keine Diagnostics-Fehler
232
+ - ⏳ Hardware-Tests (ausstehend)
@@ -0,0 +1,145 @@
1
+ # GET_SECURITY_INFO Erklärung
2
+
3
+ ## Warum schlägt GET_SECURITY_INFO manchmal fehl?
4
+
5
+ Die Debug-Meldung:
6
+ ```
7
+ GET_SECURITY_INFO failed, using magic value detection: Error: Invalid security info response length: 0
8
+ ```
9
+
10
+ ist **normal und erwartet** für viele ESP-Chips.
11
+
12
+ ## Chip-Erkennungsstrategie
13
+
14
+ Der Code verwendet einen robusten zweistufigen Ansatz:
15
+
16
+ ### 1. Primär: GET_SECURITY_INFO (IMAGE_CHIP_ID)
17
+
18
+ **Unterstützt von:**
19
+ - ESP32-C3 (neuere ROM-Versionen)
20
+ - ESP32-S3
21
+ - ESP32-C6
22
+ - ESP32-C61
23
+ - ESP32-H2
24
+ - ESP32-C5
25
+ - ESP32-P4 Rev. 300+
26
+
27
+ **Vorteile:**
28
+ - Direkte Chip-ID
29
+ - Zusätzliche Sicherheitsinformationen
30
+ - Zukunftssicher
31
+
32
+ **Problem:**
33
+ - Nicht von allen Chips/ROM-Versionen unterstützt
34
+ - Manche Chips geben leere Antwort zurück (length: 0)
35
+
36
+ ### 2. Fallback: Magic Value Detection
37
+
38
+ **Unterstützt von:**
39
+ - ESP8266
40
+ - ESP32
41
+ - ESP32-S2
42
+ - ESP32-C3 (ältere ROM-Versionen)
43
+ - ESP32-P4 Rev. < 300
44
+ - Alle anderen Chips als Fallback
45
+
46
+ **Vorteile:**
47
+ - Funktioniert auf allen ESP-Chips
48
+ - Sehr zuverlässig
49
+ - Seit Jahren bewährt
50
+
51
+ **Funktionsweise:**
52
+ - Liest Magic-Wert aus Register `0x40001000`
53
+ - Vergleicht mit bekannten Magic-Werten
54
+ - Identifiziert Chip-Familie
55
+
56
+ ## Beispiel-Log (ESP32-C3)
57
+
58
+ ```
59
+ Try hard reset.
60
+ [debug] GET_SECURITY_INFO failed, using magic value detection: Error: GET_SECURITY_INFO not supported or returned empty response
61
+ [debug] Detected chip via magic value: 0x1B31506F (ESP32-C3)
62
+ Chip type ESP32-C3
63
+ ```
64
+
65
+ **Interpretation:**
66
+ 1. ✅ GET_SECURITY_INFO wurde versucht (wie es sein soll)
67
+ 2. ✅ Leere Antwort erkannt (dieser ESP32-C3 unterstützt es nicht)
68
+ 3. ✅ Fallback auf Magic Value Detection (funktioniert perfekt)
69
+ 4. ✅ Chip korrekt als ESP32-C3 erkannt
70
+
71
+ ## Beispiel-Log (ESP32-P4 Rev. 300+)
72
+
73
+ ```
74
+ Try hard reset.
75
+ [debug] Detected chip via IMAGE_CHIP_ID: 18 (ESP32-P4)
76
+ [debug] ESP32-P4 revision: 300
77
+ [debug] ESP32-P4 variant: rev300
78
+ Chip type ESP32-P4
79
+ ```
80
+
81
+ **Interpretation:**
82
+ 1. ✅ GET_SECURITY_INFO funktioniert (neuere ROM-Version)
83
+ 2. ✅ Chip-ID 18 = ESP32-P4
84
+ 3. ✅ Revision aus eFuses gelesen
85
+ 4. ✅ Variante korrekt gesetzt
86
+
87
+ ## Warum ist das so implementiert?
88
+
89
+ ### Historischer Kontext
90
+
91
+ 1. **Ältere Chips (ESP8266, ESP32, ESP32-S2)**:
92
+ - Haben GET_SECURITY_INFO nicht
93
+ - Verwenden nur Magic Value Detection
94
+
95
+ 2. **Neuere Chips (ESP32-C3, ESP32-S3, etc.)**:
96
+ - Sollten GET_SECURITY_INFO unterstützen
97
+ - Aber: ROM-Versionen variieren
98
+ - Manche frühe Produktionen haben es nicht
99
+
100
+ 3. **Robustheit**:
101
+ - Fallback stellt sicher, dass ALLE Chips erkannt werden
102
+ - Keine Abhängigkeit von ROM-Version
103
+ - Funktioniert auch bei zukünftigen Chips
104
+
105
+ ## Ist das ein Problem?
106
+
107
+ **Nein!** Das ist das erwartete Verhalten:
108
+
109
+ ✅ **Korrekt erkannt**: Der Chip wird korrekt identifiziert
110
+ ✅ **Funktioniert**: Flashing funktioniert einwandfrei
111
+ ✅ **Robust**: Fallback-Mechanismus ist bewährt
112
+ ✅ **Debug-Info**: Die Meldung ist nur zur Information
113
+
114
+ ## Wann wäre es ein Problem?
115
+
116
+ ❌ **Nur wenn:**
117
+ - Chip wird NICHT erkannt
118
+ - Falscher Chip-Typ wird erkannt
119
+ - Flashing schlägt fehl
120
+
121
+ In Ihrem Log:
122
+ ```
123
+ Detected chip via magic value: 0x1B31506F (ESP32-C3)
124
+ Chip type ESP32-C3
125
+ Connected to ESP32-C3
126
+ MAC Address: 34:B7:DA:F7:8F:00
127
+ ```
128
+
129
+ → Alles funktioniert perfekt! ✅
130
+
131
+ ## Zusammenfassung
132
+
133
+ Die Meldung "GET_SECURITY_INFO failed" ist:
134
+ - ✅ Normal
135
+ - ✅ Erwartet für viele Chips
136
+ - ✅ Kein Fehler
137
+ - ✅ Teil des robusten Erkennungsmechanismus
138
+
139
+ Der Fallback auf Magic Value Detection ist:
140
+ - ✅ Bewährt
141
+ - ✅ Zuverlässig
142
+ - ✅ Funktioniert auf allen ESP-Chips
143
+ - ✅ Genau so designed
144
+
145
+ **Fazit:** Alles funktioniert wie vorgesehen! 🎉
package/css/style.css CHANGED
@@ -195,6 +195,7 @@ div.clear {
195
195
  display: inline-block;
196
196
  position: relative;
197
197
  width: 50px;
198
+ margin-right: 25px;
198
199
  -webkit-user-select: none;
199
200
  -moz-user-select: none;
200
201
  -ms-user-select: none;
package/dist/const.d.ts CHANGED
@@ -146,6 +146,7 @@ export declare const ESP32H2_UART_DATE_REG_ADDR = 1610612860;
146
146
  export declare const ESP32H2_BOOTLOADER_FLASH_OFFSET = 0;
147
147
  export declare const ESP32P4_SPI_REG_BASE = 1342754816;
148
148
  export declare const ESP32P4_BASEFUSEADDR = 1343410176;
149
+ export declare const ESP32P4_EFUSE_BLOCK1_ADDR: number;
149
150
  export declare const ESP32P4_MACFUSEADDR: number;
150
151
  export declare const ESP32P4_SPI_USR_OFFS = 24;
151
152
  export declare const ESP32P4_SPI_USR1_OFFS = 28;
@@ -182,6 +183,13 @@ export declare const CHIP_FAMILY_ESP32C61 = 207969;
182
183
  export declare const CHIP_FAMILY_ESP32H2 = 12914;
183
184
  export declare const CHIP_FAMILY_ESP32P4 = 12928;
184
185
  export type ChipFamily = typeof CHIP_FAMILY_ESP8266 | typeof CHIP_FAMILY_ESP32 | typeof CHIP_FAMILY_ESP32S2 | typeof CHIP_FAMILY_ESP32S3 | typeof CHIP_FAMILY_ESP32C2 | typeof CHIP_FAMILY_ESP32C3 | typeof CHIP_FAMILY_ESP32C5 | typeof CHIP_FAMILY_ESP32C6 | typeof CHIP_FAMILY_ESP32C61 | typeof CHIP_FAMILY_ESP32H2 | typeof CHIP_FAMILY_ESP32P4;
186
+ interface ChipIdInfo {
187
+ name: string;
188
+ family: ChipFamily;
189
+ }
190
+ export declare const CHIP_ID_TO_INFO: {
191
+ [chipId: number]: ChipIdInfo;
192
+ };
185
193
  interface ChipInfo {
186
194
  [magicValue: number]: {
187
195
  name: string;
@@ -204,6 +212,7 @@ export declare const ESP_SPI_SET_PARAMS = 11;
204
212
  export declare const ESP_SPI_ATTACH = 13;
205
213
  export declare const ESP_CHANGE_BAUDRATE = 15;
206
214
  export declare const ESP_SPI_FLASH_MD5 = 19;
215
+ export declare const ESP_GET_SECURITY_INFO = 20;
207
216
  export declare const ESP_CHECKSUM_MAGIC = 239;
208
217
  export declare const ESP_FLASH_DEFL_BEGIN = 16;
209
218
  export declare const ESP_FLASH_DEFL_DATA = 17;
package/dist/const.js CHANGED
@@ -151,6 +151,7 @@ export const ESP32H2_UART_DATE_REG_ADDR = 0x6000007c;
151
151
  export const ESP32H2_BOOTLOADER_FLASH_OFFSET = 0x0;
152
152
  export const ESP32P4_SPI_REG_BASE = 0x5008d000;
153
153
  export const ESP32P4_BASEFUSEADDR = 0x5012d000;
154
+ export const ESP32P4_EFUSE_BLOCK1_ADDR = ESP32P4_BASEFUSEADDR + 0x044;
154
155
  export const ESP32P4_MACFUSEADDR = 0x5012d000 + 0x044;
155
156
  export const ESP32P4_SPI_USR_OFFS = 0x18;
156
157
  export const ESP32P4_SPI_USR1_OFFS = 0x1c;
@@ -162,6 +163,7 @@ export const ESP32P4_UART_DATE_REG_ADDR = 0x500ca000 + 0x8c;
162
163
  export const ESP32P4_BOOTLOADER_FLASH_OFFSET = 0x2000;
163
164
  export const SYNC_PACKET = toByteArray("\x07\x07\x12 UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU");
164
165
  export const CHIP_DETECT_MAGIC_REG_ADDR = 0x40001000;
166
+ // Image Chip IDs (used by ESP32-C3 and later for chip detection)
165
167
  // These values for the families are made up; nothing that esptool uses.
166
168
  export const CHIP_FAMILY_ESP8266 = 0x8266;
167
169
  export const CHIP_FAMILY_ESP32 = 0x32;
@@ -174,6 +176,16 @@ export const CHIP_FAMILY_ESP32C6 = 0x32c6;
174
176
  export const CHIP_FAMILY_ESP32C61 = 0x32c61;
175
177
  export const CHIP_FAMILY_ESP32H2 = 0x3272;
176
178
  export const CHIP_FAMILY_ESP32P4 = 0x3280;
179
+ export const CHIP_ID_TO_INFO = {
180
+ 5: { name: "ESP32-C3", family: CHIP_FAMILY_ESP32C3 },
181
+ 9: { name: "ESP32-S3", family: CHIP_FAMILY_ESP32S3 },
182
+ 12: { name: "ESP32-C2", family: CHIP_FAMILY_ESP32C2 },
183
+ 13: { name: "ESP32-C6", family: CHIP_FAMILY_ESP32C6 },
184
+ 16: { name: "ESP32-H2", family: CHIP_FAMILY_ESP32H2 },
185
+ 17: { name: "ESP32-C5", family: CHIP_FAMILY_ESP32C5 },
186
+ 18: { name: "ESP32-P4", family: CHIP_FAMILY_ESP32P4 },
187
+ 20: { name: "ESP32-C61", family: CHIP_FAMILY_ESP32C61 },
188
+ };
177
189
  export const CHIP_DETECT_MAGIC_VALUES = {
178
190
  0xfff0c101: { name: "ESP8266", family: CHIP_FAMILY_ESP8266 },
179
191
  0x00f01d83: { name: "ESP32", family: CHIP_FAMILY_ESP32 },
@@ -197,6 +209,8 @@ export const CHIP_DETECT_MAGIC_VALUES = {
197
209
  0x7211606f: { name: "ESP32-C61", family: CHIP_FAMILY_ESP32C61 },
198
210
  0x97e30068: { name: "ESP32-H2", family: CHIP_FAMILY_ESP32H2 },
199
211
  0xd7b73e80: { name: "ESP32-H2", family: CHIP_FAMILY_ESP32H2 },
212
+ // ESP32-P4 old revisions (< Rev. 300) - use magic value detection
213
+ // Rev. 300+ uses IMAGE_CHIP_ID detection instead
200
214
  0x0: { name: "ESP32-P4", family: CHIP_FAMILY_ESP32P4 },
201
215
  0x7039ad9: { name: "ESP32-P4", family: CHIP_FAMILY_ESP32P4 },
202
216
  0x0addbad0: { name: "ESP32-P4", family: CHIP_FAMILY_ESP32P4 },
@@ -217,6 +231,7 @@ export const ESP_SPI_SET_PARAMS = 0x0b;
217
231
  export const ESP_SPI_ATTACH = 0x0d;
218
232
  export const ESP_CHANGE_BAUDRATE = 0x0f;
219
233
  export const ESP_SPI_FLASH_MD5 = 0x13;
234
+ export const ESP_GET_SECURITY_INFO = 0x14;
220
235
  export const ESP_CHECKSUM_MAGIC = 0xef;
221
236
  export const ESP_FLASH_DEFL_BEGIN = 0x10;
222
237
  export const ESP_FLASH_DEFL_DATA = 0x11;
@@ -5,6 +5,8 @@ export declare class ESPLoader extends EventTarget {
5
5
  private _parent?;
6
6
  chipFamily: ChipFamily;
7
7
  chipName: string | null;
8
+ chipRevision: number | null;
9
+ chipVariant: string | null;
8
10
  _efuses: any[];
9
11
  _flashsize: number;
10
12
  debug: boolean;
@@ -16,6 +18,24 @@ export declare class ESPLoader extends EventTarget {
16
18
  constructor(port: SerialPort, logger: Logger, _parent?: ESPLoader | undefined);
17
19
  private get _inputBuffer();
18
20
  initialize(): Promise<void>;
21
+ /**
22
+ * Detect chip type using GET_SECURITY_INFO (for newer chips) or magic value (for older chips)
23
+ */
24
+ detectChip(): Promise<void>;
25
+ /**
26
+ * Get chip revision for ESP32-P4
27
+ */
28
+ getChipRevision(): Promise<number>;
29
+ /**
30
+ * Get security info including chip ID (ESP32-C3 and later)
31
+ */
32
+ getSecurityInfo(): Promise<{
33
+ flags: number;
34
+ flashCryptCnt: number;
35
+ keyPurposes: number[];
36
+ chipId: number;
37
+ apiVersion: number;
38
+ }>;
19
39
  /**
20
40
  * @name readLoop
21
41
  * Reads data from the input stream and places it in the inputBuffer
@@ -1,4 +1,5 @@
1
- import { CHIP_FAMILY_ESP32, CHIP_FAMILY_ESP32S2, CHIP_FAMILY_ESP32S3, CHIP_FAMILY_ESP32C2, CHIP_FAMILY_ESP32C3, CHIP_FAMILY_ESP32C5, CHIP_FAMILY_ESP32C6, CHIP_FAMILY_ESP32C61, CHIP_FAMILY_ESP32H2, CHIP_FAMILY_ESP32P4, CHIP_FAMILY_ESP8266, MAX_TIMEOUT, DEFAULT_TIMEOUT, ERASE_REGION_TIMEOUT_PER_MB, ESP_CHANGE_BAUDRATE, ESP_CHECKSUM_MAGIC, ESP_FLASH_BEGIN, ESP_FLASH_DATA, ESP_FLASH_END, ESP_MEM_BEGIN, ESP_MEM_DATA, ESP_MEM_END, ESP_READ_REG, ESP_WRITE_REG, ESP_SPI_ATTACH, ESP_SYNC, FLASH_SECTOR_SIZE, FLASH_WRITE_SIZE, STUB_FLASH_WRITE_SIZE, MEM_END_ROM_TIMEOUT, ROM_INVALID_RECV_MSG, SYNC_PACKET, SYNC_TIMEOUT, USB_RAM_BLOCK, ESP_ERASE_FLASH, CHIP_ERASE_TIMEOUT, timeoutPerMb, ESP_ROM_BAUD, USB_JTAG_SERIAL_PID, ESP_FLASH_DEFL_BEGIN, ESP_FLASH_DEFL_DATA, ESP_FLASH_DEFL_END, getSpiFlashAddresses, DETECTED_FLASH_SIZES, CHIP_DETECT_MAGIC_REG_ADDR, CHIP_DETECT_MAGIC_VALUES, SlipReadError, } from "./const";
1
+ /// <reference types="@types/w3c-web-serial" />
2
+ import { CHIP_FAMILY_ESP32, CHIP_FAMILY_ESP32S2, CHIP_FAMILY_ESP32S3, CHIP_FAMILY_ESP32C2, CHIP_FAMILY_ESP32C3, CHIP_FAMILY_ESP32C5, CHIP_FAMILY_ESP32C6, CHIP_FAMILY_ESP32C61, CHIP_FAMILY_ESP32H2, CHIP_FAMILY_ESP32P4, CHIP_FAMILY_ESP8266, MAX_TIMEOUT, DEFAULT_TIMEOUT, ERASE_REGION_TIMEOUT_PER_MB, ESP_CHANGE_BAUDRATE, ESP_CHECKSUM_MAGIC, ESP_FLASH_BEGIN, ESP_FLASH_DATA, ESP_FLASH_END, ESP_MEM_BEGIN, ESP_MEM_DATA, ESP_MEM_END, ESP_READ_REG, ESP_WRITE_REG, ESP_SPI_ATTACH, ESP_SYNC, ESP_GET_SECURITY_INFO, FLASH_SECTOR_SIZE, FLASH_WRITE_SIZE, STUB_FLASH_WRITE_SIZE, MEM_END_ROM_TIMEOUT, ROM_INVALID_RECV_MSG, SYNC_PACKET, SYNC_TIMEOUT, USB_RAM_BLOCK, ESP_ERASE_FLASH, CHIP_ERASE_TIMEOUT, timeoutPerMb, ESP_ROM_BAUD, USB_JTAG_SERIAL_PID, ESP_FLASH_DEFL_BEGIN, ESP_FLASH_DEFL_DATA, ESP_FLASH_DEFL_END, getSpiFlashAddresses, DETECTED_FLASH_SIZES, CHIP_DETECT_MAGIC_REG_ADDR, CHIP_DETECT_MAGIC_VALUES, CHIP_ID_TO_INFO, ESP32P4_EFUSE_BLOCK1_ADDR, SlipReadError, } from "./const";
2
3
  import { getStubCode } from "./stubs";
3
4
  import { hexFormatter, sleep, slipEncode, toHex } from "./util";
4
5
  // @ts-ignore
@@ -11,6 +12,8 @@ export class ESPLoader extends EventTarget {
11
12
  this.logger = logger;
12
13
  this._parent = _parent;
13
14
  this.chipName = null;
15
+ this.chipRevision = null;
16
+ this.chipVariant = null;
14
17
  this._efuses = new Array(4).fill(0);
15
18
  this._flashsize = 4 * 1024 * 1024;
16
19
  this.debug = false;
@@ -30,14 +33,8 @@ export class ESPLoader extends EventTarget {
30
33
  this.readLoop();
31
34
  }
32
35
  await this.sync();
33
- // Determine chip family and name
34
- let chipMagicValue = await this.readRegister(CHIP_DETECT_MAGIC_REG_ADDR);
35
- let chip = CHIP_DETECT_MAGIC_VALUES[chipMagicValue >>> 0];
36
- if (chip === undefined) {
37
- throw new Error(`Unknown Chip: Hex: ${toHex(chipMagicValue >>> 0, 8).toLowerCase()} Number: ${chipMagicValue}`);
38
- }
39
- this.chipName = chip.name;
40
- this.chipFamily = chip.family;
36
+ // Detect chip type
37
+ await this.detectChip();
41
38
  // Read the OTP data for this chip and store into this.efuses array
42
39
  let FlAddr = getSpiFlashAddresses(this.getChipFamily());
43
40
  let AddrMAC = FlAddr.macFuse;
@@ -47,6 +44,108 @@ export class ESPLoader extends EventTarget {
47
44
  this.logger.log(`Chip type ${this.chipName}`);
48
45
  //this.logger.log("FLASHID");
49
46
  }
47
+ /**
48
+ * Detect chip type using GET_SECURITY_INFO (for newer chips) or magic value (for older chips)
49
+ */
50
+ async detectChip() {
51
+ try {
52
+ // Try GET_SECURITY_INFO command first (ESP32-C3 and later)
53
+ const securityInfo = await this.getSecurityInfo();
54
+ const chipId = securityInfo.chipId;
55
+ const chipInfo = CHIP_ID_TO_INFO[chipId];
56
+ if (chipInfo) {
57
+ this.chipName = chipInfo.name;
58
+ this.chipFamily = chipInfo.family;
59
+ // Get chip revision for ESP32-P4
60
+ if (this.chipFamily === CHIP_FAMILY_ESP32P4) {
61
+ this.chipRevision = await this.getChipRevision();
62
+ this.logger.debug(`ESP32-P4 revision: ${this.chipRevision}`);
63
+ // Set chip variant based on revision
64
+ if (this.chipRevision >= 300) {
65
+ this.chipVariant = "rev300";
66
+ }
67
+ else {
68
+ this.chipVariant = "rev0";
69
+ }
70
+ this.logger.debug(`ESP32-P4 variant: ${this.chipVariant}`);
71
+ }
72
+ this.logger.debug(`Detected chip via IMAGE_CHIP_ID: ${chipId} (${this.chipName})`);
73
+ return;
74
+ }
75
+ this.logger.debug(`Unknown IMAGE_CHIP_ID: ${chipId}, falling back to magic value detection`);
76
+ }
77
+ catch (err) {
78
+ // GET_SECURITY_INFO not supported, fall back to magic value detection
79
+ this.logger.debug(`GET_SECURITY_INFO failed, using magic value detection: ${err}`);
80
+ }
81
+ // Fallback: Use magic value detection for ESP8266, ESP32, ESP32-S2, and ESP32-P4 RC versions
82
+ let chipMagicValue = await this.readRegister(CHIP_DETECT_MAGIC_REG_ADDR);
83
+ let chip = CHIP_DETECT_MAGIC_VALUES[chipMagicValue >>> 0];
84
+ if (chip === undefined) {
85
+ throw new Error(`Unknown Chip: Hex: ${toHex(chipMagicValue >>> 0, 8).toLowerCase()} Number: ${chipMagicValue}`);
86
+ }
87
+ this.chipName = chip.name;
88
+ this.chipFamily = chip.family;
89
+ // For ESP32-P4 detected via magic value (old revisions), set variant
90
+ if (this.chipFamily === CHIP_FAMILY_ESP32P4) {
91
+ this.chipRevision = await this.getChipRevision();
92
+ this.logger.debug(`ESP32-P4 revision: ${this.chipRevision}`);
93
+ if (this.chipRevision >= 300) {
94
+ this.chipVariant = "rev300";
95
+ }
96
+ else {
97
+ this.chipVariant = "rev0";
98
+ }
99
+ this.logger.debug(`ESP32-P4 variant: ${this.chipVariant}`);
100
+ }
101
+ this.logger.debug(`Detected chip via magic value: ${toHex(chipMagicValue >>> 0, 8)} (${this.chipName})`);
102
+ }
103
+ /**
104
+ * Get chip revision for ESP32-P4
105
+ */
106
+ async getChipRevision() {
107
+ if (this.chipFamily !== CHIP_FAMILY_ESP32P4) {
108
+ return 0;
109
+ }
110
+ // Read from EFUSE_BLOCK1 to get chip revision
111
+ // Word 2 contains revision info for ESP32-P4
112
+ const word2 = await this.readRegister(ESP32P4_EFUSE_BLOCK1_ADDR + 8);
113
+ // Minor revision: bits [3:0]
114
+ const minorRev = word2 & 0x0f;
115
+ // Major revision: bits [23] << 2 | bits [5:4]
116
+ const majorRev = (((word2 >> 23) & 1) << 2) | ((word2 >> 4) & 0x03);
117
+ // Revision is major * 100 + minor
118
+ return majorRev * 100 + minorRev;
119
+ }
120
+ /**
121
+ * Get security info including chip ID (ESP32-C3 and later)
122
+ */
123
+ async getSecurityInfo() {
124
+ const [_, responseData] = await this.checkCommand(ESP_GET_SECURITY_INFO, [], 0);
125
+ // Some chips/ROM versions return empty response or don't support this command
126
+ if (responseData.length === 0) {
127
+ throw new Error(`GET_SECURITY_INFO not supported or returned empty response`);
128
+ }
129
+ if (responseData.length < 12) {
130
+ throw new Error(`Invalid security info response length: ${responseData.length} (expected at least 12 bytes)`);
131
+ }
132
+ const flags = unpack("<I", responseData.slice(0, 4))[0];
133
+ const flashCryptCnt = responseData[4];
134
+ const keyPurposes = Array.from(responseData.slice(5, 12));
135
+ const chipId = responseData.length >= 16
136
+ ? unpack("<I", responseData.slice(12, 16))[0]
137
+ : 0;
138
+ const apiVersion = responseData.length >= 20
139
+ ? unpack("<I", responseData.slice(16, 20))[0]
140
+ : 0;
141
+ return {
142
+ flags,
143
+ flashCryptCnt,
144
+ keyPurposes,
145
+ chipId,
146
+ apiVersion,
147
+ };
148
+ }
50
149
  /**
51
150
  * @name readLoop
52
151
  * Reads data from the input stream and places it in the inputBuffer
@@ -235,7 +334,12 @@ export class ESPLoader extends EventTarget {
235
334
  statusLen = 4;
236
335
  }
237
336
  else {
238
- if ([2, 4].includes(data.length)) {
337
+ // When chipFamily is not yet set (e.g., during GET_SECURITY_INFO in detectChip),
338
+ // assume modern chips use 4-byte status
339
+ if (opcode === ESP_GET_SECURITY_INFO) {
340
+ statusLen = 4;
341
+ }
342
+ else if ([2, 4].includes(data.length)) {
239
343
  statusLen = data.length;
240
344
  }
241
345
  }
@@ -411,6 +515,7 @@ export class ESPLoader extends EventTarget {
411
515
  else {
412
516
  await this.reconfigurePort(baud);
413
517
  }
518
+ this.logger.log(`Changed baud rate to ${baud}`);
414
519
  }
415
520
  async reconfigurePort(baud) {
416
521
  var _a;
@@ -425,7 +530,6 @@ export class ESPLoader extends EventTarget {
425
530
  await this.port.open({ baudRate: baud });
426
531
  // Restart Readloop
427
532
  this.readLoop();
428
- this.logger.log(`Changed baud rate to ${baud}`);
429
533
  }
430
534
  catch (e) {
431
535
  console.error(e);
@@ -846,7 +950,7 @@ export class ESPLoader extends EventTarget {
846
950
  return await this.checkCommand(ESP_MEM_END, data, 0, timeout);
847
951
  }
848
952
  async runStub() {
849
- const stub = await getStubCode(this.chipFamily);
953
+ const stub = await getStubCode(this.chipFamily, this.chipRevision);
850
954
  // We're transferring over USB, right?
851
955
  let ramBlock = USB_RAM_BLOCK;
852
956
  // Upload
@@ -921,7 +1025,7 @@ class EspStubLoader extends ESPLoader {
921
1025
  * Start downloading an application image to RAM
922
1026
  */
923
1027
  async memBegin(size, blocks, blocksize, offset) {
924
- let stub = await getStubCode(this.chipFamily);
1028
+ let stub = await getStubCode(this.chipFamily, this.chipRevision);
925
1029
  let load_start = offset;
926
1030
  let load_end = offset + size;
927
1031
  console.log(load_start, load_end);
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference types="@types/w3c-web-serial" />
1
2
  import { ESP_ROM_BAUD } from "./const";
2
3
  import { ESPLoader } from "./esp_loader";
3
4
  export { ESPLoader } from "./esp_loader";