Add serial support

This commit is contained in:
Michal Moskal
2017-07-07 13:08:36 +01:00
parent e8d8222d86
commit 5af3cc4345
5 changed files with 97 additions and 27 deletions

View File

@ -17,11 +17,12 @@ namespace pxt.editor {
export class Ev3Wrapper {
msgs = new U.PromiseBuffer<Uint8Array>()
private cmdSeq = U.randomUint32() & 0xffff;
private lock = new U.PromiseQueue();
constructor(public io: pxt.HF2.PacketIO) {
io.onData = buf => {
buf = buf.slice(0, HF2.read16(buf, 0) + 2)
// log("DATA: " + U.toHex(buf))
//log("DATA: " + U.toHex(buf))
this.msgs.push(buf)
}
}
@ -53,27 +54,27 @@ namespace pxt.editor {
})
}
talkAsync(buf: Uint8Array) {
return this.io.sendPacketAsync(buf)
.then(() => this.msgs.shiftAsync(1000))
.then(resp => {
if (resp[2] != buf[2] || resp[3] != buf[3])
U.userError("msg count de-sync")
if (buf[4] == 1) {
if (resp[5] != buf[5])
U.userError("cmd de-sync")
if (resp[6] != 0 && resp[6] != 1 /* LS? */ && resp[6] != 8 /* EOF */)
U.userError("cmd error: " + resp[6])
}
return resp
})
talkAsync(buf: Uint8Array, altResponse = 0) {
return this.lock.enqueue("talk", () =>
this.io.sendPacketAsync(buf)
.then(() => this.msgs.shiftAsync(1000))
.then(resp => {
if (resp[2] != buf[2] || resp[3] != buf[3])
U.userError("msg count de-sync")
if (buf[4] == 1) {
if (resp[5] != buf[5])
U.userError("cmd de-sync")
if (altResponse != -1 && resp[6] != 0 && resp[6] != altResponse)
U.userError("cmd error: " + resp[6])
}
return resp
}))
}
flashAsync(path: string, file: Uint8Array) {
log(`write ${file.length} to ${path}`)
let begin = this.allocSystem(4 + path.length + 1, 0x92)
HF2.write32(begin, 6, file.length) // fileSize
U.memcpy(begin, 10, U.stringToUint8Array(path))
let handle = -1
let loopAsync = (pos: number): Promise<void> => {
if (pos >= file.length) return Promise.resolve()
@ -82,11 +83,13 @@ namespace pxt.editor {
let upl = this.allocSystem(1 + size, 0x93, 0x1)
upl[6] = handle
U.memcpy(upl, 6 + 1, file, pos, size)
return this.talkAsync(upl)
return this.talkAsync(upl, 8) // 8=EOF
.then(() => loopAsync(pos + size))
}
let handle = -1
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]
@ -99,7 +102,7 @@ namespace pxt.editor {
HF2.write16(lsReq, 6, 1024) // maxRead
U.memcpy(lsReq, 8, U.stringToUint8Array(path))
return this.talkAsync(lsReq)
return this.talkAsync(lsReq, 8)
.then(resp =>
U.uint8ArrayToString(resp.slice(12)).split(/\n/).map(s => {
if (!s) return null as DirEntry
@ -118,6 +121,7 @@ namespace pxt.editor {
}
rmAsync(path: string): Promise<void> {
log(`rm ${path}`)
let rmReq = this.allocSystem(path.length + 1, 0x9c)
U.memcpy(rmReq, 6, U.stringToUint8Array(path))
@ -125,6 +129,47 @@ namespace pxt.editor {
.then(resp => { })
}
streamFileAsync(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<void> => {
if (buf[6] == 2) {
// handle not ready - file is missing
return restart()
}
if (buf[6] != 0 && buf[6] != 8)
U.userError("bad response when streaming file: " + buf[6])
fileSize = HF2.read32(buf, 7)
if (handle == -1)
handle = buf[11]
let data = buf.slice(12)
filePtr += data.length
if (data.length > 0)
cb(data)
if (buf[6] == 8) {
// end of file
return this.rmAsync(path).then(restart)
}
let contFileReq = this.allocSystem(1 + 2, 0x97)
HF2.write16(contFileReq, 7, 1000) // maxRead
contFileReq[6] = handle
return Promise.delay(data.length > 0 ? 0 : 500)
.then(() => this.talkAsync(contFileReq, -1))
.then(resp)
}
let getFileReq = this.allocSystem(2 + path.length + 1, 0x96)
HF2.write16(getFileReq, 6, 1000) // maxRead
U.memcpy(getFileReq, 8, U.stringToUint8Array(path))
return this.talkAsync(getFileReq, -1).then(resp)
}
private initAsync() {
return Promise.resolve()
}