Last active
September 14, 2021 05:16
-
-
Save fanoush/505a6f44532e4fdaadef4da5777d7777 to your computer and use it in GitHub Desktop.
Espruino demo code for SMA B5 smart band with GPS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
E.kickWatchdog(); | |
function KickWd(){ | |
if( (typeof(BTN1)=='undefined')||(!BTN1.read()) ) E.kickWatchdog(); | |
} | |
var wdint=setInterval(KickWd,2000); | |
E.enableWatchdog(15, false); | |
// MIT License (c) 2020 fanoush https://github.com/fanoush | |
// see full license text at https://choosealicense.com/licenses/mit/ | |
// SPI display driver below compiled with options LCD_BPP=12 | |
var SPI2 = (function(){ | |
var bin=atob("AAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////8QtQNMfEQigGCAoYDjgBC92P///wdLe0QbiUOxBEoTaAAr/NAAIxNgA0p6RBOBcEcYMQJAxv///7L///8t6fBHkEYZTBlO//fl/xlK3/hkwAAjASUTYE/w/w5TYKlGI2AQMh9G/ykA6wMKwvgAoIu//zMxYMb4AOAAIYi//znM+ACQuPEADwbQKbkLS3tEHYEAIL3o8IfU+ACguvEAD/rQJ2AAKd7R8+cYMQJASDUCQDQ1AkAQMAJAUP///y3p8E+bsM3pARJQSnpEBkaS+ACQACgA8JGAACkA8I6ACfH/MwcrAPKJgAEjA/oJ8wE727IDkwR4Q3iXiETqAyQCmxxB02gA8QILpLILsT1KE2BP6kkD27IEkz1Le0QRqAWTCKvN6QYwT/AACEFGBZsCnbP4AqADmwGaI0BE+gn0MvgTwAObI0BE+gn0MvgTIASbHUTtsgctQNiksk/qLBNDVBMSAfECDkPqDBxDGAMxqvECCiMpg/gBwB/6ivoA+A4gCd0BIv/3W//Y8QEIC78HmAaYQUYAIbrxAA/L0R1Le0QBP9uIHkS/snN4NHhE6gMkApscQQbxAguksgAvttHJsTpG//c8/xNLe0TYaBCxDUsYYAAgG7C96PCP3kYIPR74ATvtssXxCAsD+gvzHEOksvNGsuf/9w//5edP8P8w6ecAvwwFAFAIBQBQFP///8T+//9A/v//Fv7//xVKekRwtQ5GEWkFRuGxEEsZYNJoArEaYAAiASEoRv/3Af8OSwtMe0QBLhppImAE3QAicR5oHP/39f4JS3tE2GgIsSBgACBwvU/w/zD75wC/DAUAUAgFAFDC/f//nv3//4j9//8TtQAoHtsAKaa/jfgFEAIkASQAKqS/AqkJGY34BACkvwE0AfgELAAror8CqhIZATQhRgGoqL8C+AQ8//ev/yBGArAQvQAk+udwtQVGiLFGGAAkKEYQ+AEbGbFFGLVCAtlkQiBGcL3/95n/ACj50QE07+cERvXnAAA4tQ9Le0QaaZKxiLGBsdtoC7EJShNgC00ITH1EACIraSNg//eR/uhoCLEgYAAgOL1P8P8w++cAvwwFAFAIBQBQ5Pz//878//8PSjC1FGjEuQ5LG2gLsQ5MI2ARSw1Me0QABl1pJWCdaWVg3GkKS0kAHGBYYVlkByMTYAhLASAYYDC9T/D/MPvnADUCQAQzAkAIMwJACDUCQBA1AkAUMAJAivz//wVKACMTYKL1fnITYANLG2gLscL4ADJwRwA1AkAEMwJAELUGTHxExOkFAQEhAfoC8gH6A/PiYCNhEL0AvyD8//8="); | |
return { | |
cmd:E.nativeCall(569, "int(int,int)", bin), | |
cmds:E.nativeCall(741, "int(int,int)", bin), | |
cmd4:E.nativeCall(669, "int(int,int,int,int)", bin), | |
data:E.nativeCall(789, "int(int,int)", bin), | |
setpins:E.nativeCall(985, "void(int,int,int,int)", bin), | |
enable:E.nativeCall(861, "int(int,int)", bin), | |
disable:E.nativeCall(953, "void()", bin), | |
blit_setup:E.nativeCall(33, "void(int,int,int,int)", bin), | |
blt_pal:E.nativeCall(221, "int(int,int,int)", bin), | |
}; | |
})(); | |
E.kickWatchdog(); | |
// B5 display pins | |
var RST=D8,CS=D5,DC=D6,PWR=D29,SCK=D2,MOSI=D3; | |
function delayms(ms){ | |
digitalPulse(DC,0,ms); // just to wait 10ms | |
digitalPulse(DC,0,0); | |
} | |
CS.write(1); // CS | |
DC.write(1); // CD | |
RST.write(1); // RESET | |
PWR.write(0); //backlight | |
digitalPulse(RST,0,10); | |
SCK.write(0); | |
MOSI.write(0); | |
//SPI2.save(); | |
SPI2.disable(); | |
SPI2.setpins(SCK,MOSI,CS,DC); // CLK,MOSI,CS,DC | |
function toFlatString(arr){ | |
var b=E.toString(arr);if (b) return b; | |
print("toFlatString() fail&retry!");E.defrag();b=E.toString(arr);if (b) return b; | |
print("fail&retry again!");E.defrag();b=E.toString(arr);if (b) return b; | |
print("failed!"); return b; | |
} | |
function toFlatBuffer(a){return E.toArrayBuffer(toFlatString(a));} | |
function cmd(a){ | |
//CS.reset(); | |
if (typeof(a)=='number') SPI2.cmd4(a,-1,-1,-1); | |
else switch (a.length){ | |
case 2: SPI2.cmd4(a[0],a[1],-1,-1); break; | |
case 3: SPI2.cmd4(a[0],a[1],a[2],-1); break; | |
case 4: SPI2.cmd4(a[0],a[1],a[2],a[3]); break; | |
case 1: SPI2.cmd4(a[0],-1,-1,-1); break; | |
default: | |
var b=toFlatString(a); | |
SPI2.cmd(E.getAddressOf(b,true),b.length); | |
} | |
//CS.set(); | |
} | |
function cmds(arr){ | |
var b=toFlatString(arr); | |
//CS.reset(); | |
var c=SPI2.cmds(E.getAddressOf(b,true),b.length); | |
//CS.set(); | |
if (c<0)print('lcd_cmds: buffer mismatch, cnt='+c); | |
return c; | |
} | |
function init(){ | |
cmd(0x11); // sleep out | |
delayms(10); | |
cmd([0xb1,5,0x3c,0x3c]); | |
cmd([0xb2,5,0x3c,0x3c]); | |
cmd([0xb3,5,0x3c,0x3c,5,0x3c,0x3c]); | |
cmd([0xb4,3]); | |
cmd([0xc0,0x0e,0xe,0x40]); | |
cmd([0xc1,0xc5]); | |
cmd([0xc2,0xd,0xc5]); | |
cmd([0xc3,0x8d,0x2a]); | |
cmd([0xc4,0x8d,0xee]); | |
cmd([0xc5,6]); | |
cmd([0x36,200]); | |
cmd([0xe0, 0x0b,0x17,0x0a,0x0d, 0x1a,0x19,0x16,0x1d, 0x21,0x26,0x37,0x3c, 0,9,5,0x10]); | |
cmd([0xe1, 0x0c,0x19,0x09,0x0d, 0x1b,0x19,0x15,0x1d, 0x21,0x26,0x39,0x3e, 0,9,5,0x10]); | |
cmd([0x3a,3]);// 5 | |
} | |
var bpp=4; // powers of two work, 3=8 colors would be nice | |
var g=Graphics.createArrayBuffer(80,160,bpp); | |
var pal; | |
switch(bpp){ | |
case 2: pal= Uint16Array([0x000,0xf00,0x0f0,0x00f]);break; // white won't fit | |
// case 1: pal= Uint16Array([0x000,0xfff]);break; | |
case 1: | |
pal= Uint16Array( // same as 16color below, use for dynamic colors | |
[ 0x000,0x00a,0x0a0,0x0aa,0xa00,0xa0a,0xa50,0xaaa, | |
0x555,0x55f,0x5f5,0x5ff,0xf55,0xf5f,0xff5,0xfff ]); | |
g.sc=g.setColor; | |
c1=pal[1]; //save color 1 | |
g.setColor=function(c){ //change color 1 dynamically | |
c=Math.floor(c); | |
if (c > 1) { | |
pal[1]=pal[c]; g.sc(1); | |
} else if (c==1) { | |
pal[1]=c1; g.sc(1); | |
} else g.sc(c); | |
}; break; | |
case 4: pal= Uint16Array( // CGA | |
[ | |
// 12bit RGB444 | |
0x000,0x00a,0x0a0,0x0aa,0xa00,0xa0a,0xa50,0xaaa, | |
0x555,0x55f,0x5f5,0x5ff,0xf55,0xf5f,0xff5,0xfff | |
//16bit RGB565 | |
// 0x0000,0x00a8,0x0540,0x0555,0xa800,0xa815,0xaaa0,0xad55, | |
// 0x52aa,0x52bf,0x57ea,0x57ff,0xfaaa,0xfabf,0xffea,0xffff | |
]);break; | |
} | |
// preallocate setwindow command buffer for flip | |
g.winCmd=toFlatBuffer([ | |
5, 0x2a, 0, 0, 0,0, | |
5, 0x2b, 0, 0, 0,0, | |
1, 0x2c, | |
0 ]); | |
// precompute addresses for flip | |
g.winA=E.getAddressOf(g.winCmd,true); | |
g.palA=E.getAddressOf(pal.buffer,true); // pallete address | |
g.buffA=E.getAddressOf(g.buffer,true); // framebuffer address | |
g.stride=g.getWidth()*bpp/8; | |
g.flip=function(force){ | |
var r=g.getModified(true); | |
if (force) | |
r={x1:0,y1:0,x2:this.getWidth()-1,y2:this.getHeight()-1}; | |
if (r === undefined) return; | |
var x1=r.x1&0xfe;var x2=(r.x2+2)&0xfe; // for 12bit mode align to 2 pixels | |
var xw=(x2-x1); | |
var yw=(r.y2-r.y1+1); | |
if (xw<1||yw<1) {print("empty rect ",xw,yw);return;} | |
/* | |
cmd([0x2a,0,24+x1,0,23+x2]); //offset by (128-80)/2=24 | |
cmd([0x2b,0,r.y1,0,r.y2]); | |
cmd([0x2c]); | |
*/ | |
var c=g.winCmd; | |
c[3]=24+x1;c[5]=23+x2; //0x2a params | |
c[9]=r.y1;c[11]=r.y2; // 0x2b params | |
SPI2.blit_setup(xw,yw,bpp,g.stride); | |
var xbits=x1*bpp; | |
var bitoff=xbits%8; | |
var addr=g.buffA+(xbits-bitoff)/8+r.y1*g.stride; // address of upper left corner | |
//CS.reset(); | |
//VIB.set();//debug | |
SPI2.cmds(g.winA,c.length); | |
SPI2.blt_pal(addr,g.palA,bitoff); | |
//VIB.reset();//debug | |
//CS.set(); | |
}; | |
g.lev=256; | |
g.setBrightness=function(lev){ | |
if (lev>=0 && lev<=256) | |
this.lev=lev; | |
else | |
lev=this.lev; | |
if (this.isOn){ | |
val=lev/256; | |
if (val==0||val==1) | |
digitalWrite(PWR,val); | |
else | |
analogWrite(PWR,val,{freq:60}); | |
} | |
}; | |
g.isOn=false; | |
//g.doInit=true; | |
SPI2.enable(0x80,0); //8MBit, mode 0 | |
init(); | |
//SPI2.disable(); | |
g.on=function(){ | |
if (this.isOn) return; | |
//[DC,SCK,MOSI,RST,CS].forEach((p)=>{p.mode("input_pullup");p.mode("output");}); | |
// CS.write(1); // CS | |
// DC.write(1); // CD | |
// RST.write(1); // RESET | |
// SCK.write(0); | |
// MOSI.write(0); | |
//SPI2.enable(0x80,0); | |
if (g.doInit) {init();g.doInit=false;} else cmd(0x11); | |
g.flip(); | |
//cmd(0x13); //ST7735_NORON: Set Normal display on, no args, w/delay: 10 ms delay | |
cmd(0x29); //ST7735_DISPON: Set Main screen turn on, no args w/delay: 100 ms delay | |
//PWR.reset(); // full brightness | |
this.isOn=true; | |
this.setBrightness(); | |
}; | |
g.off=function(){ | |
if (!this.isOn) return; | |
cmd(0x28); | |
cmd(0x10); | |
PWR.reset(); | |
//SPI2.disable(); | |
//6,3,2,8,7 | |
// [DC,SCK,MOSI,RST,CS].forEach((p)=>{p.mode("analog");} ); // disconnect like poke32(0x50000700+4*pin,2); | |
this.isOn=false; | |
}; | |
var VIB=D30; | |
function vibon(vib){ | |
if(vib.i>=1)VIB.set();else analogWrite(VIB,vib.i); | |
setTimeout(viboff,vib.on,vib); | |
} | |
function viboff(vib){ | |
VIB.reset(); | |
if (vib.c>1){vib.c--;setTimeout(vibon,vib.off,vib);} | |
} | |
vibrate=function(intensity,count,onms,offms){ | |
vibon({i:intensity,c:count,on:onms,off:offms}); | |
}; | |
function battVolts(){ | |
return 4.20/0.320*analogRead(D4); | |
} | |
function battLevel(v){ | |
var l=3.5,h=4.19; | |
v=v?v:battVolts(); | |
if(v>=h)return 100; | |
if(v<=l)return 0; | |
return 100*(v-l)/(h-l); | |
} | |
function battInfo(v){v=v?v:battVolts();return `${battLevel(v)|0}% ${v.toFixed(2)}V`;} | |
var GPS ={ | |
GPTXT : function(a){ | |
if (a[2]!='01') print(a.join(' ')); | |
}, | |
GNRMC : function(a){ | |
print("RMC ",a[0],a[8]); | |
} | |
}; | |
// handle one line from GPS | |
function gpsline(line){ | |
var garr=line.split(','); | |
var f=GPS[garr[0]]; | |
if(f) f(garr.slice(1)); | |
else print(line); | |
} | |
function gpsum(s){ | |
var xor=0; | |
[].forEach.call(s,(c)=>{xor^=c.charCodeAt(0);}); | |
return xor.toString(16).toUpperCase(); | |
} | |
function gpsformat(line){ | |
return '$'+line+'*'+gpsum(line)+'\x0d\x0a'; | |
} | |
// PCAS00 save config to flash | |
// PCAS01,1 - speed 0=4800,1=9600,2=19200,3=38400,4=57600,5=115200 | |
// PCAS02,1000 - 1Hz, 500 250 200 100 | |
// PCAS03,0,0,0,0,0,0,0 - frequency of GGA,GLL,GSA,GSV,RMC,VTG,ZDA in periods set by PSCAS02 (0-9) | |
// Serial1.write(gpsformat("PCAS03,0,0,0,0,0,0,0")) - off | |
// gpsformat("PCAS04,5") systems 1 gps, 2 bds, 4 glonas, combinations 5 6 7 | |
var gpsbuff=""; | |
function gpsdata(data){ | |
gpsbuff+=data; | |
var idx = gpsbuff.indexOf("\n"); | |
while (idx>=0) { | |
var line = gpsbuff.substr(0,idx); | |
gpsbuff = gpsbuff.substr(idx+1); | |
if(line.startsWith("$")) gpsline(line.substr(1,line.lastIndexOf('*')-1)); | |
idx = gpsbuff.indexOf("\n"); | |
} | |
} | |
function gpson(){ | |
gpsbuff=""; | |
Serial1.setup(9600,{tx:D27,rx:D28}); | |
Serial1.on('data',gpsdata); | |
D7.write(1); | |
} | |
function gpsoff(){ | |
D7.write(0); | |
Serial1.removeListener('data',gpsdata); | |
Serial1.unsetup(); | |
} | |
// some stuff in https://github.com/infusion/GPS.js/blob/master/gps.js | |
function randomLines(){ | |
g.clear(); | |
var cols=(bpp==1)?14:(1<<bpp)-1,w=g.getWidth(),h=g.getHeight(),r=Math.random; | |
return setInterval(function(){ | |
g.setColor(1+r()*cols); | |
g.drawLine(r()*w,r()*h,r()*w,r()*h); | |
g.flip(); | |
},5); | |
} | |
function randomShapes(){ | |
g.clear(); | |
var cols=(bpp==1)?14:(1<<bpp)-1,w=g.getWidth()-10,h=g.getHeight()-10,r=Math.random; | |
return setInterval(function(){ | |
g.setBgColor(0); | |
g.setColor(1+r()*cols); | |
x1=r()*w;x2=10+r()*w; | |
y1=r()*h;y2=10+r()*h; | |
if (bpp==1 && ((x1&31)==1)) g.clear(); // for bpp==1 clear sometimes so we can see ellipses again | |
if (x1&1) | |
g.fillEllipse(Math.min(x1,x2), Math.min(y1,y2),Math.max(x1,x2), Math.max(y1,y2)); | |
else | |
g.fillRect(Math.min(x1,x2), Math.min(y1,y2),Math.max(x1,x2), Math.max(y1,y2)); | |
g.flip(); | |
},5); | |
} | |
// cube from https://www.espruino.com/Pixl.js+Cube+Badge | |
var rx = 0, ry = 0, cc = 1; | |
// Draw the cube at rotation rx and ry | |
function drawCube(xx,yy,zz) { | |
// precalculate sin&cos for rotations | |
var rcx=Math.cos(rx), rsx=Math.sin(rx); | |
var rcy=Math.cos(ry), rsy=Math.sin(ry); | |
// Project 3D into 2D | |
function p(x,y,z) { | |
var t; | |
t = x*rcy + z*rsy; | |
z = z*rcy - x*rsy; | |
x=t; | |
t = y*rcx + z*rsx; | |
z = z*rcx - y*rsx; | |
y=t; | |
z += 4; | |
return [xx + zz*x/z, yy + yy*y/z]; | |
} | |
var a,b; | |
// -z | |
a = p(-1,-1,-1); b = p(1,-1,-1); | |
g.drawLine(a[0],a[1],b[0],b[1]); | |
a = p(1,1,-1); | |
g.drawLine(a[0],a[1],b[0],b[1]); | |
b = p(-1,1,-1); | |
g.drawLine(a[0],a[1],b[0],b[1]); | |
a = p(-1,-1,-1); | |
g.drawLine(a[0],a[1],b[0],b[1]); | |
// z | |
a = p(-1,-1,1); b = p(1,-1,1); | |
g.drawLine(a[0],a[1],b[0],b[1]); | |
a = p(1,1,1); | |
g.drawLine(a[0],a[1],b[0],b[1]); | |
b = p(-1,1,1); | |
g.drawLine(a[0],a[1],b[0],b[1]); | |
a = p(-1,-1,1); | |
g.drawLine(a[0],a[1],b[0],b[1]); | |
// edges | |
a = p(-1,-1,-1); b = p(-1,-1,1); | |
g.drawLine(a[0],a[1],b[0],b[1]); | |
a = p(1,-1,-1); b = p(1,-1,1); | |
g.drawLine(a[0],a[1],b[0],b[1]); | |
a = p(1,1,-1); b = p(1,1,1); | |
g.drawLine(a[0],a[1],b[0],b[1]); | |
a = p(-1,1,-1); b = p(-1,1,1); | |
g.drawLine(a[0],a[1],b[0],b[1]); | |
} | |
function stepCube() { | |
rx += 0.1; | |
ry += 0.1; | |
g.setColor(0);g.fillRect(0,40,80,120);g.setColor(1+cc);cc=(cc+1)%15; | |
drawCube(40,80,80); | |
g.flip(); | |
} | |
//require("Font6x8").add(Graphics); | |
//require("Font6x12").add(Graphics); | |
//require("Font8x12").add(Graphics); | |
//require("Font8x16").add(Graphics); | |
function info(){ | |
g.clear(); | |
g.setFont("4x6",1/*2*/);g.setColor(10); | |
g.drawString("Espruino "+process.version,5,10); | |
if (bpp==1) g.flip(); | |
g.setFont("4x6",1);g.setColor(14); | |
g.drawString("ST7735 12 bit mode\n8Mbps SPI with DMA",4,22); | |
if (bpp==1) g.flip(); | |
for (var c=0;c<8;c++){ | |
g.setColor(c+8);g.fillRect(8+8*c,130,16+8*c,138); | |
if (bpp==1) g.flip(); | |
} | |
for ( c=0;c<8;c++) {g.setColor(c);g.fillRect(8+8*c,142,16+8*c,150); | |
if (bpp==1) g.flip(); | |
} | |
g.flip(); | |
return setInterval(function(){ | |
stepCube(); | |
},5); | |
} | |
var lastsec=-1; | |
var volts; | |
var batt=battInfo(); | |
function drawClock(){ | |
var d=Date(); | |
volts= volts ? (volts+battVolts())/2:battVolts(); // average until shown | |
if (d.getSeconds()==lastsec) return; | |
lastsec=d.getSeconds(); | |
g.clear(); | |
if (lastsec%10==0){ | |
batt=battInfo(volts);volts=0; | |
} | |
g.setFont("6x8",1);g.setColor(15); | |
g.drawString(batt,40-g.stringWidth(batt)/2,0); | |
g.setFontVector(50); | |
g.setColor(8+2); | |
d=d.toString().split(' '); | |
var sec=d[4].substr(-2); | |
//var tm=d[4].substring(0,5); | |
var hr=d[4].substr(0,2); | |
var min=d[4].substr(3,2); | |
g.drawString(hr,40-g.stringWidth(hr)/2,15); | |
g.drawString(min,40-g.stringWidth(min)/2,80); | |
//g.setColor(8+4); | |
g.setFontVector(28); | |
//if (sec&1)g.drawString("o o",40-g.stringWidth("o o")/2,60); | |
//if (sec&1)g.drawString(":",40-g.stringWidth(":")/2,42); | |
if (sec&1)g.drawString(". .",40-g.stringWidth(". .")/2,50); | |
/* | |
if (sec&1)g.drawString(":",36-g.stringWidth(":")/2,3); | |
var sx=sec*72/60; | |
g.drawLine(sx,0,71,0); | |
g.drawLine(sx,1,71,1); | |
//g.setFont8x16(); | |
*/ | |
g.setFontVector(18); | |
g.setColor(8+3); | |
var dt=/*d[0]+" "+*/d[1]+" "+d[2];//+" "+d[3]; | |
g.drawString(dt,40-g.stringWidth(dt)/2,140); | |
g.flip(); | |
} | |
function clock(){ | |
volts=null; | |
drawClock(); | |
return setInterval(function(){ | |
drawClock(); | |
},250); | |
} | |
function sleep(){ | |
g.clear();//g.flip(); | |
g.off(); | |
currscr=-1; | |
return 0; | |
} | |
var screens=[clock,info,randomShapes,randomLines,sleep]; | |
var currscr= -1; | |
var currint=0; | |
setWatch(function(){ | |
if (!g.isOn) g.on(); | |
currscr++;if (currscr>=screens.length) currscr=0; | |
if (currint>0) clearInterval(currint); | |
currint=screens[currscr](); | |
},BTN1,{ repeat:true, edge:'rising',debounce:25 } | |
); | |
/* | |
NRF.whitelist=[]; | |
NRF.on('connect',function(addr) { | |
if (!NRF.whitelist.includes(addr)){ | |
if (BTN1.read()){ // add to whitelist when button is held while connecting | |
NRF.whitelist.push(addr); | |
vibrate(1,1,100,0); | |
} else | |
NRF.disconnect(); | |
} | |
NRF.connection = {}; | |
NRF.connection.addr = addr; | |
NRF.connected=true; | |
NRF.setRSSIHandler((rssi)=>{NRF.connection.RSSI=rssi;}); | |
}); | |
NRF.on('disconnect',function(reason) { | |
NRF.connected=false; | |
NRF.connection = {}; | |
NRF.lastReason=reason; | |
}); | |
*/ | |
var fc=new SPI(); // font chip - 2MB SPI flash | |
D12.write(1); | |
fc.setup({sck:D14,miso:D11,mosi:D13,mode:0}); | |
fc.send([0xb9],D12); //put to deep sleep | |
/* | |
//print(fc.send([0xab],D23)); // wake from deep sleep | |
//print(fc.send([0x90,0,0,1,0,0],D23)); | |
//print(fc.send([0x9f,0,0,0],D23)); | |
//print(fc.send([0xb9],D23)); // put to deep sleep | |
var w25 = require("W25"); | |
var fc = new w25(fc, D23 ); | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment