Skip to content

Commit 1a51b4c

Browse files
author
Ernesto Castellotti
authored
rootLantiq: Fix BREAK received on FTDI using Uint8Array directly (#214)
1 parent 7b36443 commit 1a51b4c

2 files changed

Lines changed: 124 additions & 36 deletions

File tree

assets/js/rootLantiq.js

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,38 @@ const LOAD_ADDR = "80800000"
22
const IMAGE0_ADDR = "C0000 740000";
33
const IMAGE1_ADDR = "800000 800000";
44

5-
async function detectUboot(reader) {
6-
while (true) {
7-
const { value, done } = await reader.read();
8-
9-
if (value.startsWith('U-Boot')) {
10-
return;
5+
async function detectUboot(serial) {
6+
await serial.readLine((line) => {
7+
if (line.startsWith('U-Boot')) {
8+
return true;
119
}
12-
}
10+
});
1311
}
1412

15-
async function waitUbootStop(writer, reader, sfpModel, outputMsgCallback) {
13+
async function waitUbootStop(serial, sfpModel, outputMsgCallback) {
14+
const interruptChar = String.fromCharCode(3);
15+
1616
const interval = setInterval(function() {
17-
writer.write(String.fromCharCode(3));
17+
serial.writeString(interruptChar);
1818
}, 10);
1919

20-
await detectUboot(reader);
20+
await detectUboot(serial);
2121
outputMsgCallback(`Root in progress: Trigger characters received. DO NOT TOUCH THE ${sfpModel} UNTIL THE PROCEDURE IS COMPLETED!`);
2222
await delay(5000);
2323
clearInterval(interval);
2424
}
2525

26-
async function checkUbootUnlocked(reader) {
27-
while (true) {
28-
try {
29-
const { value, done } = await Promise.race([
30-
reader.read(),
31-
new Promise((_, reject) => setTimeout(reject, 2000, new Error("timeout")))
32-
]);
33-
34-
if (value.startsWith('Press SPACE to delay and Ctrl-C to abort autoboot')) {
35-
return true;
36-
}
37-
} catch (err) {
38-
return false;
26+
async function checkUbootUnlocked(serial) {
27+
let unlocked = false;
28+
29+
await serial.readLine((line) => {
30+
if (line.startsWith('Press SPACE to delay and Ctrl-C to abort autoboot')) {
31+
unlocked = true;
32+
return true
3933
}
40-
}
34+
}, 2000);
35+
36+
return unlocked;
4137
}
4238

4339
async function waitFailbackShell(writer, reader, outputMsgCallback) {
@@ -72,46 +68,44 @@ async function waitFailbackShell(writer, reader, outputMsgCallback) {
7268
}
7369

7470
async function lantiqRootUboot(port, sfpModel, outputMsgCallback, outputErrorCallback, baudRate = 115200) {
75-
let reader,writer, readableStreamClosed, writerStreamClosed;
71+
const serial = new SerialReadWrite(port, baudRate);
7672

7773
try {
7874
outputMsgCallback(`Please disconnect the ${sfpModel} from the SFP adapter if it is currently plugged in!`);
79-
({ reader, writer, readableStreamClosed, writerStreamClosed } = await openPortLineBreak(port, baudRate));
80-
8175
await delay(10000);
8276
outputMsgCallback(`Now you need to insert the ${sfpModel} into the SFP adapter, if the procedure does not go ahead, check the connections and then remove and reconnect the ${sfpModel} again`);
8377

8478
while(true) {
85-
await waitUbootStop(writer, reader, sfpModel, outputMsgCallback);
86-
const ubootUnlocked = await checkUbootUnlocked(reader);
79+
await waitUbootStop(serial, sfpModel, outputMsgCallback);
80+
const ubootUnlocked = await checkUbootUnlocked(serial);
8781

8882
if (ubootUnlocked == true) {
8983
break;
9084
}
9185

9286
outputMsgCallback("Root in progress: Set U-Boot bootdelay to 5...");
93-
writer.write('setenv bootdelay 5\n');
87+
await serial.writeString('setenv bootdelay 5\n');
9488
await delay(1000);
9589
outputMsgCallback("Root in progress: Enable ASC serial...");
96-
writer.write('setenv asc0 0\n');
90+
await serial.writeString('setenv asc0 0\n');
9791
await delay(1000);
9892
outputMsgCallback("Root in progress: Set GPIO to unlock serial...");
99-
writer.write('setenv preboot "gpio set 3;gpio input 2;gpio input 105;gpio input 106;gpio input 107;gpio input 108"\n');
93+
await serial.writeString('setenv preboot "gpio set 3;gpio input 2;gpio input 105;gpio input 106;gpio input 107;gpio input 108"\n');
10094
await delay(1000);
10195
outputMsgCallback("Root in progress: Save changes...");
102-
writer.write('saveenv\n');
96+
await serial.writeString('saveenv\n');
10397
await delay(1000);
10498
outputMsgCallback("Root in progress: Rebooting...");
105-
writer.write('reset\n');
99+
await serial.writeString('reset\n');
106100
await delay(1000);
107101
}
108102

109-
await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
110103
return true;
111104
} catch (err) {
112105
outputErrorCallback(`Error: ${err.message}`);
113-
await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
114106
return false;
107+
} finally {
108+
await serial.closePort();
115109
}
116110
}
117111

assets/js/serialUtil.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,100 @@ class LineBreakTransformer {
1919
}
2020
}
2121

22+
class SerialReadWrite {
23+
constructor(port, baudrate) {
24+
this.port = port;
25+
this.baudRate = baudrate;
26+
this.isPortOpen = false;
27+
this.textDecoder = new TextDecoder();
28+
this.textEncoder = new TextEncoder();
29+
}
30+
31+
async openPort() {
32+
await this.port.open({ baudRate: this.baudRate });
33+
}
34+
35+
async closePort() {
36+
await this.port.close();
37+
}
38+
39+
async readLine(readCallback, timeout = undefined) {
40+
let reader = undefined;
41+
let extraChunk = "";
42+
43+
if (this.isPortOpen === false) {
44+
await this.openPort();
45+
this.isPortOpen = true;
46+
}
47+
48+
while (true) {
49+
try {
50+
if (reader === undefined) {
51+
reader = this.port.readable.getReader();
52+
}
53+
54+
let serialValue;
55+
if (timeout === undefined) {
56+
const { value, done } = await reader.read();
57+
serialValue = value;
58+
} else {
59+
const { value, done } = await Promise.race([
60+
reader.read(),
61+
new Promise((_, reject) => setTimeout(reject, timeout, new Error("timeout")))
62+
]);
63+
serialValue = value;
64+
}
65+
66+
const linesValue = this.textDecoder.decode(serialValue).split('\n');
67+
linesValue[0] = extraChunk + linesValue[0];
68+
extraChunk = linesValue[linesValue.length - 1];
69+
70+
for (const line of linesValue) {
71+
if (readCallback(line) === true) {
72+
return;
73+
}
74+
}
75+
} catch (e) {
76+
if (e instanceof DOMException &&
77+
(e.name === "BreakError" || e.name === "FramingError" || e.name === "ParityError")) {
78+
console.log(e);
79+
} else if (e instanceof Error && e.message === "timeout") {
80+
return;
81+
} else {
82+
throw e;
83+
}
84+
} finally {
85+
if (reader) {
86+
reader.releaseLock();
87+
reader = undefined;
88+
}
89+
}
90+
}
91+
}
92+
93+
async writeString(str) {
94+
let writer = undefined;
95+
96+
if (this.isPortOpen === false) {
97+
await this.openPort();
98+
this.isPortOpen = true;
99+
}
100+
101+
try {
102+
if (writer === undefined) {
103+
writer = this.port.writable.getWriter();
104+
}
105+
106+
writer.write(textEncoder.encode(str));
107+
} finally {
108+
if (writer) {
109+
writer.releaseLock();
110+
writer = undefined;
111+
}
112+
}
113+
}
114+
}
115+
22116
async function openPortLineBreak(port, baudRate) {
23117
await port.open({ baudRate: baudRate });
24118
const textDecoder = new TextDecoderStream();

0 commit comments

Comments
 (0)