Skip to content

Commit 8eb97db

Browse files
committed
add detect chip with get security info
1 parent b922da5 commit 8eb97db

File tree

6 files changed

+93
-10
lines changed

6 files changed

+93
-10
lines changed

src/esploader.ts

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,16 @@ import { IEspLoaderTerminal } from "./types/loaderTerminal.js";
99
import { LoaderOptions } from "./types/loaderOptions.js";
1010
import { FlashOptions } from "./types/flashOptions.js";
1111
import { After, Before } from "./types/resetModes.js";
12+
import { ROM_LIST } from "./targets/index.js";
1213

13-
type FlashReadCallback = ((packet: Uint8Array, progress: number, totalSize: number) => void) | null;
14+
/**
15+
* Callback function type for handling packets received during flash memory read operations.
16+
* @callback FlashReadCallback
17+
* @param {Uint8Array} packet - The data packet received from the flash memory.
18+
* @param {number} progress - The current progress of the read operation in bytes.
19+
* @param {number} totalSize - The total size of the data to be read in bytes.
20+
*/
21+
export type FlashReadCallback = ((packet: Uint8Array, progress: number, totalSize: number) => void) | null;
1422

1523
/**
1624
* Return the chip ROM based on the given magic number
@@ -96,6 +104,8 @@ export class ESPLoader {
96104
ESP_FLASH_DEFL_END = 0x12;
97105
ESP_SPI_FLASH_MD5 = 0x13;
98106

107+
ESP_GET_SECURITY_INFO = 0x14;
108+
99109
// Only Stub supported commands
100110
ESP_ERASE_FLASH = 0xd0;
101111
ESP_ERASE_REGION = 0xd1;
@@ -389,8 +399,9 @@ export class ESPLoader {
389399
if (op == null || opRet == op) {
390400
return [val, data];
391401
} else if (data[0] != 0 && data[1] == this.ROM_INVALID_RECV_MSG) {
392-
await this.flushInput();
393-
throw new ESPError("unsupported command error");
402+
this.debug("read_packet unsupported command error " + op);
403+
// await this.flushInput();
404+
throw new ESPError("unsupported command error " + op);
394405
}
395406
}
396407
}
@@ -629,7 +640,7 @@ export class ESPLoader {
629640
this.debug("Connect attempt successful.");
630641
this.info("\n\r", false);
631642

632-
if (detecting) {
643+
if (!detecting) {
633644
const chipMagicValue = (await this.readReg(this.CHIP_DETECT_MAGIC_REG_ADDR)) >>> 0;
634645
this.debug("Chip Magic " + chipMagicValue.toString(16));
635646
const chip = await magic2Chip(chipMagicValue);
@@ -641,17 +652,49 @@ export class ESPLoader {
641652
}
642653
}
643654

655+
/**
656+
* Get the CHIP ID with ESP_GET_SECURITY_INFO check command.
657+
* @returns {number} Chip ID number
658+
*/
659+
async getChipId(): Promise<number | undefined> {
660+
const response = await this.checkCommand("get security info", this.ESP_GET_SECURITY_INFO, new Uint8Array(0));
661+
662+
this.debug("get_chip_id " + response.toString(16));
663+
664+
if (response instanceof Uint8Array && response.length > 16) {
665+
const chipId = response[12] | (response[13] << 8) | (response[14] << 16) | (response[15] << 24);
666+
return chipId;
667+
}
668+
return;
669+
}
670+
644671
/**
645672
* Connect and detect the existing chip.
646673
* @param {string} mode Reset mode to use for connection.
674+
* @param {number} attempts - Number of connection attempts
647675
*/
648-
async detectChip(mode: Before = "default_reset") {
676+
async detectChip(mode: Before = "default_reset", attempts = 7) {
649677
await this.connect(mode);
650-
this.info("Detecting chip type... ", false);
678+
try {
679+
this.info("Detecting chip type... ");
680+
const chipID = await this.getChipId();
681+
const filteredROMList = ROM_LIST.filter(
682+
(n) => n.CHIP_NAME !== "ESP8266" && n.CHIP_NAME !== "ESP32" && n.CHIP_NAME !== "ESP32-S2",
683+
);
684+
for (const cls of filteredROMList) {
685+
if (chipID === cls.IMAGE_CHIP_ID) {
686+
this.chip = cls;
687+
break;
688+
}
689+
}
690+
} catch (error) {
691+
await this.transport.disconnect();
692+
await this.connect(mode, attempts, false);
693+
}
651694
if (this.chip != null) {
652695
this.info(this.chip.CHIP_NAME);
653696
} else {
654-
this.info("unknown!");
697+
this.info("unknown chip! detectchip has failed.");
655698
}
656699
}
657700

@@ -1091,6 +1134,16 @@ export class ESPLoader {
10911134
return strmd5;
10921135
}
10931136

1137+
/**
1138+
* Read data from flash memory of the chip.
1139+
* This function reads a specified amount of data from the flash memory starting at a given address.
1140+
* It sends a read command to the chip and processes the response packets until the requested size is read.
1141+
* @param {number} addr - The starting address in flash memory to read from.
1142+
* @param {number} size - The number of bytes to read from flash memory.
1143+
* @param {FlashReadCallback} onPacketReceived - Optional callback function to handle each received packet.
1144+
* @returns {Promise<Uint8Array>} A promise that resolves to the data read from flash memory as a Uint8Array.
1145+
* @throws {ESPError} If the read operation fails or an unexpected response is received.
1146+
*/
10941147
async readFlash(addr: number, size: number, onPacketReceived: FlashReadCallback = null) {
10951148
let pkt = this._appendArray(this._intToByteArray(addr), this._intToByteArray(size));
10961149
pkt = this._appendArray(pkt, this._intToByteArray(0x1000));

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
export { ESPLoader } from "./esploader.js";
1+
export { ESPLoader, FlashReadCallback } from "./esploader.js";
22
export {
33
ClassicReset,
44
CustomReset,
55
HardReset,
66
UsbJtagSerialReset,
77
validateCustomResetStringSequence,
88
ResetConstructors,
9+
ResetStrategy,
910
} from "./reset.js";
1011
export { ROM } from "./targets/rom.js";
1112
export { Transport, SerialOptions } from "./webserial.js";

src/targets/esp8266.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export class ESP8266ROM extends ROM {
3333
public SPI_USR2_OFFS = 0x24;
3434
public SPI_MOSI_DLEN_OFFS = 0; // not in esp8266
3535
public SPI_MISO_DLEN_OFFS = 0; // not in esp8266
36+
public IMAGE_CHIP_ID = 9999; // not in esp8266
3637
public SPI_W0_OFFS = 0x40;
3738

3839
public async readEfuse(loader: ESPLoader, offset: number): Promise<number> {

src/targets/index.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { ESP32ROM } from "./esp32";
2+
import { ESP32C2ROM } from "./esp32c2";
3+
import { ESP32C3ROM } from "./esp32c3";
4+
import { ESP32C5ROM } from "./esp32c5";
5+
import { ESP32C6ROM } from "./esp32c6";
6+
import { ESP32C61ROM } from "./esp32c61";
7+
import { ESP32H2ROM } from "./esp32h2";
8+
import { ESP32P4ROM } from "./esp32p4";
9+
import { ESP32S2ROM } from "./esp32s2";
10+
import { ESP32S3ROM } from "./esp32s3";
11+
import { ESP8266ROM } from "./esp8266";
12+
13+
export const CHIP_DEFS = {
14+
esp8266: new ESP8266ROM(),
15+
esp32: new ESP32ROM(),
16+
esp32s2: new ESP32S2ROM(),
17+
esp32s3: new ESP32S3ROM(),
18+
esp32c3: new ESP32C3ROM(),
19+
esp32c2: new ESP32C2ROM(),
20+
esp32c6: new ESP32C6ROM(),
21+
esp32c61: new ESP32C61ROM(),
22+
esp32c5: new ESP32C5ROM(),
23+
esp32h2: new ESP32H2ROM(),
24+
esp32p4: new ESP32P4ROM(),
25+
};
26+
27+
export const CHIP_LIST = Object.keys(CHIP_DEFS) as Array<keyof typeof CHIP_DEFS>;
28+
export const ROM_LIST = Object.values(CHIP_DEFS);

src/targets/rom.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export abstract class ROM {
8383
// abstract EFUSE_RD_REG_BASE: number; //esp32
8484

8585
abstract FLASH_WRITE_SIZE: number;
86-
// abstract IMAGE_CHIP_ID: number; // not in esp8266
86+
abstract IMAGE_CHIP_ID: number; // not in esp8266
8787
abstract SPI_MOSI_DLEN_OFFS: number; // not in esp8266
8888
abstract SPI_MISO_DLEN_OFFS: number; // not in esp8266
8989
abstract SPI_REG_BASE: number;

src/webserial.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ class Transport {
244244
}
245245

246246
async flushInput() {
247-
if (this.reader && !(await this.reader.closed)) {
247+
if (this.reader) {
248248
await this.reader.cancel();
249249
this.reader.releaseLock();
250250
this.reader = this.device.readable?.getReader();

0 commit comments

Comments
 (0)