Generate UF2 files when no HID available

This commit is contained in:
Michal Moskal 2017-07-25 11:48:02 +01:00
parent 00ec9c510f
commit 46b78a6b27
3 changed files with 70 additions and 18 deletions

View File

@ -1,6 +1,8 @@
/// <reference path="../node_modules/pxt-core/typings/globals/node/index.d.ts"/> /// <reference path="../node_modules/pxt-core/typings/globals/node/index.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtlib.d.ts" /> /// <reference path="../node_modules/pxt-core/built/pxtlib.d.ts" />
import * as fs from 'fs';
require("./editor") require("./editor")
declare namespace pxt.editor { declare namespace pxt.editor {
@ -9,4 +11,9 @@ declare namespace pxt.editor {
export function deployCoreAsync(resp: pxtc.CompileResult) { export function deployCoreAsync(resp: pxtc.CompileResult) {
return pxt.editor.deployCoreAsync(resp, process.env["PXT_SERIAL"] ? false : true) return pxt.editor.deployCoreAsync(resp, process.env["PXT_SERIAL"] ? false : true)
.then(() => {
fs.writeFileSync("built/full-" + pxtc.BINARY_UF2, resp.outfiles[pxtc.BINARY_UF2], {
encoding: "base64"
})
})
} }

View File

@ -7,6 +7,8 @@ namespace pxt {
eval("if (typeof process === 'object' && process + '' === '[object process]') pxt = global.pxt") eval("if (typeof process === 'object' && process + '' === '[object process]') pxt = global.pxt")
namespace pxt.editor { namespace pxt.editor {
import UF2 = pxtc.UF2;
// this comes from aux/pxt.lms // this comes from aux/pxt.lms
const rbfTemplate = ` const rbfTemplate = `
4c45474f580000006d000100000000001c000000000000000e000000821b038405018130813e8053 4c45474f580000006d000100000000001c000000000000000e000000821b038405018130813e8053
@ -22,12 +24,15 @@ namespace pxt.editor {
}) })
} }
let noHID = false
let initPromise: Promise<Ev3Wrapper> let initPromise: Promise<Ev3Wrapper>
function initAsync() { function initAsync() {
if (!initPromise) if (!initPromise)
initPromise = hf2Async() initPromise = hf2Async()
.catch(err => { .catch(err => {
initPromise = null initPromise = null
noHID = true
return Promise.reject(err) return Promise.reject(err)
}) })
return initPromise return initPromise
@ -35,34 +40,73 @@ namespace pxt.editor {
export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) { export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
let w: Ev3Wrapper let w: Ev3Wrapper
let elfPath = "../prjs/BrkProg_SAVE/binary.elf"
let rbfPath = "../prjs/BrkProg_SAVE/pxt0.rbf" let filename = resp.downloadFileBaseName
let fspath = "../prjs/BrkProg_SAVE/"
let elfPath = fspath + filename + ".elf"
let rbfPath = fspath + filename + ".rbf"
let rbfHex = rbfTemplate
.replace(/\s+/g, "")
.replace("XX", U.toHex(U.stringToUint8Array(elfPath)))
let rbfBIN = U.fromHex(rbfHex)
HF2.write16(rbfBIN, 4, rbfBIN.length)
let origElfUF2 = UF2.parseFile(U.stringToUint8Array(atob(resp.outfiles[pxt.outputName()])))
let mkFile = (ext: string, data: Uint8Array = null) => {
let f = UF2.newBlockFile()
f.filename = "Projects/" + filename + ext
if (data)
UF2.writeBytes(f, 0, data)
return f
}
let elfUF2 = mkFile(".elf")
for (let b of origElfUF2) {
UF2.writeBytes(elfUF2, b.targetAddr, b.data)
}
let r = UF2.concatFiles([elfUF2, mkFile(".rbf", rbfBIN)])
let data = UF2.serializeFile(r)
resp.outfiles[pxtc.BINARY_UF2] = btoa(data)
let saveUF2Async = () => {
if (isCli || !pxt.commands.saveOnlyAsync) {
return Promise.resolve()
} else {
return pxt.commands.saveOnlyAsync(resp)
}
}
if (noHID) return saveUF2Async()
return initAsync() return initAsync()
.then(w_ => { .then(w_ => {
w = w_ w = w_
if (w.isStreaming) if (w.isStreaming)
U.userError("please stop the program first") U.userError("please stop the program first")
return w.stopAsync() return w.stopAsync()
}).then(() => { })
return w.rmAsync(elfPath) .then(() => w.rmAsync(elfPath))
}).then(() => { .then(() => w.flashAsync(elfPath, UF2.readBytes(origElfUF2, 0, origElfUF2.length * 256)))
let f = U.stringToUint8Array(atob(resp.outfiles[pxt.outputName()])) .then(() => w.flashAsync(rbfPath, rbfBIN))
return w.flashAsync(elfPath, f) .then(() => w.runAsync(rbfPath))
}).then(() => { .then(() => {
let rbfHex = rbfTemplate
.replace(/\s+/g, "")
.replace("XX", U.toHex(U.stringToUint8Array(elfPath)))
let rbf = U.fromHex(rbfHex)
HF2.write16(rbf, 4, rbf.length)
return w.flashAsync(rbfPath, rbf)
}).then(() => {
return w.runAsync(rbfPath)
}).then(() => {
if (isCli) if (isCli)
return w.disconnectAsync() return w.disconnectAsync()
else else
return Promise.resolve() return Promise.resolve()
//return Promise.delay(1000).then(() => w.dmesgAsync()) //return Promise.delay(1000).then(() => w.dmesgAsync())
}).catch(e => {
// if we failed to initalize, retry
if (noHID)
return saveUF2Async()
else
return Promise.reject(e)
}) })
} }

View File

@ -33,6 +33,7 @@
}, },
"compile": { "compile": {
"isNative": true, "isNative": true,
"useUF2": true,
"useELF": true, "useELF": true,
"hasHex": true, "hasHex": true,
"deployDrives": ".*", "deployDrives": ".*",