From a3508c8f3d3e1e7191ea767dc3b40b6cb661deff Mon Sep 17 00:00:00 2001 From: Brian Ignacio Date: Thu, 1 Feb 2024 18:27:45 +0800 Subject: [PATCH] move read to slipRead in util --- src/esploader.ts | 9 +-- src/transport/AbstractTransport.ts | 13 ++--- src/transport/WebSerialTransport.ts | 91 ++++++----------------------- src/utils/slip.ts | 48 ++++++++++++++- 4 files changed, 75 insertions(+), 86 deletions(-) diff --git a/src/esploader.ts b/src/esploader.ts index 554b1f5c..8627539f 100644 --- a/src/esploader.ts +++ b/src/esploader.ts @@ -5,6 +5,7 @@ import { ROM } from "./targets/rom"; import { classicReset, customReset, hardReset, usbJTAGSerialReset } from "./reset"; import { hexConvert } from "./utils/hex"; import { appendArray, bstrToUi8, byteArrayToInt, intToByteArray, shortToBytearray, ui8ToBstr } from "./utils/convert"; +import { slipRead } from "./utils/slip"; /** * Options for flashing a device with firmware. @@ -395,7 +396,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 this.transport.read(timeout); + const p = await slipRead(this.transport, timeout); const resp = p[0]; const opRet = p[1]; const val = byteArrayToInt(p[4], p[5], p[6], p[7]); @@ -549,7 +550,7 @@ export class ESPLoader { let keepReading = true; while (keepReading) { try { - const res = await this.transport.read(1000); + const res = await slipRead(this.transport, 1000); i += res.length; } catch (e) { this.debug((e as Error).message); @@ -1060,7 +1061,7 @@ export class ESPLoader { let resp = new Uint8Array(0); while (resp.length < size) { - const packet = await this.transport.read(this.FLASH_READ_TIMEOUT); + const packet = await slipRead(this.transport, this.FLASH_READ_TIMEOUT); if (packet instanceof Uint8Array) { if (packet.length > 0) { @@ -1121,7 +1122,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 this.transport.read(1000, 6); + const res = await slipRead(this.transport, 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/transport/AbstractTransport.ts b/src/transport/AbstractTransport.ts index e8ef7bd6..0438e4c7 100644 --- a/src/transport/AbstractTransport.ts +++ b/src/transport/AbstractTransport.ts @@ -17,6 +17,7 @@ export interface ISerialOptions { export abstract class AbstractTransport { public abstract tracing: boolean; public abstract slipReaderEnabled: boolean; + public abstract leftOver: Uint8Array; /** * Request the serial device information as string. @@ -42,20 +43,14 @@ export abstract class AbstractTransport { */ public abstract write(data: Uint8Array): Promise; - /** - * Read from serial device. - * @param {number} timeout Read timeout number - * @param {number} minData Minimum packet array length - * @returns {Promise} 8 bit unsigned data array read from device. - */ - public abstract read(timeout?: number, minData?: number): Promise; - /** * Read from serial device without 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. */ - public abstract rawRead(timeout?: number): Promise; + public abstract rawRead(timeout?: number, minData?: number, packet?: Uint8Array): Promise; /** * Send the RequestToSend (RTS) signal to given state diff --git a/src/transport/WebSerialTransport.ts b/src/transport/WebSerialTransport.ts index f5971117..78cebeef 100644 --- a/src/transport/WebSerialTransport.ts +++ b/src/transport/WebSerialTransport.ts @@ -3,7 +3,7 @@ import { AbstractTransport, ISerialOptions } from "./AbstractTransport"; import { hexConvert } from "../utils/hex"; import { appendArray } from "../utils/convert"; -import { slipReader, slipWriter } from "../utils/slip"; +import { slipWriter } from "../utils/slip"; /** * Options for device serialPort. @@ -120,100 +120,47 @@ export class WebSerialTransport implements AbstractTransport { } /** - * Read from serial device using the device ReadableStream. - * @param {number} timeout Read timeout number + * 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 = 12): Promise { - let t; - let packet = this.leftOver; - this.leftOver = new Uint8Array(0); - if (this.slipReaderEnabled) { - const slipResult = slipReader(packet); - const valFinal = slipResult.packet; - this.leftOver = slipResult.newLeftOver; - if (valFinal.length > 0) { - return valFinal; - } - packet = this.leftOver; + async rawRead(timeout: number = 0, minData: number = 0, packet?: Uint8Array): Promise { + if (this.leftOver.length != 0) { + const p = this.leftOver; this.leftOver = new Uint8Array(0); + return p; } - if (this.device.readable == null) { + if (!this.device.readable) { return this.leftOver; } - const reader = this.device.readable.getReader(); + let t; + if (!packet) { + packet = this.leftOver; + } try { if (timeout > 0) { t = setTimeout(function () { reader.cancel(); }, timeout); } + do { const { value, done } = await reader.read(); if (done) { this.leftOver = packet; throw new Error("Timeout"); } + if (this.tracing) { + console.log("Raw Read bytes"); + this.trace(`Read ${value.length} bytes: ${hexConvert(value)}`); + } const p = appendArray(packet, value); packet = p; } while (packet.length < minData); - } finally { - if (timeout > 0) { - clearTimeout(t); - } - reader.releaseLock(); - } - - if (this.tracing) { - console.log("Read bytes"); - this.trace(`Read ${packet.length} bytes: ${hexConvert(packet)}`); - } - - if (this.slipReaderEnabled) { - const slipReaderResult = slipReader(packet); - this.leftOver = slipReaderResult.newLeftOver; - if (this.tracing) { - console.log("Slip reader results"); - this.trace(`Read ${slipReaderResult.packet.length} bytes: ${hexConvert(slipReaderResult.packet)}`); - } - return slipReaderResult.packet; - } - return packet; - } - - /** - * Read from serial device without slip formatting. - * @param {number} timeout Read timeout in milliseconds (ms) - * @returns {Promise} 8 bit unsigned data array read from device. - */ - async rawRead(timeout: number = 0): Promise { - if (this.leftOver.length != 0) { - const p = this.leftOver; - this.leftOver = new Uint8Array(0); - return p; - } - if (!this.device.readable) { - return this.leftOver; - } - const reader = this.device.readable.getReader(); - let t; - try { - if (timeout > 0) { - t = setTimeout(function () { - reader.cancel(); - }, timeout); - } - const { value, done } = await reader.read(); - if (done) { - throw new Error("Timeout"); - } - if (this.tracing) { - console.log("Raw Read bytes"); - this.trace(`Read ${value.length} bytes: ${hexConvert(value)}`); - } - return value; + return packet; } finally { if (timeout > 0) { clearTimeout(t); diff --git a/src/utils/slip.ts b/src/utils/slip.ts index e0392d06..72c2621e 100644 --- a/src/utils/slip.ts +++ b/src/utils/slip.ts @@ -1,3 +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. @@ -25,7 +28,7 @@ export function slipWriter(data: Uint8Array): Uint8Array { * @param {Uint8Array} data Unsigned 8 bit array from the device read stream. * @returns Formatted packet using SLIP escape sequences. */ -export function slipReader(data: Uint8Array): { packet: Uint8Array; newLeftOver: Uint8Array } { +export function slipReaderFormat(data: Uint8Array): { packet: Uint8Array; newLeftOver: Uint8Array } { let i = 0; let dataStart = 0, dataEnd = 0; @@ -68,3 +71,46 @@ export function slipReader(data: Uint8Array): { packet: Uint8Array; newLeftOver: return { packet, newLeftOver }; } + +/** + * 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. + */ +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; + } + packet = transport.leftOver; + transport.leftOver = new Uint8Array(0); + } + + packet = await transport.rawRead(timeout, minData, packet); + + if (transport.tracing) { + console.log("Read bytes"); + transport.trace(`Read ${packet.length} bytes: ${hexConvert(packet)}`); + } + + if (transport.slipReaderEnabled) { + const slipReaderResult = slipReaderFormat(packet); + transport.leftOver = slipReaderResult.newLeftOver; + if (transport.tracing) { + console.log("Slip reader results"); + transport.trace(`Read ${slipReaderResult.packet.length} bytes: ${hexConvert(slipReaderResult.packet)}`); + } + return slipReaderResult.packet; + } + return packet; +}