0.02: Add 'pre' code that can erase the device

Wait more between sending code snippets
      Now force use of 'Storage' (assume 2v00 or later)
pull/2070/head^2
Gordon Williams 2022-08-02 11:28:14 +01:00
parent 2288b4d029
commit 73bafd4b5d
5 changed files with 66 additions and 22 deletions

View File

@ -1 +1,4 @@
0.01: New App!
0.02: Add 'pre' code that can erase the device
Wait more between sending code snippets
Now force use of 'Storage' (assume 2v00 or later)

View File

@ -13,6 +13,9 @@ Click on the Customise button in the app loader to set up the programmer.
* First you need to choose the kind of devices you want to upload to. This is
the text that should match the Bluetooth advertising name. So `Puck.js` for Puck.js
devices, or `Bangle.js` for Bangles.
* In the next box, you have code to run before the upload of the main code. By default
the code `require("Storage").list().forEach(f=>require("Storage").erase(f));reset();` will
erase all files on the device and reset it.
* Now paste in the code you want to write to the device. This is automatically
written to flash (`.bootcde`). See https://www.espruino.com/Saving#save-on-send-to-flash-
for more information.
@ -35,8 +38,6 @@ To stop scanning, long-press the button to return to the clock.
## Notes
* Right now the Espruino Tools used here are unaware of the device they're writing to,
and as a result they don't use Storage and so the size of the files you can
write to the device are quite limited. You should be find with up to 4k of code.
* This assumes the device being written to is at least version 2v00 of Espruino
* Currently, code is not minified before upload (so you need to supply pre-minified
code if you want that)

View File

