From 7191bb60eb0ad417d2eb9e8150c1a92939db6b2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Moskal?= Date: Fri, 27 Jul 2018 13:28:58 -0700 Subject: [PATCH] Add serial support over webusb (#975) * Add serial support over webusb * Disable DAPLink serial on older firmware * Disable sendMany - doesn't work with hidbridge at the moment --- editor/extension.ts | 64 ++++++++++++++++++++++++++++++++++++++++++--- external/dapjs.js | 2 +- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/editor/extension.ts b/editor/extension.ts index 436abe64..c3bfc43e 100644 --- a/editor/extension.ts +++ b/editor/extension.ts @@ -32,24 +32,30 @@ namespace pxt.editor { class DAPWrapper { cortexM: DapJS.CortexM packetIo: HF2.PacketIO; + cmsisdap: any; + flashing = true; + private useSerial = true; constructor(h: HF2.PacketIO) { this.packetIo = h; let pbuf = new U.PromiseBuffer(); + /* let sendMany = (cmds: Uint8Array[]) => { return h.talksAsync(cmds.map(c => ({ cmd: 0, data: c }))); } if (!h.talksAsync) sendMany = null; + */ let dev = new DapJS.DAP({ write: writeAsync, close: this.disconnectAsync, read: readAsync, - sendMany: sendMany + //sendMany: sendMany }); + this.cmsisdap = (dev as any).dap; this.cortexM = new DapJS.CortexM(dev); h.onData = buf => { @@ -63,11 +69,48 @@ namespace pxt.editor { function readAsync() { return pbuf.shiftAsync(); } + + const readSerial = () => { + if (!this.useSerial) { + return + } + + if (this.flashing) { + setTimeout(readSerial, 300) + return + } + + this.cmsisdap.cmdNums(0x83, []) + .then((r: number[]) => { + const len = r[1] + let str = "" + for (let i = 2; i < len + 2; ++i) { + str += String.fromCharCode(r[i]) + } + if (str.length > 0) { + U.nextTick(readSerial) + window.postMessage({ + type: 'serial', + id: 'n/a', // TODO + data: str + }, "*") + // console.log("SERIAL: " + str) + } else + setTimeout(readSerial, 50) + }, (err: any) => { + setTimeout(readSerial, 1000) + }) + } + + readSerial() } reconnectAsync(first: boolean) { if (!first) return this.packetIo.reconnectAsync() + // configure serial at 115200 + .then(() => this.cmsisdap.cmdNums(0x82, [0x00, 0xC2, 0x01, 0x00])) + .then(() => {}, err => { this.useSerial = false }) .then(() => this.cortexM.init()) else return this.cortexM.init(); @@ -117,7 +160,9 @@ namespace pxt.editor { let w = new DAPWrapper(h) previousDapWrapper = w; return w.reconnectAsync(true) - .then(() => w) + .then(() => { + return w + }) }) } @@ -290,7 +335,15 @@ namespace pxt.editor { let checksums: Uint8Array pxt.tickEvent("hid.flash.start"); - return initAsync() + return Promise.resolve() + .then(() => { + if (previousDapWrapper) { + previousDapWrapper.flashing = true + return Promise.delay(100) + } + return Promise.resolve() + }) + .then(initAsync) .then(w => { wrap = w log("reset") @@ -370,6 +423,9 @@ namespace pxt.editor { pxt.tickEvent("hid.flash.done"); return wrap.cortexM.reset(false) }) + .then(() => { + wrap.flashing = false; + }) }) .catch(e => { // TODO: (microbit master) @@ -543,7 +599,7 @@ namespace pxt.editor { pxt.debug('loading microbit target extensions...') if (!Math.imul) - Math.imul = function(a, b) { + Math.imul = function (a, b) { const ah = (a >>> 16) & 0xffff; const al = a & 0xffff; const bh = (b >>> 16) & 0xffff; diff --git a/external/dapjs.js b/external/dapjs.js index 4afceba1..9521a736 100644 --- a/external/dapjs.js +++ b/external/dapjs.js @@ -2397,7 +2397,7 @@ var CMSISDAP = (function () { case 6 /* DAP_TRANSFER_BLOCK */: break; default: - if (buf[1] !== 0) { + if (op < 0x80 && buf[1] !== 0) { throw new Error("Bad status for " + op + " -> " + buf[1]); } }