UX changes for file selection, validations etc.

This commit is contained in:
Adwait Patankar 2021-07-29 14:21:17 +05:30
parent c59f2e1861
commit 47b8c219ff
4 changed files with 158 additions and 76 deletions

View File

@ -1254,6 +1254,7 @@ class ESPLoader {
await this.run_stub();
await this.change_baud();
return chip;
}

BIN
assets/esp-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -5,6 +5,7 @@
<title>ESP Tool</title>
<link rel="stylesheet" href="styles.css" />
<link rel="stylesheet" href="node_modules/xterm/css/xterm.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<link
href="https://fonts.googleapis.com/css?family=Orbitron"
rel="stylesheet"
@ -13,52 +14,63 @@
<script src="node_modules/xterm/lib/xterm.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pako/2.0.3/pako.js"></script>
<script src="node_modules/crypto-js/crypto-js.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<h1>ESP Tool</h1>
<div>
<h1 align="center"><p><img src="../assets/esp-logo.png" width="42" height="42" style="vertical-align:middle"></img> ESP Tool</p></h1>
<h4 align="center">A Serial Flasher utility for Espressif chips</h4>
<div class="container">
<hr/>
<div id="program">
<h2> Program </h2>
<label for="baudrates">Baudrate:</label>
<h3> Program </h3>
<label for="baudrates" id="lblBaudrate">Baudrate:</label>
<label style="display:none" id="lblConnTo">Connected to device: </label>
<select name="baudrates" id="baudrates">
<option value="921600">921600</option>
<option value="460800">460800</option>
<option value="230400">230400</option>
<option value="115200">115200</option>
</select>
<input class="button" type="button" id="connectButton" value="Connect" />
<input class="button" type="button" id="disconnectButton" value="Disconnect" />
<input class="btn btn-info btn-sm" type="button" id="connectButton" value="Connect" />
<input class="btn btn-warning btn-sm" type="button" id="disconnectButton" value="Disconnect" />
<input class="btn btn-danger btn-sm" type="button" id="eraseButton" value="Erase Flash" />
<br><br>
<div id="files">
<br/>
<input class="button" type="button" id="eraseButton" value="Erase Flash" />
<br/>
<label for="offset1">Bootloader</label>
<input type="text" id="offset1" name="offset1" value="0x1000">
<input type="file" id="selectFile1" name="selected_file1">
<br/>
<label for="offset2">Partition table</label>
<input type="text" id="offset2" name="offset2" value="0x8000">
<input type="file" id="selectFile2" name="selected_file2">
<br/>
<label for="offset3">App</label>
<input type="text" id="offset3" name="offset3" value="0x10000">
<input type="file" id="selectFile3" name="selected_file3">
<br/>
<input class="button" type="button" id="programButton" value="Program" />
<table class="table table-striped" id="fileTable">
<thead class="thead-light">
<tr>
<th>Flash Address</th>
<th>Selected File</th>
<th>Remove </th>
</tr>
</thead>
<tbody id="tableBody">
<tr id="row0">
<td><input type="text" id="offset1" name="offset1" value="0x1000"></td>
<td><input type="file" id="selectFile1" name="selected_file1"></td>
<td><button class="btn disabled"> Remove </button></td>
</tr>
</tbody>
</table>
<input class="btn btn-info btn-sm" type="button" id="addFile" value="Add File" />
<input class="btn btn-info btn-sm" type="button" id="programButton" value="Program" />
</div>
<output id="list"></output>
<br/>
<hr/>
</div>
<div id="console">
<h2>Console </h2>
<input class="button" type="button" id="consoleStartButton" value="Start" />
<input class="button" type="button" id="consoleStopButton" value="Stop" />
<input class="button" type="button" id="resetButton" value="Reset" />
<h3>Console </h3>
<label style="display:none" id="lblConsoleFor">Connected to device: </label>
<input class="btn btn-info" type="button" id="consoleStartButton" value="Start" />
<input class="btn btn-info" type="button" id="consoleStopButton" value="Stop" />
<input class="btn btn-info" type="button" id="resetButton" value="Reset" />
<hr/>
</div>
<div id="terminal"></div>
</div>
<div id="terminal"></div>
<script src="index.js" type="module"></script>
</body>
</html>

165
index.js
View File

