Skip to content

Commit 04e337d

Browse files
committed
sync baudRate change read Flash new loader with serial port
1 parent 5196f9a commit 04e337d

File tree

1 file changed

+90
-18
lines changed

1 file changed

+90
-18
lines changed

src/esploader.ts

Lines changed: 90 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ export interface FlashOptions {
1717

1818
export interface LoaderOptions {
1919
transport: Transport;
20+
port: SerialPort;
2021
baudrate: number;
2122
terminal?: IEspLoaderTerminal;
2223
romBaudrate: number;
2324
debugLogging?: boolean;
2425
}
2526

27+
type FlashReadCallback = ((packet: Uint8Array, progress: number, totalSize: number) => void) | null;
28+
2629
async function magic2Chip(magic: number): Promise<ROM | null> {
2730
switch (magic) {
2831
case 0x00f01d83: {
@@ -86,6 +89,7 @@ export class ESPLoader {
8689
// Only Stub supported commands
8790
ESP_ERASE_FLASH = 0xd0;
8891
ESP_ERASE_REGION = 0xd1;
92+
ESP_READ_FLASH = 0xd2;
8993
ESP_RUN_USER_CODE = 0xd3;
9094

9195
ESP_IMAGE_MAGIC = 0xe9;
@@ -98,6 +102,7 @@ export class ESPLoader {
98102
ERASE_WRITE_TIMEOUT_PER_MB = 40000;
99103
MD5_TIMEOUT_PER_MB = 8000;
100104
CHIP_ERASE_TIMEOUT = 120000;
105+
FLASH_READ_TIMEOUT = 100000;
101106
MAX_TIMEOUT = this.CHIP_ERASE_TIMEOUT * 2;
102107

103108
CHIP_DETECT_MAGIC_REG_ADDR = 0x40001000;
@@ -112,6 +117,16 @@ export class ESPLoader {
112117
0x18: "16MB",
113118
};
114119

120+
DETECTED_FLASH_SIZES_NUM: { [key: number]: number } = {
121+
0x12: 256,
122+
0x13: 512,
123+
0x14: 1024,
124+
0x15: 2048,
125+
0x16: 4096,
126+
0x17: 8192,
127+
0x18: 16384,
128+
};
129+
115130
USB_JTAG_SERIAL_PID = 0x1001;
116131

117132
chip!: ROM;
@@ -140,6 +155,9 @@ export class ESPLoader {
140155
if (options.debugLogging) {
141156
this.debugLogging = options.debugLogging;
142157
}
158+
if (options.port) {
159+
this.transport = new Transport(options.port);
160+
}
143161

144162
this.info("esptool.js");
145163
this.info("Serial port " + this.transport.get_info());
@@ -230,6 +248,26 @@ export class ESPLoader {
230248
}
231249
}
232250

251+
async read_packet(op: number | null = null, timeout = 3000): Promise<[number, Uint8Array]> {
252+
// Check up-to next 100 packets for valid response packet
253+
for (let i = 0; i < 100; i++) {
254+
const p = await this.transport.read(timeout);
255+
const resp = p[0];
256+
const op_ret = p[1];
257+
const val = this._bytearray_to_int(p[4], p[5], p[6], p[7]);
258+
const data = p.slice(8);
259+
if (resp == 1) {
260+
if (op == null || op_ret == op) {
261+
return [val, data];
262+
} else if (data[0] != 0 && data[1] == this.ROM_INVALID_RECV_MSG) {
263+
await this.flush_input();
264+
throw new ESPError("unsupported command error");
265+
}
266+
}
267+
}
268+
throw new ESPError("invalid response");
269+
}
270+
233271
async command(
234272
op: number | null = null,
235273
data: Uint8Array = new Uint8Array(0),
@@ -259,23 +297,7 @@ export class ESPLoader {
259297
return [0, new Uint8Array(0)];
260298
}
261299

262-
// Check up-to next 100 packets for valid response packet
263-
for (let i = 0; i < 100; i++) {
264-
const p = await this.transport.read(timeout);
265-
const resp = p[0];
266-
const op_ret = p[1];
267-
const val = this._bytearray_to_int(p[4], p[5], p[6], p[7]);
268-
const data = p.slice(8);
269-
if (resp == 1) {
270-
if (op == null || op_ret == op) {
271-
return [val, data];
272-
} else if (data[0] != 0 && data[1] == this.ROM_INVALID_RECV_MSG) {
273-
await this.flush_input();
274-
throw new ESPError("unsupported command error");
275-
}
276-
}
277-
}
278-
throw new ESPError("invalid response");
300+
return this.read_packet(op, timeout);
279301
}
280302

281303
async read_reg(addr: number, timeout = 3000) {
@@ -718,6 +740,38 @@ export class ESPLoader {
718740
return strmd5;
719741
}
720742

743+
async read_flash(addr: number, size: number, onPacketReceived: FlashReadCallback = null) {
744+
let pkt = this._appendArray(this._int_to_bytearray(addr), this._int_to_bytearray(size));
745+
pkt = this._appendArray(pkt, this._int_to_bytearray(0x1000));
746+
pkt = this._appendArray(pkt, this._int_to_bytearray(1024));
747+
748+
const res = await this.check_command("read flash", this.ESP_READ_FLASH, pkt);
749+
750+
if (res != 0) {
751+
throw new ESPError("Failed to read memory: " + res);
752+
}
753+
754+
let resp = new Uint8Array(0);
755+
while (resp.length < size) {
756+
const packet = await this.transport.read(this.FLASH_READ_TIMEOUT);
757+
758+
if (packet instanceof Uint8Array) {
759+
if (packet.length > 0) {
760+
resp = this._appendArray(resp, packet);
761+
await this.transport.write(this._int_to_bytearray(resp.length));
762+
763+
if (onPacketReceived) {
764+
onPacketReceived(packet, resp.length, size);
765+
}
766+
}
767+
} else {
768+
throw new ESPError("Failed to read memory: " + packet);
769+
}
770+
}
771+
772+
return resp;
773+
}
774+
721775
async run_stub() {
722776
this.info("Uploading stub...");
723777

@@ -777,8 +831,19 @@ export class ESPLoader {
777831
await this.transport.disconnect();
778832
await this._sleep(50);
779833
await this.transport.connect(this.baudrate);
834+
835+
/* original code seemed absolutely unreliable. use retries and less sleep */
780836
try {
781-
await this.transport.rawRead(500);
837+
let i = 64;
838+
while (i--) {
839+
try {
840+
await this.sync();
841+
break;
842+
} catch (error) {
843+
this.debug((error as Error).message);
844+
}
845+
await this._sleep(10);
846+
}
782847
} catch (e) {
783848
this.debug((e as Error).message);
784849
}
@@ -1026,6 +1091,13 @@ export class ESPLoader {
10261091
this.info("Detected flash size: " + this.DETECTED_FLASH_SIZES[flid_lowbyte]);
10271092
}
10281093

1094+
async get_flash_size() {
1095+
this.debug("flash_id");
1096+
const flashid = await this.read_flash_id();
1097+
const flid_lowbyte = (flashid >> 16) & 0xff;
1098+
return this.DETECTED_FLASH_SIZES_NUM[flid_lowbyte];
1099+
}
1100+
10291101
async hard_reset() {
10301102
await this.transport.setRTS(true); // EN->LOW
10311103
await this._sleep(100);

0 commit comments

Comments
 (0)