From 403899c8045549019221d1ebf7c06877a6ed22de Mon Sep 17 00:00:00 2001 From: Brian Ignacio Date: Wed, 6 Dec 2023 18:24:03 +0800 Subject: [PATCH 01/13] refactor transport into abstract class --- .eslintrc | 3 +- examples/typescript/src/index.html | 2 - examples/typescript/src/index.ts | 21 ++- src/esploader.ts | 162 ++++++++---------- src/index.ts | 3 +- src/reset.ts | 19 +- src/targets/esp32.ts | 2 +- src/targets/esp8266.ts | 2 +- src/transport/ITransport.ts | 50 ++++++ .../WebSerialTransport.ts} | 48 ++---- 10 files changed, 170 insertions(+), 142 deletions(-) create mode 100644 src/transport/ITransport.ts rename src/{webserial.ts => transport/WebSerialTransport.ts} (89%) diff --git a/.eslintrc b/.eslintrc index c13def98..21ea0582 100644 --- a/.eslintrc +++ b/.eslintrc @@ -11,6 +11,7 @@ ], "rules": { "no-console": 1, // Means warning - "prettier/prettier": 2 // Means error + "prettier/prettier": 2, // Means error + "@typescript-eslint/no-inferrable-types": "off" } } diff --git a/examples/typescript/src/index.html b/examples/typescript/src/index.html index 82d40802..9c3c7684 100644 --- a/examples/typescript/src/index.html +++ b/examples/typescript/src/index.html @@ -26,9 +26,7 @@

A Serial Flasher utility for Espressif chips


-

Program

- diff --git a/src/esploader.ts b/src/esploader.ts index 600e096c..5ab24397 100644 --- a/src/esploader.ts +++ b/src/esploader.ts @@ -6,7 +6,7 @@ import { AbstractTransport, ISerialOptions } from "./transport/AbstractTransport import { classicReset, customReset, hardReset, usbJTAGSerialReset } from "./reset.js"; import { hexConvert } from "./utils/hex"; import { appendArray, bstrToUi8, byteArrayToInt, intToByteArray, shortToBytearray, ui8ToBstr } from "./utils/convert"; -import { slipRead } from "./utils/slip"; +import { Slip } from "./utils/slip"; /** * Options for flashing a device with firmware. @@ -285,6 +285,7 @@ export class ESPLoader { public serialOptions: SerialOptions; private debugLogging = false; private resetFunctions: ResetFunctions; + private slip: Slip; /** * Create a new ESPLoader to perform serial communication @@ -327,6 +328,7 @@ export class ESPLoader { if (typeof options.debugLogging !== "undefined") { this.debugLogging = options.debugLogging; } + this.slip = new Slip(this.transport); this.info("esptool.js"); this.info("Serial port " + this.transport.getInfo()); @@ -403,7 +405,7 @@ export class ESPLoader { async readPacket(op: number | null = null, timeout: number = 3000): Promise<[number, Uint8Array]> { // Check up-to next 100 packets for valid response packet for (let i = 0; i < 100; i++) { - const p = await slipRead(this.transport, timeout); + const p = await this.slip.read(timeout); const resp = p[0]; const opRet = p[1]; const val = byteArrayToInt(p[4], p[5], p[6], p[7]); @@ -459,7 +461,8 @@ export class ESPLoader { for (i = 0; i < data.length; i++) { pkt[8 + i] = data[i]; } - await this.transport.write(pkt); + const pktData = this.slip.encode(pkt); + await this.transport.write(pktData); } if (!waitResponse) { @@ -557,7 +560,7 @@ export class ESPLoader { let keepReading = true; while (keepReading) { try { - const res = await slipRead(this.transport, 1000); + const res = await this.slip.read(1000); i += res.length; } catch (e) { this.debug((e as Error).message); @@ -568,7 +571,7 @@ export class ESPLoader { } await this._sleep(50); } - this.transport.slipReaderEnabled = true; + this.slip.enableSlipRead = true; i = 7; while (i--) { try { @@ -1068,7 +1071,7 @@ export class ESPLoader { let resp = new Uint8Array(0); while (resp.length < size) { - const packet = await slipRead(this.transport, this.FLASH_READ_TIMEOUT); + const packet = await this.slip.read(this.FLASH_READ_TIMEOUT); if (packet instanceof Uint8Array) { if (packet.length > 0) { @@ -1128,7 +1131,7 @@ export class ESPLoader { // Check up-to next 100 packets to see if stub is running for (let i = 0; i < 100; i++) { - const res = await slipRead(this.transport, 1000, 6); + const res = await this.slip.read(1000, 6); if (res[0] === 79 && res[1] === 72 && res[2] === 65 && res[3] === 73) { this.info("Stub running..."); this.IS_STUB = true; diff --git a/src/index.ts b/src/index.ts index d8f15ae9..3edda7f0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,4 +16,4 @@ export { LoaderOptions, ResetFunctions, } from "./esploader.js"; -export { slipRead, slipReaderFormat, SlipReaderOutput, slipWriter } from "./utils/slip"; +export { Slip, SlipReaderOutput } from "./utils/slip.js"; diff --git a/src/transport/AbstractTransport.ts b/src/transport/AbstractTransport.ts index a101a882..7353a6c2 100644 --- a/src/transport/AbstractTransport.ts +++ b/src/transport/AbstractTransport.ts @@ -16,7 +16,6 @@ export interface ISerialOptions { */ export abstract class AbstractTransport { public abstract tracing: boolean; - public abstract slipReaderEnabled: boolean; public abstract leftOver: Uint8Array; /** diff --git a/src/transport/WebSerialTransport.ts b/src/transport/WebSerialTransport.ts index 4a7a7c0e..e811e5a4 100644 --- a/src/transport/WebSerialTransport.ts +++ b/src/transport/WebSerialTransport.ts @@ -3,7 +3,6 @@ import { AbstractTransport, ISerialOptions } from "./AbstractTransport"; import { hexConvert } from "../utils/hex"; import { appendArray } from "../utils/convert"; -import { slipWriter } from "../utils/slip"; /** * Options for device serialPort. @@ -45,7 +44,6 @@ export interface SerialOptions extends ISerialOptions { * Wrapper class around Webserial API to communicate with the serial device. * @param {typeof import("w3c-web-serial").SerialPort} device - Requested device prompted by the browser. * @param {boolean} tracing - Enable communication tracing - * @param {boolean} slipReaderEnabled Enable SLIP formatting * * ``` * const port = await navigator.serial.requestPort(); @@ -57,7 +55,7 @@ export class WebSerialTransport implements AbstractTransport { private lastTraceTime = Date.now(); private reader: ReadableStreamDefaultReader | undefined; - constructor(public device: SerialPort, public tracing = false, public slipReaderEnabled = true) {} + constructor(public device: SerialPort, public tracing = false) {} /** * Request the serial device vendor ID and Product ID as string. @@ -106,9 +104,7 @@ export class WebSerialTransport implements AbstractTransport { * Write binary data to device using the WebSerial device writable stream. * @param {Uint8Array} data 8 bit unsigned data array to write to device. */ - async write(data: Uint8Array) { - const outData = slipWriter(data); - + async write(outData: Uint8Array) { if (this.device.writable) { const writer = this.device.writable.getWriter(); if (this.tracing) { diff --git a/src/utils/slip.ts b/src/utils/slip.ts index fd6e6907..c9f57efe 100644 --- a/src/utils/slip.ts +++ b/src/utils/slip.ts @@ -1,27 +1,6 @@ import { AbstractTransport } from "../transport/AbstractTransport"; import { hexConvert } from "./hex"; -/** - * Format data packet using the Serial Line Internet Protocol (SLIP). - * @param {Uint8Array} data Binary unsigned 8 bit array data to format. - * @returns {Uint8Array} Formatted unsigned 8 bit data array. - */ -export function slipWriter(data: Uint8Array): Uint8Array { - const outData = []; - outData.push(0xc0); - for (let i = 0; i < data.length; i++) { - if (data[i] === 0xdb) { - outData.push(0xdb, 0xdd); - } else if (data[i] === 0xc0) { - outData.push(0xdb, 0xdc); - } else { - outData.push(data[i]); - } - } - outData.push(0xc0); - return new Uint8Array(outData); -} - /** * Slip reader output packet and left over as Uint8Array. * @interface SlipReaderOutput @@ -41,94 +20,119 @@ export interface SlipReaderOutput { } /** - * Take a data array and return the first well formed packet after - * replacing the escape sequence. Reads at least 8 bytes. - * @param {Uint8Array} data Unsigned 8 bit array from the device read stream. - * @returns {SlipReaderOutput} packet Formatted packet using SLIP escape sequences. + * Class to handle SLIP read and write serial methods. + * @param {AbstractTransport} transport Transport object with raw read and write serial methods + * @param {boolean} enableSlipRead Enable or disable read SLIP data formatting. */ -export function slipReaderFormat(data: Uint8Array): SlipReaderOutput { - let i = 0; - let dataStart = 0, - dataEnd = 0; - let state = "init"; - while (i < data.length) { - if (state === "init" && data[i] == 0xc0) { - dataStart = i + 1; - state = "valid_data"; - i++; - continue; - } - if (state === "valid_data" && data[i] == 0xc0) { - dataEnd = i - 1; - state = "packet_complete"; - break; +export class Slip { + constructor(private transport: AbstractTransport, public enableSlipRead: boolean = false) {} + + /** + * Format data packet using the Serial Line Internet Protocol (SLIP). + * @param {Uint8Array} data Binary unsigned 8 bit array data to format. + * @returns {Uint8Array} Formatted unsigned 8 bit data array. + */ + encode(data: Uint8Array): Uint8Array { + const outData = []; + outData.push(0xc0); + for (let i = 0; i < data.length; i++) { + if (data[i] === 0xdb) { + outData.push(0xdb, 0xdd); + } else if (data[i] === 0xc0) { + outData.push(0xdb, 0xdc); + } else { + outData.push(data[i]); + } } - i++; - } - if (state !== "packet_complete") { - return { packet: new Uint8Array(0), newLeftOver: data || new Uint8Array(0) }; + outData.push(0xc0); + return new Uint8Array(outData); } - const tempPkt = new Uint8Array(dataEnd - dataStart + 1); - let j = 0; - for (i = dataStart; i <= dataEnd; i++, j++) { - if (data[i] === 0xdb && data[i + 1] === 0xdc) { - tempPkt[j] = 0xc0; + /** + * Take a data array and return the first well formed packet after + * replacing the escape sequence. Reads at least 8 bytes. + * @param {Uint8Array} data Unsigned 8 bit array from the device read stream. + * @returns {SlipReaderOutput} packet Formatted packet using SLIP escape sequences. + */ + decode(data: Uint8Array): SlipReaderOutput { + let i = 0; + let dataStart = 0, + dataEnd = 0; + let state = "init"; + while (i < data.length) { + if (state === "init" && data[i] == 0xc0) { + dataStart = i + 1; + state = "valid_data"; + i++; + continue; + } + if (state === "valid_data" && data[i] == 0xc0) { + dataEnd = i - 1; + state = "packet_complete"; + break; + } i++; - continue; } - if (data[i] === 0xdb && data[i + 1] === 0xdd) { - tempPkt[j] = 0xdb; - i++; - continue; + if (state !== "packet_complete") { + return { packet: new Uint8Array(0), newLeftOver: data || new Uint8Array(0) }; } - tempPkt[j] = data[i]; - } - const packet = tempPkt.slice(0, j); /* Remove unused bytes due to escape seq */ - const newLeftOver = data.slice(dataEnd + 2); - - return { packet, newLeftOver }; -} -/** - * Read from serial device using the device ReadableStream. - * @param {AbstractTransport} transport Implementation of serial transport class to perform serial read - * @param {number} timeout Read timeout number - * @param {number} minData Minimum packet array length - * @returns {Promise} 8 bit unsigned data array read from device. - */ -export async function slipRead( - transport: AbstractTransport, - timeout: number = 0, - minData: number = 12, -): Promise { - let packet = transport.leftOver; - transport.leftOver = new Uint8Array(0); - if (transport.slipReaderEnabled) { - const slipResult = slipReaderFormat(packet); - const valFinal = slipResult.packet; - transport.leftOver = slipResult.newLeftOver; - if (valFinal.length > 0) { - return valFinal; + const tempPkt = new Uint8Array(dataEnd - dataStart + 1); + let j = 0; + for (i = dataStart; i <= dataEnd; i++, j++) { + if (data[i] === 0xdb && data[i + 1] === 0xdc) { + tempPkt[j] = 0xc0; + i++; + continue; + } + if (data[i] === 0xdb && data[i + 1] === 0xdd) { + tempPkt[j] = 0xdb; + i++; + continue; + } + tempPkt[j] = data[i]; } - packet = transport.leftOver; - transport.leftOver = new Uint8Array(0); - } - packet = await transport.rawRead(timeout, minData, packet); + const packet = tempPkt.slice(0, j); /* Remove unused bytes due to escape seq */ + const newLeftOver = data.slice(dataEnd + 2); - if (transport.tracing) { - transport.trace("Read SLIP bytes"); - transport.trace(`Read ${packet.length} bytes: ${hexConvert(packet)}`); + return { packet, newLeftOver }; } - if (transport.slipReaderEnabled) { - const slipReaderResult = slipReaderFormat(packet); - transport.leftOver = slipReaderResult.newLeftOver; - if (transport.tracing) { - transport.trace("Slip reader results"); - transport.trace(`Read ${slipReaderResult.packet.length} bytes: ${hexConvert(slipReaderResult.packet)}`); + /** + * Read from serial device using the device ReadableStream. + * @param {number} timeout Read timeout number + * @param {number} minData Minimum packet array length + * @returns {Promise} 8 bit unsigned data array read from device. + */ + async read(timeout: number = 0, minData: number = 12): Promise { + let packet = this.transport.leftOver; + this.transport.leftOver = new Uint8Array(0); + if (this.enableSlipRead) { + const slipResult = this.decode(packet); + const valFinal = slipResult.packet; + this.transport.leftOver = slipResult.newLeftOver; + if (valFinal.length > 0) { + return valFinal; + } + packet = this.transport.leftOver; + this.transport.leftOver = new Uint8Array(0); + } + packet = await this.transport.rawRead(timeout, minData, packet); + + if (this.transport.tracing) { + this.transport.trace("Read SLIP bytes"); + this.transport.trace(`Read ${packet.length} bytes: ${hexConvert(packet)}`); + } + + if (this.enableSlipRead) { + const slipReaderResult = this.decode(packet); + this.transport.leftOver = slipReaderResult.newLeftOver; + if (this.transport.tracing) { + this.transport.trace("Slip reader results"); + this.transport.trace(`Read ${slipReaderResult.packet.length} bytes: ${hexConvert(slipReaderResult.packet)}`); + } + return slipReaderResult.packet; } - return slipReaderResult.packet; + return packet; } - return packet; } From 7bf44a883f591804248766c917513b4a3e768da4 Mon Sep 17 00:00:00 2001 From: Brian Ignacio Date: Fri, 15 Mar 2024 21:38:54 +0800 Subject: [PATCH 08/13] transport interface --- src/esploader.ts | 23 ++++---- src/index.ts | 2 +- src/reset.ts | 53 +++++-------------- ...stractTransport.ts => ISerialTransport.ts} | 25 ++++----- src/transport/WebSerialTransport.ts | 8 +-- src/utils/slip.ts | 8 +-- 6 files changed, 47 insertions(+), 72 deletions(-) rename src/transport/{AbstractTransport.ts => ISerialTransport.ts} (75%) diff --git a/src/esploader.ts b/src/esploader.ts index 5ab24397..444b4205 100644 --- a/src/esploader.ts +++ b/src/esploader.ts @@ -2,8 +2,8 @@ import atob from "atob-lite"; import { Data, deflate, Inflate } from "pako"; import { ESPError } from "./error.js"; import { ROM } from "./targets/rom.js"; -import { AbstractTransport, ISerialOptions } from "./transport/AbstractTransport"; import { classicReset, customReset, hardReset, usbJTAGSerialReset } from "./reset.js"; +import { ISerialTransport, ISerialOptions } from "./transport/ISerialTransport.js"; import { hexConvert } from "./utils/hex"; import { appendArray, bstrToUi8, byteArrayToInt, intToByteArray, shortToBytearray, ui8ToBstr } from "./utils/convert"; import { Slip } from "./utils/slip"; @@ -70,22 +70,22 @@ export interface ResetFunctions { /** * Execute a classic set of commands that will reset the chip. */ - classicReset: (transport: AbstractTransport, resetDelay?: number) => Promise; + classicReset: (transport: ISerialTransport, resetDelay?: number) => Promise; /** * Execute a set of commands for USB JTAG serial reset. */ - usbJTAGSerialReset: (transport: AbstractTransport) => Promise; + usbJTAGSerialReset: (transport: ISerialTransport) => Promise; /** * Execute a set of commands that will hard reset the chip. */ - hardReset: (transport: AbstractTransport, usingUsbOtg?: boolean) => Promise; + hardReset: (transport: ISerialTransport, usingUsbOtg?: boolean) => Promise; /** * Custom reset strategy defined with a string. */ - customReset: (transport: AbstractTransport, sequenceString: string) => Promise; + customReset: (transport: ISerialTransport, sequenceString: string) => Promise; } /** @@ -95,9 +95,9 @@ export interface ResetFunctions { export interface LoaderOptions { /** * The transport mechanism to communicate with the device. - * @type {AbstractTransport} + * @type {ISerialTransport} */ - transport: AbstractTransport; + transport: ISerialTransport; /** * An optional terminal interface to interact with the loader during the process. @@ -112,7 +112,7 @@ export interface LoaderOptions { romBaudrate?: number; /** - * Set of options for AbstractTransport class implementation. Required field is baudRate: number. + * Set of options for ISerialTransport class implementation. Required field is baudRate: number. * @type {ISerialOptions} */ serialOptions: ISerialOptions; @@ -123,7 +123,8 @@ export interface LoaderOptions { */ debugLogging?: boolean; - /** Flag indicating whether to enable tracing for the loader (optional). + /** + * Flag indicating whether to enable tracing for the loader (optional). * @type {boolean} */ enableTracing?: boolean; @@ -279,7 +280,7 @@ export class ESPLoader { IS_STUB: boolean; FLASH_WRITE_SIZE: number; - public transport: AbstractTransport; + public transport: ISerialTransport; private terminal?: IEspLoaderTerminal; private romBaudrate = 115200; public serialOptions: SerialOptions; @@ -390,7 +391,7 @@ export class ESPLoader { */ async flushInput() { try { - await this.transport.rawRead(200); + await this.transport.read(200); } catch (e) { this.error((e as Error).message); } diff --git a/src/index.ts b/src/index.ts index 3edda7f0..bd95d891 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,7 @@ export { validateCustomResetStringSequence, } from "./reset.js"; export { ROM } from "./targets/rom.js"; -export { AbstractTransport, ISerialOptions } from "./transport/AbstractTransport.js"; +export { ISerialTransport, ISerialOptions } from "./transport/ISerialTransport.js"; export { SerialOptions, WebSerialTransport } from "./transport/WebSerialTransport.js"; export { IEspLoaderTerminal, diff --git a/src/reset.ts b/src/reset.ts index cf99095b..ae7f911c 100644 --- a/src/reset.ts +++ b/src/reset.ts @@ -1,4 +1,4 @@ -import { AbstractTransport } from "./transport/AbstractTransport"; +import { ISerialTransport } from "./transport/ISerialTransport"; const DEFAULT_RESET_DELAY = 50; @@ -25,17 +25,11 @@ function sleep(ms: number): Promise { * W: Wait (time delay) - positive integer number (miliseconds) * * "D0|R1|W100|D1|R0|W50|D0" represents the classic reset strategy - * @param {AbstractTransport} transport Transport class to perform serial communication. + * @param {ISerialTransport} transport Transport class to perform serial communication. * @param {number} resetDelay Delay in milliseconds for reset. */ -export async function classicReset(transport: AbstractTransport, resetDelay = DEFAULT_RESET_DELAY) { - await transport.setDTR(false); - await transport.setRTS(true); - await sleep(100); - await transport.setDTR(true); - await transport.setRTS(false); - await sleep(resetDelay); - await transport.setDTR(false); +export async function classicReset(transport: ISerialTransport, resetDelay = DEFAULT_RESET_DELAY) { + await customReset(transport, `D0|R1|W100|D1|R0|W${resetDelay}|D0`); } /** @@ -50,24 +44,10 @@ export async function classicReset(transport: AbstractTransport, resetDelay = DE * R: setRTS - 1=True / 0=False * * W: Wait (time delay) - positive integer number (miliseconds) - * @param {AbstractTransport} transport Transport class to perform serial communication. + * @param {ISerialTransport} transport Transport class to perform serial communication. */ -export async function usbJTAGSerialReset(transport: AbstractTransport) { - await transport.setRTS(false); - await transport.setDTR(false); - await sleep(100); - - await transport.setDTR(true); - await transport.setRTS(false); - await sleep(100); - - await transport.setRTS(true); - await transport.setDTR(false); - await transport.setRTS(true); - - await sleep(100); - await transport.setRTS(false); - await transport.setDTR(false); +export async function usbJTAGSerialReset(transport: ISerialTransport) { + await customReset(transport, `R0|D0|W100|D1|R0|W100|R1|D0|R1|W100|R0|D0`); } /** @@ -82,19 +62,12 @@ export async function usbJTAGSerialReset(transport: AbstractTransport) { * R: setRTS - 1=True / 0=False * * W: Wait (time delay) - positive integer number (miliseconds) - * @param {AbstractTransport} transport Transport class to perform serial communication. + * @param {ISerialTransport} transport Transport class to perform serial communication. * @param {boolean} usingUsbOtg is it using USB-OTG ? */ -export async function hardReset(transport: AbstractTransport, usingUsbOtg = false) { - await transport.setRTS(true); - if (usingUsbOtg) { - await sleep(200); - await transport.setRTS(false); - await sleep(200); - } else { - await sleep(100); - await transport.setRTS(false); - } +export async function hardReset(transport: ISerialTransport, usingUsbOtg = false) { + const resetSequence = usingUsbOtg ? `R1|W200|R0|W200` : `R1|W100|R0`; + await customReset(transport, resetSequence); } type CmdsArgsTypes = { @@ -161,10 +134,10 @@ export function validateCustomResetStringSequence(seqStr: string): boolean { * W: Wait (time delay) - positive integer number (miliseconds) * * "D0|R1|W100|D1|R0|W50|D0" represents the classic reset strategy - * @param {AbstractTransport} transport Transport class to perform serial communication. + * @param {ISerialTransport} transport Transport class to perform serial communication. * @param {string} sequenceString Custom string sequence for reset strategy */ -export async function customReset(transport: AbstractTransport, sequenceString: string) { +export async function customReset(transport: ISerialTransport, sequenceString: string) { const resetDictionary: { [K in keyof CmdsArgsTypes]: (arg: CmdsArgsTypes[K]) => Promise } = { D: async (arg: boolean) => await transport.setDTR(arg), R: async (arg: boolean) => await transport.setRTS(arg), diff --git a/src/transport/AbstractTransport.ts b/src/transport/ISerialTransport.ts similarity index 75% rename from src/transport/AbstractTransport.ts rename to src/transport/ISerialTransport.ts index 7353a6c2..0f069e38 100644 --- a/src/transport/AbstractTransport.ts +++ b/src/transport/ISerialTransport.ts @@ -13,34 +13,35 @@ export interface ISerialOptions { /** * Template to define Transport class which can be consumed by the ESPLoader. * A Webserial reference implementation is found at src/transport/WebSerialTransport.ts + * @interface ISerialTransport */ -export abstract class AbstractTransport { - public abstract tracing: boolean; - public abstract leftOver: Uint8Array; +export interface ISerialTransport { + tracing: boolean; + leftOver: Uint8Array; /** * Request the serial device information as string. * @returns {string} Return the serial device information as formatted string. */ - public abstract getInfo(): string; + getInfo(): string; /** * Request the serial device product id. * @returns {number | undefined} Return the product ID. */ - public abstract getPID(): number | undefined; + getPID(): number | undefined; /** * Format received or sent data for tracing output. * @param {string} message Message to format as trace line. */ - public abstract trace(message: string): void; + trace(message: string): void; /** * Write binary data to device. * @param {Uint8Array} data 8 bit unsigned data array to write to device. */ - public abstract write(data: Uint8Array): Promise; + write(data: Uint8Array): Promise; /** * Read from serial device without formatting. @@ -49,30 +50,30 @@ export abstract class AbstractTransport { * @param {Uint8Array} packet Unsigned 8 bit array from the device read stream. * @returns {Promise} 8 bit unsigned data array read from device. */ - public abstract rawRead(timeout?: number, minData?: number, packet?: Uint8Array): Promise; + read(timeout?: number, minData?: number, packet?: Uint8Array): Promise; /** * Send the RequestToSend (RTS) signal to given state * # True for EN=LOW, chip in reset and False EN=HIGH, chip out of reset * @param {boolean} state Boolean state to set the signal */ - public abstract setRTS(state: boolean): Promise; + setRTS(state: boolean): Promise; /** * Send the dataTerminalReady (DTS) signal to given state * # True for IO0=LOW, chip in reset and False IO0=HIGH * @param {boolean} state Boolean state to set the signal */ - public abstract setDTR(state: boolean): Promise; + setDTR(state: boolean): Promise; /** * Connect to serial device using the Webserial open method. * @param {ISerialOptions} serialOptions Serial Options for WebUSB SerialPort class. */ - public abstract connect(serialOptions: ISerialOptions): Promise; + connect(serialOptions: ISerialOptions): Promise; /** * Disconnect from serial device by running SerialPort.close() after streams unlock. */ - public abstract disconnect(): Promise; + disconnect(): Promise; } diff --git a/src/transport/WebSerialTransport.ts b/src/transport/WebSerialTransport.ts index e811e5a4..28de6e34 100644 --- a/src/transport/WebSerialTransport.ts +++ b/src/transport/WebSerialTransport.ts @@ -1,6 +1,6 @@ /* global SerialPort, ParityType, FlowControlType */ -import { AbstractTransport, ISerialOptions } from "./AbstractTransport"; +import { ISerialTransport, ISerialOptions } from "./ISerialTransport"; import { hexConvert } from "../utils/hex"; import { appendArray } from "../utils/convert"; @@ -49,7 +49,7 @@ export interface SerialOptions extends ISerialOptions { * const port = await navigator.serial.requestPort(); * ``` */ -export class WebSerialTransport implements AbstractTransport { +export class WebSerialTransport implements ISerialTransport { public leftOver = new Uint8Array(0); private traceLog = ""; private lastTraceTime = Date.now(); @@ -102,7 +102,7 @@ export class WebSerialTransport implements AbstractTransport { /** * Write binary data to device using the WebSerial device writable stream. - * @param {Uint8Array} data 8 bit unsigned data array to write to device. + * @param {Uint8Array} outData 8 bit unsigned data array to write to device. */ async write(outData: Uint8Array) { if (this.device.writable) { @@ -123,7 +123,7 @@ export class WebSerialTransport implements AbstractTransport { * @param {Uint8Array} packet Unsigned 8 bit array from the device read stream. * @returns {Promise} 8 bit unsigned data array read from device. */ - async rawRead(timeout: number = 0, minData: number = 0, packet?: Uint8Array): Promise { + async read(timeout: number = 0, minData: number = 0, packet?: Uint8Array): Promise { if (this.leftOver.length != 0) { const p = this.leftOver; this.leftOver = new Uint8Array(0); diff --git a/src/utils/slip.ts b/src/utils/slip.ts index c9f57efe..78949f8d 100644 --- a/src/utils/slip.ts +++ b/src/utils/slip.ts @@ -1,4 +1,4 @@ -import { AbstractTransport } from "../transport/AbstractTransport"; +import { ISerialTransport } from "../transport/ISerialTransport"; import { hexConvert } from "./hex"; /** @@ -21,11 +21,11 @@ export interface SlipReaderOutput { /** * Class to handle SLIP read and write serial methods. - * @param {AbstractTransport} transport Transport object with raw read and write serial methods + * @param {ISerialTransport} transport Transport object with raw read and write serial methods * @param {boolean} enableSlipRead Enable or disable read SLIP data formatting. */ export class Slip { - constructor(private transport: AbstractTransport, public enableSlipRead: boolean = false) {} + constructor(private transport: ISerialTransport, public enableSlipRead: boolean = false) {} /** * Format data packet using the Serial Line Internet Protocol (SLIP). @@ -117,7 +117,7 @@ export class Slip { packet = this.transport.leftOver; this.transport.leftOver = new Uint8Array(0); } - packet = await this.transport.rawRead(timeout, minData, packet); + packet = await this.transport.read(timeout, minData, packet); if (this.transport.tracing) { this.transport.trace("Read SLIP bytes"); From edc96c8794ce6319d340d7ca990b9ccad7384c8a Mon Sep 17 00:00:00 2001 From: Brian Ignacio Date: Fri, 15 Mar 2024 22:06:14 +0800 Subject: [PATCH 09/13] move trace to trace object --- examples/typescript/src/index.ts | 37 +++++++++++++++++++++----- src/esploader.ts | 15 +++++++++-- src/index.ts | 1 + src/transport/ISerialTransport.ts | 7 ----- src/transport/WebSerialTransport.ts | 41 ++++++----------------------- src/utils/ITrace.ts | 18 +++++++++++++ src/utils/slip.ts | 18 +++++++------ 7 files changed, 81 insertions(+), 56 deletions(-) create mode 100644 src/utils/ITrace.ts diff --git a/examples/typescript/src/index.ts b/examples/typescript/src/index.ts index 019add94..8dc41bb1 100644 --- a/examples/typescript/src/index.ts +++ b/examples/typescript/src/index.ts @@ -23,7 +23,7 @@ const alertDiv = document.getElementById("alertDiv"); // This is a frontend example of Esptool-JS using local bundle file // To optimize use a CDN hosted version like // https://unpkg.com/esptool-js/bundle.js -import { ESPLoader, FlashOptions, LoaderOptions, WebSerialTransport, SerialOptions } from "../../../lib"; +import { ESPLoader, FlashOptions, LoaderOptions, WebSerialTransport, SerialOptions, ITrace } from "../../../lib"; declare let Terminal; // Terminal is imported in HTML script declare let CryptoJS; // CryptoJS is imported in HTML script @@ -79,10 +79,35 @@ const espLoaderTerminal = { }, }; +class TraceObject implements ITrace { + traceBuffer: string; + private lastTraceTime = Date.now(); + + trace(message: string) { + const delta = Date.now() - this.lastTraceTime; + const prefix = `TRACE ${delta.toFixed(3)}`; + const traceMessage = `${prefix} ${message}`; + console.log(traceMessage); + this.traceBuffer += traceMessage + "\n"; + } + + async returnTrace() { + try { + await navigator.clipboard.writeText(this.traceBuffer); + console.log("Text copied to clipboard!"); + } catch (err) { + console.error("Failed to copy text:", err); + } + return this.traceBuffer; + } +} + +const traceObj = new TraceObject(); + connectButton.onclick = async () => { if (device === null) { device = await navigator.serial.requestPort({}); - transport = new WebSerialTransport(device, true); + transport = new WebSerialTransport(device, traceObj); } const serialOptions = { baudRate: parseInt(baudrates.value) } as SerialOptions; @@ -118,8 +143,8 @@ connectButton.onclick = async () => { }; traceButton.onclick = async () => { - if (transport) { - transport.returnTrace(); + if (traceObj) { + traceObj.returnTrace(); } }; @@ -233,7 +258,7 @@ let isConsoleClosed = false; consoleStartButton.onclick = async () => { if (device === null) { device = await navigator.serial.requestPort({}); - transport = new WebSerialTransport(device, true); + transport = new WebSerialTransport(device, traceObj); } lblConsoleFor.style.display = "block"; lblConsoleBaudrate.style.display = "none"; @@ -248,7 +273,7 @@ consoleStartButton.onclick = async () => { isConsoleClosed = false; while (true && !isConsoleClosed) { - const val = await transport.rawRead(); + const val = await transport.read(); if (typeof val !== "undefined") { term.write(val); } else { diff --git a/src/esploader.ts b/src/esploader.ts index 444b4205..a06f84b9 100644 --- a/src/esploader.ts +++ b/src/esploader.ts @@ -7,6 +7,7 @@ import { ISerialTransport, ISerialOptions } from "./transport/ISerialTransport.j import { hexConvert } from "./utils/hex"; import { appendArray, bstrToUi8, byteArrayToInt, intToByteArray, shortToBytearray, ui8ToBstr } from "./utils/convert"; import { Slip } from "./utils/slip"; +import { ITrace } from "./utils/ITrace"; /** * Options for flashing a device with firmware. @@ -134,6 +135,12 @@ export interface LoaderOptions { * @type {ResetFunctions} */ resetFunctions?: ResetFunctions; + + /** + * The Trace object to log all communication output. + * @type {ITrace} + */ + tracer?: ITrace; } /** @@ -287,6 +294,7 @@ export class ESPLoader { private debugLogging = false; private resetFunctions: ResetFunctions; private slip: Slip; + private tracer?: ITrace; /** * Create a new ESPLoader to perform serial communication @@ -329,6 +337,9 @@ export class ESPLoader { if (typeof options.debugLogging !== "undefined") { this.debugLogging = options.debugLogging; } + if (options.tracer) { + this.tracer = options.tracer; + } this.slip = new Slip(this.transport); this.info("esptool.js"); @@ -440,8 +451,8 @@ export class ESPLoader { timeout: number = 3000, ): Promise<[number, Uint8Array]> { if (op != null) { - if (this.transport.tracing) { - this.transport.trace( + if (this.tracer) { + this.tracer.trace( `command op:0x${op.toString(16).padStart(2, "0")} data len=${data.length} wait_response=${ waitResponse ? 1 : 0 } timeout=${(timeout / 1000).toFixed(3)} data=${hexConvert(data)}`, diff --git a/src/index.ts b/src/index.ts index bd95d891..d526fad4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,3 +17,4 @@ export { ResetFunctions, } from "./esploader.js"; export { Slip, SlipReaderOutput } from "./utils/slip.js"; +export { ITrace } from "./utils/ITrace.js"; diff --git a/src/transport/ISerialTransport.ts b/src/transport/ISerialTransport.ts index 0f069e38..6cb72999 100644 --- a/src/transport/ISerialTransport.ts +++ b/src/transport/ISerialTransport.ts @@ -16,7 +16,6 @@ export interface ISerialOptions { * @interface ISerialTransport */ export interface ISerialTransport { - tracing: boolean; leftOver: Uint8Array; /** @@ -31,12 +30,6 @@ export interface ISerialTransport { */ getPID(): number | undefined; - /** - * Format received or sent data for tracing output. - * @param {string} message Message to format as trace line. - */ - trace(message: string): void; - /** * Write binary data to device. * @param {Uint8Array} data 8 bit unsigned data array to write to device. diff --git a/src/transport/WebSerialTransport.ts b/src/transport/WebSerialTransport.ts index 28de6e34..7838066b 100644 --- a/src/transport/WebSerialTransport.ts +++ b/src/transport/WebSerialTransport.ts @@ -3,6 +3,7 @@ import { ISerialTransport, ISerialOptions } from "./ISerialTransport"; import { hexConvert } from "../utils/hex"; import { appendArray } from "../utils/convert"; +import { ITrace } from "../utils/ITrace"; /** * Options for device serialPort. @@ -51,11 +52,9 @@ export interface SerialOptions extends ISerialOptions { */ export class WebSerialTransport implements ISerialTransport { public leftOver = new Uint8Array(0); - private traceLog = ""; - private lastTraceTime = Date.now(); private reader: ReadableStreamDefaultReader | undefined; - constructor(public device: SerialPort, public tracing = false) {} + constructor(public device: SerialPort, private tracer?: ITrace) {} /** * Request the serial device vendor ID and Product ID as string. @@ -76,30 +75,6 @@ export class WebSerialTransport implements ISerialTransport { return this.device.getInfo().usbProductId; } - /** - * Format received or sent data for tracing output. - * @param {string} message Message to format as trace line. - */ - trace(message: string) { - const delta = Date.now() - this.lastTraceTime; - const prefix = `TRACE ${delta.toFixed(3)}`; - const traceMessage = `${prefix} ${message}`; - console.log(traceMessage); - this.traceLog += traceMessage + "\n"; - } - - /** - * Return the whole trace output to the user clipboard. - */ - async returnTrace() { - try { - await navigator.clipboard.writeText(this.traceLog); - console.log("Text copied to clipboard!"); - } catch (err) { - console.error("Failed to copy text:", err); - } - } - /** * Write binary data to device using the WebSerial device writable stream. * @param {Uint8Array} outData 8 bit unsigned data array to write to device. @@ -107,9 +82,9 @@ export class WebSerialTransport implements ISerialTransport { async write(outData: Uint8Array) { if (this.device.writable) { const writer = this.device.writable.getWriter(); - if (this.tracing) { - console.log("Write bytes"); - this.trace(`Write ${outData.length} bytes: ${hexConvert(outData)}`); + if (this.tracer) { + this.tracer.trace("Write bytes"); + this.tracer.trace(`Write ${outData.length} bytes: ${hexConvert(outData)}`); } await writer.write(outData); writer.releaseLock(); @@ -152,9 +127,9 @@ export class WebSerialTransport implements ISerialTransport { this.leftOver = packet; throw new Error("Timeout"); } - if (this.tracing) { - console.log("Raw Read bytes"); - this.trace(`Read ${value.length} bytes: ${hexConvert(value)}`); + if (this.tracer) { + this.tracer.trace("Raw Read bytes"); + this.tracer.trace(`Read ${value.length} bytes: ${hexConvert(value)}`); } const p = appendArray(packet, value); packet = p; diff --git a/src/utils/ITrace.ts b/src/utils/ITrace.ts new file mode 100644 index 00000000..c9efb08e --- /dev/null +++ b/src/utils/ITrace.ts @@ -0,0 +1,18 @@ +export interface ITrace { + /** + * Buffer with all trace messages. + * @type {string} + */ + traceBuffer: string; + + /** + * Send message for tracing output. + * @param {string} message Message to format as trace line. + */ + trace(message: string): void; + + /** + * Method to return content of tracing buffer. + */ + returnTrace(): Promise; +} diff --git a/src/utils/slip.ts b/src/utils/slip.ts index 78949f8d..568e25c7 100644 --- a/src/utils/slip.ts +++ b/src/utils/slip.ts @@ -1,4 +1,5 @@ import { ISerialTransport } from "../transport/ISerialTransport"; +import { ITrace } from "./ITrace"; import { hexConvert } from "./hex"; /** @@ -22,10 +23,11 @@ export interface SlipReaderOutput { /** * Class to handle SLIP read and write serial methods. * @param {ISerialTransport} transport Transport object with raw read and write serial methods - * @param {boolean} enableSlipRead Enable or disable read SLIP data formatting. + * @param {boolean} enableSlipRead Enable or disable read SLIP data formatting. + * @param {ITrace} trace Object that log or trace all serial messages. */ export class Slip { - constructor(private transport: ISerialTransport, public enableSlipRead: boolean = false) {} + constructor(private transport: ISerialTransport, public enableSlipRead: boolean = false, private tracer?: ITrace) {} /** * Format data packet using the Serial Line Internet Protocol (SLIP). @@ -119,17 +121,17 @@ export class Slip { } packet = await this.transport.read(timeout, minData, packet); - if (this.transport.tracing) { - this.transport.trace("Read SLIP bytes"); - this.transport.trace(`Read ${packet.length} bytes: ${hexConvert(packet)}`); + if (this.tracer) { + this.tracer.trace("Read SLIP bytes"); + this.tracer.trace(`Read ${packet.length} bytes: ${hexConvert(packet)}`); } if (this.enableSlipRead) { const slipReaderResult = this.decode(packet); this.transport.leftOver = slipReaderResult.newLeftOver; - if (this.transport.tracing) { - this.transport.trace("Slip reader results"); - this.transport.trace(`Read ${slipReaderResult.packet.length} bytes: ${hexConvert(slipReaderResult.packet)}`); + if (this.tracer) { + this.tracer.trace("Slip reader results"); + this.tracer.trace(`Read ${slipReaderResult.packet.length} bytes: ${hexConvert(slipReaderResult.packet)}`); } return slipReaderResult.packet; } From 02444a7e88964657515214f29bbe4dbfc93034ed Mon Sep 17 00:00:00 2001 From: Brian Ignacio Date: Mon, 18 Mar 2024 18:25:32 +0800 Subject: [PATCH 10/13] rm packet from read arg --- src/transport/ISerialTransport.ts | 2 +- src/transport/WebSerialTransport.ts | 6 ++---- src/utils/slip.ts | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/transport/ISerialTransport.ts b/src/transport/ISerialTransport.ts index 6cb72999..cc8ab283 100644 --- a/src/transport/ISerialTransport.ts +++ b/src/transport/ISerialTransport.ts @@ -43,7 +43,7 @@ export interface ISerialTransport { * @param {Uint8Array} packet Unsigned 8 bit array from the device read stream. * @returns {Promise} 8 bit unsigned data array read from device. */ - read(timeout?: number, minData?: number, packet?: Uint8Array): Promise; + read(timeout?: number, minData?: number): Promise; /** * Send the RequestToSend (RTS) signal to given state diff --git a/src/transport/WebSerialTransport.ts b/src/transport/WebSerialTransport.ts index 7838066b..9055ebf6 100644 --- a/src/transport/WebSerialTransport.ts +++ b/src/transport/WebSerialTransport.ts @@ -98,7 +98,7 @@ export class WebSerialTransport implements ISerialTransport { * @param {Uint8Array} packet Unsigned 8 bit array from the device read stream. * @returns {Promise} 8 bit unsigned data array read from device. */ - async read(timeout: number = 0, minData: number = 0, packet?: Uint8Array): Promise { + async read(timeout: number = 0, minData: number = 0): Promise { if (this.leftOver.length != 0) { const p = this.leftOver; this.leftOver = new Uint8Array(0); @@ -109,9 +109,7 @@ export class WebSerialTransport implements ISerialTransport { } this.reader = this.device.readable.getReader(); let t; - if (!packet) { - packet = this.leftOver; - } + let packet = this.leftOver; try { if (timeout > 0) { t = setTimeout(() => { diff --git a/src/utils/slip.ts b/src/utils/slip.ts index 568e25c7..d57680eb 100644 --- a/src/utils/slip.ts +++ b/src/utils/slip.ts @@ -119,7 +119,7 @@ export class Slip { packet = this.transport.leftOver; this.transport.leftOver = new Uint8Array(0); } - packet = await this.transport.read(timeout, minData, packet); + packet = await this.transport.read(timeout, minData); if (this.tracer) { this.tracer.trace("Read SLIP bytes"); From 4e04a9db182e5c95c2047f9a15e7da33e6fac10f Mon Sep 17 00:00:00 2001 From: Brian Ignacio Date: Wed, 20 Mar 2024 14:43:42 +0800 Subject: [PATCH 11/13] fix lint add js extension import --- src/esploader.ts | 15 +++++++++++---- src/reset.ts | 2 +- src/transport/WebSerialTransport.ts | 9 ++++----- src/utils/slip.ts | 6 +++--- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/esploader.ts b/src/esploader.ts index a06f84b9..90f0ab49 100644 --- a/src/esploader.ts +++ b/src/esploader.ts @@ -4,10 +4,17 @@ import { ESPError } from "./error.js"; import { ROM } from "./targets/rom.js"; import { classicReset, customReset, hardReset, usbJTAGSerialReset } from "./reset.js"; import { ISerialTransport, ISerialOptions } from "./transport/ISerialTransport.js"; -import { hexConvert } from "./utils/hex"; -import { appendArray, bstrToUi8, byteArrayToInt, intToByteArray, shortToBytearray, ui8ToBstr } from "./utils/convert"; -import { Slip } from "./utils/slip"; -import { ITrace } from "./utils/ITrace"; +import { hexConvert } from "./utils/hex.js"; +import { + appendArray, + bstrToUi8, + byteArrayToInt, + intToByteArray, + shortToBytearray, + ui8ToBstr, +} from "./utils/convert.js"; +import { Slip } from "./utils/slip.js"; +import { ITrace } from "./utils/ITrace.js"; /** * Options for flashing a device with firmware. diff --git a/src/reset.ts b/src/reset.ts index ae7f911c..3623a180 100644 --- a/src/reset.ts +++ b/src/reset.ts @@ -1,4 +1,4 @@ -import { ISerialTransport } from "./transport/ISerialTransport"; +import { ISerialTransport } from "./transport/ISerialTransport.js"; const DEFAULT_RESET_DELAY = 50; diff --git a/src/transport/WebSerialTransport.ts b/src/transport/WebSerialTransport.ts index 9055ebf6..1d56603f 100644 --- a/src/transport/WebSerialTransport.ts +++ b/src/transport/WebSerialTransport.ts @@ -1,9 +1,9 @@ /* global SerialPort, ParityType, FlowControlType */ -import { ISerialTransport, ISerialOptions } from "./ISerialTransport"; -import { hexConvert } from "../utils/hex"; -import { appendArray } from "../utils/convert"; -import { ITrace } from "../utils/ITrace"; +import { ISerialTransport, ISerialOptions } from "./ISerialTransport.js"; +import { hexConvert } from "../utils/hex.js"; +import { appendArray } from "../utils/convert.js"; +import { ITrace } from "../utils/ITrace.js"; /** * Options for device serialPort. @@ -95,7 +95,6 @@ export class WebSerialTransport implements ISerialTransport { * Read from serial device without slip formatting. * @param {number} timeout Read timeout in milliseconds (ms) * @param {number} minData Minimum packet array length - * @param {Uint8Array} packet Unsigned 8 bit array from the device read stream. * @returns {Promise} 8 bit unsigned data array read from device. */ async read(timeout: number = 0, minData: number = 0): Promise { diff --git a/src/utils/slip.ts b/src/utils/slip.ts index d57680eb..b1d724df 100644 --- a/src/utils/slip.ts +++ b/src/utils/slip.ts @@ -1,6 +1,6 @@ -import { ISerialTransport } from "../transport/ISerialTransport"; -import { ITrace } from "./ITrace"; -import { hexConvert } from "./hex"; +import { ISerialTransport } from "../transport/ISerialTransport.js"; +import { ITrace } from "./ITrace.js"; +import { hexConvert } from "./hex.js"; /** * Slip reader output packet and left over as Uint8Array. From d388c71d1e0a633e2293818e5c32d9cea2f92d44 Mon Sep 17 00:00:00 2001 From: Brian Ignacio Date: Tue, 26 Mar 2024 17:48:39 +0800 Subject: [PATCH 12/13] fix crystal freq wrong baudrate fix lint --- examples/typescript/src/index.ts | 1 + src/esploader.ts | 10 ++-------- src/targets/esp32.ts | 2 +- src/targets/esp32c2.ts | 2 +- src/targets/esp8266.ts | 2 +- src/transport/WebSerialTransport.ts | 3 +-- 6 files changed, 7 insertions(+), 13 deletions(-) diff --git a/examples/typescript/src/index.ts b/examples/typescript/src/index.ts index 8dc41bb1..bb4531d1 100644 --- a/examples/typescript/src/index.ts +++ b/examples/typescript/src/index.ts @@ -117,6 +117,7 @@ connectButton.onclick = async () => { transport, serialOptions, terminal: espLoaderTerminal, + tracer: traceObj, } as LoaderOptions; esploader = new ESPLoader(loaderOptions); diff --git a/src/esploader.ts b/src/esploader.ts index 90f0ab49..15f1d57f 100644 --- a/src/esploader.ts +++ b/src/esploader.ts @@ -131,12 +131,6 @@ export interface LoaderOptions { */ debugLogging?: boolean; - /** - * Flag indicating whether to enable tracing for the loader (optional). - * @type {boolean} - */ - enableTracing?: boolean; - /** * Reset functions for connection. If undefined will use default ones. * @type {ResetFunctions} @@ -296,7 +290,7 @@ export class ESPLoader { public transport: ISerialTransport; private terminal?: IEspLoaderTerminal; - private romBaudrate = 115200; + public romBaudrate = 115200; public serialOptions: SerialOptions; private debugLogging = false; private resetFunctions: ResetFunctions; @@ -347,7 +341,7 @@ export class ESPLoader { if (options.tracer) { this.tracer = options.tracer; } - this.slip = new Slip(this.transport); + this.slip = new Slip(this.transport, false, options.tracer); this.info("esptool.js"); this.info("Serial port " + this.transport.getInfo()); diff --git a/src/targets/esp32.ts b/src/targets/esp32.ts index cc101dea..ea448cdc 100644 --- a/src/targets/esp32.ts +++ b/src/targets/esp32.ts @@ -163,7 +163,7 @@ export class ESP32ROM extends ROM { public async getCrystalFreq(loader: ESPLoader) { const uartDiv = (await loader.readReg(this.UART_CLKDIV_REG)) & this.UART_CLKDIV_MASK; - const etsXtal = (loader.serialOptions.baudRate * uartDiv) / 1000000 / this.XTAL_CLK_DIVIDER; + const etsXtal = (loader.romBaudrate * uartDiv) / 1000000 / this.XTAL_CLK_DIVIDER; let normXtal; if (etsXtal > 33) { normXtal = 40; diff --git a/src/targets/esp32c2.ts b/src/targets/esp32c2.ts index 6005c946..5a8e1038 100644 --- a/src/targets/esp32c2.ts +++ b/src/targets/esp32c2.ts @@ -74,7 +74,7 @@ export class ESP32C2ROM extends ROM { public async getCrystalFreq(loader: ESPLoader) { const uartDiv = (await loader.readReg(this.UART_CLKDIV_REG)) & this.UART_CLKDIV_MASK; - const etsXtal = (loader.serialOptions.baudRate * uartDiv) / 1000000 / this.XTAL_CLK_DIVIDER; + const etsXtal = (loader.romBaudrate * uartDiv) / 1000000 / this.XTAL_CLK_DIVIDER; let normXtal; if (etsXtal > 33) { normXtal = 40; diff --git a/src/targets/esp8266.ts b/src/targets/esp8266.ts index 8c2216f8..acd3c695 100644 --- a/src/targets/esp8266.ts +++ b/src/targets/esp8266.ts @@ -64,7 +64,7 @@ export class ESP8266ROM extends ROM { public async getCrystalFreq(loader: ESPLoader) { const uartDiv = (await loader.readReg(this.UART_CLKDIV_REG)) & this.UART_CLKDIV_MASK; - const etsXtal = (loader.serialOptions.baudRate * uartDiv) / 1000000 / this.XTAL_CLK_DIVIDER; + const etsXtal = (loader.romBaudrate * uartDiv) / 1000000 / this.XTAL_CLK_DIVIDER; let normXtal; if (etsXtal > 33) { normXtal = 40; diff --git a/src/transport/WebSerialTransport.ts b/src/transport/WebSerialTransport.ts index 1d56603f..17f2411e 100644 --- a/src/transport/WebSerialTransport.ts +++ b/src/transport/WebSerialTransport.ts @@ -128,8 +128,7 @@ export class WebSerialTransport implements ISerialTransport { this.tracer.trace("Raw Read bytes"); this.tracer.trace(`Read ${value.length} bytes: ${hexConvert(value)}`); } - const p = appendArray(packet, value); - packet = p; + packet = appendArray(packet, value); } while (packet.length < minData); return packet; } finally { From 1459bda9df5049ca3b11ac8e16cde86943b11fd4 Mon Sep 17 00:00:00 2001 From: Brian Ignacio Date: Tue, 28 May 2024 17:55:43 +0800 Subject: [PATCH 13/13] make reset functions optional --- src/esploader.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/esploader.ts b/src/esploader.ts index 15f1d57f..ca2bdfce 100644 --- a/src/esploader.ts +++ b/src/esploader.ts @@ -78,22 +78,22 @@ export interface ResetFunctions { /** * Execute a classic set of commands that will reset the chip. */ - classicReset: (transport: ISerialTransport, resetDelay?: number) => Promise; + classicReset?: (transport: ISerialTransport, resetDelay?: number) => Promise; /** * Execute a set of commands for USB JTAG serial reset. */ - usbJTAGSerialReset: (transport: ISerialTransport) => Promise; + usbJTAGSerialReset?: (transport: ISerialTransport) => Promise; /** * Execute a set of commands that will hard reset the chip. */ - hardReset: (transport: ISerialTransport, usingUsbOtg?: boolean) => Promise; + hardReset?: (transport: ISerialTransport, usingUsbOtg?: boolean) => Promise; /** * Custom reset strategy defined with a string. */ - customReset: (transport: ISerialTransport, sequenceString: string) => Promise; + customReset?: (transport: ISerialTransport, sequenceString: string) => Promise; } /** @@ -563,10 +563,14 @@ export class ESPLoader { if (this.transport.getPID() === this.USB_JTAG_SERIAL_PID) { // Custom reset sequence, which is required when the device // is connecting via its USB-JTAG-Serial peripheral - await this.resetFunctions.usbJTAGSerialReset(this.transport); + if (this.resetFunctions.usbJTAGSerialReset) { + await this.resetFunctions.usbJTAGSerialReset(this.transport); + } } else { const strSequence = esp32r0Delay ? "D0|R1|W100|W2000|D1|R0|W50|D0" : "D0|R1|W100|D1|R0|W50|D0"; - await this.resetFunctions.customReset(this.transport, strSequence); + if (this.resetFunctions.customReset) { + await this.resetFunctions.customReset(this.transport, strSequence); + } } } let i = 0;