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.
- package/.github/workflows/build_upload.yml +8 -5
- package/.github/workflows/ci.yml +3 -3
- package/BUGFIX_GET_SECURITY_INFO.md +126 -0
- package/CHANGELOG_CHIP_VARIANT.md +169 -0
- package/CHIP_VARIANT_SUPPORT.md +184 -0
- package/IMPLEMENTATION_SUMMARY.md +232 -0
- package/SECURITY_INFO_EXPLANATION.md +145 -0
- package/css/style.css +1 -0
- package/dist/const.d.ts +9 -0
- package/dist/const.js +15 -0
- package/dist/esp_loader.d.ts +20 -0
- package/dist/esp_loader.js +117 -13
- package/dist/index.js +1 -0
- package/dist/stubs/esp32c5.json +4 -4
- package/dist/stubs/esp32p4r3.json +8 -0
- package/dist/stubs/index.d.ts +1 -1
- package/dist/stubs/index.js +8 -2
- package/dist/web/esp32c5-mcj52-K1.js +1 -0
- package/dist/web/esp32p4r3-Cle9QJmZ.js +1 -0
- package/dist/web/index.js +1 -1
- package/index.html +13 -0
- package/js/modules/esp32c5-mcj52-K1.js +1 -0
- package/js/modules/esp32p4r3-Cle9QJmZ.js +1 -0
- package/js/modules/esptool.js +1 -1
- package/js/script.js +23 -0
- package/package.json +1 -1
- package/src/const.ts +22 -0
- package/src/esp_loader.ts +164 -13
- package/src/index.ts +2 -0
- package/src/stubs/esp32c5.json +4 -4
- package/src/stubs/esp32p4r3.json +8 -0
- package/src/stubs/index.ts +10 -2
- package/tsconfig.json +2 -1
- package/dist/web/esp32c5-C8uE-s4t.js +0 -1
- package/js/modules/esp32c5-C8uE-s4t.js +0 -1
|
@@ -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
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;
|
package/dist/esp_loader.d.ts
CHANGED
|
@@ -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
|
package/dist/esp_loader.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
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
|
-
//
|
|
34
|
-
|
|
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
|
-
|
|
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