const baudrates = document.getElementById('baudrates'); const connectButton = document.getElementById('connectButton'); const disconnectButton = document.getElementById('disconnectButton'); 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'); 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 table = document.getElementById('fileTable'); const alertDiv = document.getElementById('alertDiv'); // import { Transport } from './cp210x-webusb.js' import * as esptooljs from "./bundle.js"; const ESPLoader = esptooljs.ESPLoader; const Transport = esptooljs.Transport; let term = new Terminal({ cols: 120, rows: 40 }); term.open(terminal); let device = null; let transport; let chip = null; let esploader; let file1 = null; // let temp_bin_file = null; let connected = false; disconnectButton.style.display = 'none'; eraseButton.style.display = 'none'; consoleStopButton.style.display = 'none'; filesDiv.style.display = 'none'; function handleFileSelect(evt) { var file = evt.target.files[0]; if (!file) return; var reader = new FileReader(); reader.onload = (function (theFile) { return function (e) { file1 = e.target.result; evt.target.data = file1; }; })(file); reader.readAsBinaryString(file); } function sleep(milliseconds) { const date = Date.now(); let currentDate = null; do { currentDate = Date.now(); } while (currentDate - date < milliseconds); } function SyncFileReader(file) { let self = this; let ready = false; let result = ''; const sleep = function (ms) { return new Promise(resolve => setTimeout(resolve, ms)); } self.readAsBinaryString = async function() { while (ready === false) { await sleep(100); } return result; } const reader = new FileReader(); reader.onloadend = function(evt) { result = evt.target.result; if( result ){ console.log(result); } ready = true; }; reader.readAsBinaryString(file); } // function binary_reader_helper(file) { // var ready = false; // var result = ''; // var check = function() { // if (ready === true) { // // do what you want with the result variable // return; // } // setTimeout(check, 1000); // } // check(); // var reader = new FileReader(); // reader.onloadend = function(evt) { // // file is loaded // result = evt.target.result; // ready = true; // }; // reader.readAsBinaryString(file); // return (' ' + reader.result).slice(1); // // let reader = new FileReader(); // // reader.onload = function(evt) { // // var bin = evt.target.result; //get file content // // // do sth with text // // console.log(bin); // // // temp_bin_file = (' ' + bin).slice(1); // // // var li = document.createElement("li"); // // // li.innerHTML = name; // // // ul.appendChild(li); // // }; // // reader.onloadend = () => { // // console.log("DONE", reader.readyState); // readyState will be 2 // // }; // } let espLoaderTerminal = { clean() { term.clear(); }, writeLine(data) { term.writeln(data); }, write(data) { term.write(data) } } connectButton.onclick = async () => { if (device === null) { device = await navigator.serial.requestPort({}); transport = new Transport(device); } try { esploader = new ESPLoader(transport, baudrates.value, espLoaderTerminal); connected = true; chip = await esploader.main_fn(); // Temporarily broken // await esploader.flash_id(); } catch (e) { console.error(e); term.writeln(`Error: ${e.message}`); } 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'; }; 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; try { await esploader.erase_flash(); } catch (e) { console.error(e); term.writeln(`Error: ${e.message}`); } finally { eraseButton.disabled = false; } }; // addFile.onclick = () => { // 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.value = '0x1000'; // 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 - Progress // var cell3 = row.insertCell(2); // cell3.classList.add('progress-cell'); // cell3.style.display = 'none'; // cell3.innerHTML = ``; // // 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 () { // removeRow(row); // }; // cell4.appendChild(element4); // } // }; // function removeRow(row) { // const rowIndex = Array.from(table.rows).indexOf(row); // table.deleteRow(rowIndex); // } // to be called on disconnect - remove any stale references of older connections if any function cleanUp() { device = null; transport = null; chip = null; } disconnectButton.onclick = async () => { if (transport) await transport.disconnect(); term.clear(); connected = false; baudrates.style.display = 'initial'; connectButton.style.display = 'initial'; disconnectButton.style.display = 'none'; eraseButton.style.display = 'none'; lblConnTo.style.display = 'none'; filesDiv.style.display = 'none'; alertDiv.style.display = 'none'; consoleDiv.style.display = 'initial'; cleanUp(); }; let isConsoleClosed = false; consoleStartButton.onclick = async () => { if (device === null) { device = await navigator.serial.requestPort({}); transport = new Transport(device); } lblConsoleFor.style.display = 'block'; consoleStartButton.style.display = 'none'; consoleStopButton.style.display = 'initial'; programDiv.style.display = 'none'; await transport.connect(); isConsoleClosed = false; while (true && !isConsoleClosed) { let val = await transport.rawRead(); if (typeof val !== 'undefined') { term.write(val); } else { break; } } console.log('quitting console'); }; consoleStopButton.onclick = async () => { isConsoleClosed = true; await transport.disconnect(); await transport.waitForUnlock(1500); term.clear(); consoleStartButton.style.display = 'initial'; consoleStopButton.style.display = 'none'; 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 () => { // const alertMsg = document.getElementById('alertmsg'); // const err = validate_program_inputs(); // if (err != 'success') { // alertMsg.innerHTML = '' + err + ''; // alertDiv.style.display = 'block'; // return; // } // Hide error message // alertDiv.style.display = 'none'; let temp_bin_file = null; const fileArray = []; // const progressBars = []; // for (let index = 1; index < table.rows.length; index++) { // const row = table.rows[index]; // const offSetObj = row.cells[0].childNodes[0]; // const offset = parseInt(offSetObj.value); // const fileObj = row.cells[1].childNodes[0]; // const progressBar = row.cells[2].childNodes[0]; // progressBar.value = 0; // progressBars.push(progressBar); // row.cells[2].style.display = 'initial'; // row.cells[3].style.display = 'none'; // fileArray.push({ data: fileObj.data, address: offset }); // } // ################################################################### // ################################################################### let response = await fetch("/binary_blob/bootloader.bin"); if(response.status != 200) { throw new Error("Server Error"); } // read response stream as text // let text_data = await response.text(); let blob_data = await response.blob(); if(!blob_data) { throw new Error("Can't read file to flash as blob !") } let file = new File( [blob_data], "bootloader.bin", { type: "text/plain", }); // let reader = new FileReader(); // reader.onload = (function (theFile) { // return function (e) { // file1 = e.target.result; // }; // })(file); // reader.onloadend = function (theFile){ // file1 = this.result; // console.log(this.result); // }; console.log( file ); let fileReader = new SyncFileReader(file); temp_bin_file = await fileReader.readAsBinaryString(); if( !temp_bin_file ){ temp_bin_file = await fileReader.readAsBinaryString(); if( temp_bin_file ){ console.log( temp_bin_file ); fileArray.push({ data: (' ' + temp_bin_file).slice(1) , address: 0x1000 }); } }else{ console.log( temp_bin_file ); fileArray.push({ data: (' ' + temp_bin_file).slice(1) , address: 0x1000 }); } temp_bin_file = null; // ################################################################### // ################################################################### response = await fetch("/binary_blob/partitions.bin"); if(response.status != 200) { throw new Error("Server Error"); } blob_data = await response.blob(); if(!blob_data) { throw new Error("Can't read file to flash as blob !") } file = new File( [blob_data], "partitions.bin", { type: "text/plain", }); console.log( file ); fileReader = new SyncFileReader(file); temp_bin_file = await fileReader.readAsBinaryString(); if( !temp_bin_file ){ temp_bin_file = await fileReader.readAsBinaryString(); if( temp_bin_file ){ console.log( temp_bin_file ); fileArray.push({ data: (' ' + temp_bin_file).slice(1) , address: 0x8000 }); } }else{ console.log( temp_bin_file ); fileArray.push({ data: (' ' + temp_bin_file).slice(1) , address: 0x8000 }); } temp_bin_file = null; // ################################################################### // ################################################################### response = await fetch("/binary_blob/boot_app0.bin"); if(response.status != 200) { throw new Error("Server Error"); } blob_data = await response.blob(); if(!blob_data) { throw new Error("Can't read file to flash as blob !") } file = new File( [blob_data], "boot_app0.bin", { type: "text/plain", }); console.log( file ); fileReader = new SyncFileReader(file); temp_bin_file = await fileReader.readAsBinaryString(); if( !temp_bin_file ){ temp_bin_file = await fileReader.readAsBinaryString(); if( temp_bin_file ){ console.log( temp_bin_file ); fileArray.push({ data: temp_bin_file , address: 0xe000 }); } }else{ console.log( temp_bin_file ); fileArray.push({ data: temp_bin_file , address: 0xe000 }); } temp_bin_file = null; // ################################################################### // ################################################################### response = await fetch("/binary_blob/opendtu-generic.bin"); if(response.status != 200) { throw new Error("Server Error"); } blob_data = await response.blob(); if(!blob_data) { throw new Error("Can't read file to flash as blob !") } file = new File( [blob_data], "opendtu-gernic.bin", { type: "text/plain", }); console.log( file ); fileReader = new SyncFileReader(file); temp_bin_file = await fileReader.readAsBinaryString(); if( !temp_bin_file ){ temp_bin_file = await fileReader.readAsBinaryString(); if( temp_bin_file ){ console.log( temp_bin_file ); fileArray.push({ data: temp_bin_file , address: 0x10000 }); } }else{ console.log( temp_bin_file ); fileArray.push({ data: temp_bin_file , address: 0x10000 }); } temp_bin_file = null; sleep(3000) console.log(fileArray) try { await esploader.write_flash( fileArray, 'keep', undefined, undefined, false, true, null, (image) => CryptoJS.MD5(CryptoJS.enc.Latin1.parse(image)), ); } catch (e) { console.error(e); term.writeln(`Error: ${e.message}`); } finally { // Hide progress bars and show erase buttons // for (let index = 1; index < table.rows.length; index++) { // table.rows[index].cells[2].style.display = 'none'; // table.rows[index].cells[3].style.display = 'initial'; // } } }; // addFile.onclick();