Adding deploy code
This commit is contained in:
parent
cbbc51641e
commit
e6a72ba56a
@ -1,7 +1,10 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
LEGO=$HOME/src/lego/lms2012
|
LEGO=$HOME/src/lego/lms2012
|
||||||
F=`pwd`/pxt
|
P="`pwd`"
|
||||||
|
F="$P"/pxt
|
||||||
set -xe
|
set -xe
|
||||||
cd $LEGO/lmssrc/adk/lmsasm
|
cd $LEGO/lmssrc/adk/lmsasm
|
||||||
java -jar assembler.jar $F
|
java -jar assembler.jar $F
|
||||||
|
cd "$P"
|
||||||
|
node -p 'require("fs").readFileSync("pxt.rbf").toString("hex")'
|
||||||
|
@ -8,7 +8,8 @@ vmthread MAIN
|
|||||||
UI_WRITE(LED,LED_RED)
|
UI_WRITE(LED,LED_RED)
|
||||||
UI_DRAW(TEXT,FG_COLOR,48,62,'Starting...')
|
UI_DRAW(TEXT,FG_COLOR,48,62,'Starting...')
|
||||||
UI_DRAW(UPDATE)
|
UI_DRAW(UPDATE)
|
||||||
SYSTEM('../prjs/BrkProg_SAVE/binary.elf', Status)
|
SYSTEM('XXXXXXXXX', Status)
|
||||||
|
//SYSTEM('../prjs/BrkProg_SAVE/binary.elf', Status)
|
||||||
Loop:
|
Loop:
|
||||||
UI_BUTTON(WAIT_FOR_PRESS)
|
UI_BUTTON(WAIT_FOR_PRESS)
|
||||||
UI_BUTTON(SHORTPRESS,BACK_BUTTON,State)
|
UI_BUTTON(SHORTPRESS,BACK_BUTTON,State)
|
||||||
|
BIN
aux/pxt.rbf
BIN
aux/pxt.rbf
Binary file not shown.
12
cmds/cmds.ts
Normal file
12
cmds/cmds.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/// <reference path="../node_modules/pxt-core/typings/globals/node/index.d.ts"/>
|
||||||
|
/// <reference path="../node_modules/pxt-core/built/pxtlib.d.ts" />
|
||||||
|
|
||||||
|
require("./editor")
|
||||||
|
|
||||||
|
declare namespace pxt.editor {
|
||||||
|
function deployCoreAsync(resp: pxtc.CompileResult, isCli?: boolean): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deployCoreAsync(resp: pxtc.CompileResult) {
|
||||||
|
return pxt.editor.deployCoreAsync(resp, true)
|
||||||
|
}
|
64
editor/extension.ts
Normal file
64
editor/extension.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/// <reference path="../node_modules/pxt-core/built/pxteditor.d.ts" />
|
||||||
|
|
||||||
|
// When require()d from node, bind the global pxt namespace
|
||||||
|
namespace pxt {
|
||||||
|
export const dummyExport = 1;
|
||||||
|
}
|
||||||
|
eval("if (typeof process === 'object' && process + '' === '[object process]') pxt = global.pxt")
|
||||||
|
|
||||||
|
namespace pxt.editor {
|
||||||
|
// this comes from aux/pxt.lms
|
||||||
|
const rbfTemplate = "4c45474f5d0000006d000100000000001c0000000000000008000000821b028405018130813e805374617274696e672e2e2e00840060805858585858585858580044830383010640414082f5ff8405018130813e80427965210084000a";
|
||||||
|
|
||||||
|
|
||||||
|
function hf2Async() {
|
||||||
|
return pxt.HF2.mkPacketIOAsync()
|
||||||
|
.then(h => {
|
||||||
|
let w = new Ev3Wrapper(h)
|
||||||
|
return w.reconnectAsync(true)
|
||||||
|
.then(() => w)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let initPromise: Promise<Ev3Wrapper>
|
||||||
|
function initAsync() {
|
||||||
|
if (!initPromise)
|
||||||
|
initPromise = hf2Async()
|
||||||
|
.catch(err => {
|
||||||
|
initPromise = null
|
||||||
|
return Promise.reject(err)
|
||||||
|
})
|
||||||
|
return initPromise
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
|
||||||
|
let w: Ev3Wrapper
|
||||||
|
let elfPath = "../prjs/BrkProg_SAVE/binary.elf"
|
||||||
|
let rbfPath = "../prjs/BrkProg_SAVE/pxt0.rbf"
|
||||||
|
return initAsync()
|
||||||
|
.then(w_ => {
|
||||||
|
w = w_
|
||||||
|
let f = U.stringToUint8Array(atob(resp.outfiles[pxt.outputName()]))
|
||||||
|
return w.flashAsync(elfPath, f)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
let rbfHex = rbfTemplate.replace(/58585858(58)+/, U.toHex(U.stringToUint8Array(elfPath)))
|
||||||
|
let rbf = U.fromHex(rbfHex)
|
||||||
|
HF2.write16(rbf, 4, rbf.length)
|
||||||
|
return w.flashAsync(rbfPath, rbf)
|
||||||
|
}).then(() => {
|
||||||
|
if (isCli)
|
||||||
|
return w.disconnectAsync()
|
||||||
|
else
|
||||||
|
return Promise.resolve()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): Promise<pxt.editor.ExtensionResult> {
|
||||||
|
pxt.debug('loading pxt-adafruit target extensions...')
|
||||||
|
const res: pxt.editor.ExtensionResult = {
|
||||||
|
deployCoreAsync,
|
||||||
|
};
|
||||||
|
return Promise.resolve<pxt.editor.ExtensionResult>(res);
|
||||||
|
}
|
||||||
|
}
|
12
editor/tsconfig.json
Normal file
12
editor/tsconfig.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"declaration": true,
|
||||||
|
"out": "../built/editor.js",
|
||||||
|
"rootDir": ".",
|
||||||
|
"newLine": "LF",
|
||||||
|
"sourceMap": false
|
||||||
|
}
|
||||||
|
}
|
122
editor/wrap.ts
Normal file
122
editor/wrap.ts
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
namespace pxt.editor {
|
||||||
|
import HF2 = pxt.HF2
|
||||||
|
import U = pxt.U
|
||||||
|
|
||||||
|
function log(msg: string) {
|
||||||
|
pxt.log("EWRAP: " + msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DirEntry {
|
||||||
|
name: string;
|
||||||
|
md5?: string;
|
||||||
|
size?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Ev3Wrapper {
|
||||||
|
msgs = new U.PromiseBuffer<Uint8Array>()
|
||||||
|
private cmdSeq = U.randomUint32() & 0xffff;
|
||||||
|
|
||||||
|
constructor(public io: pxt.HF2.PacketIO) {
|
||||||
|
io.onData = buf => {
|
||||||
|
buf = buf.slice(0, HF2.read16(buf, 0) + 2)
|
||||||
|
// log("DATA: " + U.toHex(buf))
|
||||||
|
this.msgs.push(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private alloc(addSize: number, cmd: number, replyType = 1) {
|
||||||
|
let len = 6 + addSize
|
||||||
|
let buf = new Uint8Array(len)
|
||||||
|
HF2.write16(buf, 0, len - 2) // pktLen
|
||||||
|
HF2.write16(buf, 2, this.cmdSeq++) // msgCount
|
||||||
|
buf[4] = replyType
|
||||||
|
buf[5] = cmd
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (resp[5] != buf[5])
|
||||||
|
U.userError("cmd de-sync")
|
||||||
|
if (resp[6] != 0 && resp[6] != 8 /* EOF */)
|
||||||
|
U.userError("cmd error: " + resp[6])
|
||||||
|
return resp
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
flashAsync(path: string, file: Uint8Array) {
|
||||||
|
log(`write ${file.length} to ${path}`)
|
||||||
|
let begin = this.alloc(4 + path.length + 1, 0x92)
|
||||||
|
HF2.write32(begin, 6, file.length) // fileSize
|
||||||
|
U.memcpy(begin, 10, U.stringToUint8Array(path))
|
||||||
|
|
||||||
|
let loopAsync = (pos: number): Promise<void> => {
|
||||||
|
if (pos >= file.length) return Promise.resolve()
|
||||||
|
let size = file.length - pos
|
||||||
|
if (size > 1000) size = 1000
|
||||||
|
let upl = this.alloc(1 + size, 0x93, 0x1)
|
||||||
|
upl[6] = handle
|
||||||
|
U.memcpy(upl, 6 + 1, file, pos, size)
|
||||||
|
return this.talkAsync(upl)
|
||||||
|
.then(() => loopAsync(pos + size))
|
||||||
|
}
|
||||||
|
|
||||||
|
let handle = -1
|
||||||
|
return this.talkAsync(begin)
|
||||||
|
.then(resp => {
|
||||||
|
handle = resp[7]
|
||||||
|
return loopAsync(0)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
lsAsync(path: string): Promise<DirEntry[]> {
|
||||||
|
let lsReq = this.alloc(2 + path.length + 1, 0x99)
|
||||||
|
HF2.write16(lsReq, 6, 1024) // maxRead
|
||||||
|
U.memcpy(lsReq, 8, U.stringToUint8Array(path))
|
||||||
|
|
||||||
|
return this.talkAsync(lsReq)
|
||||||
|
.then(resp =>
|
||||||
|
U.uint8ArrayToString(resp.slice(12)).split(/\n/).map(s => {
|
||||||
|
if (!s) return null as DirEntry
|
||||||
|
let m = /^([A-F0-9]+) ([A-F0-9]+) ([^\/]*)$/.exec(s)
|
||||||
|
if (m)
|
||||||
|
return {
|
||||||
|
md5: m[1],
|
||||||
|
size: parseInt(m[2], 16),
|
||||||
|
name: m[3]
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return {
|
||||||
|
name: s.replace(/\/$/, "")
|
||||||
|
}
|
||||||
|
}).filter(v => !!v))
|
||||||
|
}
|
||||||
|
|
||||||
|
private initAsync() {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
private resetState() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
reconnectAsync(first = false): Promise<void> {
|
||||||
|
this.resetState()
|
||||||
|
if (first) return this.initAsync()
|
||||||
|
log(`reconnect`);
|
||||||
|
return this.io.reconnectAsync()
|
||||||
|
.then(() => this.initAsync())
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectAsync() {
|
||||||
|
log(`disconnect`);
|
||||||
|
return this.io.disconnectAsync()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -39,6 +39,11 @@
|
|||||||
"taggedInts": true,
|
"taggedInts": true,
|
||||||
"stackAlign": 2
|
"stackAlign": 2
|
||||||
},
|
},
|
||||||
|
"serial": {
|
||||||
|
"vendorId": "0x0694",
|
||||||
|
"productId": "0x0005",
|
||||||
|
"rawHID": true
|
||||||
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"mathBlocks": true,
|
"mathBlocks": true,
|
||||||
"loopsBlocks": true,
|
"loopsBlocks": true,
|
||||||
|
Loading…
Reference in New Issue
Block a user