mirror of
https://github.com/alexandrebobkov/ESP-Nodes.git
synced 2025-08-08 09:50:52 +00:00
199 lines
6.0 KiB
JavaScript
199 lines
6.0 KiB
JavaScript
/**
|
|
* Sleep for ms milliseconds
|
|
* @param {number} ms Milliseconds to wait
|
|
* @returns {Promise<void>}
|
|
*/
|
|
function sleep(ms) {
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
}
|
|
/**
|
|
* Execute a classic set of commands that will reset the chip.
|
|
*
|
|
* Commands (e.g. R0) are defined by a code (R) and an argument (0).
|
|
*
|
|
* The commands are:
|
|
*
|
|
* D: setDTR - 1=True / 0=False
|
|
*
|
|
* R: setRTS - 1=True / 0=False
|
|
*
|
|
* W: Wait (time delay) - positive integer number (miliseconds)
|
|
*
|
|
* "D0|R1|W100|D1|R0|W50|D0" represents the classic reset strategy
|
|
* @param {Transport} transport Transport class to perform serial communication.
|
|
* @param {number} resetDelay Delay in milliseconds for reset.
|
|
*/
|
|
export class ClassicReset {
|
|
constructor(transport, resetDelay) {
|
|
this.resetDelay = resetDelay;
|
|
this.transport = transport;
|
|
}
|
|
async reset() {
|
|
await this.transport.setDTR(false);
|
|
await this.transport.setRTS(true);
|
|
await sleep(100);
|
|
await this.transport.setDTR(true);
|
|
await this.transport.setRTS(false);
|
|
await sleep(this.resetDelay);
|
|
await this.transport.setDTR(false);
|
|
}
|
|
}
|
|
/**
|
|
* Execute a set of commands for USB JTAG serial reset.
|
|
*
|
|
* Commands (e.g. R0) are defined by a code (R) and an argument (0).
|
|
*
|
|
* The commands are:
|
|
*
|
|
* D: setDTR - 1=True / 0=False
|
|
*
|
|
* R: setRTS - 1=True / 0=False
|
|
*
|
|
* W: Wait (time delay) - positive integer number (miliseconds)
|
|
* @param {Transport} transport Transport class to perform serial communication.
|
|
*/
|
|
export class UsbJtagSerialReset {
|
|
constructor(transport) {
|
|
this.transport = transport;
|
|
}
|
|
async reset() {
|
|
await this.transport.setRTS(false);
|
|
await this.transport.setDTR(false);
|
|
await sleep(100);
|
|
await this.transport.setDTR(true);
|
|
await this.transport.setRTS(false);
|
|
await sleep(100);
|
|
await this.transport.setRTS(true);
|
|
await this.transport.setDTR(false);
|
|
await this.transport.setRTS(true);
|
|
await sleep(100);
|
|
await this.transport.setRTS(false);
|
|
await this.transport.setDTR(false);
|
|
}
|
|
}
|
|
/**
|
|
* Execute a set of commands that will hard reset the chip.
|
|
*
|
|
* Commands (e.g. R0) are defined by a code (R) and an argument (0).
|
|
*
|
|
* The commands are:
|
|
*
|
|
* D: setDTR - 1=True / 0=False
|
|
*
|
|
* R: setRTS - 1=True / 0=False
|
|
*
|
|
* W: Wait (time delay) - positive integer number (miliseconds)
|
|
* @param {Transport} transport Transport class to perform serial communication.
|
|
* @param {boolean} usingUsbOtg is it using USB-OTG ?
|
|
*/
|
|
export class HardReset {
|
|
constructor(transport, usingUsbOtg = false) {
|
|
this.transport = transport;
|
|
this.usingUsbOtg = usingUsbOtg;
|
|
this.transport = transport;
|
|
}
|
|
async reset() {
|
|
if (this.usingUsbOtg) {
|
|
await sleep(200);
|
|
await this.transport.setRTS(false);
|
|
await sleep(200);
|
|
}
|
|
else {
|
|
await sleep(100);
|
|
await this.transport.setRTS(false);
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* Validate a sequence string based on the following format:
|
|
*
|
|
* Commands (e.g. R0) are defined by a code (R) and an argument (0).
|
|
*
|
|
* The commands are:
|
|
*
|
|
* D: setDTR - 1=True / 0=False
|
|
*
|
|
* R: setRTS - 1=True / 0=False
|
|
*
|
|
* W: Wait (time delay) - positive integer number (miliseconds)
|
|
* @param {string} seqStr Sequence string to validate
|
|
* @returns {boolean} Is the sequence string valid ?
|
|
*/
|
|
export function validateCustomResetStringSequence(seqStr) {
|
|
const commands = ["D", "R", "W"];
|
|
const commandsList = seqStr.split("|");
|
|
for (const cmd of commandsList) {
|
|
const code = cmd[0];
|
|
const arg = cmd.slice(1);
|
|
if (!commands.includes(code)) {
|
|
return false; // Invalid command code
|
|
}
|
|
if (code === "D" || code === "R") {
|
|
if (arg !== "0" && arg !== "1") {
|
|
return false; // Invalid argument for D and R commands
|
|
}
|
|
}
|
|
else if (code === "W") {
|
|
const delay = parseInt(arg);
|
|
if (isNaN(delay) || delay <= 0) {
|
|
return false; // Invalid argument for W command
|
|
}
|
|
}
|
|
}
|
|
return true; // All commands are valid
|
|
}
|
|
/**
|
|
* Custom reset strategy defined with a string.
|
|
*
|
|
* The sequenceString input string consists of individual commands divided by "|".
|
|
*
|
|
* Commands (e.g. R0) are defined by a code (R) and an argument (0).
|
|
*
|
|
* The commands are:
|
|
*
|
|
* D: setDTR - 1=True / 0=False
|
|
*
|
|
* R: setRTS - 1=True / 0=False
|
|
*
|
|
* W: Wait (time delay) - positive integer number (miliseconds)
|
|
*
|
|
* "D0|R1|W100|D1|R0|W50|D0" represents the classic reset strategy
|
|
* @param {Transport} transport Transport class to perform serial communication.
|
|
* @param {string} sequenceString Custom string sequence for reset strategy
|
|
*/
|
|
export class CustomReset {
|
|
constructor(transport, sequenceString) {
|
|
this.transport = transport;
|
|
this.sequenceString = sequenceString;
|
|
this.transport = transport;
|
|
}
|
|
async reset() {
|
|
const resetDictionary = {
|
|
D: async (arg) => await this.transport.setDTR(arg),
|
|
R: async (arg) => await this.transport.setRTS(arg),
|
|
W: async (delay) => await sleep(delay),
|
|
};
|
|
try {
|
|
const isValidSequence = validateCustomResetStringSequence(this.sequenceString);
|
|
if (!isValidSequence) {
|
|
return;
|
|
}
|
|
const cmds = this.sequenceString.split("|");
|
|
for (const cmd of cmds) {
|
|
const cmdKey = cmd[0];
|
|
const cmdVal = cmd.slice(1);
|
|
if (cmdKey === "W") {
|
|
await resetDictionary["W"](Number(cmdVal));
|
|
}
|
|
else if (cmdKey === "D" || cmdKey === "R") {
|
|
await resetDictionary[cmdKey](cmdVal === "1");
|
|
}
|
|
}
|
|
}
|
|
catch (error) {
|
|
throw new Error("Invalid custom reset sequence");
|
|
}
|
|
}
|
|
}
|
|
export default { ClassicReset, CustomReset, HardReset, UsbJtagSerialReset, validateCustomResetStringSequence };
|