Layout and UX changes. Added a few validations

This commit is contained in:
Adwait Patankar 2021-08-04 19:45:21 +05:30
parent eda1f2043c
commit 45f0af6a7f
4 changed files with 174 additions and 81 deletions

View File

@ -1254,6 +1254,7 @@ class ESPLoader {
await this.run_stub(); await this.run_stub();
await this.change_baud(); 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> <title>ESP Tool</title>
<link rel="stylesheet" href="styles.css" /> <link rel="stylesheet" href="styles.css" />
<link rel="stylesheet" href="node_modules/xterm/css/xterm.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 <link
href="https://fonts.googleapis.com/css?family=Orbitron" href="https://fonts.googleapis.com/css?family=Orbitron"
rel="stylesheet" rel="stylesheet"
@ -13,52 +14,70 @@
<script src="node_modules/xterm/lib/xterm.js"></script> <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="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="node_modules/crypto-js/crypto-js.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head> </head>
<body> <body>
<h1>ESP Tool</h1> <h1 align="center"><p><img src="./assets/esp-logo.png" width="42" height="42" style="vertical-align:middle"></img> ESP Tool</p></h1>
<div> <h4 align="center">A Serial Flasher utility for Espressif chips</h4>
<div class="container">
<hr/>
<div id="program"> <div id="program">
<h2> Program </h2> <h3> Program </h3>
<label for="baudrates">Baudrate:</label> <label for="baudrates" id="lblBaudrate">Baudrate:</label>
<label style="display:none" id="lblConnTo">Connected to device: </label>
<select name="baudrates" id="baudrates"> <select name="baudrates" id="baudrates">
<option value="921600">921600</option> <option value="921600">921600</option>
<option value="460800">460800</option> <option value="460800">460800</option>
<option value="230400">230400</option> <option value="230400">230400</option>
<option value="115200">115200</option> <option value="115200">115200</option>
</select> </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 class="alert alert-danger alert-dismissible" id="alertDiv" style="display:none">
<a href="#" class="close" aria-label="close" onclick="$('.alert').hide()">&times;</a>
<span id="alertmsg"></span>
</div>
<div id="files"> <div id="files">
<br/> <table class="table table-striped" id="fileTable">
<input class="button" type="button" id="eraseButton" value="Erase Flash" /> <thead class="thead-light">
<br/> <tr>
<label for="offset1">Bootloader</label> <th>Flash Address</th>
<input type="text" id="offset1" name="offset1" value="0x1000"> <th>Selected File</th>
<input type="file" id="selectFile1" name="selected_file1"> <th>Remove </th>
<br/> </tr>
<label for="offset2">Partition table</label> </thead>
<input type="text" id="offset2" name="offset2" value="0x8000"> <tbody id="tableBody">
<input type="file" id="selectFile2" name="selected_file2"> <tr id="row0">
<br/> <td><input type="text" id="offset1" name="offset1" value="0x1000"></td>
<label for="offset3">App</label> <td><input type="file" id="selectFile1" name="selected_file1"></td>
<input type="text" id="offset3" name="offset3" value="0x10000"> <td><button class="btn disabled"> Remove </button></td>
<input type="file" id="selectFile3" name="selected_file3"> </tr>
<br/> </tbody>
<input class="button" type="button" id="programButton" value="Program" /> </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> </div>
<output id="list"></output> <output id="list"></output>
<br/>
<hr/> <hr/>
</div> </div>
<div id="console"> <div id="console">
<h2>Console </h2> <h3>Console </h3>
<input class="button" type="button" id="consoleStartButton" value="Start" /> <label style="display:none" id="lblConsoleFor">Connected to device: </label>
<input class="button" type="button" id="consoleStopButton" value="Stop" />
<input class="button" type="button" id="resetButton" value="Reset" /> <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/> <hr/>
</div> </div>
<div id="terminal"></div>
</div> </div>
<div id="terminal"></div>
<script src="index.js" type="module"></script> <script src="index.js" type="module"></script>
</body> </body>
</html> </html>

179
index.js
View File

@ -10,7 +10,11 @@ const filesDiv = document.getElementById("files");
const terminal = document.getElementById("terminal"); const terminal = document.getElementById("terminal");
const programDiv = document.getElementById("program"); const programDiv = document.getElementById("program");
const consoleDiv = document.getElementById("console"); 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');
const alertDiv = document.getElementById('alertDiv');
//import { Transport } from './cp210x-webusb.js' //import { Transport } from './cp210x-webusb.js'
import { Transport } from './webserial.js' import { Transport } from './webserial.js'
@ -21,12 +25,14 @@ term.open(terminal);
let device = null; let device = null;
let transport; let transport;
let chip; let chip = "deFault";
let esploader; let esploader;
let file1 = null, file2 = null, file3 = null; let file1 = null;
let connected = false; let connected = false;
let index = 1;
disconnectButton.style.display = "none"; disconnectButton.style.display = "none";
eraseButton.style.display = "none";
consoleStopButton.style.display = "none"; consoleStopButton.style.display = "none";
filesDiv.style.display = "none"; filesDiv.style.display = "none";
@ -47,52 +53,23 @@ function convertBinaryStringToUint8Array(bStr) {
return u8_array; return u8_array;
} }
function handleFileSelect1(evt) { function handleFileSelect(evt) {
var file = evt.target.files[0]; var file = evt.target.files[0];
console.log(file);
var reader = new FileReader(); var reader = new FileReader();
reader.onload = (function(theFile) { reader.onload = (function(theFile) {
return function(e) { return function(e) {
file1 = e.target.result; file1 = e.target.result;
evt.target.data = file1;
}; };
})(file); })(file);
reader.readAsBinaryString(file); reader.readAsBinaryString(file);
} }
function handleFileSelect2(evt) {
var file = evt.target.files[0];
console.log(file);
var reader = new FileReader();
reader.onload = (function(theFile) { document.getElementById('selectFile1').addEventListener('change', handleFileSelect, false);
return function(e) {
file2 = e.target.result;
};
})(file);
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) { function _sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms)); return new Promise(resolve => setTimeout(resolve, ms));
} }
@ -113,15 +90,20 @@ connectButton.onclick = async () => {
esploader = new ESPLoader(transport, baudrates.value, term); esploader = new ESPLoader(transport, baudrates.value, term);
connected = true; connected = true;
await esploader.main_fn(); chip = await esploader.main_fn();
await esploader.flash_id(); await esploader.flash_id();
} catch(e) { } 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"; baudrates.style.display = "none";
connectButton.style.display = "none"; connectButton.style.display = "none";
disconnectButton.style.display = "initial"; disconnectButton.style.display = "initial";
eraseButton.style.display = "initial";
filesDiv.style.display = "initial"; filesDiv.style.display = "initial";
consoleDiv.style.display = "none"; consoleDiv.style.display = "none";
} }
@ -141,11 +123,57 @@ resetButton.onclick = async () => {
eraseButton.onclick = async () => { eraseButton.onclick = async () => {
eraseButton.disabled = true; eraseButton.disabled = true;
console.log("Erase Flash");
await esploader.erase_flash(); await esploader.erase_flash();
eraseButton.disabled = false; 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 () => { disconnectButton.onclick = async () => {
await transport.disconnect(); await transport.disconnect();
term.clear(); term.clear();
@ -153,7 +181,10 @@ disconnectButton.onclick = async () => {
baudrates.style.display = "initial"; baudrates.style.display = "initial";
connectButton.style.display = "initial"; connectButton.style.display = "initial";
disconnectButton.style.display = "none"; disconnectButton.style.display = "none";
eraseButton.style.display = "none";
lblConnTo.style.display = "none";
filesDiv.style.display = "none"; filesDiv.style.display = "none";
alertDiv.style.display = "none";
consoleDiv.style.display = "initial"; consoleDiv.style.display = "initial";
}; };
@ -164,7 +195,7 @@ consoleStartButton.onclick = async () => {
}); });
transport = new Transport(device); transport = new Transport(device);
} }
lblConsoleFor.style.display = "block";
consoleStartButton.style.display = "none"; consoleStartButton.style.display = "none";
consoleStopButton.style.display = "initial"; consoleStopButton.style.display = "initial";
programDiv.style.display = "none"; programDiv.style.display = "none";
@ -190,19 +221,61 @@ consoleStopButton.onclick = async () => {
programDiv.style.display = "initial"; programDiv.style.display = "initial";
} }
programButton.onclick = async () => { function validate_program_inputs() {
let fileArr = []; let offsetArr = []
if (file1 != null) { var rowCount = table.rows.length;
let offset1 = parseInt(document.getElementById("offset1").value); var row;
fileArr.push({data:file1, address:offset1}); 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 + "!";
} }
if (file2 != null) { return "success"
let offset2 = parseInt(document.getElementById("offset2").value); }
fileArr.push({data:file2, address:offset2});
} programButton.onclick = async () => {
if (file3 != null) { var err = validate_program_inputs();
let offset3 = parseInt(document.getElementById("offset3").value); if (err != "success") {
fileArr.push({data:file3, address:offset3}); const alertMsg = document.getElementById("alertmsg");
} alertMsg.innerHTML = "<strong>" + err + "</strong>";
await esploader.write_flash({fileArray: fileArr, flash_size: 'keep'}); alertDiv.style.display = "block";
return;
}
let fileArr = [];
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});
}
esploader.write_flash({fileArray: fileArr, flash_size: 'keep'});
} }