From b9729c8b524109c65888769107884d242b0e7447 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Thu, 25 Oct 2018 11:37:41 -0700 Subject: [PATCH 1/8] Increased postResetDelay adjustment for failure recovery, decreased Micro Boot Loader and User Application delivery timeouts, decreased number of retry attempts, and set retries to adjust postResetDelay only on Windows platforms. --- loader.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/loader.js b/loader.js index 9303219..4bc2af2 100644 --- a/loader.js +++ b/loader.js @@ -17,7 +17,7 @@ // Programming metrics let postResetDelay = null; //Delay after reset and before serial stream; Post-Reset Delay is set by loadPropeller() -let autoAdjust = 20; //Amount to adjust postResetDelay upon each failure +let autoAdjust = 30; //Amount to adjust postResetDelay upon each failure let txData; //Data to transmit to the Propeller (size/contents created later) const defaultClockSpeed = 80000000; @@ -150,7 +150,7 @@ function loadPropeller(sock, portPath, action, payload, debug) { connect = function() {return openPort(sock, portPath, initialBaudrate, "programming")} } } else { - //Virtually-clear postResetDelay (it's controlled by wireless device) + //Nearly-clear the postResetDelay (it's controlled by wireless device) postResetDelay = 1; //TODO Retrieve actual current baudrate originalBaudrate = initialBaudrate; @@ -304,7 +304,9 @@ function talkToProp(sock, port, binImage, toEEPROM) { .catch(function(e) { //Error! if (noticeCode(e.message) === nePropellerNotFound && --attempts) { // Retry (if "Propeller not found" and more attempts available) log("Propeller not found: retrying...", mDeep); - postResetDelay = Math.max(postResetDelay - autoAdjust, 1); // Shorten Post Reset Delay upon every attempt (min 1) + if (platform === pfWin) { // If Windows platform, + postResetDelay = Math.max(postResetDelay - autoAdjust, 1); // Shorten Post Reset Delay upon every attempt (min 1) + } return sendLoader(); // note: sendLoader does not return execution below (promises continue at next .then/.catch) } return reject(e); // Or if other error (or out of retry attempts), reject with message @@ -429,15 +431,15 @@ function talkToProp(sock, port, binImage, toEEPROM) { var next; /* Calculate expected Micro Boot Loader and User Application delivery times - = 300 [>max post-reset-delay] + ((10 [bits per byte] * (data bytes [transmitting] + 20 silence bytes [MBL waiting] + 8 MBL "ready" bytes [MBL responding])) / - initial baud rate) * 1,000 [to scale ms to integer] + 1 [to always round up] + 500 [Rx hardware to OS slack time] */ - var mblDeliveryTime = 300+((10*(txData.byteLength+20+8))/initialBaudrate)*1000+1 + (port.isWireless) ? 1500 : 250; + = 210 [max post-reset-delay] + ((10 [bits per byte] * (data bytes [transmitting] + 20 silence bytes [MBL waiting] + 8 MBL "ready" bytes [MBL responding])) / + initial baud rate) * 1,000 [to scale ms to integer] + 1 [to always round up] + 250 or 1500 [Rx hardware or Network to OS slack time] */ + var mblDeliveryTime = Math.trunc(210+((10*(txData.byteLength+20+8))/initialBaudrate)*1000+1 + ((port.isWired) ? 250 : 1500)); //=((10 [bits per byte] * [max packet size]) / final baud rate) * 1,000 [to scale ms to integer] + 1 [to always round up] + 1500 or 250 [Network or Rx hardware to OS slack time] - var userDeliveryTime = ((10*maxDataSize)/finalBaudrate)*1000+1 + (port.isWireless) ? 1500 : 250; + var userDeliveryTime = Math.trunc(((10*maxDataSize)/finalBaudrate)*1000+1 + ((port.isWired) ? 250 : 1500)); - //Set for limited retry attempts (multiple when wired to try various post-reset timing) - var attempts = (port.isWired) ? Math.trunc(postResetDelay / autoAdjust) + 1 : 1; + //Set for limited retry attempts (multiple when wired; potentially trying various post-reset timing) + var attempts = (port.isWired) ? (platform === pfWin) ? Math.max(Math.trunc(postResetDelay / autoAdjust), 1) : 2 : 1; Promise.resolve() .then(function() {return sendLoader();}) //Get Propeller's attention and send initial application (Micro Boot Loader) From c5c1a1b9b163037b6916f07b0316ba891c4bb981 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Thu, 25 Oct 2018 11:48:46 -0700 Subject: [PATCH 2/8] Bumped to v0.9.3. --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 9fa5841..73ba946 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.2", + "version": "0.9.3", "manifest_version": 2, "minimum_chrome_version": "45", From aeda30f93077a36fb860ca85745333687b3834d6 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Thu, 8 Nov 2018 16:40:55 -0800 Subject: [PATCH 3/8] Fixed loadPropeller()'s connect().catch error that wasn't catching the changeBaudrate promise. Also adjusted the final closeport() call. --- loader.js | 8 +++++--- serial.js | 15 ++++++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/loader.js b/loader.js index 4bc2af2..2275f9d 100644 --- a/loader.js +++ b/loader.js @@ -180,9 +180,11 @@ function loadPropeller(sock, portPath, action, payload, debug) { log(e.message, mAll, sock); log(notice(neDownloadFailed), mAll, sock); updatePort(port, {mode: "none"}); - if ((port.isWired && port.connId) || port.isWireless) {changeBaudrate(port, originalBaudrate)} - if (port.isWireless) {closePort(port, false)} - }); + if ((port.isWired && port.connId) || port.isWireless) {return changeBaudrate(port, originalBaudrate)} + }) + .catch(function(e) {log(e.message, mAll, sock)}) + .then(function() {if (port.isWireless) return closePort(port, false)}) + .catch(function(e) {log(e.message, mAll, sock);}); } else { // Port not found log(notice(neCanNotFindPort, [portPath]), mAll, sock); diff --git a/serial.js b/serial.js index ae75fd4..b50133d 100644 --- a/serial.js +++ b/serial.js @@ -108,11 +108,11 @@ function closePort(port, command) { function socketClose(socket) { // Nullify port's HTTP or Telnet socket reference let sID = port[socket]; - updatePort(port, {[socket]: null}); if (sID) { - log("Closing socket", mDbug); + updatePort(port, {[socket]: null}); // Disconnect and/or close socket (if necessary) chrome.sockets.tcp.getInfo(sID, function(info) { + log("Closed socket " + sID, mDbug); if (info.connected) { chrome.sockets.tcp.disconnect(sID, function() { chrome.sockets.tcp.close(sID, function() { @@ -126,7 +126,6 @@ function closePort(port, command) { } }); } else { - log("Not closing socket", mDbug); reject(Error(notice(neCanNotClosePort, [port.path]))); } } @@ -315,9 +314,15 @@ function debugErrorReceiver(info) { // log("Error: PortID "+info.connectionId+" "+info.error, mDeep); } else { switch (info.resultCode) { - case -100: //port closed + case -100: //Port closed + //Find port by Propeller Telnet ID or HTTP ID and clear record let port = findPort(byPTID, info.socketId); - if (!port) {port = findPort(byPHID, info.socketId)} + if (port) { + updatePort(port, {ptSocket: null}); + } else { + port = findPort(byPHID, info.socketId); + if (port) {updatePort(port, {phSocket: null})} + } if (port) { log("SocketID "+info.socketId+" connection closed" + ((port) ? " for port " + port.path + "." : "."), mDeep); } From 4a7f75edda929f226b8164a5ef33cc9052cae745 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Thu, 8 Nov 2018 17:41:34 -0800 Subject: [PATCH 4/8] Enhanced port open/close messages to appear in debug stream. Set loadPropeller() to close and reopen port (if necessary) hoping to resolve CrOS v67+ download failures. --- loader.js | 12 ++++++++---- serial.js | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/loader.js b/loader.js index 2275f9d..8418d5b 100644 --- a/loader.js +++ b/loader.js @@ -140,10 +140,14 @@ 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) ? 60 : 100; if (port.connId) { - // 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 close it first (to reset it), then open it (fresh) + originalBaudrate = initialBaudrate; + connect = function() {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)} } else { // No connection yet, prep to create one originalBaudrate = initialBaudrate; diff --git a/serial.js b/serial.js index b50133d..1e21aff 100644 --- a/serial.js +++ b/serial.js @@ -50,7 +50,7 @@ function openPort(sock, portPath, baudrate, connMode) { if (!chrome.runtime.lastError) { // No error; update serial port object updatePort(port, {connId: openInfo.connectionId, bSocket: sock, mode: connMode, baud: baudrate}); - log("Port " + portPath + " open with ID " + openInfo.connectionId, mStat); + log("Port " + portPath + " open with ID " + openInfo.connectionId, mDbug); resolve(); } else { // Error @@ -136,12 +136,12 @@ function closePort(port, command) { if (port.connId) { chrome.serial.disconnect(port.connId, function (closeResult) { if (closeResult) { - log("Closed port " + port.path + " (id " + port.connId + ")", mStat); + log("Closed port " + port.path + " (id " + port.connId + ")", mDbug); // Clear connection id to indicate port is closed updatePort(port, {connId: null}); resolve(); } else { - log("Could not close port " + port.path + " (id " + port.connId + ")", mStat); + log("Could not close port " + port.path + " (id " + port.connId + ")", mDbug); reject(Error(notice(neCanNotClosePort, [port.path]))); } }); From f4e0ab135437214ec1ebba0f40d688e666acb496 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Thu, 8 Nov 2018 17:46:45 -0800 Subject: [PATCH 5/8] Set CrOS for just one attempt per download. --- loader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loader.js b/loader.js index 8418d5b..79757a2 100644 --- a/loader.js +++ b/loader.js @@ -445,7 +445,7 @@ function talkToProp(sock, port, binImage, toEEPROM) { var userDeliveryTime = Math.trunc(((10*maxDataSize)/finalBaudrate)*1000+1 + ((port.isWired) ? 250 : 1500)); //Set for limited retry attempts (multiple when wired; potentially trying various post-reset timing) - var attempts = (port.isWired) ? (platform === pfWin) ? Math.max(Math.trunc(postResetDelay / autoAdjust), 1) : 2 : 1; + var attempts = (port.isWired) ? ((platform === pfWin) ? Math.max(Math.trunc(postResetDelay / autoAdjust), 1) : 1) : 1; Promise.resolve() .then(function() {return sendLoader();}) //Get Propeller's attention and send initial application (Micro Boot Loader) From 170bef490883e2c85554670b9a682fb05284ec25 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Thu, 8 Nov 2018 17:48:07 -0800 Subject: [PATCH 6/8] Bumped to v0.9.4 --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 73ba946..b433faf 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.3", + "version": "0.9.4", "manifest_version": 2, "minimum_chrome_version": "45", From ec05a8386cd956982b4fc2b79eee4b92b600c598 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Thu, 8 Nov 2018 18:17:02 -0800 Subject: [PATCH 7/8] Enhanced openPort() to update port record's baudrate without adjusting the actual port's baudrate once again. --- serial.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/serial.js b/serial.js index 1e21aff..432c079 100644 --- a/serial.js +++ b/serial.js @@ -49,8 +49,9 @@ function openPort(sock, portPath, baudrate, connMode) { function (openInfo) { if (!chrome.runtime.lastError) { // No error; update serial port object - updatePort(port, {connId: openInfo.connectionId, bSocket: sock, mode: connMode, baud: baudrate}); - log("Port " + portPath + " open with ID " + openInfo.connectionId, mDbug); + updatePort(port, {connId: openInfo.connectionId, bSocket: sock, mode: connMode}); + port.baud = baudrate; //Update baud; does not use updatePort() to avoid unnecessary port activity + log("Port " + portPath + " open with ID " + openInfo.connectionId + " at " + baudrate + " baud", mDbug); resolve(); } else { // Error @@ -169,7 +170,7 @@ function changeBaudrate(port, baudrate) { if (port.isWired) { chrome.serial.update(port.connId, {'bitrate': baudrate}, function (updateResult) { if (updateResult) { - port.baud = baudrate; //Update baud; does not use updatePort() because of circular reference //!!! + port.baud = baudrate; //Update baud; does not use updatePort() to avoid circular reference resolve(); } else { reject(Error(notice(neCanNotSetBaudrate, [port.path, baudrate]))); From 1b4b1df2bc483ca50a5a5c0dc20c25ccfb6b9516 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Thu, 8 Nov 2018 19:28:15 -0800 Subject: [PATCH 8/8] Fixed broken promise in loadPropeller() and delayed closePort()'s resolve by 250 ms to prevent future openPort() calls from arriving too soon for the OS to accommodate. --- loader.js | 2 +- serial.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/loader.js b/loader.js index 79757a2..d2330eb 100644 --- a/loader.js +++ b/loader.js @@ -142,7 +142,7 @@ function loadPropeller(sock, portPath, action, payload, debug) { if (port.connId) { // Connection exists, prep to close it first (to reset it), then open it (fresh) originalBaudrate = initialBaudrate; - connect = function() {closePort(port).then(function() {return openPort(sock, portPath, initialBaudrate, "programming")}).catch(function(e) {return Promise.reject(e)})} + 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; diff --git a/serial.js b/serial.js index 432c079..c801eca 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}); - resolve(); + setTimeout(resolve, 250); //Delay resolve() to prevent future openPort() calls from arriving too soon to accommodate } else { log("Could not close port " + port.path + " (id " + port.connId + ")", mDbug); reject(Error(notice(neCanNotClosePort, [port.path])));