@ -58,21 +58,31 @@ function scanAndConnect() {
term.print("Connected...\r\n");
uart.removeAllListeners();
uart.on('data', function(d) { term.print(d); });
uart.write(json.code+"\n").then(() => {
term.print("\r\nUpload Complete...\r\n");
// main upload completed - wait a bit
term.print("Upload initial...\r\n");
uart.write((json.pre||"")+"\n").then(() => {
term.print("\r\Done.\r\n");
uploadTimeout = setTimeout(function() {
term.print("\r\nFinal Upload...\r\n");
// now upload the code to run after...
uart.write(json.post+"\n").then(() => {
term.print("\r\nDone.\r\n");
// now wait and disconnect (if not already done!)
uploadTimeout = undefined;
term.print("\r\nUpload Code...\r\n");
uart.write((json.code||"")+"\n").then(() => {
term.print("\r\Done.\r\n");
// main upload completed - wait a bit
uploadTimeout = setTimeout(function() {
term.print("\r\nDisconnecting...\r\n");
if (uart) uart.disconnect();
}, 500);
uploadTimeout = undefined;
term.print("\r\Upload final...\r\n");
// now upload the code to run after...
uart.write((json.post||"")+"\n").then(() => {
term.print("\r\nDone.\r\n");
// now wait and disconnect (if not already done!)
uploadTimeout = setTimeout(function() {
uploadTimeout = undefined;
term.print("\r\nDisconnecting...\r\n");
if (uart) uart.disconnect();
}, 500);
});
}, 2000);
});
}, 1000);
}, 2000);
});
});
}).catch(err => {

View File

@ -17,6 +17,8 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/jshint/2.11.0/jshint.min.js"></script>
<p>Upload code to devices with names starting with:</p>
<p><input type="text" id="nameprefix"></input></p>
<p>Enter the code to send before upload here:</p>
<p><textarea id="pre-code"></textarea></p>
<p>Enter your program to upload here:</p>
<p><textarea id="js-code"></textarea></p>
<p>Enter the code to send after upload here:</p>
@ -24,12 +26,17 @@
<p>Then click <button id="upload" class="btn btn-primary">Upload</button>&nbsp;<span id="btninfo" style="color:orange"></span> </p>
<p><a id="setdefault">Click here</a> to reset to defaults.</p>
<script>
const LS_PRECODE = "espruinoprog.precode";
const LS_JSCODE = "espruinoprog.code";
const LS_POSTCODE = "espruinoprog.postcode";
const LS_NAMEPREFIX = "espruinoprog.namePrefix";
var jseditor,posteditor;
var preeditor,jseditor,posteditor;
function setDefaults() {
if (localStorage.getItem(LS_PRECODE) === null) {
localStorage.setItem(LS_PRECODE, `// Erase all files (faster than eraseall)
require("Storage").list().forEach(f=>require("Storage").erase(f));reset();`);
}
if (localStorage.getItem(LS_JSCODE) === null) {
localStorage.setItem(LS_JSCODE, `// Flash LED2 every 2 seconds
setInterval(function() {
@ -47,6 +54,8 @@ LED.set();NRF.sleep();`);
if (localStorage.getItem(LS_NAMEPREFIX) === null) {
localStorage.setItem(LS_NAMEPREFIX, "Puck.js");
}
document.getElementById("pre-code").value = localStorage.getItem(LS_PRECODE);
if (preeditor) preeditor.setValue(document.getElementById("pre-code").value);
document.getElementById("js-code").value = localStorage.getItem(LS_JSCODE);
if (jseditor) jseditor.setValue(document.getElementById("js-code").value);
document.getElementById("post-code").value = localStorage.getItem(LS_POSTCODE);
@ -55,8 +64,6 @@ LED.set();NRF.sleep();`);
}
setDefaults();
// The code editor
var lintFlags = {
esversion: 6, // Enable ES6 for literals, arrow fns, binary
@ -64,6 +71,17 @@ LED.set();NRF.sleep();`);
laxbreak: true, // don't warn about newlines in expressions
laxcomma: true // don't warn about commas at the start of the line
};
preeditor = CodeMirror.fromTextArea(document.getElementById("pre-code"), {
width: "100%",
height: "auto",
matchBrackets: true,
mode: { name: "javascript", globalVars: false },
lineWrapping: true,
showTrailingSpace: true,
lint: lintFlags,
gutters: ["CodeMirror-linenumbers", "CodeMirror-lint-markers"],
lineNumbers: true
});
jseditor = CodeMirror.fromTextArea(document.getElementById("js-code"), {
width: "100%",
height: "auto",
@ -87,7 +105,9 @@ LED.set();NRF.sleep();`);
lineNumbers: true
});
function hasWarnings() {
return jseditor.state.lint.marked.length!=0 || posteditor.state.lint.marked.length!=0;
return preeditor.state.lint.marked.length!=0 ||
jseditor.state.lint.marked.length!=0 ||
posteditor.state.lint.marked.length!=0;
}
var editorChangedTimeout;
function editorChanged() {
@ -95,26 +115,34 @@ LED.set();NRF.sleep();`);
editorChangedTimeout = setTimeout(function() {
if (hasWarnings()) {
document.getElementById("btninfo").innerHTML = "There are warnings in the code to be uploaded";
document.getElementById("upload").classList.add("disabled");
//document.getElementById("upload").classList.add("disabled");
} else {
document.getElementById("btninfo").innerHTML = "";
document.getElementById("upload").classList.remove("disabled");
//document.getElementById("upload").classList.remove("disabled");
}
}, 500);
}
preeditor.on("change", editorChanged);
jseditor.on("change", editorChanged);
posteditor.on("change", editorChanged);
document.getElementById("upload").addEventListener("click", function() {
if (!hasWarnings()) {
var precode = preeditor.getValue();
var jscode = jseditor.getValue();
var postcode = posteditor.getValue();
var namePrefix = document.getElementById("nameprefix").value;
localStorage.setItem(LS_PRECODE, precode);
localStorage.setItem(LS_JSCODE, jscode);
localStorage.setItem(LS_POSTCODE, postcode);
localStorage.setItem(LS_NAMEPREFIX, namePrefix);
// force version - as long as we're above 1v96 we get the ability to upload to different storage files
var ENV = Espruino.Core.Env.getData();
ENV.VERSION_MAJOR = 2;
ENV.VERSION_MINOR = 0;
// Now compile
Espruino.transform(jscode, {
SET_TIME_ON_WRITE : false, // time would just be out of date
SAVE_ON_SEND : 1, // save to flash
@ -125,6 +153,7 @@ LED.set();NRF.sleep();`);
sendCustomizedApp({
storage: [{ name: "espruinoprog.json", content: JSON.stringify({
namePrefix : namePrefix,
pre : Espruino.Core.CodeWriter.reformatCode(precode),
code : Espruino.Core.CodeWriter.reformatCode(content),
post : Espruino.Core.CodeWriter.reformatCode(postcode)
})}]
@ -134,6 +163,7 @@ LED.set();NRF.sleep();`);
});
document.getElementById("setdefault").addEventListener("click", function(e) {
e.preventDefault();
localStorage.removeItem(LS_PRECODE);
localStorage.removeItem(LS_JSCODE);
localStorage.removeItem(LS_POSTCODE);
localStorage.removeItem(LS_NAMEPREFIX);

View File

@ -2,7 +2,7 @@
"id": "espruinoprog",
"name": "Espruino Programmer",
"shortName": "Programmer",
"version": "0.01",
"version": "0.02",
"description": "Finds Bluetooth devices with a specific name (eg 'Puck.js'), connects and uploads code. Great for programming many devices at once!",
"icon": "app.png",
"tags": "tool,bluetooth",