Merge branch 'master' into ESP32-V3.1

This commit is contained in:
wilberforce 2018-10-20 17:21:14 +13:00
commit 69c34c52ca
41 changed files with 358 additions and 192 deletions

View File

@ -1,4 +1,7 @@
Allow changeInterval with large (>32 bit) intervals (fix #1438)
Fix issues with Class Extends
Improve Tab Completions for extended classes
2v00 : Allow changeInterval with large (>32 bit) intervals (fix #1438)
changeInterval now changes the interval immediately when it's called inside the interval it is changing (fix #1440)
Fix parsing of try..catch when not executing (fix #1439)
Add extra ReferenceError checks, even if variable is not used
@ -103,6 +106,18 @@
Espruino WiFi: Only rename `EspruinoWiFi` to `WiFi` if not found (allows easier debug)
Check Flash Storage for modules when using `require`
Add 'bits' option for Software SPI
STM32 reset pin IRQs before storing the state - makes lost setWatches far less likely
Ensure that setBusyIndicator updates output state after the very first initialisation.
MDBT42Q: Add LED2 var in the Espruino interpreter, but don't use it for the bootloader
ESP8266: release heap used by logDebug(true) (fix #1508)
ESP8266: remove SHA256 SHA512 (fix #1517)
Ensure `Date.getTimezoneOffset()` returns the correct timezone offset (fix #1515)
Search for and execute files '.boot0'/1/2/3 in Storage at boot time if they exist
Pixl.js: reduce saved code area to 9 x 4kb to allow for extra features
ESP8266: switch to SDK 2.2.1 (fix #1207)
Fix Serial port path regression on Linux, and add docs
microbit: remove line-by-line debug capability to free up some space
Added ES6 String.prototype.repeat
1v99 : Increase jslMatch error buffer size to handle "UNFINISHED TEMPLATE LITERAL" string (#1426)
nRF5x: Make FlashWrite cope with flash writes > 4k

View File

@ -26,7 +26,7 @@ info = {
'NET',
'TELNET',
'GRAPHICS',
'CRYPTO','SHA256','SHA512',
'CRYPTO',
'NEOPIXEL',
#'FILESYSTEM',
#'FLASHFS'

View File

@ -71,6 +71,7 @@ chip = {
devices = {
'LED1' : { 'pin' : 'D1' },
'LED2' : { 'pin' : 'D2', 'no_bootloader':True }, # don't use LED2 in the bootloader since we may be using a bare module
'BTN1' : { 'pin' : 'D0', 'pinstate' : 'IN_PULLDOWN' },
'NFC': { 'pin_a':'D9', 'pin_b':'D10' },
# Pin D22 is used for clock when driving neopixels - as not specifying a pin seems to break things

View File

@ -34,7 +34,7 @@ info = {
'makefile' : [
'SAVE_ON_FLASH=1',
'DEFINES+=-DCONFIG_GPIO_AS_PINRESET', # Allow the reset pin to work
'DEFINES+=-DUSE_DEBUGGER -DUSE_TAB_COMPLETE',
'DEFINES+=-DUSE_TAB_COMPLETE', # Removed -DUSE_DEBUGGER due to firmware size issues
'INCLUDE += -I$(ROOT)/libs/microbit',
'WRAPPERSOURCES += libs/microbit/jswrap_microbit.c'
]

View File

@ -69,10 +69,10 @@ chip = {
'adc' : 1,
'dac' : 0,
'saved_code' : {
'address' : ((118 - 10) * 4096), # Bootloader takes pages 120-127, FS takes 118-119
'address' : ((118 - 9) * 4096), # Bootloader takes pages 120-127, FS takes 118-119
'page_size' : 4096,
'pages' : 10,
'flash_available' : 512 - ((31 + 8 + 2 + 10)*4) # Softdevice uses 31 pages of flash, bootloader 8, FS 2, code 10. Each page is 4 kb.
'pages' : 9,
'flash_available' : 512 - ((31 + 8 + 2 + 9)*4) # Softdevice uses 31 pages of flash, bootloader 8, FS 2, code 10. Each page is 4 kb.
},
};

View File

@ -287,7 +287,7 @@ JsVar *jswrap_graphics_createSDL(int width, int height) {
"#if" : "!defined(SAVE_ON_FLASH) && !defined(ESPRUINOBOARD)",
"generate" : "jswrap_graphics_createImage",
"params" : [
["str","JsVar","A String containing newline-separated "]
["str","JsVar","A String containing a newline-separated image - space is 0, anything else is 1"]
],
"return" : ["JsVar","An Image object that can be used with `Graphics.drawImage`"]
}
@ -297,12 +297,12 @@ Use as follows:
```
var img = Graphics.createImage(`
#########
# #
# # #
# # #
# #
#########
XXXXXXXXX
X X
X X X
X X X
X X
XXXXXXXXX
`);
g.drawImage(img, x,y);
```

8
libs/js/AT.min.js vendored
View File

@ -1,4 +1,4 @@
exports.connect=function(n){var m=!1,b="",g,d=0,l,e={},h={},k=[];n.on("data",function q(a){if(d){b&&(a=b+a,b="");if(a.length<=d){d-=a.length;l(a);0==d&&(l=void 0);return}l(a.substr(0,d));a=a.substr(d);d=0;l=void 0}b+=a;m&&console.log("] "+JSON.stringify(a));if(e)for(var c in e)for(;b.substr(0,c.length)==c;)if(a=b,b=e[c](b),a==b)return;for(a=b.indexOf("\r\n");0<=a;){var f=b.substr(0,a),p=!1;if(0<f.length){for(c in h)f.substr(0,c.length)==c&&(h[c](f),p=!0);p||g&&g(f)}b=b.substr(a+2);if(p&&
d)return q("");if(b.length&&e)for(c in e)b.substr(0,c.length)==c&&(b=e[c](b));a=b.indexOf("\r\n")}});var f={debug:function(a){m=!1!==a;return{line:b,lineCallback:g,handlers:e,lineHandlers:h,waiting:k,dataCount:d}},cmd:function(a,b,c){if(g)m&&console.log("Queued "+JSON.stringify(a)),k.push([a,b,c]);else if(m&&console.log("["+JSON.stringify(a)),n.write(a),b){var d=setTimeout(function(){g=void 0;c&&c();void 0===g&&0<k.length&&f.cmd.apply(f,k.shift())},b),e=function(a){g=void 0;var b;c&&(b=c(a))?(g=e,
c=b):clearTimeout(d);void 0===g&&0<k.length&&f.cmd.apply(f,k.shift())};g=e}},write:function(a){n.write(a)},cmdReg:function(a,b,c,d,e){f.registerLine(c,d);f.cmd(a,b,function(a){f.unregisterLine(c);e(a)})},registerLine:function(a,b){if(h[a])throw Error(a+" already registered");h[a]=b},unregisterLine:function(a){delete h[a]},register:function(a,b){if(e[a])throw Error(a+" already registered");e[a]=b},unregister:function(a){delete e[a]},isBusy:function(){return void 0!==g},getData:function(a,b){if(d)throw Error("Already grabbing data");
d=a;l=b}};return f}
exports.connect=function(n){var m=!1,b="",g,d=0,l,e={},h={},k=[];n.on("data",function q(a){if(d){b&&(a=b+a,b="");if(a.length<=d){d-=a.length;l(a);0==d&&(l=void 0);return}l(a.substr(0,d));a=a.substr(d);d=0;l=void 0}b+=a;m&&console.log("] "+JSON.stringify(a));"\n"==b[0]&&(b=b.substr(1));if(e)for(var c in e)for(;b.substr(0,c.length)==c;)if(a=b,b=e[c](b),a==b)return;for(a=b.indexOf("\r");0<=a;){var f=b.substr(0,a),p=!1;if(0<f.length){for(c in h)f.substr(0,c.length)==c&&(h[c](f),p=!0);p||g&&
g(f)}b=b.substr(a+1);if(p&&d)return q("");"\n"==b[0]&&(b=b.substr(1));if(b.length&&e)for(c in e)b.substr(0,c.length)==c&&(b=e[c](b));a=b.indexOf("\r")}});var f={debug:function(a){m=!1!==a;return{line:b,lineCallback:g,handlers:e,lineHandlers:h,waiting:k,dataCount:d}},cmd:function(a,b,c){if(g)m&&console.log("Queued "+JSON.stringify(a)),k.push([a,b,c]);else if(m&&console.log("["+JSON.stringify(a)),n.write(a),b){var d=setTimeout(function(){g=void 0;c&&c();void 0===g&&0<k.length&&f.cmd.apply(f,k.shift())},
b),e=function(a){g=void 0;var b;c&&(b=c(a))?(g=e,c=b):clearTimeout(d);void 0===g&&0<k.length&&f.cmd.apply(f,k.shift())};g=e}},write:function(a){n.write(a)},cmdReg:function(a,b,c,d,e){f.registerLine(c,d);f.cmd(a,b,function(a){f.unregisterLine(c);e(a)})},registerLine:function(a,b){if(h[a])throw Error(a+" already registered");h[a]=b},unregisterLine:function(a){delete h[a]},register:function(a,b){if(e[a])throw Error(a+" already registered");e[a]=b},unregister:function(a){delete e[a]},isBusy:function(){return void 0!==
g},getData:function(a,b){if(d)throw Error("Already grabbing data");d=a;l=b}};return f}

View File

@ -1,4 +1,4 @@
function c(a,e){var d=this;this.serial=a;this.at=require("AT").connect(a);this.at.registerLine('+CMTI: "SM",',function(a){d.emit("message",a.substr(12));return""})}function g(a){if(0!=(a.length&3))return a;for(var e="",d=0;d<a.length;d+=4){var b=parseInt(a.substr(d,4),16);if(isNaN(b))return a;e+=String.fromCharCode(b)}return e}c.prototype.init=function(a){var e=this.at;this.at.cmd("ATE0\r\n",3E3,function k(b){if(b&&"ATE0"==b.trim())return k;"OK"!=b&&a("ATE0 ERROR "+b);e.cmd("AT+CMGF=1\r\n",
1E3,function(b){a&&a("OK"==b?null:"CMGF ERROR "+b)})})};c.prototype.send=function(a,e,d){var b=this.at;b.register(">",function(){b.unregister(">");b.write(e+"\u001a\r");return""});b.cmd('AT+CMGS="'+a+'"\r\n',1E4,function f(a){b.unregister(">");if(a&&"+CMGS"==a.substr(0,5))return f;d&&d("OK"==a?null:"CMGS ERROR "+a)})};c.prototype.list=function(a,e){var d=[],b;this.at.cmd('AT+CMGL="'+a+'"\r\n',1E4,function f(a){if(void 0!==b&&void 0!==a)return b.text=g(a),b=void 0,f;if(a&&"+CMGL: "==a.substr(0,7)){try{var c=
function c(a,e){var d=this;this.serial=a;this.at=require("AT").connect(a);this.at.registerLine('+CMTI: "SM",',function(a){d.emit("message",a.substr(12));return""})}function g(a){if(0!=(a.length&3))return a;for(var e="",d=0;d<a.length;d+=4){var b=parseInt(a.substr(d,4),16);if(isNaN(b))return a;e+=String.fromCharCode(b)}return e}c.prototype.init=function(a){var e=this.at;this.at.cmd("ATE0\r\n",3E3,function k(b){if("ATE0"==b)return k;"OK"!=b&&a("ATE0 ERROR "+b);e.cmd("AT+CMGF=1\r\n",1E3,
function(b){a&&a("OK"==b?null:"CMGF ERROR "+b)})})};c.prototype.send=function(a,e,d){var b=this.at;b.register(">",function(){b.unregister(">");b.write(e+"\u001a\r");return""});b.cmd('AT+CMGS="'+a+'"\r\n',1E4,function f(a){b.unregister(">");if(a&&"+CMGS"==a.substr(0,5))return f;d&&d("OK"==a?null:"CMGS ERROR "+a)})};c.prototype.list=function(a,e){var d=[],b;this.at.cmd('AT+CMGL="'+a+'"\r\n',1E4,function f(a){if(void 0!==b&&void 0!==a)return b.text=g(a),b=void 0,f;if(a&&"+CMGL: "==a.substr(0,7)){try{var c=
JSON.parse("["+a.substr(7)+"]");b={index:c[0],isRead:"REC READ"==c[1],oaddr:c[2],oname:c[3],time:c[4],text:""};d.push(b)}catch(m){}return f}e&&e("OK"==a?null:"CMGL ERROR "+a,d)})};c.prototype.get=function(a,e){var d;this.at.cmd("AT+CMGR="+a+"\r\n",1E4,function h(a){if("OK"==a)return e(null,d);if(void 0!==d&&void 0!==a&&"OK"!=a)return d.text=g(a),h;if(a&&"+CMGR: "==a.substr(0,7)){try{var c=JSON.parse("["+a.substr(7)+"]");d={isRead:"REC READ"==c[0],oaddr:c[1],oname:c[2],time:c[3],text:""}}catch(l){}return h}e&&
e("OK"==a?null:"CMGR ERROR "+a,list)})};c.prototype["delete"]=function(a,c){"ALL"==a&&(a="1,4");this.at.cmd("AT+CMGD="+a+"\r\n",1E3,function(a){c&&c("OK"==a?null:"CMGD ERROR "+a)})};exports=c

View File

@ -1,6 +1,6 @@
function k(){}function g(a,b){return new Promise(function(c,n){var l="";d.cmd(a+"\r\n",b||1E3,function p(b){if(void 0===b||"ERROR"==b)n(a+": "+b?b:"TIMEOUT");else if("OK"==b)c(l);else return l+=(l?"\n":"")+b,p})})}var d,e=[],f=" ".split(" "),h=!1,q={create:function(a,b){var c=0;if(void 0===a)return k("Server not implemented"),-1;for(;void 0!==e[c];)c++;if(6<=c)throw Error("No free sockets.");e[c]="Wait";f[c]="";h=!0;d.cmd("AT+QIOPEN=1,"+c+',"TCP",'+JSON.stringify(a)+","+b+",0,1\r\n",
1E4,function(a){"OK"!=a&&(e[c]=void 0,h=!1)});return c},close:function(a){void 0!==e[a]&&d.cmd("AT+QICLOSE="+a+"\r\n",1E3,function(){e[a]=void 0})},accept:function(a){return-1},recv:function(a,b){if(f[a]){if(f[a].length>b){var c=f[a].substr(0,b);f[a]=f[a].substr(b)}else c=f[a],f[a]="";return c}return e[a]?"":-1},send:function(a,b){if(h||d.isBusy()||"Wait"==e[a])return 0;if(!e[a])return-1;h=!0;d.write("AT+QISEND="+a+","+b.length+"\r\n");setTimeout(function(){d.cmd(b,2E3,function(b){k("AT+QISEND response "+
JSON.stringify(b));"SEND OK"==b&&(h=!1);"SEND FAIL"==b&&(e[a]=null)})},500);return b.length}},m={debug:function(a){k=a||void 0===a?function(a){print("[M35]",a)}:function(){};return{socks:e,sockData:f,busy:h}},getVersion:function(a){g("AT+GMR").then(function(b){a(null,b)})["catch"](function(b){a(b)})},getIP:function(a){var b;d.cmd("AT+QISTATE=0,1\r\n",1E3,function(c){"OK"==c?a(null,b):c.startsWith("+QISTATE")?b=c.split(",")[2]:a(null,c)})}};exports.connect=function(a,b,c){b=b||{};a.removeAllListeners();
m.at=d=require("AT").connect(a);require("NetworkJS").create(q);d.registerLine('+QIURC: "recv"',function(a){var b=a.split(",");k(b);d.getData(0|b[2],function(a){f[0|b[1]]+=a})});d.registerLine('+QIURC: "closed"',function(a){e[0|a.substr(17)]=null;h=!1});d.registerLine("+QIOPEN: ",function(a){a=a.substr(9).split(",");e[0|a[0]]=0==a[1]?!0:void 0;h=!1});d.registerLine("+CME ERROR",function(a){console.log(a)});g("ATE0").then(function(){return g(b.lte?"AT+CEREG?":"AT+CREG?")}).then(function(a){var b=a.split(",")[1];
if(1!=b&&5!=b)throw Error("GSM not registered, "+a);k("Forcing GPRS connect");return g("AT+CGATT=1",1E4)}).then(function(){return g("AT+CGREG?")}).then(function(a){var b=a.split(",")[1];if(2==b)throw Error("GPRS still connecting, "+a);if(1!=b&&5!=b)throw Error("GPRS not registered, "+a);return g("AT+COPS?")}).then(function(a){var c=a.split(",")[2];if(!c)throw Error("No Operator, "+a);k("Operator "+c);return g("AT+QICSGP=1,1,"+JSON.stringify(b.apn||"")+","+JSON.stringify(b.username||"")+","+JSON.stringify(b.password||
""),6E4)}).then(function(){return g("AT+QIACT=1",6E4)}).then(function(){c&&c(null)})["catch"](function(a){c&&c(a)});return m}
function l(){}function h(a,b){return new Promise(function(c,f){var m="";d.cmd(a+"\r\n",b||1E3,function p(b){if(void 0===b||"ERROR"==b)f(a+": "+b?b:"TIMEOUT");else if("OK"==b)c(m);else return m+=(m?"\n":"")+b,p})})}var d,g=[],e=" ".split(" "),k=!1,q={create:function(a,b){var c=0;if(void 0===a)return l("Server not implemented"),-1;for(;void 0!==g[c];)c++;if(6<=c)throw Error("No free sockets.");g[c]="Wait";e[c]="";k=!0;d.cmd("AT+QIOPEN=1,"+c+',"TCP",'+JSON.stringify(a)+","+b+",0,1\r\n",
1E4,function(a){"OK"!=a&&(g[c]=void 0,k=!1)});return c},close:function(a){void 0!==g[a]&&(e[a]="",d.cmd("AT+QICLOSE="+a+"\r\n",1E3,function(){g[a]=void 0}))},accept:function(a){return-1},recv:function(a,b){if(e[a]){if(e[a].length>b){var c=e[a].substr(0,b);e[a]=e[a].substr(b)}else c=e[a],e[a]="";return c}return g[a]?"":-1},send:function(a,b){if(k||d.isBusy()||"Wait"==g[a])return 0;if(!g[a])return-1;k=!0;d.cmd("AT+QISEND="+a+","+b.length+"\r\n",1E4,function m(f){l("AT+QISEND response "+JSON.stringify(f));
if("OK"==f)return d.register("> ",function(a){d.unregister("> ");d.write(b);return a.substr(2)}),m;"SEND OK"==f?k=!1:(d.unregister("> "),g[a]=null)});return b.length}},n={debug:function(a){l=a||void 0===a?function(a){print("[BG96]",a)}:function(){};return{socks:g,sockData:e,busy:k}},getVersion:function(a){h("AT+GMR").then(function(b){a(null,b)})["catch"](function(b){a(b)})},getIP:function(a){var b;d.cmd("AT+QISTATE=0,1\r\n",1E3,function(c){"OK"==c?a(null,b):c.startsWith("+QISTATE")?b=c.split(",")[2]:
a(null,c)})}};exports.connect=function(a,b,c){b=b||{};a.removeAllListeners();n.at=d=require("AT").connect(a);require("NetworkJS").create(q);d.register('+QIURC: "recv"',function(a){var b=a.indexOf("\r\n");if(0>b)return a;var f=a.split(",");a=a.substr(b+2);e[0|f[1]]+=a;l(f);d.getData((0|f[2])-a.length,function(a){e[0|f[1]]+=a});return""});d.registerLine('+QIURC: "closed"',function(a){g[0|a.substr(17)]=null;k=!1});d.registerLine("+QIOPEN: ",function(a){a=a.substr(9).split(",");g[0|a[0]]=0==a[1]?!0:void 0;
k=!1});d.registerLine("+CME ERROR",function(a){console.log(a)});h("ATE0").then(function(){return h(b.lte?"AT+CEREG?":"AT+CREG?")}).then(function(a){var b=a.split(",")[1];if(1!=b&&5!=b)throw Error("GSM not registered, "+a);l("Forcing GPRS connect");return h("AT+CGATT=1",1E4)}).then(function(){return h("AT+CGREG?")}).then(function(a){var b=a.split(",")[1];if(2==b)throw Error("GPRS still connecting, "+a);if(1!=b&&5!=b)throw Error("GPRS not registered, "+a);return h("AT+COPS?")}).then(function(a){var c=
a.split(",")[2];if(!c)throw Error("No Operator, "+a);l("Operator "+c);return h("AT+QICSGP=1,1,"+JSON.stringify(b.apn||"")+","+JSON.stringify(b.username||"")+","+JSON.stringify(b.password||""),6E4)}).then(function(){return h("AT+QIACT=1",6E4)}).then(function(){c&&c(null)})["catch"](function(a){c&&c(a)});return n}

View File

@ -1,7 +1,7 @@
function z(a){return{ip:a.charCodeAt(0)+"."+a.charCodeAt(1)+"."+a.charCodeAt(2)+"."+a.charCodeAt(3),port:a.charCodeAt(5)<<8|a.charCodeAt(4),len:a.charCodeAt(7)<<8|a.charCodeAt(6)}}function D(a){var b=a.indexOf(":");if(0>b)return a;var c=a.substring(5,b).split(",");c[1]|=0;var d=a.length-(b+1),e=c[0];if(v[e]){var l=(c[2]||"0.0.0.0").split(".").map(function(a){return 0|a}),A=0|c[3];g[e]+=String.fromCharCode(l[0],l[1],l[2],l[3],A&255,A>>8,d&255,d>>8)}if(d>=c[1])return g[e]+=a.substr(b+1,
c[1]),a.substr(b+c[1]+1);g[e]+=a.substr(b+1,d);f.getData(c[1]-d,function(a){g[e]+=a});return""}function w(a,b){if(b)return a(b);f.cmd("AT+CWMODE="+p+"\r\n",1E3,function(b){"no change"!=b&&"OK"!=b&&"WIFI DISCONNECT"!=b?a("CWMODE failed: "+(b?b:"Timeout")):a(null)})}function q(a){var b=a[0];void 0===e[b]&&e[5]?e[b]="Accept":"Wait"==e[b]?e[b]=!0:f.cmd("AT+CIPCLOSE="+b+"\r\n",1E3,function(a){e[b]=void 0})}function r(a){e[a[0]]=""!=g[a[0]]?"DataClose":void 0}function u(a,b){var c=0==p;p|=a;c?("1v91"==
process.version?(x.reset(),t.setup(115200,{rx:A3,tx:A2})):t.setup(115200,{rx:A3,tx:A2,cts:x}),f=require("AT").connect(t),f.register("+IPD",D),f.registerLine("0,CONNECT",q),f.registerLine("1,CONNECT",q),f.registerLine("2,CONNECT",q),f.registerLine("3,CONNECT",q),f.registerLine("4,CONNECT",q),f.registerLine("0,CLOSED",r),f.registerLine("1,CLOSED",r),f.registerLine("2,CLOSED",r),f.registerLine("3,CLOSED",r),f.registerLine("4,CLOSED",r),f.registerLine("WIFI CONNECTED",function(){n|=k.CLIENT;exports.emit("associated")}),
f.registerLine("WIFI GOT IP",function(){exports.emit("connected")}),f.registerLine("WIFI DISCONNECTED",function(){n&=~k.CLIENT;exports.emit("disconnected")}),exports.at=f,require("NetworkJS").create(B),f.cmd("\r\nAT+RST\r\n",1E4,function l(a){if("ready"==a||"Ready."==a)setTimeout(function(){f.cmd("ATE0\r\n",1E3,function F(a){if(a&&"ATE0"==a.trim())return F;"OK"==a?f.cmd("AT+CIPDINFO=1\r\n",1E3,function(a){if("OK"!=a)return b("CIPDINFO failed: "+(a?a:"Timeout"));f.cmd("AT+CIPMUX=1\r\n",1E3,function(a){if("OK"!=
f.registerLine("WIFI GOT IP",function(){exports.emit("connected")}),f.registerLine("WIFI DISCONNECTED",function(){n&=~k.CLIENT;exports.emit("disconnected")}),exports.at=f,require("NetworkJS").create(B),f.cmd("\r\nAT+RST\r\n",1E4,function l(a){if("ready"==a||"Ready."==a)setTimeout(function(){f.cmd("ATE0\r\n",1E3,function F(a){if("ATE0"==a)return F;"OK"==a?f.cmd("AT+CIPDINFO=1\r\n",1E3,function(a){if("OK"!=a)return b("CIPDINFO failed: "+(a?a:"Timeout"));f.cmd("AT+CIPMUX=1\r\n",1E3,function(a){if("OK"!=
a)return b("CIPMUX failed: "+(a?a:"Timeout"));f.cmd("AT+UART_CUR=115200,8,1,0,2\r\n",500,function(a){if("OK"!=a)return b("UART_CUR failed: "+(a?a:"Timeout"));w(b)})})}):b("ATE0 failed: "+(a?a:"Timeout"))})},500);else if(void 0===a)b("No 'ready' after AT+RST");else return l}),digitalWrite(G,1),digitalWrite(y,1)):w(b)}function C(a,b){b=b||function(){};(p&=~a)?w(b,null):(t.removeAllListeners(),f=void 0,exports.at=void 0,digitalWrite(y,0),e=[],setTimeout(b,1))}var G=A13,y=A14,x=A15,t=Serial2;digitalWrite(y,
0);var k={CLIENT:1,AP:2},H=["open","wep","wpa_psk","wpa2_psk","wpa_wpa2_psk"],p=0,n=0,f,e=[],v=[],g=["","","","",""],B={create:function(a,b,c){if(!f||!n)return-1;if(void 0===a&&2!=c)return d=5,e[d]="Wait",g[d]="",f.cmd("AT+CIPSERVER=1,"+b+"\r\n",1E4,function(a){"OK"==a?e[d]=!0:(e[d]=void 0,setTimeout(function(){throw Error("CIPSERVER failed ("+(a?a:"Timeout")+")");},0))}),5;for(var d=0;void 0!==e[d];)d++;if(5<=d)return-7;g[d]="";e[d]="Wait";var h;2==c?(b?h="AT+CIPSTART="+d+',"UDP","255.255.255.255",'+
b+","+b+",2\r\n":e[d]="UDP",v[d]=!0):(h="AT+CIPSTART="+d+',"TCP",'+JSON.stringify(a)+","+b+"\r\n",delete v[d]);h&&f.cmd(h,1E4,function m(a){if("ALREADY CONNECTED"==a)return m;if("OK"!=a||!0!==e[d])e[d]=-6});return d},close:function(a){"Wait"==e[a]?e[a]="WaitClose":void 0!==e[a]&&(0>e[a]||"UDP"==e[a]?e[a]=void 0:f.cmd((5==a?"AT+CIPSERVER=0":"AT+CIPCLOSE="+a)+"\r\n",1E3,function(b){e[a]=void 0}))},accept:function(a){for(a=0;5>a;a++)if("Accept"==e[a])return e[a]=!0,a;return-1},recv:function(a,b,c){return g[a]?

View File

@ -125,7 +125,8 @@ int net_esp32_createsocket(JsNetwork *net, SocketType socketType, uint32_t host,
return 0;
}
if (jsvGetBoolAndUnLock(jsvObjectGetChild(options, "reuseAddr", 0))) {
if (scktType != SOCK_DGRAM ||
jsvGetBoolAndUnLock(jsvObjectGetChild(options, "reuseAddr", 0))) {
int optval = 1;
if (setsockopt(sckt,SOL_SOCKET,SO_REUSEADDR,(const char *)&optval,sizeof(optval)) < 0)
jsWarn("setsockopt(SO_REUSADDR) failed\n");

View File

@ -126,7 +126,8 @@ int net_linux_createsocket(JsNetwork *net, SocketType socketType, uint32_t host,
return 0;
}
if (jsvGetBoolAndUnLock(jsvObjectGetChild(options, "reuseAddr", 0))) {
if (scktType != SOCK_DGRAM ||
jsvGetBoolAndUnLock(jsvObjectGetChild(options, "reuseAddr", 0))) {
int optval = 1;
if (setsockopt(sckt,SOL_SOCKET,SO_REUSEADDR,(const char *)&optval,sizeof(optval)) < 0)
jsWarn("setsockopt(SO_REUSADDR) failed\n");
@ -197,13 +198,6 @@ int net_linux_createsocket(JsNetwork *net, SocketType socketType, uint32_t host,
if (setsockopt(sckt,SOL_SOCKET,SO_NOSIGPIPE,(const char *)&optval,sizeof(optval))<0)
jsWarn("setsockopt(SO_NOSIGPIPE) failed\n");
#endif
#ifdef SO_LINGER
struct linger lngr;
lngr.l_onoff = 1;
lngr.l_linger = 0;
if (setsockopt(sckt, SOL_SOCKET, SO_LINGER, (const char *)&lngr, sizeof(lngr))<0)
jsWarn("setsockopt(SO_LINGER) failed\n");
#endif
return sckt;
}

View File

@ -375,6 +375,12 @@ static bool pixl_selfTest() {
jshPinOutput(LED1_PININDEX, LED1_ONSTATE);
jshPinSetState(BTN1_PININDEX, BTN1_PINSTATE);
v = jshReadVRef();
if (v<3.2 || v>3.4) {
jsiConsolePrintf("VCC out of range 3.2-3.4 (%f)\n", v);
ok = false;
}
if (jshPinGetValue(BTN1_PININDEX)==BTN1_ONSTATE)
jsiConsolePrintf("Release BTN1\n");
if (jshPinGetValue(BTN4_PININDEX)==BTN4_ONSTATE)
@ -422,7 +428,6 @@ static bool pixl_selfTest() {
if (jshHasEvents()) {
jsiConsolePrintf("Have events - no BLE test\n");
} else {
bool bleWorking = false;
uint32_t err_code;
err_code = jsble_set_scanning(true);
jsble_check_error(err_code);

View File

@ -257,6 +257,7 @@ endif
include make/common/ARM.make
$(PROJ_NAME).app_hex: $(PROJ_NAME).elf
python scripts/check_elf_size.py $(BOARD) $(PROJ_NAME).elf
@echo $(call $(quiet_)obj_to_bin,ihex,hex)
@$(call obj_to_bin,ihex,hex)
@mv $(PROJ_NAME).hex $(PROJ_NAME).app_hex

View File

@ -255,7 +255,7 @@ jsondatas = sorted(jsondatas, key=lambda s: common.get_name_or_space(s).lower())
html(' <div id="contents">')
html(" <h2><a name=\"contents\"></a>Contents</h2>")
html(" <ul>")
html(" <li><a class=\"blush\" name=\"t__global\" href=\"#_global\" onclick=\"place('_global');\">Globals</A></li>")
html(" <li><a class=\"blush\" name=\"t__global\" href=\"#_global\" onclick=\"place('_global');\">Globals</a></li>")
for jsondata in jsondatas:
if "name" in jsondata and not "class" in jsondata:
add_link(jsondata)
@ -289,6 +289,7 @@ for jsondata in detail:
niceName="Globals"
linkName="_global"
# If we're on to a different class now, put up the heading for it
if className!=lastClass:
lastClass=className
html("<h2 class=\"class\"><a class=\"blush\" name=\""+linkName+"\" href=\"#t_"+linkName+"\" onclick=\"place('t_"+linkName+"');\">"+niceName+"</a></h2>")
@ -313,10 +314,12 @@ for jsondata in detail:
html(" <h4>Methods and Fields</h4>")
html(" <ul>")
for j in jsondatas:
if ("name" in j) and (className!="" or not "instanceof" in j) and ((className=="" and not "class" in j) or ("class" in j and j["class"]==className)):
if ("name" in j) and ((className=="" and not "class" in j) or ("class" in j and j["class"]==className)):
link = get_link(j)
html(" <li><a name=\"t_"+link+"\" href=\"#"+link+"\">"+get_surround(j)+"</a></li>")
html(" </ul>")
# Otherwise just output detail
link = get_link(jsondata)
html(" <h3 class=\"detail\"><a class=\"blush\" name=\""+link+"\" href=\"#t_"+link+"\" onclick=\"place('t_"+link+"','"+linkName+"');\">"+get_fullname(jsondata)+"</a>")
#html("<!-- "+json.dumps(jsondata, sort_keys=True, indent=2)+"-->");

View File

@ -140,6 +140,8 @@ def codeOutDevice(device):
codeOut("#define "+device+"_PINSTATE JSHPINSTATE_GPIO_"+board.devices[device]["pinstate"]);
if device[0:3]=="LED":
codeOut("#define "+device+"_ONSTATE "+("0" if "inverted" in board.devices[device] else "1"))
if "no_bootloader" in board.devices[device]:
codeOut("#define "+device+"_NO_BOOTLOADER 1 // don't use this in the bootloader");
def codeOutDevicePin(device, pin, definition_name):
if device in board.devices:

48
scripts/check_elf_size.py Normal file
View File

@ -0,0 +1,48 @@
#!/usr/bin/python
# Checks to see if an Elf file will fit in memory before the
# area reserved for Storage (saved code). This is mainly used
# for nRF5x parts (which don't generate binaries and which
# put Storage *after* code)
import subprocess;
import re;
import json;
import sys;
import os;
import importlib;
scriptdir = os.path.dirname(os.path.realpath(__file__))
basedir = scriptdir+"/../"
sys.path.append(basedir+"scripts");
sys.path.append(basedir+"boards");
if len(sys.argv)!=3:
print("USAGE:")
print("scripts/check_elf_size.py BOARDNAME board.elf")
exit(1)
BOARD=sys.argv[1]
ELF=sys.argv[2]
print("Testing "+ELF+" for "+BOARD)
# import the board def
board = importlib.import_module(BOARD)
# Call the included board_specific file - it sets up 'pins' and 'fill_gaps'
storageStart = board.chip['saved_code']['address']
storageEnd = storageStart + board.chip['saved_code']['page_size'] * board.chip['saved_code']['pages']
print("STORAGE: "+str(storageStart)+" -> "+str(storageEnd));
text = subprocess.check_output('arm-none-eabi-objdump -h '+ELF+' | grep "\\.text"', shell=True).strip().split()
codeSize = int(text[2], 16)
codeStart = int(text[3], 16)
codeEnd = codeSize + codeStart
print("CODE: "+str(codeStart)+" -> "+str(codeEnd));
if codeEnd<storageStart and codeStart<storageStart:
print("Code area Fits before Storage Area")
elif codeEnd>storageEnd and codeStart>storageEnd:
print("Code area Fits after Storage Area")
else:
print("CODE AND STORAGE OVERLAP")
exit(1)

View File

@ -376,6 +376,7 @@ def get_ifdef_description(d):
if d=="PUCKJS": return "Puck.js devices"
if d=="PIXLJS": return "Pixl.js boards"
if d=="ESPRUINOWIFI": return "Espruino WiFi boards"
if d=="ESPRUINOBOARD": return "'Original' Espruino boards"
if d=="ESP8266": return "ESP8266 boards running Espruino"
if d=="ESP32": return "ESP32 boards"
if d=="EFM32": return "EFM32 devices"

View File

@ -61,21 +61,21 @@ if [ "$FAMILY" = "ESP32" ]; then
return 0
elif [ "$FAMILY" = "ESP8266" ]; then
echo ESP8266
if [ ! -d "esp_iot_sdk_v2.0.0.p1" ]; then
echo esp_iot_sdk_v2.0.0.p1
curl -Ls http://s3.voneicken.com/esp_iot_sdk_v2.0.0.p1.tgx | tar Jxf - --no-same-owner
if [ ! -d "ESP8266_NONOS_SDK-2.2.1" ]; then
echo ESP8266_NONOS_SDK-2.2.1
curl -Ls https://github.com/espruino/EspruinoBuildTools/raw/master/esp8266/ESP8266_NONOS_SDK-2.2.1.tar.gz | tar xfz - --no-same-owner
fi
if ! type xtensa-lx106-elf-gcc 2> /dev/null > /dev/null; then
echo installing xtensa-lx106-elf-gcc
if [ ! -d "xtensa-lx106-elf" ]; then
curl -Ls http://s3.voneicken.com/xtensa-lx106-elf-20160330.tgx | tar Jxf - --no-same-owner
curl -Ls https://github.com/espruino/EspruinoBuildTools/raw/master/esp8266/xtensa-lx106-elf-20160330.tgx | tar Jxf - --no-same-owner
else
echo "Folder found"
fi
fi
which xtensa-lx106-elf-gcc
export ESP8266_SDK_ROOT=`pwd`/esp_iot_sdk_v2.0.0.p1
export ESP8266_SDK_ROOT=`pwd`/ESP8266_NONOS_SDK-2.2.1
export PATH=$PATH:`pwd`/xtensa-lx106-elf/bin/
return 0
elif [ "$FAMILY" = "LINUX" ]; then

View File

@ -731,6 +731,15 @@ JsVar *jsfGetBootCodeFromFlash(bool isReset) {
}
bool jsfLoadBootCodeFromFlash(bool isReset) {
// Load code in .boot0/1/2/3
char filename[6] = ".bootX";
for (int i=0;i<4;i++) {
filename[5] = (char)('0'+i);
JsVar *code = jsfReadFile(jsfNameFromString(filename));
if (code)
jsvUnLock2(jspEvaluateVar(code,0,0), code);
}
// Load normal boot code
JsVar *code = jsfGetBootCodeFromFlash(isReset);
if (!code) return false;
jsvUnLock2(jspEvaluateVar(code,0,0), code);

View File

@ -861,6 +861,8 @@ void jsiInit(bool autoLoad) {
#endif
jsiSemiInit(autoLoad);
// just in case, update the busy indicator
jsiSetBusy(BUSY_INTERACTIVE, false);
}
#ifndef LINUX

View File

@ -1504,9 +1504,13 @@ NO_INLINE JsVar *jspeClassDefinition(bool parseNamedClass) {
JSP_MATCH_WITH_CLEANUP_AND_RETURN(LEX_ID,jsvUnLock4(extendsFrom,classFunction,classInternalName,classPrototype),0);
if (classPrototype) {
if (jsvIsFunction(extendsFrom)) {
jsvObjectSetChild(classPrototype, JSPARSE_INHERITS_VAR, extendsFrom);
// link in default constructor if ours isn't supplied
jsvObjectSetChildAndUnLock(classFunction, JSPARSE_FUNCTION_CODE_NAME, jsvNewFromString("if(this.__proto__.__proto__)this.__proto__.__proto__.apply(this,arguments)"));
JsVar *extendsFromProto = jsvObjectGetChild(extendsFrom, JSPARSE_PROTOTYPE_VAR, 0);
if (extendsFromProto) {
jsvObjectSetChild(classPrototype, JSPARSE_INHERITS_VAR, extendsFromProto);
// link in default constructor if ours isn't supplied
jsvObjectSetChildAndUnLock(classFunction, JSPARSE_FUNCTION_CODE_NAME, jsvNewFromString("if(this.__proto__.__proto__.constructor)this.__proto__.__proto__.constructor.apply(this,arguments)"));
jsvUnLock(extendsFromProto);
}
} else
jsExceptionHere(JSET_SYNTAXERROR, "'extends' argument should be a function, got %t", extendsFrom);
}
@ -1682,11 +1686,14 @@ NO_INLINE JsVar *jspeFactor() {
jsExceptionHere(JSET_SYNTAXERROR, "Calling 'super' outside of class");
return 0;
}
if (lex->tk=='(') return proto2; // eg. used in a constructor
// But if we're doing something else - eg '.' or '[' then it needs to reference the prototype
JsVar *proto3 = jsvIsFunction(proto2) ? jsvObjectGetChild(proto2, JSPARSE_PROTOTYPE_VAR, 0) : 0;
jsvUnLock(proto2);
return proto3;
// If we're doing super() we want the constructor
if (lex->tk=='(') {
JsVar *constr = jsvObjectGetChild(proto2, JSPARSE_CONSTRUCTOR_VAR, 0);
jsvUnLock(proto2);
return constr;
}
// But if we're doing something else - eg 'super.' or 'super[' then it needs to reference the prototype
return proto2;
} else if (jsvIsFunction(execInfo.thisVar)) {
// 'this' is a function - must be calling a static method
JsVar *proto1 = jsvObjectGetChild(execInfo.thisVar, JSPARSE_PROTOTYPE_VAR, 0);
@ -1696,7 +1703,9 @@ NO_INLINE JsVar *jspeFactor() {
jsExceptionHere(JSET_SYNTAXERROR, "Calling 'super' outside of class");
return 0;
}
return proto2;
JsVar *constr = jsvObjectGetChild(proto2, JSPARSE_CONSTRUCTOR_VAR, 0);
jsvUnLock(proto2);
return constr;
}
jsExceptionHere(JSET_SYNTAXERROR, "Calling 'super' outside of class");
return 0;

View File

@ -104,6 +104,9 @@ bool jsserialPopulateUSARTInfo(
{"cts", JSV_PIN, &inf->pinCTS},
{"bytesize", JSV_INTEGER, &inf->bytesize},
{"stopbits", JSV_INTEGER, &inf->stopbits},
#ifdef LINUX
{"path", JSV_STRING_0, 0}, // not used - just here to avoid errors
#endif
{"parity", JSV_OBJECT /* a variable */, &parity},
{"flow", JSV_OBJECT /* a variable */, &flow},
{"errors", JSV_BOOLEAN, &inf->errorHandling},
@ -147,7 +150,6 @@ bool jsserialPopulateUSARTInfo(
}
jsvUnLock(parity);
jsvUnLock(flow);
return ok;
}

View File

@ -26,9 +26,9 @@
#include <math.h>
#ifndef BUILDNUMBER
#define JS_VERSION "1v99"
#define JS_VERSION "2v00"
#else
#define JS_VERSION "1v99." BUILDNUMBER
#define JS_VERSION "2v00." BUILDNUMBER
#endif
/*
In code:

View File

@ -33,15 +33,24 @@ This class helps
"name" : "DataView",
"generate" : "jswrap_dataview_constructor",
"params" : [
["buffer","JsVar","The ArrayBuffer to base this on"],
["buffer","JsVar","The `ArrayBuffer` to base this on"],
["byteOffset","int","(optional) The offset of this view in bytes"],
["byteLength","int","(optional) The length in bytes"]
],
"return" : ["JsVar","A DataView object"],
"return" : ["JsVar","A `DataView` object"],
"return_object" : "DataView",
"ifndef" : "SAVE_ON_FLASH"
}
Create a DataView object
Create a `DataView` object that can be used to access the data in an `ArrayBuffer`.
```
var b = new ArrayBuffer(8)
var v = new DataView(b)
v.setUint16(0,"0x1234")
v.setUint8(3,"0x56")
console.log("0x"+v.getUint32(0).toString(16))
// prints 0x12340056
```
*/
JsVar *jswrap_dataview_constructor(JsVar *buffer, int byteOffset, int byteLength) {
if (!jsvIsArrayBuffer(buffer) ||

View File

@ -152,6 +152,14 @@ static int getDay(const char *s) {
return -1;
}
static TimeInDay getTimeFromDateVar(JsVar *date, bool forceGMT) {
return getTimeFromMilliSeconds(jswrap_date_getTime(date), forceGMT);
}
static CalendarDate getCalendarDateFromDateVar(JsVar *date, bool forceGMT) {
return getCalendarDate(getTimeFromDateVar(date, forceGMT).daysSinceEpoch);
}
/*JSON{
"type" : "class",
"class" : "Date"
@ -233,16 +241,20 @@ JsVar *jswrap_date_constructor(JsVar *args) {
/*JSON{
"type" : "method",
"ifndef" : "SAVE_ON_FLASH",
"class" : "Date",
"name" : "getTimezoneOffset",
"generate" : "jswrap_date_getTimezoneOffset",
"return" : ["float","The difference, in minutes, between UTC and local time"]
"return" : ["int32","The difference, in minutes, between UTC and local time"]
}
The getTimezoneOffset() method returns the time-zone offset from UTC, in minutes, for the current locale.
This returns Espruino's time-zone offset from UTC, in minutes.
This is set with `E.setTimeZone` and is System-wide. The value returned
has nothing to do with the instance of `Date` that it is called on.
*/
JsVarFloat jswrap_date_getTimezoneOffset(JsVar *parent) {
NOT_USED(parent);
return 0;
int jswrap_date_getTimezoneOffset(JsVar *parent) {
return -getTimeFromDateVar(parent, false/*system timezone*/).zone;
}
@ -286,15 +298,6 @@ JsVarFloat jswrap_date_setTime(JsVar *date, JsVarFloat timeValue) {
}
static TimeInDay getTimeFromDateVar(JsVar *date, bool forceGMT) {
return getTimeFromMilliSeconds(jswrap_date_getTime(date), forceGMT);
}
static CalendarDate getCalendarDateFromDateVar(JsVar *date, bool forceGMT) {
return getCalendarDate(getTimeFromDateVar(date, forceGMT).daysSinceEpoch);
}
/*JSON{
"type" : "method",
"class" : "Date",

View File

@ -36,7 +36,7 @@ JsVarFloat jswrap_date_now();
JsVar *jswrap_date_from_milliseconds(JsVarFloat time);
JsVar *jswrap_date_constructor(JsVar *args);
JsVarFloat jswrap_date_getTimezoneOffset(JsVar *parent);
int jswrap_date_getTimezoneOffset(JsVar *parent);
JsVarFloat jswrap_date_getTime(JsVar *parent);
JsVarFloat jswrap_date_setTime(JsVar *date, JsVarFloat timeValue);
int jswrap_date_getHours(JsVar *parent);

View File

@ -1146,7 +1146,7 @@ JsVar *jswrap_espruino_getSizeOf(JsVar *v, int depth) {
"generate" : "jswrap_espruino_getAddressOf",
"params" : [
["v","JsVar","A variable to get the address of"],
["flatAddress","bool","If a flat String or flat ArrayBuffer is supplied, return the address of the data inside it - otherwise 0"]
["flatAddress","bool","(boolean) If `true` and a Flat String or Flat ArrayBuffer is supplied, return the address of the data inside it - otherwise 0. If `false` (the default) return the address of the JsVar itself."]
],
"return" : ["int","The address of the given variable"]
}

View File

@ -171,7 +171,7 @@ Returns an array of all properties (enumerable or not) found directly on a given
*/
void _jswrap_object_keys_or_property_names_iterator(
static void _jswrap_object_keys_or_property_names_iterator(
const JswSymList *symbols,
void (*callback)(void *data, JsVar *name),
void *data) {
@ -204,6 +204,7 @@ void jswrap_object_keys_or_property_names_cb(
void (*callback)(void *data, JsVar *name),
void *data
) {
// add the keys that are on this object itself
// strings are iterable, but we shouldn't try and show keys for them
if (jsvIsIterable(obj)) {
JsvIsInternalChecker checkerFunction = jsvGetInternalFunctionCheckerFor(obj);
@ -232,6 +233,8 @@ void jswrap_object_keys_or_property_names_cb(
Assume that ALL builtins are non-enumerable. This isn't great but
seems to work quite well right now! */
if (includeNonEnumerable) {
const JswSymList *objSymbols = jswGetSymbolListForObjectProto(0);
JsVar *protoOwner = jspGetPrototypeOwner(obj);
if (protoOwner) {
// If protoOwner then this is the prototype (protoOwner is the object)
@ -245,23 +248,22 @@ void jswrap_object_keys_or_property_names_cb(
}
if (includePrototype) {
JsVar *proto = 0;
if (jsvIsObject(obj) || jsvIsFunction(obj)) {
JsVar *proto = jsvObjectGetChild(obj, JSPARSE_INHERITS_VAR, 0);
while (jsvIsObject(proto)) {
const JswSymList *symbols = jswGetSymbolListForObjectProto(proto);
_jswrap_object_keys_or_property_names_iterator(symbols, callback, data);
JsVar *p2 = jsvObjectGetChild(proto, JSPARSE_INHERITS_VAR, 0);
jsvUnLock(proto);
proto = p2;
}
proto = jsvObjectGetChild(obj, JSPARSE_INHERITS_VAR, 0);
}
// include Object/String/etc
const JswSymList *symbols = jswGetSymbolListForObjectProto(obj);
_jswrap_object_keys_or_property_names_iterator(symbols, callback, data);
// if the last call wasn't an Object, add the object proto as well
const JswSymList *objSymbols = jswGetSymbolListForObjectProto(0);
if (objSymbols!=symbols)
_jswrap_object_keys_or_property_names_iterator(objSymbols, callback, data);
if (jsvIsObject(proto)) {
jswrap_object_keys_or_property_names_cb(proto, includeNonEnumerable, includePrototype, callback, data);
} else {
// include Object/String/etc
const JswSymList *symbols = jswGetSymbolListForObjectProto(obj);
_jswrap_object_keys_or_property_names_iterator(symbols, callback, data);
// if the last call wasn't an Object, add the object proto as well
if (objSymbols!=symbols)
_jswrap_object_keys_or_property_names_iterator(objSymbols, callback, data);
}
jsvUnLock(proto);
}
if (jsvIsArray(obj) || jsvIsString(obj)) {

View File

@ -248,6 +248,9 @@ storage in the queue. If you're intending to receive a lot of malformed
data then the queue might overflow `E.getErrorFlags()` would return `FIFO_FULL`.
However if you need to respond to `framing` or `parity` errors then
you'll need to use `errors:true` when initialising serial.
On Linux builds there is no default Serial device, so you must specify
a path to a device - for instance: `Serial1.setup(9600,{path:"/dev/ttyACM0"})`
*/
void jswrap_serial_setup(JsVar *parent, JsVar *baud, JsVar *options) {
IOEventFlags device = jsiGetDeviceFromClass(parent);
@ -259,7 +262,6 @@ void jswrap_serial_setup(JsVar *parent, JsVar *baud, JsVar *options) {
jsvLockAgain(options);
bool ok = jsserialPopulateUSARTInfo(&inf, baud, options);
#ifdef LINUX
if (ok && jsvIsObject(options))
jsvObjectSetChildAndUnLock(parent, "path", jsvObjectGetChild(options, "path", 0));

View File

@ -678,3 +678,29 @@ bool jswrap_string_endsWith(JsVar *parent, JsVar *search, JsVar *length) {
"return" : ["bool","`true` if the given characters are in the string, otherwise, `false`."]
}
*/
/*JSON{
"type" : "method",
"class" : "String",
"name" : "repeat",
"ifndef" : "SAVE_ON_FLASH",
"generate" : "jswrap_string_repeat",
"params" : [
["count","int","An integer with the amount of times to repeat this String"]
],
"return" : ["JsVar","A string containing repetitions of this string"],
"return_object" : "String"
}
Repeat this string the given number of times.
*/
JsVar *jswrap_string_repeat(JsVar *parent, int count) {
if (count<0) {
jsExceptionHere(JSET_ERROR, "Invalid count value");
return 0;
}
JsVar *result = jsvNewFromEmptyString();
while (count-- && !jspIsInterrupted())
jsvAppendStringVarComplete(result, parent);
return result;
}

View File

@ -28,3 +28,4 @@ JsVar *jswrap_string_toUpperLowerCase(JsVar *parent, bool upper);
JsVar *jswrap_string_trim(JsVar *parent);
bool jswrap_string_startsWith(JsVar *parent, JsVar *search, int position);
bool jswrap_string_endsWith(JsVar *parent, JsVar *search, JsVar *length);
JsVar *jswrap_string_repeat(JsVar *parent, int count);

View File

@ -151,6 +151,31 @@ SECTIONS
} >dram0_0_seg :dram0_0_bss_phdr
/* __stack = 0x3ffc8000; */
.irom0.text : ALIGN(4)
{
_irom0_text_start = ABSOLUTE(.);
*libat.a:(.literal.* .text.*)
*libcrypto.a:(.literal.* .text.*)
*libespnow.a:(.literal.* .text.*)
*libjson.a:(.literal.* .text.*)
*liblwip.a:(.literal.* .text.*)
*libnet80211.a:(.literal.* .text.*)
*libsmartconfig.a:(.literal.* .text.*)
*libssl.a:(.literal.* .text.*)
*libupgrade.a:(.literal.* .text.*)
*libwpa.a:(.literal.* .text.*)
*libwpa2.a:(.literal.* .text.*)
*libwps.a:(.literal.* .text.*)
*libmbedtls.a:(.literal.* .text.*)
*libm.a:(.literal .text .literal.* .text.*)
*(.irom0.literal .irom.literal .irom.literal2 .irom.text.literal .irom0.text .irom.text)
_irom0_text_end = ABSOLUTE(.);
} >irom0_0_seg :irom0_0_phdr
.text : ALIGN(4)
{
_stext = .;
@ -199,12 +224,7 @@ SECTIONS
_lit4_end = ABSOLUTE(.);
} >iram1_0_seg :iram1_0_phdr
.irom0.text : ALIGN(4)
{
_irom0_text_start = ABSOLUTE(.);
*(.irom0.literal .irom.literal .irom.literal2 .irom.text.literal .irom0.text .irom.text)
_irom0_text_end = ABSOLUTE(.);
} >irom0_0_seg :irom0_0_phdr
}
/* get ROM code address */

View File

@ -5,7 +5,7 @@ MEMORY
dport0_0_seg : org = 0x3FF00000, len = 0x10
dram0_0_seg : org = 0x3FFE8000, len = 0x14000
iram1_0_seg : org = 0x40100000, len = 0x8000
irom0_0_seg : org = 0x40281010, len = 0x7C000
irom0_0_seg : org = 0x40201010, len = 0x7C000
}
PHDRS
@ -119,7 +119,7 @@ SECTIONS
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
. = ALIGN(4); /* this table MUST be 4-byte aligned */
. = ALIGN(4); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_bss_start)
LONG(_bss_end)
@ -151,6 +151,31 @@ SECTIONS
} >dram0_0_seg :dram0_0_bss_phdr
/* __stack = 0x3ffc8000; */
.irom0.text : ALIGN(4)
{
_irom0_text_start = ABSOLUTE(.);
*libat.a:(.literal.* .text.*)
*libcrypto.a:(.literal.* .text.*)
*libespnow.a:(.literal.* .text.*)
*libjson.a:(.literal.* .text.*)
*liblwip.a:(.literal.* .text.*)
*libnet80211.a:(.literal.* .text.*)
*libsmartconfig.a:(.literal.* .text.*)
*libssl.a:(.literal.* .text.*)
*libupgrade.a:(.literal.* .text.*)
*libwpa.a:(.literal.* .text.*)
*libwpa2.a:(.literal.* .text.*)
*libwps.a:(.literal.* .text.*)
*libmbedtls.a:(.literal.* .text.*)
*libm.a:(.literal .text .literal.* .text.*)
*(.irom0.literal .irom.literal .irom.literal2 .irom.text.literal .irom0.text .irom.text)
_irom0_text_end = ABSOLUTE(.);
} >irom0_0_seg :irom0_0_phdr
.text : ALIGN(4)
{
_stext = .;
@ -199,12 +224,8 @@ SECTIONS
_lit4_end = ABSOLUTE(.);
} >iram1_0_seg :iram1_0_phdr
.irom0.text : ALIGN(4)
{
_irom0_text_start = ABSOLUTE(.);
*(.irom0.literal .irom.literal .irom.literal2 .irom.text.literal .irom0.text .irom.text)
_irom0_text_end = ABSOLUTE(.);
} >irom0_0_seg :irom0_0_phdr
}
/* get ROM code address */

View File

@ -119,7 +119,7 @@ SECTIONS
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
. = ALIGN(4); /* this table MUST be 4-byte aligned */
. = ALIGN(4); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_bss_start)
LONG(_bss_end)
@ -151,6 +151,31 @@ SECTIONS
} >dram0_0_seg :dram0_0_bss_phdr
/* __stack = 0x3ffc8000; */
.irom0.text : ALIGN(4)
{
_irom0_text_start = ABSOLUTE(.);
*libat.a:(.literal.* .text.*)
*libcrypto.a:(.literal.* .text.*)
*libespnow.a:(.literal.* .text.*)
*libjson.a:(.literal.* .text.*)
*liblwip.a:(.literal.* .text.*)
*libnet80211.a:(.literal.* .text.*)
*libsmartconfig.a:(.literal.* .text.*)
*libssl.a:(.literal.* .text.*)
*libupgrade.a:(.literal.* .text.*)
*libwpa.a:(.literal.* .text.*)
*libwpa2.a:(.literal.* .text.*)
*libwps.a:(.literal.* .text.*)
*libmbedtls.a:(.literal.* .text.*)
*libm.a:(.literal .text .literal.* .text.*)
*(.irom0.literal .irom.literal .irom.literal2 .irom.text.literal .irom0.text .irom.text)
_irom0_text_end = ABSOLUTE(.);
} >irom0_0_seg :irom0_0_phdr
.text : ALIGN(4)
{
_stext = .;
@ -199,14 +224,8 @@ SECTIONS
_lit4_end = ABSOLUTE(.);
} >iram1_0_seg :iram1_0_phdr
.irom0.text : ALIGN(4)
{
_irom0_text_start = ABSOLUTE(.);
*(.irom0.literal .irom.literal .irom.literal2 .irom.text.literal .irom0.text .irom.text)
_irom0_text_end = ABSOLUTE(.);
} >irom0_0_seg :irom0_0_phdr
}
/* get ROM code address */
INCLUDE "../ld/eagle.rom.addr.v6.ld"

View File

@ -32,8 +32,6 @@ char *wifi_station_get_hostname(void);
int atoi(const char *nptr);
void ets_install_putc1(void *routine); // necessary for #define os_xxx -> ets_xxx
void ets_isr_attach(int intr, void *handler, void *arg);
void ets_isr_mask(unsigned intr);
void ets_isr_unmask(unsigned intr);
void ets_intr_lock(void);
@ -48,12 +46,9 @@ int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (pri
int ets_str2macaddr(void *, void *);
int ets_strcmp(const char *s1, const char *s2);
char *ets_strcpy(char *dest, const char *src);
size_t ets_strlen(const char *s);
int ets_strncmp(const char *s1, const char *s2, int len);
char *ets_strncpy(char *dest, const char *src, size_t n);
char *ets_strstr(const char *haystack, const char *needle);
void ets_timer_arm_new(ETSTimer *a, int b, int c, int isMstimer);
void ets_timer_disarm(ETSTimer *a);
void ets_timer_setfn(ETSTimer *t, ETSTimerFunc *fn, void *parg);
@ -62,36 +57,12 @@ void ets_update_cpu_frequency(int freqmhz);
int os_snprintf(char *str, size_t size, const char *format, ...) __attribute__((format(printf, 3, 4)));
int os_printf_plus(const char *format, ...) __attribute__((format(printf, 1, 2)));
// memory allocation functions are "different" due to memory debugging functionality
// added in SDK 1.4.0
#ifndef ESPSDK_1_3_0
void vPortFree(void *ptr, char * file, int line);
void *pvPortMalloc(size_t xWantedSize, char * file, int line);
void *pvPortZalloc(size_t, char * file, int line);
void *vPortMalloc(size_t xWantedSize);
void pvPortFree(void *ptr);
void *pvPortRealloc(void *pv, size_t size, char * file, int line);
#else
void vPortFree(void *ptr);
void *pvPortMalloc(size_t xWantedSize);
void *pvPortZalloc(size_t);
void *vPortMalloc(size_t xWantedSize);
void pvPortFree(void *ptr);
void *pvPortRealloc(void *pv, size_t size);
#define os_realloc pvPortRealloc
void *pvPortRealloc(void* ptr, size_t size);
#endif
void uart_div_modify(int no, unsigned int freq);
uint32 system_get_time();
int rand(void);
void ets_bzero(void *s, size_t n);
void ets_delay_us(int ms);
// disappeared in SDK 1.1.0:
#define os_timer_done ets_timer_done
#define os_timer_handler_isr ets_timer_handler_isr
#define os_timer_init ets_timer_init
// This is not missing in SDK 1.1.0 but causes a parens error
#undef PIN_FUNC_SELECT
@ -101,12 +72,4 @@ void ets_delay_us(int ms);
|( (((FUNC&BIT2)<<2)|(FUNC&0x3))<<PERIPHS_IO_MUX_FUNC_S) ); \
} while (0)
// Shortcuts for memory functions
//#define os_malloc pvPortMalloc // defined in SDK 1.4.0 onwards
//#define os_free vPortFree // defined in SDK 1.4.0 onwards
//#define os_zalloc pvPortZalloc // defined in SDK 1.4.0 onwards
//uint8 wifi_get_opmode(void); // defined in SDK 1.0.0 onwards
//int os_random(); // defined in SDK 1.1.0 onwards
#endif

View File

@ -261,6 +261,10 @@ static void initDone() {
jswrap_wifi_restore();
#ifdef RELEASE
jswrap_ESP8266_logDebug(false);
#endif
// Register the idle callback handler to run the main loop
//ets_set_idle_cb(idle_cb, NULL); //
queueTaskMainLoop(); // get things going without idle callback

View File

@ -104,24 +104,29 @@ JsVarInt sysfs_read_int(const char *path) {
return stringToIntWithRadix(buf, 10, NULL, NULL);
}
#endif
// ----------------------------------------------------------------------------
#ifdef USE_WIRINGPI
#if EXTI_COUNT < 16
#error EXTI_COUNT needs to be 16 or above for WiringPi
#endif
void irqEXTI0() { jshPushIOWatchEvent(EV_EXTI0); }
void irqEXTI1() { jshPushIOWatchEvent(EV_EXTI1); }
void irqEXTI2() { jshPushIOWatchEvent(EV_EXTI2); }
void irqEXTI3() { jshPushIOWatchEvent(EV_EXTI3); }
void irqEXTI4() { jshPushIOWatchEvent(EV_EXTI4); }
void irqEXTI5() { jshPushIOWatchEvent(EV_EXTI5); }
void irqEXTI6() { jshPushIOWatchEvent(EV_EXTI6); }
void irqEXTI7() { jshPushIOWatchEvent(EV_EXTI7); }
void irqEXTI8() { jshPushIOWatchEvent(EV_EXTI8); }
void irqEXTI9() { jshPushIOWatchEvent(EV_EXTI9); }
void irqEXTI10() { jshPushIOWatchEvent(EV_EXTI10); }
void irqEXTI11() { jshPushIOWatchEvent(EV_EXTI11); }
void irqEXTI12() { jshPushIOWatchEvent(EV_EXTI12); }
void irqEXTI13() { jshPushIOWatchEvent(EV_EXTI13); }
void irqEXTI14() { jshPushIOWatchEvent(EV_EXTI14); }
void irqEXTI15() { jshPushIOWatchEvent(EV_EXTI15); }
void irqEXTI1() { jshPushIOWatchEvent(EV_EXTI0+1); }
void irqEXTI2() { jshPushIOWatchEvent(EV_EXTI0+2); }
void irqEXTI3() { jshPushIOWatchEvent(EV_EXTI0+3); }
void irqEXTI4() { jshPushIOWatchEvent(EV_EXTI0+4); }
void irqEXTI5() { jshPushIOWatchEvent(EV_EXTI0+5); }
void irqEXTI6() { jshPushIOWatchEvent(EV_EXTI0+6); }
void irqEXTI7() { jshPushIOWatchEvent(EV_EXTI0+7); }
void irqEXTI8() { jshPushIOWatchEvent(EV_EXTI0+8); }
void irqEXTI9() { jshPushIOWatchEvent(EV_EXTI0+9); }
void irqEXTI10() { jshPushIOWatchEvent(EV_EXTI0+10); }
void irqEXTI11() { jshPushIOWatchEvent(EV_EXTI0+11); }
void irqEXTI12() { jshPushIOWatchEvent(EV_EXTI0+12); }
void irqEXTI13() { jshPushIOWatchEvent(EV_EXTI0+13); }
void irqEXTI14() { jshPushIOWatchEvent(EV_EXTI0+14); }
void irqEXTI15() { jshPushIOWatchEvent(EV_EXTI0+15); }
void irqEXTIDoNothing() { }
void (*irqEXTIs[16])(void) = {

View File

@ -43,7 +43,7 @@
#define UPDATE_IN_PROGRESS_LED LED1_PININDEX /**< Led used to indicate that DFU is active. */
#define UPDATE_IN_PROGRESS_LED_ONSTATE LED1_ONSTATE /**< Led used to indicate that DFU is active. */
#endif
#ifdef LED2_PININDEX
#if defined(LED2_PININDEX) && !defined(LED2_NO_BOOTLOADER)
#define BOOTLOADER_BUTTON_PRESS_LED LED2_PININDEX /**< Led used to indicate that DFU is active. */
#define BOOTLOADER_BUTTON_PRESS_LED_ONSTATE LED2_ONSTATE /**< Led used to indicate that DFU is active. */
#else

View File

@ -178,80 +178,80 @@ void SysTick_Handler(void)
void EXTI0_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line0) == SET) {
jshPushIOWatchEvent(EV_EXTI0);
EXTI_ClearITPendingBit(EXTI_Line0);
jshPushIOWatchEvent(EV_EXTI0);
}
}
void EXTI1_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line1) == SET) {
jshPushIOWatchEvent(EV_EXTI0+1);
EXTI_ClearITPendingBit(EXTI_Line1);
jshPushIOWatchEvent(EV_EXTI0+1);
}
}
void EXTI2_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line2) == SET) {
jshPushIOWatchEvent(EV_EXTI0+2);
EXTI_ClearITPendingBit(EXTI_Line2);
jshPushIOWatchEvent(EV_EXTI0+2);
}
}
void EXTI3_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line3) == SET) {
jshPushIOWatchEvent(EV_EXTI0+3);
EXTI_ClearITPendingBit(EXTI_Line3);
jshPushIOWatchEvent(EV_EXTI0+3);
}
}
void EXTI4_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line4) == SET) {
jshPushIOWatchEvent(EV_EXTI0+4);
EXTI_ClearITPendingBit(EXTI_Line4);
jshPushIOWatchEvent(EV_EXTI0+4);
}
}
void EXTI9_5_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line5) == SET) {
jshPushIOWatchEvent(EV_EXTI0+5);
EXTI_ClearITPendingBit(EXTI_Line5);
jshPushIOWatchEvent(EV_EXTI0+5);
}
if (EXTI_GetITStatus(EXTI_Line6) == SET) {
jshPushIOWatchEvent(EV_EXTI0+6);
EXTI_ClearITPendingBit(EXTI_Line6);
jshPushIOWatchEvent(EV_EXTI0+6);
}
if (EXTI_GetITStatus(EXTI_Line7) == SET) {
jshPushIOWatchEvent(EV_EXTI0+7);
EXTI_ClearITPendingBit(EXTI_Line7);
jshPushIOWatchEvent(EV_EXTI0+7);
}
if (EXTI_GetITStatus(EXTI_Line8) == SET) {
jshPushIOWatchEvent(EV_EXTI0+8);
EXTI_ClearITPendingBit(EXTI_Line8);
jshPushIOWatchEvent(EV_EXTI0+8);
}
if (EXTI_GetITStatus(EXTI_Line9) == SET) {
jshPushIOWatchEvent(EV_EXTI0+9);
EXTI_ClearITPendingBit(EXTI_Line9);
jshPushIOWatchEvent(EV_EXTI0+9);
}
}
void EXTI15_10_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line10) == SET) {
jshPushIOWatchEvent(EV_EXTI0+10);
EXTI_ClearITPendingBit(EXTI_Line10);
jshPushIOWatchEvent(EV_EXTI0+10);
}
if (EXTI_GetITStatus(EXTI_Line11) == SET) {
jshPushIOWatchEvent(EV_EXTI0+11);
EXTI_ClearITPendingBit(EXTI_Line11);
jshPushIOWatchEvent(EV_EXTI0+11);
}
if (EXTI_GetITStatus(EXTI_Line12) == SET) {
jshPushIOWatchEvent(EV_EXTI0+12);
EXTI_ClearITPendingBit(EXTI_Line12);
jshPushIOWatchEvent(EV_EXTI0+12);
}
if (EXTI_GetITStatus(EXTI_Line13) == SET) {
jshPushIOWatchEvent(EV_EXTI0+13);
EXTI_ClearITPendingBit(EXTI_Line13);
jshPushIOWatchEvent(EV_EXTI0+13);
}
if (EXTI_GetITStatus(EXTI_Line14) == SET) {
jshPushIOWatchEvent(EV_EXTI0+14);
EXTI_ClearITPendingBit(EXTI_Line14);
jshPushIOWatchEvent(EV_EXTI0+14);
}
if (EXTI_GetITStatus(EXTI_Line15) == SET) {
jshPushIOWatchEvent(EV_EXTI0+15);
EXTI_ClearITPendingBit(EXTI_Line15);
jshPushIOWatchEvent(EV_EXTI0+15);
}
}

View File

@ -28,33 +28,31 @@ class Cat {
speak() {
return this.name + ' makes a noise.';
}
getLegs() {
return 4;
}
static isDog() {
return false;
}
}
class Lion extends Cat {
speak() {
speak() {
return super.speak()+this.name + ' roars.';
}
static isReallyADog() {
trace(super);
return super.isDog();
}
}
class Lion2 extends Cat {
constructor(name) {
super(name);
}
speak() {
return super.speak()+this.name + ' roars.';
}
class Lion2 extends Lion {
}
var c = new Cat("Tiddles");
var l = new Lion("Alan");
var l2 = new Lion("Nigel");
var rb = c.speak()=="Tiddles makes a noise." && l.speak()=="Alan makes a noise.Alan roars." && l2.speak()=="Nigel makes a noise.Nigel roars." && Lion.isReallyADog()===false;
var l2 = new Lion("Nigel"); // NOTE: making this an instance of Lion2 breaks things
var rb = l.getLegs()==4 && c.speak()=="Tiddles makes a noise." && l.speak()=="Alan makes a noise.Alan roars." && l2.speak()=="Nigel makes a noise.Nigel roars." && Lion.isReallyADog()===false;
// --------------------------------------------