tasmota-webserial-esptool 7.0.1 → 7.1.0

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/src/esp_loader.ts CHANGED
@@ -62,7 +62,7 @@ import {
62
62
  } from "./const";
63
63
  import { getStubCode } from "./stubs";
64
64
  import { hexFormatter, sleep, slipEncode, toHex } from "./util";
65
- // @ts-ignore
65
+ // @ts-expect-error pako ESM module doesn't have proper type definitions
66
66
  import { deflate } from "pako/dist/pako.esm.mjs";
67
67
  import { pack, unpack } from "./struct";
68
68
 
@@ -193,8 +193,8 @@ export class ESPLoader extends EventTarget {
193
193
  await this.detectChip();
194
194
 
195
195
  // Read the OTP data for this chip and store into this.efuses array
196
- let FlAddr = getSpiFlashAddresses(this.getChipFamily());
197
- let AddrMAC = FlAddr.macFuse;
196
+ const FlAddr = getSpiFlashAddresses(this.getChipFamily());
197
+ const AddrMAC = FlAddr.macFuse;
198
198
  for (let i = 0; i < 4; i++) {
199
199
  this._efuses[i] = await this.readRegister(AddrMAC + 4 * i);
200
200
  }
@@ -241,10 +241,10 @@ export class ESPLoader extends EventTarget {
241
241
  this.logger.debug(
242
242
  `Unknown IMAGE_CHIP_ID: ${chipId}, falling back to magic value detection`,
243
243
  );
244
- } catch (err) {
244
+ } catch (error) {
245
245
  // GET_SECURITY_INFO not supported, fall back to magic value detection
246
246
  this.logger.debug(
247
- `GET_SECURITY_INFO failed, using magic value detection: ${err}`,
247
+ `GET_SECURITY_INFO failed, using magic value detection: ${error}`,
248
248
  );
249
249
 
250
250
  // Clear input buffer and re-sync to recover from failed command
@@ -262,8 +262,8 @@ export class ESPLoader extends EventTarget {
262
262
  }
263
263
 
264
264
  // Fallback: Use magic value detection for ESP8266, ESP32, ESP32-S2, and ESP32-P4 RC versions
265
- let chipMagicValue = await this.readRegister(CHIP_DETECT_MAGIC_REG_ADDR);
266
- let chip = CHIP_DETECT_MAGIC_VALUES[chipMagicValue >>> 0];
265
+ const chipMagicValue = await this.readRegister(CHIP_DETECT_MAGIC_REG_ADDR);
266
+ const chip = CHIP_DETECT_MAGIC_VALUES[chipMagicValue >>> 0];
267
267
  if (chip === undefined) {
268
268
  throw new Error(
269
269
  `Unknown Chip: Hex: ${toHex(
@@ -325,7 +325,7 @@ export class ESPLoader extends EventTarget {
325
325
  chipId: number;
326
326
  apiVersion: number;
327
327
  }> {
328
- const [_, responseData] = await this.checkCommand(
328
+ const [, responseData] = await this.checkCommand(
329
329
  ESP_GET_SECURITY_INFO,
330
330
  [],
331
331
  0,
@@ -377,10 +377,12 @@ export class ESPLoader extends EventTarget {
377
377
  this._reader = this.port.readable!.getReader();
378
378
 
379
379
  try {
380
- while (true) {
380
+ let keepReading = true;
381
+ while (keepReading) {
381
382
  const { value, done } = await this._reader.read();
382
383
  if (done) {
383
384
  this._reader.releaseLock();
385
+ keepReading = false;
384
386
  break;
385
387
  }
386
388
  if (!value || value.length === 0) {
@@ -395,8 +397,8 @@ export class ESPLoader extends EventTarget {
395
397
  // Track total bytes read from serial port
396
398
  this._totalBytesRead += value.length;
397
399
  }
398
- } catch (err) {
399
- console.error("Read loop got disconnected");
400
+ } catch {
401
+ this.logger.error("Read loop got disconnected");
400
402
  }
401
403
  // Disconnected!
402
404
  this.connected = false;
@@ -474,11 +476,11 @@ export class ESPLoader extends EventTarget {
474
476
  * The MAC address burned into the OTP memory of the ESP chip
475
477
  */
476
478
  macAddr() {
477
- let macAddr = new Array(6).fill(0);
478
- let mac0 = this._efuses[0];
479
- let mac1 = this._efuses[1];
480
- let mac2 = this._efuses[2];
481
- let mac3 = this._efuses[3];
479
+ const macAddr = new Array(6).fill(0);
480
+ const mac0 = this._efuses[0];
481
+ const mac1 = this._efuses[1];
482
+ const mac2 = this._efuses[2];
483
+ const mac3 = this._efuses[3];
482
484
  let oui;
483
485
  if (this.chipFamily == CHIP_FAMILY_ESP8266) {
484
486
  if (mac3 != 0) {
@@ -534,9 +536,9 @@ export class ESPLoader extends EventTarget {
534
536
  if (this.debug) {
535
537
  this.logger.debug("Reading from Register " + toHex(reg, 8));
536
538
  }
537
- let packet = pack("<I", reg);
539
+ const packet = pack("<I", reg);
538
540
  await this.sendCommand(ESP_READ_REG, packet);
539
- let [val, _data] = await this.getResponse(ESP_READ_REG);
541
+ const [val] = await this.getResponse(ESP_READ_REG);
540
542
  return val;
541
543
  }
542
544
 
@@ -554,12 +556,13 @@ export class ESPLoader extends EventTarget {
554
556
  ): Promise<[number, number[]]> {
555
557
  timeout = Math.min(timeout, MAX_TIMEOUT);
556
558
  await this.sendCommand(opcode, buffer, checksum);
557
- let [value, data] = await this.getResponse(opcode, timeout);
559
+ const [value, responseData] = await this.getResponse(opcode, timeout);
558
560
 
559
- if (data === null) {
561
+ if (responseData === null) {
560
562
  throw new Error("Didn't get enough status bytes");
561
563
  }
562
564
 
565
+ let data = responseData;
563
566
  let statusLen = 0;
564
567
 
565
568
  if (this.IS_STUB || this.chipFamily == CHIP_FAMILY_ESP8266) {
@@ -595,7 +598,7 @@ export class ESPLoader extends EventTarget {
595
598
  if (data.length < statusLen) {
596
599
  throw new Error("Didn't get enough status bytes");
597
600
  }
598
- let status = data.slice(-statusLen, data.length);
601
+ const status = data.slice(-statusLen, data.length);
599
602
  data = data.slice(0, -statusLen);
600
603
  if (this.debug) {
601
604
  this.logger.debug("status", status);
@@ -619,7 +622,7 @@ export class ESPLoader extends EventTarget {
619
622
  * does not check response
620
623
  */
621
624
  async sendCommand(opcode: number, buffer: number[], checksum = 0) {
622
- let packet = slipEncode([
625
+ const packet = slipEncode([
623
626
  ...pack("<BBHI", 0x00, opcode, buffer.length, checksum),
624
627
  ...buffer,
625
628
  ]);
@@ -643,7 +646,7 @@ export class ESPLoader extends EventTarget {
643
646
  let inEscape = false;
644
647
  let readBytes: number[] = [];
645
648
  while (true) {
646
- let stamp = Date.now();
649
+ const stamp = Date.now();
647
650
  readBytes = [];
648
651
  while (Date.now() - stamp < timeout) {
649
652
  if (this._inputBuffer.length > 0) {
@@ -655,14 +658,14 @@ export class ESPLoader extends EventTarget {
655
658
  }
656
659
  }
657
660
  if (readBytes.length == 0) {
658
- let waitingFor = partialPacket === null ? "header" : "content";
661
+ const waitingFor = partialPacket === null ? "header" : "content";
659
662
  throw new SlipReadError("Timed out waiting for packet " + waitingFor);
660
663
  }
661
664
  if (this.debug)
662
665
  this.logger.debug(
663
666
  "Read " + readBytes.length + " bytes: " + hexFormatter(readBytes),
664
667
  );
665
- for (let b of readBytes) {
668
+ for (const b of readBytes) {
666
669
  if (partialPacket === null) {
667
670
  // waiting for packet header
668
671
  if (b == 0xc0) {
@@ -738,7 +741,7 @@ export class ESPLoader extends EventTarget {
738
741
  continue;
739
742
  }
740
743
 
741
- const [resp, opRet, _lenRet, val] = unpack("<BBHI", packet.slice(0, 8));
744
+ const [resp, opRet, , val] = unpack("<BBHI", packet.slice(0, 8));
742
745
  if (resp != 1) {
743
746
  continue;
744
747
  }
@@ -759,7 +762,7 @@ export class ESPLoader extends EventTarget {
759
762
  * Calculate checksum of a blob, as it is defined by the ROM
760
763
  */
761
764
  checksum(data: number[], state = ESP_CHECKSUM_MAGIC) {
762
- for (let b of data) {
765
+ for (const b of data) {
763
766
  state ^= b;
764
767
  }
765
768
  return state;
@@ -772,10 +775,10 @@ export class ESPLoader extends EventTarget {
772
775
 
773
776
  try {
774
777
  // Send ESP_ROM_BAUD(115200) as the old one if running STUB otherwise 0
775
- let buffer = pack("<II", baud, this.IS_STUB ? ESP_ROM_BAUD : 0);
778
+ const buffer = pack("<II", baud, this.IS_STUB ? ESP_ROM_BAUD : 0);
776
779
  await this.checkCommand(ESP_CHANGE_BAUDRATE, buffer);
777
780
  } catch (e) {
778
- console.error(e);
781
+ this.logger.error(`Baudrate change error: ${e}`);
779
782
  throw new Error(
780
783
  `Unable to change the baud rate to ${baud}: No response from set baud rate command.`,
781
784
  );
@@ -828,7 +831,7 @@ export class ESPLoader extends EventTarget {
828
831
  // Restart Readloop
829
832
  this.readLoop();
830
833
  } catch (e) {
831
- console.error(e);
834
+ this.logger.error(`Reconfigure port error: ${e}`);
832
835
  throw new Error(`Unable to change the baud rate to ${baud}: ${e}`);
833
836
  }
834
837
  }
@@ -841,7 +844,7 @@ export class ESPLoader extends EventTarget {
841
844
  async sync() {
842
845
  for (let i = 0; i < 5; i++) {
843
846
  this._inputBuffer.length = 0;
844
- let response = await this._sync();
847
+ const response = await this._sync();
845
848
  if (response) {
846
849
  await sleep(SYNC_TIMEOUT);
847
850
  return true;
@@ -861,11 +864,11 @@ export class ESPLoader extends EventTarget {
861
864
  await this.sendCommand(ESP_SYNC, SYNC_PACKET);
862
865
  for (let i = 0; i < 8; i++) {
863
866
  try {
864
- let [_reply, data] = await this.getResponse(ESP_SYNC, SYNC_TIMEOUT);
867
+ const [, data] = await this.getResponse(ESP_SYNC, SYNC_TIMEOUT);
865
868
  if (data.length > 1 && data[0] == 0 && data[1] == 0) {
866
869
  return true;
867
870
  }
868
- } catch (err) {
871
+ } catch {
869
872
  // If read packet fails.
870
873
  }
871
874
  }
@@ -898,10 +901,10 @@ export class ESPLoader extends EventTarget {
898
901
  ) {
899
902
  if (binaryData.byteLength >= 8) {
900
903
  // unpack the (potential) image header
901
- var header = Array.from(new Uint8Array(binaryData, 0, 4));
902
- let headerMagic = header[0];
903
- let headerFlashMode = header[2];
904
- let headerFlashSizeFreq = header[3];
904
+ const header = Array.from(new Uint8Array(binaryData, 0, 4));
905
+ const headerMagic = header[0];
906
+ const headerFlashMode = header[2];
907
+ const headerFlashSizeFreq = header[3];
905
908
 
906
909
  this.logger.log(
907
910
  `Image header, Magic=${toHex(headerMagic)}, FlashMode=${toHex(
@@ -910,7 +913,7 @@ export class ESPLoader extends EventTarget {
910
913
  );
911
914
  }
912
915
 
913
- let uncompressedFilesize = binaryData.byteLength;
916
+ const uncompressedFilesize = binaryData.byteLength;
914
917
  let compressedFilesize = 0;
915
918
 
916
919
  let dataToFlash;
@@ -939,10 +942,10 @@ export class ESPLoader extends EventTarget {
939
942
  let seq = 0;
940
943
  let written = 0;
941
944
  let position = 0;
942
- let stamp = Date.now();
943
- let flashWriteSize = this.getFlashWriteSize();
945
+ const stamp = Date.now();
946
+ const flashWriteSize = this.getFlashWriteSize();
944
947
 
945
- let filesize = compress ? compressedFilesize : uncompressedFilesize;
948
+ const filesize = compress ? compressedFilesize : uncompressedFilesize;
946
949
 
947
950
  while (filesize - position > 0) {
948
951
  if (this.debug) {
@@ -1028,8 +1031,7 @@ export class ESPLoader extends EventTarget {
1028
1031
  await this.flushSerialBuffers();
1029
1032
 
1030
1033
  let eraseSize;
1031
- let buffer;
1032
- let flashWriteSize = this.getFlashWriteSize();
1034
+ const flashWriteSize = this.getFlashWriteSize();
1033
1035
  if (
1034
1036
  !this.IS_STUB &&
1035
1037
  [
@@ -1050,22 +1052,19 @@ export class ESPLoader extends EventTarget {
1050
1052
  ) {
1051
1053
  await this.checkCommand(ESP_SPI_ATTACH, new Array(8).fill(0));
1052
1054
  }
1053
- let numBlocks = Math.floor((size + flashWriteSize - 1) / flashWriteSize);
1055
+ const numBlocks = Math.floor((size + flashWriteSize - 1) / flashWriteSize);
1054
1056
  if (this.chipFamily == CHIP_FAMILY_ESP8266) {
1055
1057
  eraseSize = this.getEraseSize(offset, size);
1056
1058
  } else {
1057
1059
  eraseSize = size;
1058
1060
  }
1059
1061
 
1060
- let timeout;
1061
- if (this.IS_STUB) {
1062
- timeout = DEFAULT_TIMEOUT;
1063
- } else {
1064
- timeout = timeoutPerMb(ERASE_REGION_TIMEOUT_PER_MB, size);
1065
- }
1062
+ const timeout = this.IS_STUB
1063
+ ? DEFAULT_TIMEOUT
1064
+ : timeoutPerMb(ERASE_REGION_TIMEOUT_PER_MB, size);
1066
1065
 
1067
- let stamp = Date.now();
1068
- buffer = pack("<IIII", eraseSize, numBlocks, flashWriteSize, offset);
1066
+ const stamp = Date.now();
1067
+ let buffer = pack("<IIII", eraseSize, numBlocks, flashWriteSize, offset);
1069
1068
  if (
1070
1069
  this.chipFamily == CHIP_FAMILY_ESP32 ||
1071
1070
  this.chipFamily == CHIP_FAMILY_ESP32S2 ||
@@ -1109,22 +1108,18 @@ export class ESPLoader extends EventTarget {
1109
1108
  *
1110
1109
  */
1111
1110
 
1112
- async flashDeflBegin(
1113
- size = 0,
1114
- compressedSize = 0,
1115
- offset = 0,
1116
- encrypted = false,
1117
- ) {
1111
+ async flashDeflBegin(size = 0, compressedSize = 0, offset = 0) {
1118
1112
  // Start downloading compressed data to Flash (performs an erase)
1119
1113
  // Returns number of blocks to write.
1120
- let flashWriteSize = this.getFlashWriteSize();
1121
- let numBlocks = Math.floor(
1114
+ const flashWriteSize = this.getFlashWriteSize();
1115
+ const numBlocks = Math.floor(
1122
1116
  (compressedSize + flashWriteSize - 1) / flashWriteSize,
1123
1117
  );
1124
- let eraseBlocks = Math.floor((size + flashWriteSize - 1) / flashWriteSize);
1118
+ const eraseBlocks = Math.floor(
1119
+ (size + flashWriteSize - 1) / flashWriteSize,
1120
+ );
1125
1121
  let writeSize = 0;
1126
1122
  let timeout = 0;
1127
- let buffer;
1128
1123
 
1129
1124
  if (this.IS_STUB) {
1130
1125
  writeSize = size; // stub expects number of bytes here, manages erasing internally
@@ -1133,7 +1128,7 @@ export class ESPLoader extends EventTarget {
1133
1128
  writeSize = eraseBlocks * flashWriteSize; // ROM expects rounded up to erase block size
1134
1129
  timeout = DEFAULT_TIMEOUT;
1135
1130
  }
1136
- buffer = pack("<IIII", writeSize, numBlocks, flashWriteSize, offset);
1131
+ const buffer = pack("<IIII", writeSize, numBlocks, flashWriteSize, offset);
1137
1132
 
1138
1133
  await this.checkCommand(ESP_FLASH_DEFL_BEGIN, buffer, 0, timeout);
1139
1134
 
@@ -1141,24 +1136,24 @@ export class ESPLoader extends EventTarget {
1141
1136
  }
1142
1137
 
1143
1138
  async flashFinish() {
1144
- let buffer = pack("<I", 1);
1139
+ const buffer = pack("<I", 1);
1145
1140
  await this.checkCommand(ESP_FLASH_END, buffer);
1146
1141
  }
1147
1142
 
1148
1143
  async flashDeflFinish() {
1149
- let buffer = pack("<I", 1);
1144
+ const buffer = pack("<I", 1);
1150
1145
  await this.checkCommand(ESP_FLASH_DEFL_END, buffer);
1151
1146
  }
1152
1147
 
1153
1148
  getBootloaderOffset() {
1154
- let bootFlashOffs = getSpiFlashAddresses(this.getChipFamily());
1155
- let BootldrFlashOffs = bootFlashOffs.flashOffs;
1149
+ const bootFlashOffs = getSpiFlashAddresses(this.getChipFamily());
1150
+ const BootldrFlashOffs = bootFlashOffs.flashOffs;
1156
1151
  return BootldrFlashOffs;
1157
1152
  }
1158
1153
 
1159
1154
  async flashId() {
1160
- let SPIFLASH_RDID = 0x9f;
1161
- let result = await this.runSpiFlashCommand(SPIFLASH_RDID, [], 24);
1155
+ const SPIFLASH_RDID = 0x9f;
1156
+ const result = await this.runSpiFlashCommand(SPIFLASH_RDID, [], 24);
1162
1157
  return result;
1163
1158
  }
1164
1159
 
@@ -1176,7 +1171,7 @@ export class ESPLoader extends EventTarget {
1176
1171
  let buffer = pack("<IIII", address, value, mask, delayUs);
1177
1172
  if (delayAfterUs > 0) {
1178
1173
  // add a dummy write to a date register as an excuse to have a delay
1179
- buffer.concat(
1174
+ buffer = buffer.concat(
1180
1175
  pack(
1181
1176
  "<IIII",
1182
1177
  getSpiFlashAddresses(this.getChipFamily()).uartDateReg,
@@ -1196,8 +1191,10 @@ export class ESPLoader extends EventTarget {
1196
1191
  ) {
1197
1192
  if (spiAddresses.mosiDlenOffs != -1) {
1198
1193
  // ESP32/32S2/32S3/32C3 has a more sophisticated way to set up "user" commands
1199
- let SPI_MOSI_DLEN_REG = spiAddresses.regBase + spiAddresses.mosiDlenOffs;
1200
- let SPI_MISO_DLEN_REG = spiAddresses.regBase + spiAddresses.misoDlenOffs;
1194
+ const SPI_MOSI_DLEN_REG =
1195
+ spiAddresses.regBase + spiAddresses.mosiDlenOffs;
1196
+ const SPI_MISO_DLEN_REG =
1197
+ spiAddresses.regBase + spiAddresses.misoDlenOffs;
1201
1198
  if (mosiBits > 0) {
1202
1199
  await this.writeRegister(SPI_MOSI_DLEN_REG, mosiBits - 1);
1203
1200
  }
@@ -1205,19 +1202,19 @@ export class ESPLoader extends EventTarget {
1205
1202
  await this.writeRegister(SPI_MISO_DLEN_REG, misoBits - 1);
1206
1203
  }
1207
1204
  } else {
1208
- let SPI_DATA_LEN_REG = spiAddresses.regBase + spiAddresses.usr1Offs;
1209
- let SPI_MOSI_BITLEN_S = 17;
1210
- let SPI_MISO_BITLEN_S = 8;
1211
- let mosiMask = mosiBits == 0 ? 0 : mosiBits - 1;
1212
- let misoMask = misoBits == 0 ? 0 : misoBits - 1;
1213
- let value =
1205
+ const SPI_DATA_LEN_REG = spiAddresses.regBase + spiAddresses.usr1Offs;
1206
+ const SPI_MOSI_BITLEN_S = 17;
1207
+ const SPI_MISO_BITLEN_S = 8;
1208
+ const mosiMask = mosiBits == 0 ? 0 : mosiBits - 1;
1209
+ const misoMask = misoBits == 0 ? 0 : misoBits - 1;
1210
+ const value =
1214
1211
  (misoMask << SPI_MISO_BITLEN_S) | (mosiMask << SPI_MOSI_BITLEN_S);
1215
1212
  await this.writeRegister(SPI_DATA_LEN_REG, value);
1216
1213
  }
1217
1214
  }
1218
1215
  async waitDone(spiCmdReg: number, spiCmdUsr: number) {
1219
1216
  for (let i = 0; i < 10; i++) {
1220
- let cmdValue = await this.readRegister(spiCmdReg);
1217
+ const cmdValue = await this.readRegister(spiCmdReg);
1221
1218
  if ((cmdValue & spiCmdUsr) == 0) {
1222
1219
  return;
1223
1220
  }
@@ -1241,23 +1238,23 @@ export class ESPLoader extends EventTarget {
1241
1238
  // reads back 'read_bits' of reply on MISO. Result is a number.
1242
1239
 
1243
1240
  // SPI_USR register flags
1244
- let SPI_USR_COMMAND = 1 << 31;
1245
- let SPI_USR_MISO = 1 << 28;
1246
- let SPI_USR_MOSI = 1 << 27;
1241
+ const SPI_USR_COMMAND = 1 << 31;
1242
+ const SPI_USR_MISO = 1 << 28;
1243
+ const SPI_USR_MOSI = 1 << 27;
1247
1244
 
1248
1245
  // SPI registers, base address differs ESP32* vs 8266
1249
- let spiAddresses = getSpiFlashAddresses(this.getChipFamily());
1250
- let base = spiAddresses.regBase;
1251
- let SPI_CMD_REG = base;
1252
- let SPI_USR_REG = base + spiAddresses.usrOffs;
1253
- let SPI_USR2_REG = base + spiAddresses.usr2Offs;
1254
- let SPI_W0_REG = base + spiAddresses.w0Offs;
1246
+ const spiAddresses = getSpiFlashAddresses(this.getChipFamily());
1247
+ const base = spiAddresses.regBase;
1248
+ const SPI_CMD_REG = base;
1249
+ const SPI_USR_REG = base + spiAddresses.usrOffs;
1250
+ const SPI_USR2_REG = base + spiAddresses.usr2Offs;
1251
+ const SPI_W0_REG = base + spiAddresses.w0Offs;
1255
1252
 
1256
1253
  // SPI peripheral "command" bitmasks for SPI_CMD_REG
1257
- let SPI_CMD_USR = 1 << 18;
1254
+ const SPI_CMD_USR = 1 << 18;
1258
1255
 
1259
1256
  // shift values
1260
- let SPI_USR2_COMMAND_LEN_SHIFT = 28;
1257
+ const SPI_USR2_COMMAND_LEN_SHIFT = 28;
1261
1258
 
1262
1259
  if (readBits > 32) {
1263
1260
  throw new Error(
@@ -1270,9 +1267,9 @@ export class ESPLoader extends EventTarget {
1270
1267
  );
1271
1268
  }
1272
1269
 
1273
- let dataBits = data.length * 8;
1274
- let oldSpiUsr = await this.readRegister(SPI_USR_REG);
1275
- let oldSpiUsr2 = await this.readRegister(SPI_USR2_REG);
1270
+ const dataBits = data.length * 8;
1271
+ const oldSpiUsr = await this.readRegister(SPI_USR_REG);
1272
+ const oldSpiUsr2 = await this.readRegister(SPI_USR2_REG);
1276
1273
 
1277
1274
  let flags = SPI_USR_COMMAND;
1278
1275
 
@@ -1293,9 +1290,10 @@ export class ESPLoader extends EventTarget {
1293
1290
  if (dataBits == 0) {
1294
1291
  await this.writeRegister(SPI_W0_REG, 0); // clear data register before we read it
1295
1292
  } else {
1296
- data.concat(new Array(data.length % 4).fill(0x00)); // pad to 32-bit multiple
1293
+ const padLen = (4 - (data.length % 4)) % 4;
1294
+ data = data.concat(new Array(padLen).fill(0x00)); // pad to 32-bit multiple
1297
1295
 
1298
- let words = unpack("I".repeat(Math.floor(data.length / 4)), data);
1296
+ const words = unpack("I".repeat(Math.floor(data.length / 4)), data);
1299
1297
  let nextReg = SPI_W0_REG;
1300
1298
 
1301
1299
  this.logger.debug(`Words Length: ${words.length}`);
@@ -1311,7 +1309,7 @@ export class ESPLoader extends EventTarget {
1311
1309
  await this.writeRegister(SPI_CMD_REG, SPI_CMD_USR);
1312
1310
  await this.waitDone(SPI_CMD_REG, SPI_CMD_USR);
1313
1311
 
1314
- let status = await this.readRegister(SPI_W0_REG);
1312
+ const status = await this.readRegister(SPI_W0_REG);
1315
1313
  // restore some SPI controller registers
1316
1314
  await this.writeRegister(SPI_USR_REG, oldSpiUsr);
1317
1315
  await this.writeRegister(SPI_USR2_REG, oldSpiUsr2);
@@ -1320,9 +1318,9 @@ export class ESPLoader extends EventTarget {
1320
1318
  async detectFlashSize() {
1321
1319
  this.logger.log("Detecting Flash Size");
1322
1320
 
1323
- let flashId = await this.flashId();
1324
- let manufacturer = flashId & 0xff;
1325
- let flashIdLowbyte = (flashId >> 16) & 0xff;
1321
+ const flashId = await this.flashId();
1322
+ const manufacturer = flashId & 0xff;
1323
+ const flashIdLowbyte = (flashId >> 16) & 0xff;
1326
1324
 
1327
1325
  this.logger.log(`FlashId: ${toHex(flashId)}`);
1328
1326
  this.logger.log(`Flash Manufacturer: ${manufacturer.toString(16)}`);
@@ -1342,10 +1340,10 @@ export class ESPLoader extends EventTarget {
1342
1340
  * Provides a workaround for the bootloader erase bug on ESP8266.
1343
1341
  */
1344
1342
  getEraseSize(offset: number, size: number) {
1345
- let sectorsPerBlock = 16;
1346
- let sectorSize = FLASH_SECTOR_SIZE;
1347
- let numSectors = Math.floor((size + sectorSize - 1) / sectorSize);
1348
- let startSector = Math.floor(offset / sectorSize);
1343
+ const sectorsPerBlock = 16;
1344
+ const sectorSize = FLASH_SECTOR_SIZE;
1345
+ const numSectors = Math.floor((size + sectorSize - 1) / sectorSize);
1346
+ const startSector = Math.floor(offset / sectorSize);
1349
1347
 
1350
1348
  let headSectors = sectorsPerBlock - (startSector % sectorsPerBlock);
1351
1349
  if (numSectors < headSectors) {
@@ -1397,16 +1395,13 @@ export class ESPLoader extends EventTarget {
1397
1395
  * ignore errors.
1398
1396
  */
1399
1397
  async memFinish(entrypoint = 0) {
1400
- let timeout = this.IS_STUB ? DEFAULT_TIMEOUT : MEM_END_ROM_TIMEOUT;
1401
- let data = pack("<II", entrypoint == 0 ? 1 : 0, entrypoint);
1398
+ const timeout = this.IS_STUB ? DEFAULT_TIMEOUT : MEM_END_ROM_TIMEOUT;
1399
+ const data = pack("<II", entrypoint == 0 ? 1 : 0, entrypoint);
1402
1400
  return await this.checkCommand(ESP_MEM_END, data, 0, timeout);
1403
1401
  }
1404
1402
 
1405
1403
  async runStub(skipFlashDetection = false): Promise<EspStubLoader> {
1406
- const stub: Record<string, any> | null = await getStubCode(
1407
- this.chipFamily,
1408
- this.chipRevision,
1409
- );
1404
+ const stub = await getStubCode(this.chipFamily, this.chipRevision);
1410
1405
 
1411
1406
  // No stub available for this chip, return ROM loader
1412
1407
  if (stub === null) {
@@ -1417,32 +1412,29 @@ export class ESPLoader extends EventTarget {
1417
1412
  }
1418
1413
 
1419
1414
  // We're transferring over USB, right?
1420
- let ramBlock = USB_RAM_BLOCK;
1415
+ const ramBlock = USB_RAM_BLOCK;
1421
1416
 
1422
1417
  // Upload
1423
1418
  this.logger.log("Uploading stub...");
1424
- for (let field of ["text", "data"]) {
1425
- if (Object.keys(stub).includes(field)) {
1426
- let offset = stub[field + "_start"];
1427
- let length = stub[field].length;
1428
- let blocks = Math.floor((length + ramBlock - 1) / ramBlock);
1429
- await this.memBegin(length, blocks, ramBlock, offset);
1430
- for (let seq of Array(blocks).keys()) {
1431
- let fromOffs = seq * ramBlock;
1432
- let toOffs = fromOffs + ramBlock;
1433
- if (toOffs > length) {
1434
- toOffs = length;
1435
- }
1436
- await this.memBlock(stub[field].slice(fromOffs, toOffs), seq);
1419
+ for (const field of ["text", "data"] as const) {
1420
+ const fieldData = stub[field];
1421
+ const offset = stub[`${field}_start` as "text_start" | "data_start"];
1422
+ const length = fieldData.length;
1423
+ const blocks = Math.floor((length + ramBlock - 1) / ramBlock);
1424
+ await this.memBegin(length, blocks, ramBlock, offset);
1425
+ for (const seq of Array(blocks).keys()) {
1426
+ const fromOffs = seq * ramBlock;
1427
+ let toOffs = fromOffs + ramBlock;
1428
+ if (toOffs > length) {
1429
+ toOffs = length;
1437
1430
  }
1431
+ await this.memBlock(fieldData.slice(fromOffs, toOffs), seq);
1438
1432
  }
1439
1433
  }
1440
- await this.memFinish(stub["entry"]);
1441
-
1442
- let pChar: string;
1434
+ await this.memFinish(stub.entry);
1443
1435
 
1444
1436
  const p = await this.readPacket(500);
1445
- pChar = String.fromCharCode(...p);
1437
+ const pChar = String.fromCharCode(...p);
1446
1438
 
1447
1439
  if (pChar != "OHAI") {
1448
1440
  throw new Error("Failed to start stub. Unexpected response: " + pChar);
@@ -1464,7 +1456,7 @@ export class ESPLoader extends EventTarget {
1464
1456
  try {
1465
1457
  writer.releaseLock();
1466
1458
  } catch (err) {
1467
- console.error("Ignoring release lock error", err);
1459
+ this.logger.error(`Ignoring release lock error: ${err}`);
1468
1460
  }
1469
1461
  }
1470
1462
 
@@ -1708,8 +1700,8 @@ export class ESPLoader extends EventTarget {
1708
1700
  );
1709
1701
 
1710
1702
  // Send read flash command for this chunk
1711
- let pkt = pack("<IIII", currentAddr, chunkSize, 0x1000, 1024);
1712
- const [res, _] = await this.checkCommand(ESP_READ_FLASH, pkt);
1703
+ const pkt = pack("<IIII", currentAddr, chunkSize, 0x1000, 1024);
1704
+ const [res] = await this.checkCommand(ESP_READ_FLASH, pkt);
1713
1705
 
1714
1706
  if (res != 0) {
1715
1707
  throw new Error("Failed to read memory: " + res);
@@ -1798,7 +1790,7 @@ export class ESPLoader extends EventTarget {
1798
1790
  remainingSize -= chunkSize;
1799
1791
 
1800
1792
  this.logger.debug(
1801
- `Total progress: 0x${allData.length.toString(16)}/0x${size.toString(16)} bytes`,
1793
+ `Total progress: 0x${allData.length.toString(16)} from 0x${size.toString(16)} bytes`,
1802
1794
  );
1803
1795
  }
1804
1796
 
@@ -1820,27 +1812,26 @@ class EspStubLoader extends ESPLoader {
1820
1812
  */
1821
1813
  async memBegin(
1822
1814
  size: number,
1823
- blocks: number,
1824
- blocksize: number,
1815
+ _blocks: number,
1816
+ _blocksize: number,
1825
1817
  offset: number,
1826
- ): Promise<any> {
1827
- let stub = await getStubCode(this.chipFamily, this.chipRevision);
1818
+ ): Promise<[number, number[]]> {
1819
+ const stub = await getStubCode(this.chipFamily, this.chipRevision);
1828
1820
 
1829
1821
  // Stub may be null for chips without stub support
1830
1822
  if (stub === null) {
1831
- return;
1823
+ return [0, []];
1832
1824
  }
1833
1825
 
1834
- let load_start = offset;
1835
- let load_end = offset + size;
1836
- console.log(load_start, load_end);
1837
- console.log(
1838
- stub.data_start,
1839
- stub.data.length,
1840
- stub.text_start,
1841
- stub.text.length,
1826
+ const load_start = offset;
1827
+ const load_end = offset + size;
1828
+ this.logger.debug(
1829
+ `Load range: ${toHex(load_start, 8)}-${toHex(load_end, 8)}`,
1830
+ );
1831
+ this.logger.debug(
1832
+ `Stub data: ${toHex(stub.data_start, 8)}, len: ${stub.data.length}, text: ${toHex(stub.text_start, 8)}, len: ${stub.text.length}`,
1842
1833
  );
1843
- for (let [start, end] of [
1834
+ for (const [start, end] of [
1844
1835
  [stub.data_start, stub.data_start + stub.data.length],
1845
1836
  [stub.text_start, stub.text_start + stub.text.length],
1846
1837
  ]) {
@@ -1860,6 +1851,7 @@ class EspStubLoader extends ESPLoader {
1860
1851
  );
1861
1852
  }
1862
1853
  }
1854
+ return [0, []];
1863
1855
  }
1864
1856
 
1865
1857
  /**