Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 24 additions & 16 deletions loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -140,17 +140,21 @@ 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() {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)}
} else {
// No connection yet, prep to create one
originalBaudrate = initialBaudrate;
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;
Expand Down Expand Up @@ -180,9 +184,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);
Expand Down Expand Up @@ -304,7 +310,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
Expand Down Expand Up @@ -429,15 +437,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) : 1) : 1;

Promise.resolve()
.then(function() {return sendLoader();}) //Get Propeller's attention and send initial application (Micro Boot Loader)
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -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.4",
"manifest_version": 2,
"minimum_chrome_version": "45",

Expand Down
28 changes: 17 additions & 11 deletions serial.js
Original file line number Diff line number Diff line change
Expand Up @@ -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, mStat);
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
Expand Down Expand Up @@ -108,11 +109,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() {
Expand All @@ -126,7 +127,6 @@ function closePort(port, command) {
}
});
} else {
log("Not closing socket", mDbug);
reject(Error(notice(neCanNotClosePort, [port.path])));
}
}
Expand All @@ -137,12 +137,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();
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 + ")", mStat);
log("Could not close port " + port.path + " (id " + port.connId + ")", mDbug);
reject(Error(notice(neCanNotClosePort, [port.path])));
}
});
Expand Down Expand Up @@ -170,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])));
Expand Down Expand Up @@ -315,9 +315,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);
}
Expand Down