@ -10,7 +10,10 @@ const filesDiv = document.getElementById("files");
const terminal = document.getElementById("terminal");
const programDiv = document.getElementById("program");
const consoleDiv = document.getElementById("console");
const lblBaudrate = document.getElementById("lblBaudrate");
const lblConnTo = document.getElementById("lblConnTo");
const tableBody = document.getElementById("tableBody");
const table = document.getElementById('fileTable');
//import { Transport } from './cp210x-webusb.js'
import { Transport } from './webserial.js'
@ -21,12 +24,14 @@ term.open(terminal);
let device = null;
let transport;
let chip;
let chip = "deFault";
let esploader;
let file1 = null, file2 = null, file3 = null;
let file1 = null;
let connected = false;
let index = 1;
disconnectButton.style.display = "none";
eraseButton.style.display = "none";
consoleStopButton.style.display = "none";
filesDiv.style.display = "none";
@ -47,7 +52,7 @@ function convertBinaryStringToUint8Array(bStr) {
return u8_array;
}
function handleFileSelect1(evt) {
function handleFileSelect(evt) {
var file = evt.target.files[0];
console.log(file);
var reader = new FileReader();
@ -60,39 +65,12 @@ function handleFileSelect1(evt) {
})(file);
reader.readAsBinaryString(file);
evt.target.data = file1;
}
function handleFileSelect2(evt) {
var file = evt.target.files[0];
console.log(file);
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
file2 = e.target.result;
};
})(file);
document.getElementById('selectFile1').addEventListener('change', handleFileSelect, false);
reader.readAsBinaryString(file);
}
function handleFileSelect3(evt) {
var file = evt.target.files[0];
console.log(file);
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
file3 = e.target.result;
};
})(file);
reader.readAsBinaryString(file);
}
document.getElementById('selectFile1').addEventListener('change', handleFileSelect1, false);
document.getElementById('selectFile2').addEventListener('change', handleFileSelect2, false);
document.getElementById('selectFile3').addEventListener('change', handleFileSelect3, false);
function _sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
@ -113,15 +91,20 @@ connectButton.onclick = async () => {
esploader = new ESPLoader(transport, baudrates.value, term);
connected = true;
await esploader.main_fn();
chip = await esploader.main_fn();
await esploader.flash_id();
} catch(e) {
}
console.log("Settings done");
console.log("Settings done for :" + chip);
lblBaudrate.style.display = "none";
lblConnTo.innerHTML = "Connected to device: " + chip;
lblConnTo.style.display = "block";
baudrates.style.display = "none";
connectButton.style.display = "none";
disconnectButton.style.display = "initial";
eraseButton.style.display = "initial";
filesDiv.style.display = "initial";
consoleDiv.style.display = "none";
}
@ -141,11 +124,57 @@ resetButton.onclick = async () => {
eraseButton.onclick = async () => {
eraseButton.disabled = true;
console.log("Erase Flash");
await esploader.erase_flash();
eraseButton.disabled = false;
}
addFile.onclick = async () => {
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;
element1.setAttribute('value', '0x8000');
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);
// Column 3 - Remove File
var cell3 = row.insertCell(2);
var element3 = document.createElement("input");
element3.type = "button";
var btnName = "button" + rowCount;
element3.name = btnName;
element3.setAttribute('class', "btn");
element3.setAttribute('value', 'Remove'); // or element1.value = "button";
element3.onclick = function() {
removeRow(btnName);
}
cell3.appendChild(element3);
}
function removeRow(btnName) {
var rowCount = table.rows.length;
for (var i = 0; i < rowCount; i++) {
var row = table.rows[i];
var rowObj = row.cells[2].childNodes[0];
if (rowObj.name == btnName) {
table.deleteRow(i);
rowCount--;
}
}
}
disconnectButton.onclick = async () => {
await transport.disconnect();
term.clear();
@ -153,6 +182,8 @@ disconnectButton.onclick = async () => {
baudrates.style.display = "initial";
connectButton.style.display = "initial";
disconnectButton.style.display = "none";
eraseButton.style.display = "none";
lblConnTo.style.display = "none";
filesDiv.style.display = "none";
consoleDiv.style.display = "initial";
};
@ -164,7 +195,7 @@ consoleStartButton.onclick = async () => {
});
transport = new Transport(device);
}
lblConsoleFor.style.display = "block";
consoleStartButton.style.display = "none";
consoleStopButton.style.display = "initial";
programDiv.style.display = "none";
@ -190,19 +221,57 @@ consoleStopButton.onclick = async () => {
programDiv.style.display = "initial";
}
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"
}
programButton.onclick = async () => {
var err = validate_program_inputs();
if (err != "success")
alert(err);
let fileArr = [];
if (file1 != null) {
let offset1 = parseInt(document.getElementById("offset1").value);
fileArr.push({data:file1, address:offset1});
}
if (file2 != null) {
let offset2 = parseInt(document.getElementById("offset2").value);
fileArr.push({data:file2, address:offset2});
}
if (file3 != null) {
let offset3 = parseInt(document.getElementById("offset3").value);
fileArr.push({data:file3, address:offset3});
let offset = 0x1000;
var rowCount = table.rows.length;
var row;
for (let index = 1; index < rowCount; index ++) {
row = table.rows[index];
var offSetObj = row.cells[0].childNodes[0];
offset = parseInt(offSetObj.value);
var fileObj = row.cells[1].childNodes[0];
fileArr.push({data:fileObj.data, address:offset});
}
await esploader.write_flash({fileArray: fileArr, flash_size: 'keep'});
}