2021-07-18 16:13:30 +00:00
|
|
|
const baudrates = document.getElementById("baudrates");
|
2021-04-18 17:46:46 +00:00
|
|
|
const connectButton = document.getElementById("connectButton");
|
|
|
|
const disconnectButton = document.getElementById("disconnectButton");
|
2021-05-30 14:47:40 +00:00
|
|
|
const resetButton = document.getElementById("resetButton");
|
|
|
|
const consoleStartButton = document.getElementById("consoleStartButton");
|
|
|
|
const consoleStopButton = document.getElementById("consoleStopButton");
|
|
|
|
const eraseButton = document.getElementById("eraseButton");
|
|
|
|
const programButton = document.getElementById("programButton");
|
|
|
|
const filesDiv = document.getElementById("files");
|
2021-04-18 17:46:46 +00:00
|
|
|
const terminal = document.getElementById("terminal");
|
2021-05-30 14:47:40 +00:00
|
|
|
const programDiv = document.getElementById("program");
|
|
|
|
const consoleDiv = document.getElementById("console");
|
2021-07-29 08:51:17 +00:00
|
|
|
const lblBaudrate = document.getElementById("lblBaudrate");
|
|
|
|
const lblConnTo = document.getElementById("lblConnTo");
|
|
|
|
const tableBody = document.getElementById("tableBody");
|
|
|
|
const table = document.getElementById('fileTable');
|
2021-07-30 10:07:54 +00:00
|
|
|
const alertDiv = document.getElementById('alertDiv');
|
2021-04-18 17:46:46 +00:00
|
|
|
|
|
|
|
//import { Transport } from './cp210x-webusb.js'
|
|
|
|
import { Transport } from './webserial.js'
|
|
|
|
import { ESPLoader } from './ESPLoader.js'
|
2022-07-08 17:54:19 +00:00
|
|
|
import { ESPError } from './error.js'
|
2021-04-18 17:46:46 +00:00
|
|
|
|
2021-05-30 14:47:40 +00:00
|
|
|
let term = new Terminal({cols:120, rows:40});
|
2021-04-18 17:46:46 +00:00
|
|
|
term.open(terminal);
|
|
|
|
|
2021-05-30 14:47:40 +00:00
|
|
|
let device = null;
|
|
|
|
let transport;
|
2022-07-12 17:05:32 +00:00
|
|
|
let chip = null;
|
2021-05-03 04:00:25 +00:00
|
|
|
let esploader;
|
2021-07-29 08:51:17 +00:00
|
|
|
let file1 = null;
|
2021-05-30 14:47:40 +00:00
|
|
|
let connected = false;
|
2021-07-29 08:51:17 +00:00
|
|
|
let index = 1;
|
2021-05-30 14:47:40 +00:00
|
|
|
|
|
|
|
disconnectButton.style.display = "none";
|
2021-07-29 08:51:17 +00:00
|
|
|
eraseButton.style.display = "none";
|
2021-05-30 14:47:40 +00:00
|
|
|
consoleStopButton.style.display = "none";
|
|
|
|
filesDiv.style.display = "none";
|
|
|
|
|
|
|
|
|
|
|
|
function convertUint8ArrayToBinaryString(u8Array) {
|
|
|
|
var i, len = u8Array.length, b_str = "";
|
|
|
|
for (i=0; i<len; i++) {
|
|
|
|
b_str += String.fromCharCode(u8Array[i]);
|
|
|
|
}
|
|
|
|
return b_str;
|
|
|
|
}
|
|
|
|
|
|
|
|
function convertBinaryStringToUint8Array(bStr) {
|
|
|
|
var i, len = bStr.length, u8_array = new Uint8Array(len);
|
|
|
|
for (var i = 0; i < len; i++) {
|
|
|
|
u8_array[i] = bStr.charCodeAt(i);
|
|
|
|
}
|
|
|
|
return u8_array;
|
|
|
|
}
|
|
|
|
|
2021-07-29 08:51:17 +00:00
|
|
|
function handleFileSelect(evt) {
|
2021-05-30 14:47:40 +00:00
|
|
|
var file = evt.target.files[0];
|
|
|
|
var reader = new FileReader();
|
|
|
|
|
|
|
|
reader.onload = (function(theFile) {
|
|
|
|
return function(e) {
|
|
|
|
file1 = e.target.result;
|
2021-07-30 10:07:54 +00:00
|
|
|
evt.target.data = file1;
|
2021-05-30 14:47:40 +00:00
|
|
|
};
|
|
|
|
})(file);
|
|
|
|
|
|
|
|
reader.readAsBinaryString(file);
|
|
|
|
}
|
|
|
|
|
2021-04-18 17:46:46 +00:00
|
|
|
function _sleep(ms) {
|
|
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
|
|
}
|
|
|
|
|
|
|
|
connectButton.onclick = async () => {
|
|
|
|
// device = await navigator.usb.requestDevice({
|
|
|
|
// filters: [{ vendorId: 0x10c4 }]
|
|
|
|
// });
|
|
|
|
|
2021-05-30 14:47:40 +00:00
|
|
|
if (device === null) {
|
|
|
|
device = await navigator.serial.requestPort({
|
|
|
|
});
|
|
|
|
transport = new Transport(device);
|
|
|
|
}
|
2021-04-18 17:46:46 +00:00
|
|
|
|
2021-05-30 14:47:40 +00:00
|
|
|
try {
|
2021-07-18 16:13:30 +00:00
|
|
|
esploader = new ESPLoader(transport, baudrates.value, term);
|
|
|
|
connected = true;
|
2021-04-18 17:46:46 +00:00
|
|
|
|
2021-07-29 08:51:17 +00:00
|
|
|
chip = await esploader.main_fn();
|
|
|
|
|
2022-07-08 17:54:19 +00:00
|
|
|
// Temporarily broken
|
|
|
|
// await esploader.flash_id();
|
2021-05-30 14:47:40 +00:00
|
|
|
} catch(e) {
|
2022-07-08 17:54:19 +00:00
|
|
|
console.error(e);
|
|
|
|
term.writeln(`Error: ${e.message}`);
|
2021-05-30 14:47:40 +00:00
|
|
|
}
|
|
|
|
|
2021-07-29 08:51:17 +00:00
|
|
|
console.log("Settings done for :" + chip);
|
|
|
|
lblBaudrate.style.display = "none";
|
|
|
|
lblConnTo.innerHTML = "Connected to device: " + chip;
|
|
|
|
lblConnTo.style.display = "block";
|
2021-07-18 16:13:30 +00:00
|
|
|
baudrates.style.display = "none";
|
2021-04-18 17:46:46 +00:00
|
|
|
connectButton.style.display = "none";
|
|
|
|
disconnectButton.style.display = "initial";
|
2021-07-29 08:51:17 +00:00
|
|
|
eraseButton.style.display = "initial";
|
2021-05-30 14:47:40 +00:00
|
|
|
filesDiv.style.display = "initial";
|
|
|
|
consoleDiv.style.display = "none";
|
|
|
|
}
|
|
|
|
|
|
|
|
resetButton.onclick = async () => {
|
|
|
|
if (device === null) {
|
|
|
|
device = await navigator.serial.requestPort({
|
|
|
|
});
|
|
|
|
transport = new Transport(device);
|
|
|
|
}
|
|
|
|
|
|
|
|
await transport.setDTR(false);
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
await transport.setDTR(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
eraseButton.onclick = async () => {
|
|
|
|
eraseButton.disabled = true;
|
2022-07-08 17:54:19 +00:00
|
|
|
try{
|
|
|
|
await esploader.erase_flash();
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
term.writeln(`Error: ${e.message}`);
|
|
|
|
} finally {
|
|
|
|
eraseButton.disabled = false;
|
|
|
|
}
|
2021-05-30 14:47:40 +00:00
|
|
|
}
|
2021-04-18 17:46:46 +00:00
|
|
|
|
2022-07-12 17:05:32 +00:00
|
|
|
addFile.onclick = () => {
|
2021-07-29 08:51:17 +00:00
|
|
|
var rowCount = table.rows.length;
|
|
|
|
var row = table.insertRow(rowCount);
|
|
|
|
|
|
|
|
//Column 1 - Offset
|
|
|
|
var cell1 = row.insertCell(0);
|
|
|
|
var element1 = document.createElement("input");
|
|
|
|
element1.type = "text";
|
|
|
|
element1.id = "offset" + rowCount;
|
2022-07-12 17:05:32 +00:00
|
|
|
element1.value = '0x1000';
|
2021-07-29 08:51:17 +00:00
|
|
|
cell1.appendChild(element1);
|
|
|
|
|
|
|
|
// Column 2 - File selector
|
|
|
|
var cell2 = row.insertCell(1);
|
|
|
|
var element2 = document.createElement("input");
|
|
|
|
element2.type = "file";
|
|
|
|
element2.id = "selectFile" + rowCount;
|
|
|
|
element2.name = "selected_File" + rowCount;
|
|
|
|
element2.addEventListener('change', handleFileSelect, false);
|
|
|
|
cell2.appendChild(element2);
|
|
|
|
|
2022-07-12 17:05:32 +00:00
|
|
|
// Column 3 - Progress
|
2021-07-29 08:51:17 +00:00
|
|
|
var cell3 = row.insertCell(2);
|
2022-07-12 17:05:32 +00:00
|
|
|
cell3.classList.add("progress-cell");
|
|
|
|
cell3.style.display = 'none'
|
|
|
|
cell3.innerHTML = `<progress value="0" max="100"></progress>`;
|
|
|
|
|
|
|
|
// Column 4 - Remove File
|
|
|
|
var cell4 = row.insertCell(3);
|
|
|
|
cell4.classList.add('action-cell');
|
|
|
|
if (rowCount > 1) {
|
|
|
|
var element4 = document.createElement("input");
|
|
|
|
element4.type = "button";
|
|
|
|
var btnName = "button" + rowCount;
|
|
|
|
element4.name = btnName;
|
|
|
|
element4.setAttribute('class', "btn");
|
|
|
|
element4.setAttribute('value', 'Remove'); // or element1.value = "button";
|
|
|
|
element4.onclick = function() {
|
2022-07-19 04:28:15 +00:00
|
|
|
removeRow(row);
|
2022-07-12 17:05:32 +00:00
|
|
|
}
|
|
|
|
cell4.appendChild(element4);
|
2021-07-29 08:51:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 04:28:15 +00:00
|
|
|
function removeRow(row) {
|
|
|
|
const rowIndex = Array.from(table.rows).indexOf(row);
|
|
|
|
table.deleteRow(rowIndex);
|
2021-07-29 08:51:17 +00:00
|
|
|
}
|
|
|
|
|
2022-02-24 11:08:07 +00:00
|
|
|
// to be called on disconnect - remove any stale references of older connections if any
|
|
|
|
function cleanUp() {
|
|
|
|
device = null;
|
|
|
|
transport = null;
|
2022-07-12 17:05:32 +00:00
|
|
|
chip = null;
|
2022-02-24 11:08:07 +00:00
|
|
|
}
|
|
|
|
|
2021-04-18 17:46:46 +00:00
|
|
|
disconnectButton.onclick = async () => {
|
2022-02-24 11:08:07 +00:00
|
|
|
if(transport)
|
|
|
|
await transport.disconnect();
|
|
|
|
|
2021-04-18 17:46:46 +00:00
|
|
|
term.clear();
|
2021-05-30 14:47:40 +00:00
|
|
|
connected = false;
|
2021-07-18 16:13:30 +00:00
|
|
|
baudrates.style.display = "initial";
|
2021-04-18 17:46:46 +00:00
|
|
|
connectButton.style.display = "initial";
|
|
|
|
disconnectButton.style.display = "none";
|
2021-07-29 08:51:17 +00:00
|
|
|
eraseButton.style.display = "none";
|
|
|
|
lblConnTo.style.display = "none";
|
2021-05-30 14:47:40 +00:00
|
|
|
filesDiv.style.display = "none";
|
2021-07-30 10:07:54 +00:00
|
|
|
alertDiv.style.display = "none";
|
2021-05-30 14:47:40 +00:00
|
|
|
consoleDiv.style.display = "initial";
|
2022-02-24 11:08:07 +00:00
|
|
|
cleanUp();
|
2021-04-18 17:46:46 +00:00
|
|
|
};
|
2021-05-30 14:47:40 +00:00
|
|
|
|
|
|
|
consoleStartButton.onclick = async () => {
|
|
|
|
if (device === null) {
|
|
|
|
device = await navigator.serial.requestPort({
|
|
|
|
});
|
|
|
|
transport = new Transport(device);
|
|
|
|
}
|
2021-07-29 08:51:17 +00:00
|
|
|
lblConsoleFor.style.display = "block";
|
2021-05-30 14:47:40 +00:00
|
|
|
consoleStartButton.style.display = "none";
|
|
|
|
consoleStopButton.style.display = "initial";
|
|
|
|
programDiv.style.display = "none";
|
|
|
|
|
|
|
|
await transport.connect();
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
let val = await transport.rawRead();
|
|
|
|
if (typeof val !== 'undefined') {
|
|
|
|
term.write(val);
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
console.log("quitting console");
|
|
|
|
}
|
|
|
|
|
|
|
|
consoleStopButton.onclick = async () => {
|
|
|
|
await transport.disconnect();
|
|
|
|
term.clear();
|
|
|
|
consoleStartButton.style.display = "initial";
|
|
|
|
consoleStopButton.style.display = "none";
|
|
|
|
programDiv.style.display = "initial";
|
|
|
|
}
|
|
|
|
|
2021-07-29 08:51:17 +00:00
|
|
|
function validate_program_inputs() {
|
|
|
|
let offsetArr = []
|
|
|
|
var rowCount = table.rows.length;
|
|
|
|
var row;
|
|
|
|
let offset = 0;
|
|
|
|
let fileData = null;
|
|
|
|
|
|
|
|
// check for mandatory fields
|
|
|
|
for (let index = 1; index < rowCount; index ++) {
|
|
|
|
row = table.rows[index];
|
|
|
|
|
|
|
|
//offset fields checks
|
|
|
|
var offSetObj = row.cells[0].childNodes[0];
|
|
|
|
offset = parseInt(offSetObj.value);
|
|
|
|
|
|
|
|
// Non-numeric or blank offset
|
|
|
|
if (Number.isNaN(offset))
|
|
|
|
return "Offset field in row " + index + " is not a valid address!"
|
|
|
|
// Repeated offset used
|
|
|
|
else if (offsetArr.includes(offset))
|
|
|
|
return "Offset field in row " + index + " is already in use!";
|
|
|
|
else
|
|
|
|
offsetArr.push(offset);
|
|
|
|
|
|
|
|
var fileObj = row.cells[1].childNodes[0];
|
|
|
|
fileData = fileObj.data;
|
|
|
|
if (fileData == null)
|
|
|
|
return "No file selected for row: " + index + "!";
|
|
|
|
|
|
|
|
}
|
|
|
|
return "success"
|
|
|
|
}
|
|
|
|
|
2021-05-30 14:47:40 +00:00
|
|
|
programButton.onclick = async () => {
|
2021-07-29 08:51:17 +00:00
|
|
|
var err = validate_program_inputs();
|
2021-07-30 10:07:54 +00:00
|
|
|
if (err != "success") {
|
|
|
|
const alertMsg = document.getElementById("alertmsg");
|
|
|
|
alertMsg.innerHTML = "<strong>" + err + "</strong>";
|
|
|
|
alertDiv.style.display = "block";
|
|
|
|
return;
|
|
|
|
}
|
2021-07-29 08:51:17 +00:00
|
|
|
|
2022-07-12 17:05:32 +00:00
|
|
|
let fileArray = [];
|
2021-07-29 08:51:17 +00:00
|
|
|
let offset = 0x1000;
|
|
|
|
var rowCount = table.rows.length;
|
|
|
|
var row;
|
2022-07-12 17:05:32 +00:00
|
|
|
const progressBars = [];
|
2021-07-29 08:51:17 +00:00
|
|
|
for (let index = 1; index < rowCount; index ++) {
|
|
|
|
row = table.rows[index];
|
|
|
|
var offSetObj = row.cells[0].childNodes[0];
|
|
|
|
offset = parseInt(offSetObj.value);
|
2021-07-30 10:07:54 +00:00
|
|
|
|
2021-07-29 08:51:17 +00:00
|
|
|
var fileObj = row.cells[1].childNodes[0];
|
2022-07-12 17:05:32 +00:00
|
|
|
|
|
|
|
progressBars.push(row.cells[2].childNodes[0]);
|
|
|
|
|
|
|
|
row.cells[2].style.display = "initial";
|
|
|
|
row.cells[3].style.display = "none";
|
|
|
|
|
|
|
|
fileArray.push({data:fileObj.data, address:offset});
|
2021-05-30 14:47:40 +00:00
|
|
|
}
|
2022-07-12 17:05:32 +00:00
|
|
|
|
2022-07-08 17:54:19 +00:00
|
|
|
try {
|
2022-07-12 17:05:32 +00:00
|
|
|
await esploader.write_flash({
|
|
|
|
fileArray,
|
|
|
|
flash_size: 'keep',
|
|
|
|
reportProgress(fileIndex, written, total) {
|
|
|
|
progressBars[fileIndex].value = written / total * 100;
|
|
|
|
}
|
|
|
|
});
|
2022-07-08 17:54:19 +00:00
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
term.writeln(`Error: ${e.message}`);
|
2022-07-12 17:05:32 +00:00
|
|
|
} finally {
|
|
|
|
for (let index = 1; index < rowCount; index ++) {
|
|
|
|
row.cells[2].style.display = "none";
|
|
|
|
row.cells[3].style.display = "initial";
|
|
|
|
}
|
2022-07-08 17:54:19 +00:00
|
|
|
}
|
2021-05-30 14:47:40 +00:00
|
|
|
}
|
2022-07-12 17:05:32 +00:00
|
|
|
|
|
|
|
addFile.onclick();
|