private quickHidFlashAsync()

in editor/flash.ts [244:345]


    private quickHidFlashAsync(resp: pxtc.CompileResult): Promise<void> {
        log("quick flash")
        let logV = (msg: string) => { }
        //let logV = log
        let aborted = false;

        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(() => {
                    logV("dbg en")
                    // starts the program
                    return this.cortexM.debug.enable()
                })
        }

        let checksums: Uint8Array
        return this.getFlashChecksumsAsync()
            .then(buf => {
                checksums = buf;
                log("write code");
                return this.cortexM.memory.writeBlock(loadAddr, flashPageBIN);
            })
            .then(() => {
                log("convert");
                // TODO this is seriously inefficient (130ms on a fast machine)
                let uf2 = ts.pxtc.UF2.newBlockFile();
                ts.pxtc.UF2.writeHex(uf2, resp.outfiles[this.binName].split(/\r?\n/));
                let bytes = pxt.U.stringToUint8Array(ts.pxtc.UF2.serializeFile(uf2));
                let parsed = ts.pxtc.UF2.parseFile(bytes);

                let aligned = DAPWrapper.pageAlignBlocks(parsed, this.pageSize);
                log(`initial: ${aligned.length} pages`);
                aligned = DAPWrapper.onlyChanged(aligned, checksums, this.pageSize);
                log(`incremental: ${aligned.length} pages`);

                return Promise.mapSeries(pxt.U.range(aligned.length),
                    i => {
                        if (aborted) return Promise.resolve();
                        let b = aligned[i];
                        if (b.targetAddr >= 0x10000000)
                            return Promise.resolve();

                        logV("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 = aligned[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("flash done");
                        pxt.tickEvent("hid.flash.done");
                        return this.cortexM.reset(false);
                    });
            })
            .timeout(25000, timeoutMessage)
            .catch((e) => {
                aborted = true;
                return Promise.reject(e);
            });
    }