Last active
January 1, 2020 18:58
-
-
Save fanoush/56db50bd2392abedc15039bc6e7e5f06 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
//manual watchdog pinging mode is dangerous for Espruino Web IDE upload with 'reset() before upload' enabled | |
//you can brick your device with partial upload caused by watchdog reboot in the middle of upload | |
//E.enableWatchdog(6, false); | |
//var wdint=setInterval(function(){if(!BTN1.read())E.kickWatchdog();},1000); | |
var log=console.log; | |
Modules.addCached("HX03WLCD",function(){ | |
// commands sent when initialising the display | |
var initCmds = new Uint8Array([ | |
0xAE, // 0 disp off | |
0xD5, // 1 clk div | |
0x51, //0x50, // 2 suggested ratio | |
0xA8, 63, // 3 set multiplex | |
0xD3,0x60, //0x0, // 5 display offset | |
0x20, //??? //0x40, // 7 start line | |
0xAD,0x81, //0x8B, // 8 enable charge pump | |
0xa0, //0xA1, // 10 seg remap 1, pin header at the top | |
0xc0, //0xC8, // 11 comscandec, pin header at the top | |
0xDA,0x12, // 12 set compins | |
0x81,0x80, // 14 set contrast | |
0xD9,0x22, // 16 set precharge | |
0xDB,0x35, // 18 set vcom detect | |
0xa4, | |
0xA6, // 20 display normal (non-inverted) | |
0x00, 0x10, 0xb0, | |
0xAF // 21 disp on | |
]); | |
/* bootloader OLED init | |
GPIO_CfgPinOutput(5); | |
GPIO_CfgPinOutput(6); | |
GPIO_CfgPinOutput(0x1d); | |
GPIO_CfgPinOutput(0x10); | |
*GPIO_OUTCLR = 0x10000; // D16 low | |
GPIO_ConfOutput4_28(); | |
D4_PulseZero50ms(); | |
SPILCD_SendCMD(0xae); | |
SPILCD_SendCMD(0); | |
SPILCD_SendCMD(0x10); | |
SPILCD_SendCMD(0xb0); | |
SPILCD_SendCMD(0x81); SPILCD_SendCMD(0x14); | |
SPILCD_SendCMD(0x20); // ???? | |
SPILCD_SendCMD(0xa0); | |
SPILCD_SendCMD(0xc0); | |
SPILCD_SendCMD(0xa4); | |
SPILCD_SendCMD(0xa6); | |
SPILCD_SendCMD(0xa8); SPILCD_SendCMD(0x3f); | |
SPILCD_SendCMD(0xd3); SPILCD_SendCMD(0x60); | |
SPILCD_SendCMD(0xd5); SPILCD_SendCMD(0x51); | |
SPILCD_SendCMD(0xd9); SPILCD_SendCMD(0x22); | |
SPILCD_SendCMD(0xdb); SPILCD_SendCMD(0x35); | |
SPILCD_SendCMD(0xad); SPILCD_SendCMD(0x81); | |
SPILCD_SendCMD(0xaf); | |
*/ | |
exports.connectSPI = function(spi, dc, rst, callback, options) { | |
var cs = options?options.cs:undefined; | |
var W=options&&options.width?options.width:128; | |
var H=options&&options.height?options.height:64; | |
initCmds[4] = H-1; | |
initCmds[13] = H==64 ? 0x12 : 0x02; | |
if (options && options.contrast) { | |
initCmds[15] = options.contrast; | |
} | |
if (rst) rst.reset(); | |
var oled = Graphics.createArrayBuffer(H,W,1,{vertical_byte:true}); | |
if (rst) digitalPulse(rst,0,30); | |
setTimeout(function() { | |
// configure the OLED | |
D16.reset(); // HX03W oled power? | |
if (cs) digitalWrite(cs,0); | |
digitalWrite(dc,0); // command | |
spi.write(initCmds); | |
digitalWrite(dc,1); // data | |
if (cs) digitalWrite(cs,1); | |
// if there is a callback, call it now(ish) | |
if (callback !== undefined) setTimeout(callback, 10); | |
}, 50); | |
oled.isOn=true; | |
// write to the screen | |
oled.flip = function() { | |
// 16 pages x 64 bytes | |
var page = 0xB0; | |
if (cs) digitalWrite(cs,0); | |
for (var i=0;page<0xC0;i+=H) { | |
digitalWrite(dc,0); // command | |
spi.write([page, 0x0, 0x10]); | |
page++; | |
digitalWrite(dc,1);// data | |
spi.write(new Uint8Array(this.buffer,i,H)); | |
} | |
if (cs) digitalWrite(cs,1); | |
}; | |
// set contrast, 0..255 | |
oled.setContrast = function(c) { | |
if (cs) cs.reset(); | |
spi.write(0x81,c,dc); | |
if (cs) cs.set(); | |
}; | |
// set off | |
oled.off = function() { | |
if (cs) cs.reset(); | |
spi.write(0xAE,dc); | |
if (cs) cs.set(); | |
poke32(0x50000700+4*16,2); // disconnect pin 16 | |
oled.isOn=false; | |
}; | |
// set on | |
oled.on = function() { | |
D16.reset(); // pin 16 output low - power for oled | |
if (cs) cs.reset(); | |
spi.write(0xAF,dc); | |
if (cs) cs.set(); | |
oled.isOn=true; | |
}; | |
// return graphics | |
return oled; | |
}; | |
}); | |
Modules.addCached("HX03W",function(){ | |
function pinOff(pin){ | |
if (pin>=0&&pin<32) poke32(0x50000700+4*pin,2); | |
} | |
exports.battVoltage=function(){ | |
var v=6.61207596594*analogRead(D3);pinOff(3);return v; | |
}; | |
function vibon(vib){ | |
if(vib.i>=1)D25.set();else analogWrite(D25,vib.i); | |
setTimeout(viboff,vib.on,vib); | |
} | |
function viboff(vib){ | |
D25.reset(); | |
if (vib.c>1){vib.c=vib.c-1;setTimeout(vibon,vib.off,vib);} | |
} | |
exports.vibrate=function(intensity,count,onms,offms){ | |
vibon({i:intensity,c:count,on:onms,off:offms}); | |
}; | |
exports.initOLED=function(rot,f){ | |
require("Font4x4").add(Graphics); | |
require("Font6x8").add(Graphics); | |
require("Font6x12").add(Graphics); | |
require("Font8x12").add(Graphics); | |
require("Font8x16").add(Graphics); | |
var spi=SPI1; //new SPI() | |
spi.setup({mosi:D6,sck:D5,baud:8000000}); | |
if (f===undefined) f=function(){ | |
o.setRotation(1,0); | |
o.clear(); | |
o.setFont8x12(); | |
o.drawString("Espruino on HX03W",20,24); | |
o.flip(); | |
}; | |
var o=require("HX03WLCD").connectSPI(spi,D28,D4,f,{cs:D29}); | |
exports.OLED=o; | |
}; | |
var tOff=0; | |
exports.setClock = function(t, z) { | |
var c=getTime(); | |
if(z!==void(0))E.setTimeZone(z); | |
setTime(Date.parse(t)/1E3); | |
tOff+=getTime()-c; | |
}; | |
exports.getUptime = function() { | |
return getTime()-tOff; | |
}; | |
//var i2c=new I2C() | |
var i2c=I2C1; | |
exports.initAccel=function(){ | |
i2c.setup({scl:13, sda:14, bitrate:400000}); | |
}; | |
function accRead(reg,len){i2c.writeTo(0x1f,reg);return i2c.readFrom(0x1f,len);} | |
function accWrite(reg,data){i2c.writeTo(0x1f,reg,data);} | |
function accRegDump(reg){ | |
val=accRead(reg,1)[0];return val.toString(10)+" 0x"+val.toString(16)+" %"+val.toString(2); | |
} | |
exports.accINSDump=function(){ | |
console.log("INS1:",accRegDump(0x12),"INS2:",accRegDump(0x13),"INS3:",accRegDump(0x14)); | |
}; | |
exports.accelCoords=function(){ | |
coords=new Int16Array(accRead(0x06,6).buffer); | |
return {x:coords[0],y:coords[1],z:coords[2]}; | |
}; | |
exports.accRead=accRead; | |
exports.accWrite=accWrite; | |
exports.accRegDump=accRegDump; | |
}); | |
var w=require("HX03W"); | |
w.initOLED(270); | |
var o=w.OLED; | |
function setupSerial(s){ | |
if (!s) s=Serial1; | |
s.setup(38400,{rx:D22,tx:D23}); | |
} | |
function resumeConsole(s){ | |
setupSerial(s); | |
setTimeout(()=>{s.setConsole();},50); | |
} | |
function pauseConsole(s){ | |
if (!s) s=Serial1; | |
if(s._options){ | |
Bluetooth.setConsole(1); | |
setTimeout(()=>{ | |
rx=s._options.rx; | |
s.unsetup(); | |
rx.mode("input_pulldown"); | |
setWatch(()=>{resumeConsole(s);},rx,{edge:'rising',debounce:30});} | |
,500); | |
} | |
} | |
// show clock in landscape mode | |
var clockFace = { | |
show : function(o){ | |
log("clockFace:show"); | |
var g=o; //.gfx; | |
g.setFont6x8(); | |
g.clear(); | |
var d=(Date()).toString().split(' '); | |
var dt=d[0]+" "+d[1]+" "+d[2]+" "+d[3]; | |
g.drawString(dt,64-g.stringWidth(dt)/2,0); | |
var v=w.battVoltage().toString().substr(0,5)+"V"; | |
g.drawString(v,0,48); | |
g.setFont8x16(); | |
g.drawString(d[4],64-g.stringWidth(d[4])/2,9); | |
o.flip();o.on(); | |
}, | |
exit: function(o){ | |
log("clockFace:exit"); | |
return true; | |
} | |
}; | |
var termFace = { | |
vars: {term: 0, | |
buffer: 0, | |
tid:0}, | |
message: "Hello world\nThis is a test ", | |
show: function(o){ | |
log("termFace:show"); | |
var v=this.vars; | |
var g=o; | |
if (!v.term){ | |
v.term = require("VT100").connect(g, { | |
charWidth : 4, | |
charHeight : 4 | |
}); | |
} | |
for (var i in this.message) v.term.char(this.message[i]); | |
o.flip();o.on(); | |
}, | |
exit: function(o){ | |
log("termFace:exit"); | |
var v=this.vars; | |
if (v.tid) clearInterval(v.tid); | |
v.tid=0; | |
if (v.buffer) v.buffer.set(o.buffer,0); | |
return true; | |
}, | |
init: function(o){ | |
log("termFace:init"); | |
var v=this.vars; | |
if (!v.buffer) | |
v.buffer=new Uint8Array(128*64/8); | |
var b=new Uint8Array(o.buffer); | |
b.set(v.buffer,0); | |
o.setFont4x4(); | |
if (!v.tid) v.tid=setInterval(()=>{this.show(o);},1000); | |
}, | |
timeout: 7000 | |
}; | |
var happyFace = { | |
exitcnt: 0, | |
show: function(o){ | |
if (this.exitcnt<3) return; | |
var g=o; | |
g.setFont8x12();g.clear(); | |
g.drawString("Happy face :-)",10,16); | |
o.flip();o.on(); | |
}, | |
exit: function(o){ | |
var g=o.gfx; | |
g.clear(); | |
g.drawString("Exit countdown "+this.exitcnt,10,16); | |
o.flip(); | |
return 0 >= this.exitcnt--; | |
}, | |
init: function(){ | |
this.exitcnt=3; | |
} | |
}; | |
var offid=-1; | |
var offms=5000; | |
var fcurr=-1; | |
var fprev=-1; | |
var faces = [ | |
clockFace, | |
termFace | |
]; | |
function buttonHandler(s){ | |
log("buttonHandler"); | |
//var dbl=(s && s.lastTime && (s.time-s.lastTime)<0.5); | |
//if (dbl)console.log("double click"); | |
if (fcurr<0){ | |
// nothing active, make first one | |
fprev=fcurr; | |
fcurr=0; | |
if (faces[fcurr].init) faces[fcurr].init(o); | |
} else { | |
// ask active one to exit | |
if (!faces[fcurr].exit || faces[fcurr].exit(o)){ | |
log("buttonHandler:exit from "+fcurr+"ok"); | |
// ok exit from current face allowed | |
fprev=fcurr; | |
if(o.isOn) { | |
// if display is on switch to next, otherwise swith to first | |
fcurr++; if (fcurr >= faces.length) fcurr=0; | |
} else fcurr=0; | |
if (faces[fcurr].init) faces[fcurr].init(o); | |
} | |
} | |
if (offid>=0) clearTimeout(offid); | |
var t=(faces[fcurr].timeout)?faces[fcurr].timeout:offms; | |
if (t>0) offid=setTimeout((f)=>{ | |
log("timeout "+fcurr); | |
if(f>=0 && faces[f].exit) faces[f].exit(o); | |
o.off();offid=-1;fcurr=-1; | |
},offms,fcurr); | |
faces[fcurr].show(o); | |
} | |
setTimeout(function(){ | |
//o.setContrast(10); | |
o.off(); | |
setWatch(buttonHandler,BTN1,true); | |
},3000); | |
setupSerial(); | |
// pause serial console for power saving, it will be enabled when RX goes high, it should be enough to connect to serial adapter | |
pauseConsole(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment