diff --git a/editor/extension.ts b/editor/extension.ts index 8101cee7..4ef27f93 100644 --- a/editor/extension.ts +++ b/editor/extension.ts @@ -41,9 +41,8 @@ namespace pxt.editor { return initAsync() .then(w_ => { w = w_ - // run LS to make sure we can talk to device first - // otherwise flashing a file might lock it - return w.lsAsync("/") + if (w.isStreaming) + U.userError("please stop the program first") }).then(() => { let f = U.stringToUint8Array(atob(resp.outfiles[pxt.outputName()])) return w.flashAsync(elfPath, f) diff --git a/editor/wrap.ts b/editor/wrap.ts index 8bdda4b7..c96b8f02 100644 --- a/editor/wrap.ts +++ b/editor/wrap.ts @@ -18,6 +18,7 @@ namespace pxt.editor { msgs = new U.PromiseBuffer() private cmdSeq = U.randomUint32() & 0xffff; private lock = new U.PromiseQueue(); + isStreaming = false; constructor(public io: pxt.HF2.PacketIO) { io.onData = buf => { @@ -90,11 +91,12 @@ namespace pxt.editor { let begin = this.allocSystem(4 + path.length + 1, 0x92) HF2.write32(begin, 6, file.length) // fileSize U.memcpy(begin, 10, U.stringToUint8Array(path)) - return this.talkAsync(begin) - .then(resp => { - handle = resp[7] - return loopAsync(0) - }) + return this.lock.enqueue("file", () => + this.talkAsync(begin) + .then(resp => { + handle = resp[7] + return loopAsync(0) + })) } lsAsync(path: string): Promise { @@ -129,23 +131,26 @@ namespace pxt.editor { .then(resp => { }) } - streamFileAsync(path: string, cb: (d: Uint8Array) => void) { + private streamFileOnceAsync(path: string, cb: (d: Uint8Array) => void) { let fileSize = 0 let filePtr = 0 let handle = -1 - let restart = () => Promise.delay(500).then(() => this.streamFileAsync(path, cb)) let resp = (buf: Uint8Array): Promise => { if (buf[6] == 2) { // handle not ready - file is missing - return restart() + this.isStreaming = false + return Promise.resolve() } if (buf[6] != 0 && buf[6] != 8) - U.userError("bad response when streaming file: " + buf[6]) + U.userError("bad response when streaming file: " + buf[6] + " " + U.toHex(buf)) + this.isStreaming = true fileSize = HF2.read32(buf, 7) - if (handle == -1) + if (handle == -1) { handle = buf[11] + log(`stream on, handle=${handle}`) + } let data = buf.slice(12) filePtr += data.length if (data.length > 0) @@ -153,7 +158,8 @@ namespace pxt.editor { if (buf[6] == 8) { // end of file - return this.rmAsync(path).then(restart) + this.isStreaming = false + return this.rmAsync(path) } let contFileReq = this.allocSystem(1 + 2, 0x97) @@ -170,6 +176,15 @@ namespace pxt.editor { return this.talkAsync(getFileReq, -1).then(resp) } + streamFileAsync(path: string, cb: (d: Uint8Array) => void) { + let loop = (): Promise => + this.lock.enqueue("file", () => + this.streamFileOnceAsync(path, cb)) + .then(() => Promise.delay(500)) + .then(loop) + return loop() + } + private initAsync() { return Promise.resolve() }