in editor/flash.ts [492:580]
private quickHidFlashAsync(changed: ts.pxtc.UF2.Block[]): Promise<void> {
log("quick flash")
pxt.tickEvent("hid.flash.quick.start");
const runFlash = (b: ts.pxtc.UF2.Block, dataAddr: number) => {
const cmd = this.cortexM.prepareCommand();
cmd.halt();
cmd.writeCoreRegister(DapJS.CortexReg.PC, loadAddr + 4 + 1);
cmd.writeCoreRegister(DapJS.CortexReg.LR, loadAddr + 1);
cmd.writeCoreRegister(DapJS.CortexReg.SP, stackAddr);
cmd.writeCoreRegister(0, b.targetAddr);
cmd.writeCoreRegister(1, dataAddr);
cmd.writeCoreRegister(2, this.pageSize >> 2);
return Promise.resolve()
.then(() => {
logV("setregs")
return cmd.go()
})
.then(() => {
// starts the program
logV(`cortex.debug.enable`)
return this.cortexM.debug.enable()
})
}
return pxt.Util.promiseTimeout(
PARTIAL_FLASH_TIMEOUT,
Promise.resolve()
.then(() => this.cortexM.memory.writeBlock(loadAddr, flashPageBIN))
.then(() => pxt.Util.promiseMapAllSeries(pxt.U.range(changed.length),
i => {
this.checkAborted();
let b = changed[i];
if (b.targetAddr >= 0x10000000) {
log(`target address 0x${b.targetAddr.toString(16)} > 0x10000000`)
return Promise.resolve();
}
log(`about to write at 0x${b.targetAddr.toString(16)}`);
let writeBl = Promise.resolve();
let thisAddr = (i & 1) ? dataAddr : dataAddr + this.pageSize;
let nextAddr = (i & 1) ? dataAddr + this.pageSize : dataAddr;
if (i == 0) {
let u32data = new Uint32Array(b.data.length / 4);
for (let i = 0; i < b.data.length; i += 4)
u32data[i >> 2] = pxt.HF2.read32(b.data, i);
writeBl = this.cortexM.memory.writeBlock(thisAddr, u32data);
}
return writeBl
.then(() => runFlash(b, thisAddr))
.then(() => {
let next = changed[i + 1];
if (!next)
return Promise.resolve();
logV("write next");
let buf = new Uint32Array(next.data.buffer);
return this.cortexM.memory.writeBlock(nextAddr, buf);
})
.then(() => {
logV("wait");
return this.cortexM.waitForHalt(500);
})
.then(() => {
logV("done block");
});
}))
.then(() => {
log("quick flash done");
return this.cortexM.reset(false);
})
.then(() => {
pxt.tickEvent("hid.flash.quick.success");
return this.checkStateAsync(true)
}),
timeoutMessage
).catch((e) => {
pxt.tickEvent("hid.flash.quick.error");
this.flashAborted = true;
return this.resetAndThrowAsync(e);
});
}