From 0887f47ae4ab3bd70f33126d74c03f06d2408eb2 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Sat, 10 Nov 2018 14:22:34 -0800 Subject: [PATCH 1/4] Added wait() to consume CPU time for better critical-timing control. --- loader.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/loader.js b/loader.js index d2330eb..cf7bea3 100644 --- a/loader.js +++ b/loader.js @@ -261,6 +261,14 @@ function clearPropCommTimer() { } } +function wait(ms) { + /* Delay (consume CPU time) for ms milliseconds. + This should only be used for time-critical delays as it doesn't release to the task queue but instead consumes CPU time until finished. + */ + let Done = Date.now() + ms; + while (Date.now() < Done){} +} + function talkToProp(sock, port, binImage, toEEPROM) { /* Return promise to deliver Propeller Application (binImage) to Propeller sock is the websocket to direct mUser messages at @@ -283,7 +291,7 @@ function talkToProp(sock, port, binImage, toEEPROM) { function sendMBL() { return new Promise(function(resolve, reject) { - setTimeout(function() { +// setTimeout(function() { //Prep for expected packetID:transmissionId response (Micro-Boot-Loader's "Ready" signal) propComm.mblEPacketId[0] = packetId; propComm.mblETransId[0] = 0; //MBL transmission's Id is always 0 @@ -295,7 +303,7 @@ function talkToProp(sock, port, binImage, toEEPROM) { .then(function() {log(notice(000, ["Found Propeller"]), mUser+mDbug, sock)}) //Succeeded! .then(function() {return resolve()}) .catch(function(e) {return reject(e)}); //Failed! - }, postResetDelay); +// }, postResetDelay); }); }; @@ -306,6 +314,7 @@ function talkToProp(sock, port, binImage, toEEPROM) { .then(function() {if (port.isWired) {return flush(port);}}) // Flush transmit/receive buffers (during Propeller reset) .then(function() {if (port.isWired) {return setControl(port, {dtr: true});}}) // End Propeller Reset .then(function() {if (port.isWired) {log("Waiting " + Math.trunc(postResetDelay) + " ms", mDeep);}}) // Wait post-reset-delay and... + .then(function() { wait(postResetDelay);}) .then(function() { return sendMBL();}) //send comm package, including Micro Boot Loader; verify receipt .catch(function(e) { //Error! if (noticeCode(e.message) === nePropellerNotFound && --attempts) { // Retry (if "Propeller not found" and more attempts available) From e9d9708ea417b77268a99834b19e7ae6026483fa Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Sat, 10 Nov 2018 15:19:07 -0800 Subject: [PATCH 2/4] Added experimental timing checkbox and enhanced loadPropeller() to use normal timing by default, not timing when checkbox checked. --- index.html | 4 ++++ index.js | 8 +++++++- loader.js | 19 +++++++++++++------ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/index.html b/index.html index 9ffb344..6549f86 100644 --- a/index.html +++ b/index.html @@ -46,6 +46,10 @@ Verbose Logging: + + Experimental Timing: + +
diff --git a/index.js b/index.js index 91cb965..fc3cca1 100644 --- a/index.js +++ b/index.js @@ -104,6 +104,8 @@ var portLister = []; // Is verbose loggin turned on? var verboseLogging = false; +// Is experimental timing turned on? +var experimentalTiming = false; document.addEventListener('DOMContentLoaded', function() { @@ -182,7 +184,11 @@ document.addEventListener('DOMContentLoaded', function() { $('bpc-trace').onclick = function() { verboseLogging = $('bpc-trace').checked; }; - + + $('exp-timing').onclick = function() { + experimentalTiming = $('exp-timing').checked; + }; + $('wx-allow').onclick = function() { var wx_enabled = $('wx-allow').checked; if(wx_enabled) { diff --git a/loader.js b/loader.js index cf7bea3..6f90c73 100644 --- a/loader.js +++ b/loader.js @@ -138,7 +138,7 @@ function loadPropeller(sock, portPath, action, payload, debug) { if (port.isWired) { //Set postResetDelay based on platform; ideal Post-Reset Delay = 100 ms; adjust downward according to typically-busy operating systems - postResetDelay = (platform === pfWin) ? 60 : 100; + postResetDelay = ((platform === pfWin) && (!experimentalTiming)) ? 60 : 100; if (port.connId) { // Connection exists, prep to close it first (to reset it), then open it (fresh) originalBaudrate = initialBaudrate; @@ -262,7 +262,7 @@ function clearPropCommTimer() { } function wait(ms) { - /* Delay (consume CPU time) for ms milliseconds. + /* Actively delay for ms milliseconds. This should only be used for time-critical delays as it doesn't release to the task queue but instead consumes CPU time until finished. */ let Done = Date.now() + ms; @@ -291,7 +291,8 @@ function talkToProp(sock, port, binImage, toEEPROM) { function sendMBL() { return new Promise(function(resolve, reject) { -// setTimeout(function() { + + function txmit() { //Prep for expected packetID:transmissionId response (Micro-Boot-Loader's "Ready" signal) propComm.mblEPacketId[0] = packetId; propComm.mblETransId[0] = 0; //MBL transmission's Id is always 0 @@ -303,9 +304,16 @@ function talkToProp(sock, port, binImage, toEEPROM) { .then(function() {log(notice(000, ["Found Propeller"]), mUser+mDbug, sock)}) //Succeeded! .then(function() {return resolve()}) .catch(function(e) {return reject(e)}); //Failed! -// }, postResetDelay); + } + + if (!experimentalTiming) { + setTimeout(txmit, postResetDelay); + } else { + wait(postResetDelay); + txmit(); + } }); - }; + } Promise.resolve() .then(function() { resetPropComm(port, mblDeliveryTime, null, null, true);}) //Reset propComm object @@ -314,7 +322,6 @@ function talkToProp(sock, port, binImage, toEEPROM) { .then(function() {if (port.isWired) {return flush(port);}}) // Flush transmit/receive buffers (during Propeller reset) .then(function() {if (port.isWired) {return setControl(port, {dtr: true});}}) // End Propeller Reset .then(function() {if (port.isWired) {log("Waiting " + Math.trunc(postResetDelay) + " ms", mDeep);}}) // Wait post-reset-delay and... - .then(function() { wait(postResetDelay);}) .then(function() { return sendMBL();}) //send comm package, including Micro Boot Loader; verify receipt .catch(function(e) { //Error! if (noticeCode(e.message) === nePropellerNotFound && --attempts) { // Retry (if "Propeller not found" and more attempts available) From 2e5e001a76bcba8878346825f24c89e7ae8937c4 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Sat, 10 Nov 2018 16:00:20 -0800 Subject: [PATCH 3/4] Undid port close+reopen change in commit 4a7f75edda since it didn't solve the CrOS v67+ download failure problem. --- loader.js | 12 ++++-------- serial.js | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/loader.js b/loader.js index 6f90c73..a21006f 100644 --- a/loader.js +++ b/loader.js @@ -140,14 +140,10 @@ function loadPropeller(sock, portPath, action, payload, debug) { //Set postResetDelay based on platform; ideal Post-Reset Delay = 100 ms; adjust downward according to typically-busy operating systems postResetDelay = ((platform === pfWin) && (!experimentalTiming)) ? 60 : 100; if (port.connId) { - // Connection exists, prep to close it first (to reset it), then open it (fresh) - originalBaudrate = initialBaudrate; - connect = function() {return closePort(port).then(function() {return openPort(sock, portPath, initialBaudrate, "programming")}).catch(function(e) {return Promise.reject(e)})} -// The following temporarily removed (and replaced above) to intentionally close and reopen port in hopes it eliminates the CrOS v67+ failed download problem -// // Connection exists, prep to reuse it -// originalBaudrate = port.baud; -// updatePort(port, {mode: "programming", bSocket: sock}); -// connect = function() {return changeBaudrate(port, initialBaudrate)} + // Connection exists, prep to reuse it + originalBaudrate = port.baud; + updatePort(port, {mode: "programming", bSocket: sock}); + connect = function() {return changeBaudrate(port, initialBaudrate)} } else { // No connection yet, prep to create one originalBaudrate = initialBaudrate; diff --git a/serial.js b/serial.js index c801eca..432c079 100644 --- a/serial.js +++ b/serial.js @@ -140,7 +140,7 @@ function closePort(port, command) { log("Closed port " + port.path + " (id " + port.connId + ")", mDbug); // Clear connection id to indicate port is closed updatePort(port, {connId: null}); - setTimeout(resolve, 250); //Delay resolve() to prevent future openPort() calls from arriving too soon to accommodate + resolve(); } else { log("Could not close port " + port.path + " (id " + port.connId + ")", mDbug); reject(Error(notice(neCanNotClosePort, [port.path]))); From 98b8c19f1989238df271f5f9ed6db6ebf7ff6cac Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Sat, 10 Nov 2018 16:12:43 -0800 Subject: [PATCH 4/4] Bumped version to 0.9.5. --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index b433faf..805681f 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "BlocklyProp Launcher", "description": "A Chrome application that connects your Propeller-Powered Hardware to the BlocklyProp website.", - "version": "0.9.4", + "version": "0.9.5", "manifest_version": 2, "minimum_chrome_version": "45",