pxt-microbit 4.1.37 → 4.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/built/editor.js +91 -59
- package/built/sim.d.ts +1 -0
- package/built/sim.js +4 -0
- package/built/target.js +555 -38
- package/built/target.json +555 -38
- package/built/targetlight.json +5 -5
- package/docs/reference/basic/pause.md +4 -0
- package/docs/reference/basic/show-number.md +4 -0
- package/package.json +3 -3
- package/targetconfig.json +73 -3
package/built/editor.js
CHANGED
|
@@ -3160,14 +3160,13 @@ function bufferConcat(a, b) {
|
|
|
3160
3160
|
class DAPWrapper {
|
|
3161
3161
|
constructor(io) {
|
|
3162
3162
|
this.io = io;
|
|
3163
|
-
this.flashing = false;
|
|
3164
3163
|
this.flashAborted = false;
|
|
3165
|
-
this.
|
|
3164
|
+
this.connectionId = 0;
|
|
3166
3165
|
this.pbuf = new pxt.U.PromiseBuffer();
|
|
3167
3166
|
this.pageSize = 1024;
|
|
3168
3167
|
this.numPages = 256;
|
|
3169
|
-
|
|
3170
|
-
this.jacdacInHex =
|
|
3168
|
+
// we don't know yet if jacdac was compiled in the hex
|
|
3169
|
+
this.jacdacInHex = undefined;
|
|
3171
3170
|
this.forceFullFlash = /webusbfullflash=1/.test(window.location.href);
|
|
3172
3171
|
this.onSerial = (buf, isStderr) => { };
|
|
3173
3172
|
this.onCustomEvent = (type, payload) => { };
|
|
@@ -3178,7 +3177,14 @@ class DAPWrapper {
|
|
|
3178
3177
|
this.io.onDeviceConnectionChanged = (connect) => {
|
|
3179
3178
|
log(`device connection changed`);
|
|
3180
3179
|
this.disconnectAsync()
|
|
3181
|
-
.then(() =>
|
|
3180
|
+
.then(() => {
|
|
3181
|
+
if (!connect)
|
|
3182
|
+
return;
|
|
3183
|
+
// we don't know what's being connected
|
|
3184
|
+
this.usesCODAL = undefined;
|
|
3185
|
+
this.jacdacInHex = undefined;
|
|
3186
|
+
this.reconnectAsync();
|
|
3187
|
+
});
|
|
3182
3188
|
};
|
|
3183
3189
|
this.io.onData = buf => {
|
|
3184
3190
|
// console.log("RD: " + pxt.Util.toHex(buf))
|
|
@@ -3186,9 +3192,6 @@ class DAPWrapper {
|
|
|
3186
3192
|
};
|
|
3187
3193
|
this.allocDAP();
|
|
3188
3194
|
}
|
|
3189
|
-
get useJACDAC() {
|
|
3190
|
-
return this.jacdacInHex && this.usesCODAL;
|
|
3191
|
-
}
|
|
3192
3195
|
processSerialLine(line) {
|
|
3193
3196
|
if (this.onSerial) {
|
|
3194
3197
|
try {
|
|
@@ -3243,12 +3246,12 @@ class DAPWrapper {
|
|
|
3243
3246
|
return len;
|
|
3244
3247
|
}
|
|
3245
3248
|
startReadSerial() {
|
|
3246
|
-
const rid = this.
|
|
3249
|
+
const rid = this.connectionId;
|
|
3247
3250
|
const startTime = Date.now();
|
|
3248
3251
|
log(`start read serial ${rid}`);
|
|
3249
3252
|
const readSerialLoop = async () => {
|
|
3250
3253
|
try {
|
|
3251
|
-
while (rid === this.
|
|
3254
|
+
while (rid === this.connectionId) {
|
|
3252
3255
|
const len = await this.readSerial();
|
|
3253
3256
|
const hasData = len > 0;
|
|
3254
3257
|
//if (hasData)
|
|
@@ -3260,7 +3263,7 @@ class DAPWrapper {
|
|
|
3260
3263
|
catch (err) {
|
|
3261
3264
|
log(`serial error ${rid}: ${err.message}`);
|
|
3262
3265
|
console.error(err);
|
|
3263
|
-
if (rid != this.
|
|
3266
|
+
if (rid != this.connectionId) {
|
|
3264
3267
|
log(`stopped serial reader ${rid}`);
|
|
3265
3268
|
}
|
|
3266
3269
|
else {
|
|
@@ -3277,9 +3280,9 @@ class DAPWrapper {
|
|
|
3277
3280
|
};
|
|
3278
3281
|
readSerialLoop();
|
|
3279
3282
|
}
|
|
3280
|
-
|
|
3281
|
-
log(`cancelling
|
|
3282
|
-
this.
|
|
3283
|
+
stopReadersAsync() {
|
|
3284
|
+
log(`cancelling connection ${this.connectionId}`);
|
|
3285
|
+
this.connectionId++;
|
|
3283
3286
|
return pxt.Util.delay(200);
|
|
3284
3287
|
}
|
|
3285
3288
|
allocDAP() {
|
|
@@ -3291,7 +3294,6 @@ class DAPWrapper {
|
|
|
3291
3294
|
read: () => this.recvPacketAsync(),
|
|
3292
3295
|
//sendMany: sendMany
|
|
3293
3296
|
});
|
|
3294
|
-
this.cmsisdap = this.dap.dap;
|
|
3295
3297
|
this.cortexM = new DapJS.CortexM(this.dap);
|
|
3296
3298
|
}
|
|
3297
3299
|
get binName() {
|
|
@@ -3309,7 +3311,7 @@ class DAPWrapper {
|
|
|
3309
3311
|
function stringResponse(buf) {
|
|
3310
3312
|
return pxt.U.uint8ArrayToString(buf.slice(2, 2 + buf[1]));
|
|
3311
3313
|
}
|
|
3312
|
-
await this.
|
|
3314
|
+
await this.stopReadersAsync();
|
|
3313
3315
|
this.allocDAP(); // clean dap apis
|
|
3314
3316
|
await this.io.reconnectAsync();
|
|
3315
3317
|
// before calling into dapjs, we use our dapCmdNums() a few times, which which will make sure the responses
|
|
@@ -3337,7 +3339,8 @@ class DAPWrapper {
|
|
|
3337
3339
|
this.numPages = res[1];
|
|
3338
3340
|
log(`page size ${this.pageSize}, num pages ${this.numPages}`);
|
|
3339
3341
|
await this.checkStateAsync(true);
|
|
3340
|
-
|
|
3342
|
+
// start jacdac, serial async
|
|
3343
|
+
this.startJacdacSetup();
|
|
3341
3344
|
this.startReadSerial();
|
|
3342
3345
|
}
|
|
3343
3346
|
async checkStateAsync(resume) {
|
|
@@ -3361,7 +3364,7 @@ class DAPWrapper {
|
|
|
3361
3364
|
disconnectAsync() {
|
|
3362
3365
|
log(`disconnect`);
|
|
3363
3366
|
this.flashAborted = true;
|
|
3364
|
-
return this.
|
|
3367
|
+
return this.stopReadersAsync()
|
|
3365
3368
|
.then(() => this.io.disconnectAsync());
|
|
3366
3369
|
}
|
|
3367
3370
|
reflashAsync(resp) {
|
|
@@ -3369,13 +3372,12 @@ class DAPWrapper {
|
|
|
3369
3372
|
pxt.tickEvent("hid.flash.start");
|
|
3370
3373
|
log("reflash");
|
|
3371
3374
|
startTime = 0;
|
|
3372
|
-
const codalJson = resp.outfiles["codal.json"];
|
|
3373
3375
|
// JACDAC_WEBUSB is defined in microsoft/pxt-jacdac/pxt.json
|
|
3376
|
+
const codalJson = resp.outfiles["codal.json"];
|
|
3374
3377
|
this.jacdacInHex = codalJson && !!((_b = (_a = pxt.Util.jsonTryParse(codalJson)) === null || _a === void 0 ? void 0 : _a.definitions) === null || _b === void 0 ? void 0 : _b.JACDAC_WEBUSB);
|
|
3375
3378
|
this.flashAborted = false;
|
|
3376
|
-
this.flashing = true;
|
|
3377
3379
|
return (this.io.isConnected() ? Promise.resolve() : this.io.reconnectAsync())
|
|
3378
|
-
.then(() => this.
|
|
3380
|
+
.then(() => this.stopReadersAsync())
|
|
3379
3381
|
.then(() => this.cortexM.init())
|
|
3380
3382
|
.then(() => this.cortexM.reset(true))
|
|
3381
3383
|
.then(() => this.checkStateAsync())
|
|
@@ -3399,8 +3401,7 @@ class DAPWrapper {
|
|
|
3399
3401
|
});
|
|
3400
3402
|
})
|
|
3401
3403
|
.then(() => this.checkStateAsync(true))
|
|
3402
|
-
.then(() => pxt.tickEvent("hid.flash.success"))
|
|
3403
|
-
.finally(() => { this.flashing = false; });
|
|
3404
|
+
.then(() => pxt.tickEvent("hid.flash.success"));
|
|
3404
3405
|
// don't disconnect here
|
|
3405
3406
|
// the micro:bit will automatically disconnect and reconnect
|
|
3406
3407
|
// via the webusb events
|
|
@@ -3691,7 +3692,7 @@ class DAPWrapper {
|
|
|
3691
3692
|
writeWord(addr, val) {
|
|
3692
3693
|
return this.cortexM.memory.write32(addr, val);
|
|
3693
3694
|
}
|
|
3694
|
-
async findJacdacXchgAddr() {
|
|
3695
|
+
async findJacdacXchgAddr(cid) {
|
|
3695
3696
|
const memStart = 536870912;
|
|
3696
3697
|
const memStop = memStart + 128 * 1024;
|
|
3697
3698
|
const checkSize = 1024;
|
|
@@ -3709,7 +3710,7 @@ class DAPWrapper {
|
|
|
3709
3710
|
}
|
|
3710
3711
|
return 0;
|
|
3711
3712
|
};
|
|
3712
|
-
while (
|
|
3713
|
+
while (cid == this.connectionId) {
|
|
3713
3714
|
const a0 = await check(p0);
|
|
3714
3715
|
if (a0)
|
|
3715
3716
|
return a0;
|
|
@@ -3721,46 +3722,77 @@ class DAPWrapper {
|
|
|
3721
3722
|
p0 -= checkSize;
|
|
3722
3723
|
p1 += checkSize;
|
|
3723
3724
|
}
|
|
3725
|
+
return null;
|
|
3724
3726
|
}
|
|
3725
|
-
|
|
3727
|
+
/**
|
|
3728
|
+
* Start trying to connect to Jacdac in the background
|
|
3729
|
+
* and gracefull cancel as needed
|
|
3730
|
+
* @returns
|
|
3731
|
+
*/
|
|
3732
|
+
async startJacdacSetup() {
|
|
3726
3733
|
this.xchgAddr = null;
|
|
3727
|
-
|
|
3728
|
-
|
|
3734
|
+
this.irqn = undefined;
|
|
3735
|
+
if (!this.usesCODAL) {
|
|
3736
|
+
log(`jacdac: CODAL disabled`);
|
|
3729
3737
|
return;
|
|
3730
3738
|
}
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
await pxt.Util.delay(1000);
|
|
3734
|
-
let xchgRetry = 0;
|
|
3735
|
-
let xchg;
|
|
3736
|
-
while (xchg == null && xchgRetry++ < 2) {
|
|
3737
|
-
log(`jacdac: finding xchg address (retry ${xchgRetry})`);
|
|
3738
|
-
await pxt.Util.delay(100); // wait for the program to start and setup memory correctly
|
|
3739
|
-
xchg = await this.findJacdacXchgAddr();
|
|
3740
|
-
}
|
|
3741
|
-
log(`jacdac: exchange address 0x${xchg ? xchg.toString(16) : "?"}; ${xchgRetry} retries; ${(pxt.U.now() - now) | 0}ms`);
|
|
3742
|
-
if (xchg == null) {
|
|
3743
|
-
log("jacdac: xchg address not found");
|
|
3744
|
-
pxt.tickEvent("hid.flash.jacdac.error.missingxchg");
|
|
3739
|
+
if (this.jacdacInHex === false) {
|
|
3740
|
+
log(`jacdac: jacdac not compiled in`);
|
|
3745
3741
|
return;
|
|
3746
3742
|
}
|
|
3747
|
-
const
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
pxt.
|
|
3752
|
-
|
|
3753
|
-
|
|
3743
|
+
const cid = this.connectionId;
|
|
3744
|
+
try {
|
|
3745
|
+
// allow jacdac to boot
|
|
3746
|
+
const now = pxt.U.now();
|
|
3747
|
+
await pxt.Util.delay(1000);
|
|
3748
|
+
let xchgRetry = 0;
|
|
3749
|
+
let xchg;
|
|
3750
|
+
while (xchg == null && xchgRetry++ < 2) {
|
|
3751
|
+
log(`jacdac: finding xchg address (retry ${xchgRetry})`);
|
|
3752
|
+
await pxt.Util.delay(100); // wait for the program to start and setup memory correctly
|
|
3753
|
+
if (cid != this.connectionId)
|
|
3754
|
+
return;
|
|
3755
|
+
xchg = await this.findJacdacXchgAddr(cid);
|
|
3756
|
+
}
|
|
3757
|
+
log(`jacdac: exchange address 0x${xchg ? xchg.toString(16) : "?"}; ${xchgRetry} retries; ${(pxt.U.now() - now) | 0}ms`);
|
|
3758
|
+
if (xchg == null) {
|
|
3759
|
+
log("jacdac: xchg address not found");
|
|
3760
|
+
this.jacdacInHex = false;
|
|
3761
|
+
pxt.tickEvent("hid.flash.jacdac.error.missingxchg");
|
|
3762
|
+
return;
|
|
3763
|
+
}
|
|
3764
|
+
if (cid != this.connectionId)
|
|
3765
|
+
return;
|
|
3766
|
+
const info = await this.readBytes(xchg, 16);
|
|
3767
|
+
if (info[12 + 2] != 0xff) {
|
|
3768
|
+
log("jacdac: invalid memory; try power-cycling the micro:bit");
|
|
3769
|
+
pxt.tickEvent("hid.flash.jacdac.error.invalidmemory");
|
|
3770
|
+
console.debug({ info, xchg });
|
|
3771
|
+
return;
|
|
3772
|
+
}
|
|
3773
|
+
// make sure connection is not outdated
|
|
3774
|
+
if (cid != this.connectionId)
|
|
3775
|
+
return;
|
|
3776
|
+
// clear initial lock
|
|
3777
|
+
await this.writeWord(xchg + 12, 0);
|
|
3778
|
+
// allow serial thread to use jacdac
|
|
3779
|
+
this.irqn = info[8];
|
|
3780
|
+
this.xchgAddr = xchg;
|
|
3781
|
+
log(`jacdac: exchange address 0x${this.xchgAddr.toString(16)}; irqn=${this.irqn}`);
|
|
3782
|
+
pxt.tickEvent("hid.flash.jacdac.connected");
|
|
3783
|
+
}
|
|
3784
|
+
catch (e) {
|
|
3785
|
+
if (cid != this.connectionId) {
|
|
3786
|
+
log(`jacdac: setup aborted`);
|
|
3787
|
+
return;
|
|
3788
|
+
}
|
|
3789
|
+
else
|
|
3790
|
+
throw e;
|
|
3754
3791
|
}
|
|
3755
|
-
this.xchgAddr = xchg;
|
|
3756
|
-
// clear initial lock
|
|
3757
|
-
await this.writeWord(xchg + 12, 0);
|
|
3758
|
-
log(`jacdac: exchange address 0x${xchg.toString(16)}; irqn=${this.irqn}`);
|
|
3759
|
-
pxt.tickEvent("hid.flash.jacdac.connected");
|
|
3760
3792
|
}
|
|
3761
|
-
async triggerIRQ(
|
|
3762
|
-
const addr = 0xE000E200 + (irqn >> 5) * 4;
|
|
3763
|
-
await this.writeWord(addr, 1 << (irqn & 31));
|
|
3793
|
+
async triggerIRQ() {
|
|
3794
|
+
const addr = 0xE000E200 + (this.irqn >> 5) * 4;
|
|
3795
|
+
await this.writeWord(addr, 1 << (this.irqn & 31));
|
|
3764
3796
|
}
|
|
3765
3797
|
async jacdacProcess(hadSerial) {
|
|
3766
3798
|
if (this.xchgAddr == null) {
|
|
@@ -3778,7 +3810,7 @@ class DAPWrapper {
|
|
|
3778
3810
|
let inp = await this.readBytes(this.xchgAddr + 12, 256);
|
|
3779
3811
|
if (inp[2]) {
|
|
3780
3812
|
await this.writeWord(this.xchgAddr + 12, 0);
|
|
3781
|
-
await this.triggerIRQ(
|
|
3813
|
+
await this.triggerIRQ();
|
|
3782
3814
|
inp = inp.slice(0, inp[2] + 12);
|
|
3783
3815
|
this.onCustomEvent("jacdac", inp);
|
|
3784
3816
|
numev++;
|
|
@@ -3805,7 +3837,7 @@ class DAPWrapper {
|
|
|
3805
3837
|
await this.writeWords(this.xchgAddr + 12 + 256 + 4, new Uint32Array(bbody.buffer));
|
|
3806
3838
|
const bhead = this.currSend.buf.slice(0, 4);
|
|
3807
3839
|
await this.writeWords(this.xchgAddr + 12 + 256, new Uint32Array(bhead.buffer));
|
|
3808
|
-
await this.triggerIRQ(
|
|
3840
|
+
await this.triggerIRQ();
|
|
3809
3841
|
this.lastSend = Date.now();
|
|
3810
3842
|
numev++;
|
|
3811
3843
|
}
|
package/built/sim.d.ts
CHANGED
|
@@ -585,6 +585,7 @@ declare namespace pxsim.serial {
|
|
|
585
585
|
function setTxBufferSize(size: number): void;
|
|
586
586
|
function readBuffer(length: number): RefBuffer;
|
|
587
587
|
function setBaudRate(rate: number): void;
|
|
588
|
+
function writeDmesg(): void;
|
|
588
589
|
}
|
|
589
590
|
declare namespace pxsim.music {
|
|
590
591
|
function __playSoundExpression(notes: string, waitTillDone: boolean): void;
|
package/built/sim.js
CHANGED
|
@@ -2359,6 +2359,10 @@ var pxsim;
|
|
|
2359
2359
|
// TODO
|
|
2360
2360
|
}
|
|
2361
2361
|
serial.setBaudRate = setBaudRate;
|
|
2362
|
+
function writeDmesg() {
|
|
2363
|
+
// TODO
|
|
2364
|
+
}
|
|
2365
|
+
serial.writeDmesg = writeDmesg;
|
|
2362
2366
|
})(serial = pxsim.serial || (pxsim.serial = {}));
|
|
2363
2367
|
})(pxsim || (pxsim = {}));
|
|
2364
2368
|
var pxsim;
|