pxt-microbit 4.1.37 → 4.1.40
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/common-sim.d.ts +44 -0
- package/built/common-sim.js +139 -0
- package/built/editor.js +103 -90
- package/built/sim.d.ts +1 -0
- package/built/sim.js +4 -0
- package/built/target.js +712 -39
- package/built/target.json +712 -39
- 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/common-sim.d.ts
CHANGED
|
@@ -728,6 +728,50 @@ declare namespace pxsim {
|
|
|
728
728
|
}
|
|
729
729
|
declare namespace pxsim.info {
|
|
730
730
|
}
|
|
731
|
+
declare namespace pxsim.keymap {
|
|
732
|
+
enum Key {
|
|
733
|
+
None = 0,
|
|
734
|
+
Left = 1,
|
|
735
|
+
Up = 2,
|
|
736
|
+
Right = 3,
|
|
737
|
+
Down = 4,
|
|
738
|
+
A = 5,
|
|
739
|
+
B = 6,
|
|
740
|
+
Menu = 7,
|
|
741
|
+
Screenshot = -1,
|
|
742
|
+
Gif = -2,
|
|
743
|
+
Reset = -3,
|
|
744
|
+
TogglePause = -4
|
|
745
|
+
}
|
|
746
|
+
function _setPlayerKeys(player: number, // player number is 1-based
|
|
747
|
+
up: number, down: number, left: number, right: number, A: number, B: number): void;
|
|
748
|
+
function _setSystemKeys(screenshot: number, gif: number, menu: number, reset: number): void;
|
|
749
|
+
}
|
|
750
|
+
declare namespace pxsim {
|
|
751
|
+
import Key = pxsim.keymap.Key;
|
|
752
|
+
interface KeymapBoard extends EventBusBoard {
|
|
753
|
+
keymapState: KeymapState;
|
|
754
|
+
}
|
|
755
|
+
function getKeymapState(): KeymapState;
|
|
756
|
+
class KeymapState {
|
|
757
|
+
keymap: {
|
|
758
|
+
[keyCode: number]: Key;
|
|
759
|
+
};
|
|
760
|
+
altmap: {
|
|
761
|
+
[keyCode: number]: Key;
|
|
762
|
+
};
|
|
763
|
+
mappings: {
|
|
764
|
+
[name: string]: number[];
|
|
765
|
+
};
|
|
766
|
+
constructor();
|
|
767
|
+
setPlayerKeys(player: number, // player number is 1-based
|
|
768
|
+
up: number, down: number, left: number, right: number, A: number, B: number): void;
|
|
769
|
+
setSystemKeys(screenshot: number, gif: number, menu: number, reset: number): void;
|
|
770
|
+
getKey(keyCode: number): Key;
|
|
771
|
+
private saveMap;
|
|
772
|
+
private clearMap;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
731
775
|
declare namespace pxsim.multiplayer {
|
|
732
776
|
function postImage(im: pxsim.RefImage, goal: string): void;
|
|
733
777
|
function getCurrentImage(): pxsim.RefImage;
|
package/built/common-sim.js
CHANGED
|
@@ -2395,6 +2395,145 @@ var pxsim;
|
|
|
2395
2395
|
pxsim.ToggleState = ToggleState;
|
|
2396
2396
|
})(pxsim || (pxsim = {}));
|
|
2397
2397
|
var pxsim;
|
|
2398
|
+
(function (pxsim) {
|
|
2399
|
+
var keymap;
|
|
2400
|
+
(function (keymap) {
|
|
2401
|
+
// Keep in sync with pxt-arcade-sim/api.ts
|
|
2402
|
+
let Key;
|
|
2403
|
+
(function (Key) {
|
|
2404
|
+
Key[Key["None"] = 0] = "None";
|
|
2405
|
+
// Player 1
|
|
2406
|
+
Key[Key["Left"] = 1] = "Left";
|
|
2407
|
+
Key[Key["Up"] = 2] = "Up";
|
|
2408
|
+
Key[Key["Right"] = 3] = "Right";
|
|
2409
|
+
Key[Key["Down"] = 4] = "Down";
|
|
2410
|
+
Key[Key["A"] = 5] = "A";
|
|
2411
|
+
Key[Key["B"] = 6] = "B";
|
|
2412
|
+
Key[Key["Menu"] = 7] = "Menu";
|
|
2413
|
+
// Player 2 = Player 1 + 7
|
|
2414
|
+
// Player 3 = Player 2 + 7
|
|
2415
|
+
// Player 4 = Player 3 + 7
|
|
2416
|
+
// system keys
|
|
2417
|
+
Key[Key["Screenshot"] = -1] = "Screenshot";
|
|
2418
|
+
Key[Key["Gif"] = -2] = "Gif";
|
|
2419
|
+
Key[Key["Reset"] = -3] = "Reset";
|
|
2420
|
+
Key[Key["TogglePause"] = -4] = "TogglePause";
|
|
2421
|
+
})(Key = keymap.Key || (keymap.Key = {}));
|
|
2422
|
+
function _setPlayerKeys(player, // player number is 1-based
|
|
2423
|
+
up, down, left, right, A, B) {
|
|
2424
|
+
pxsim.getKeymapState().setPlayerKeys(player, up, down, left, right, A, B);
|
|
2425
|
+
}
|
|
2426
|
+
keymap._setPlayerKeys = _setPlayerKeys;
|
|
2427
|
+
function _setSystemKeys(screenshot, gif, menu, reset) {
|
|
2428
|
+
pxsim.getKeymapState().setSystemKeys(screenshot, gif, menu, reset);
|
|
2429
|
+
}
|
|
2430
|
+
keymap._setSystemKeys = _setSystemKeys;
|
|
2431
|
+
})(keymap = pxsim.keymap || (pxsim.keymap = {}));
|
|
2432
|
+
})(pxsim || (pxsim = {}));
|
|
2433
|
+
(function (pxsim) {
|
|
2434
|
+
var Key = pxsim.keymap.Key;
|
|
2435
|
+
function getKeymapState() {
|
|
2436
|
+
return pxsim.board().keymapState;
|
|
2437
|
+
}
|
|
2438
|
+
pxsim.getKeymapState = getKeymapState;
|
|
2439
|
+
const reservedKeyCodes = [
|
|
2440
|
+
27,
|
|
2441
|
+
9 // Tab
|
|
2442
|
+
];
|
|
2443
|
+
class KeymapState {
|
|
2444
|
+
constructor() {
|
|
2445
|
+
this.keymap = {};
|
|
2446
|
+
this.altmap = {};
|
|
2447
|
+
this.mappings = {};
|
|
2448
|
+
// Player 1 keymap
|
|
2449
|
+
this.setPlayerKeys(1, // Player 1
|
|
2450
|
+
87, // W - Up
|
|
2451
|
+
83, // D - Down
|
|
2452
|
+
65, // A - Left
|
|
2453
|
+
83, // S - Right
|
|
2454
|
+
32, // Space - A
|
|
2455
|
+
13 // Enter - B
|
|
2456
|
+
);
|
|
2457
|
+
// Player 2 keymap
|
|
2458
|
+
this.setPlayerKeys(2, // Player 2
|
|
2459
|
+
73, // I - Up
|
|
2460
|
+
75, // K - Down
|
|
2461
|
+
74, // J - Left
|
|
2462
|
+
75, // K - Right
|
|
2463
|
+
85, // U - A
|
|
2464
|
+
79 // O - B
|
|
2465
|
+
);
|
|
2466
|
+
// Note: Player 3 and 4 have no default keyboard mapping
|
|
2467
|
+
// System keymap
|
|
2468
|
+
this.setSystemKeys(80, // P - Screenshot
|
|
2469
|
+
82, // R - Gif
|
|
2470
|
+
0, // Menu - not mapped
|
|
2471
|
+
0 // Reset - not mapped
|
|
2472
|
+
);
|
|
2473
|
+
// Player 1 alternate mapping. This is cleared when the game sets any player keys explicitly
|
|
2474
|
+
this.altmap[38] = Key.Up; // UpArrow
|
|
2475
|
+
this.altmap[37] = Key.Left; // LeftArrow
|
|
2476
|
+
this.altmap[40] = Key.Down; // DownArrow
|
|
2477
|
+
this.altmap[39] = Key.Right; // RightArrow
|
|
2478
|
+
this.altmap[81] = Key.A; // Q
|
|
2479
|
+
this.altmap[90] = Key.A; // Z
|
|
2480
|
+
this.altmap[88] = Key.B; // X
|
|
2481
|
+
this.altmap[69] = Key.B; // E
|
|
2482
|
+
}
|
|
2483
|
+
setPlayerKeys(player, // player number is 1-based
|
|
2484
|
+
up, down, left, right, A, B) {
|
|
2485
|
+
// We only support four players
|
|
2486
|
+
if (player < 1 || player > 4)
|
|
2487
|
+
return;
|
|
2488
|
+
const keyCodes = [up, down, left, right, A, B];
|
|
2489
|
+
// Check for reserved key codes
|
|
2490
|
+
// TODO: How to surface this runtime error to the user?
|
|
2491
|
+
// TODO: Send message to UI: "Keyboard mapping contains a reserved key code"
|
|
2492
|
+
const filtered = keyCodes.filter(keyCode => reservedKeyCodes.includes(keyCode));
|
|
2493
|
+
if (filtered.length)
|
|
2494
|
+
return;
|
|
2495
|
+
// Clear existing mapped keys for player
|
|
2496
|
+
const mapName = `player-${player}`;
|
|
2497
|
+
this.clearMap(mapName);
|
|
2498
|
+
// Clear altmap When explicitly setting the player keys
|
|
2499
|
+
this.altmap = {};
|
|
2500
|
+
// Map the new keys
|
|
2501
|
+
const offset = (player - 1) * 7; // +7 for player 2's keys
|
|
2502
|
+
this.keymap[up] = Key.Up + offset;
|
|
2503
|
+
this.keymap[down] = Key.Down + offset;
|
|
2504
|
+
this.keymap[left] = Key.Left + offset;
|
|
2505
|
+
this.keymap[right] = Key.Right + offset;
|
|
2506
|
+
this.keymap[A] = Key.A + offset;
|
|
2507
|
+
this.keymap[B] = Key.B + offset;
|
|
2508
|
+
// Remember this mapping
|
|
2509
|
+
this.saveMap(mapName, keyCodes);
|
|
2510
|
+
}
|
|
2511
|
+
setSystemKeys(screenshot, gif, menu, reset) {
|
|
2512
|
+
const mapName = "system";
|
|
2513
|
+
// Clear existing mapped keys for system
|
|
2514
|
+
this.clearMap(mapName);
|
|
2515
|
+
this.keymap[screenshot] = Key.Screenshot;
|
|
2516
|
+
this.keymap[gif] = Key.Gif;
|
|
2517
|
+
this.keymap[menu] = Key.Menu;
|
|
2518
|
+
this.keymap[reset] = Key.Reset;
|
|
2519
|
+
// Remember this mapping
|
|
2520
|
+
this.saveMap(mapName, [screenshot, gif, menu, reset]);
|
|
2521
|
+
}
|
|
2522
|
+
getKey(keyCode) {
|
|
2523
|
+
return keyCode ? this.keymap[keyCode] || this.altmap[keyCode] || Key.None : Key.None;
|
|
2524
|
+
}
|
|
2525
|
+
saveMap(name, keyCodes) {
|
|
2526
|
+
this.mappings[name] = keyCodes;
|
|
2527
|
+
}
|
|
2528
|
+
clearMap(name) {
|
|
2529
|
+
const keyCodes = this.mappings[name];
|
|
2530
|
+
keyCodes === null || keyCodes === void 0 ? void 0 : keyCodes.forEach(keyCode => delete this.keymap[keyCode]);
|
|
2531
|
+
delete this.mappings[name];
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
pxsim.KeymapState = KeymapState;
|
|
2535
|
+
})(pxsim || (pxsim = {}));
|
|
2536
|
+
var pxsim;
|
|
2398
2537
|
(function (pxsim) {
|
|
2399
2538
|
var multiplayer;
|
|
2400
2539
|
(function (multiplayer) {
|
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 {
|
|
@@ -3242,26 +3245,25 @@ class DAPWrapper {
|
|
|
3242
3245
|
}
|
|
3243
3246
|
return len;
|
|
3244
3247
|
}
|
|
3245
|
-
startReadSerial() {
|
|
3246
|
-
const rid = this.readSerialId;
|
|
3248
|
+
startReadSerial(connectionId) {
|
|
3247
3249
|
const startTime = Date.now();
|
|
3248
|
-
log(`start read serial ${
|
|
3250
|
+
log(`start read serial ${connectionId}`);
|
|
3249
3251
|
const readSerialLoop = async () => {
|
|
3250
3252
|
try {
|
|
3251
|
-
while (
|
|
3253
|
+
while (connectionId === this.connectionId) {
|
|
3252
3254
|
const len = await this.readSerial();
|
|
3253
3255
|
const hasData = len > 0;
|
|
3254
3256
|
//if (hasData)
|
|
3255
3257
|
// logV(`serial read ${len} bytes`)
|
|
3256
3258
|
await this.jacdacProcess(hasData);
|
|
3257
3259
|
}
|
|
3258
|
-
log(`stopped serial reader ${
|
|
3260
|
+
log(`stopped serial reader ${connectionId}`);
|
|
3259
3261
|
}
|
|
3260
3262
|
catch (err) {
|
|
3261
|
-
log(`serial error ${
|
|
3263
|
+
log(`serial error ${connectionId}: ${err.message}`);
|
|
3262
3264
|
console.error(err);
|
|
3263
|
-
if (
|
|
3264
|
-
log(`stopped serial reader ${
|
|
3265
|
+
if (connectionId != this.connectionId) {
|
|
3266
|
+
log(`stopped serial reader ${connectionId}`);
|
|
3265
3267
|
}
|
|
3266
3268
|
else {
|
|
3267
3269
|
pxt.tickEvent("hid.flash.serial.error");
|
|
@@ -3277,9 +3279,9 @@ class DAPWrapper {
|
|
|
3277
3279
|
};
|
|
3278
3280
|
readSerialLoop();
|
|
3279
3281
|
}
|
|
3280
|
-
|
|
3281
|
-
log(`cancelling
|
|
3282
|
-
this.
|
|
3282
|
+
stopReadersAsync() {
|
|
3283
|
+
log(`cancelling connection ${this.connectionId}`);
|
|
3284
|
+
this.connectionId++;
|
|
3283
3285
|
return pxt.Util.delay(200);
|
|
3284
3286
|
}
|
|
3285
3287
|
allocDAP() {
|
|
@@ -3291,7 +3293,6 @@ class DAPWrapper {
|
|
|
3291
3293
|
read: () => this.recvPacketAsync(),
|
|
3292
3294
|
//sendMany: sendMany
|
|
3293
3295
|
});
|
|
3294
|
-
this.cmsisdap = this.dap.dap;
|
|
3295
3296
|
this.cortexM = new DapJS.CortexM(this.dap);
|
|
3296
3297
|
}
|
|
3297
3298
|
get binName() {
|
|
@@ -3309,7 +3310,7 @@ class DAPWrapper {
|
|
|
3309
3310
|
function stringResponse(buf) {
|
|
3310
3311
|
return pxt.U.uint8ArrayToString(buf.slice(2, 2 + buf[1]));
|
|
3311
3312
|
}
|
|
3312
|
-
await this.
|
|
3313
|
+
await this.stopReadersAsync();
|
|
3313
3314
|
this.allocDAP(); // clean dap apis
|
|
3314
3315
|
await this.io.reconnectAsync();
|
|
3315
3316
|
// before calling into dapjs, we use our dapCmdNums() a few times, which which will make sure the responses
|
|
@@ -3337,8 +3338,10 @@ class DAPWrapper {
|
|
|
3337
3338
|
this.numPages = res[1];
|
|
3338
3339
|
log(`page size ${this.pageSize}, num pages ${this.numPages}`);
|
|
3339
3340
|
await this.checkStateAsync(true);
|
|
3340
|
-
|
|
3341
|
-
this.
|
|
3341
|
+
// start jacdac, serial async
|
|
3342
|
+
const connectionId = this.connectionId;
|
|
3343
|
+
this.startJacdacSetup(connectionId)
|
|
3344
|
+
.then(() => this.startReadSerial(connectionId));
|
|
3342
3345
|
}
|
|
3343
3346
|
async checkStateAsync(resume) {
|
|
3344
3347
|
const states = ["reset", "lockup", "sleeping", "halted", "running"];
|
|
@@ -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,76 +3692,88 @@ 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
|
-
const
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
return null;
|
|
3705
|
-
const buf = await this.readWords(addr, checkSize >> 2);
|
|
3706
|
-
for (let i = 0; i < buf.length; ++i) {
|
|
3707
|
-
if (buf[i] == 0x786D444A && buf[i + 1] == 0xB0A6C0E9)
|
|
3708
|
-
return addr + (i << 2);
|
|
3709
|
-
}
|
|
3710
|
-
return 0;
|
|
3711
|
-
};
|
|
3712
|
-
while (true) {
|
|
3713
|
-
const a0 = await check(p0);
|
|
3714
|
-
if (a0)
|
|
3715
|
-
return a0;
|
|
3716
|
-
const a1 = await check(p1);
|
|
3717
|
-
if (a1)
|
|
3718
|
-
return a1;
|
|
3719
|
-
if (a0 === null && a1 === null)
|
|
3720
|
-
return null;
|
|
3721
|
-
p0 -= checkSize;
|
|
3722
|
-
p1 += checkSize;
|
|
3698
|
+
const addr = (await this.readWords(memStop - 4, 1))[0];
|
|
3699
|
+
if (cid != this.connectionId)
|
|
3700
|
+
return null;
|
|
3701
|
+
if (memStart <= addr && addr < memStop) {
|
|
3702
|
+
const buf = await this.readWords(addr, 2);
|
|
3703
|
+
if (buf[0] == 0x786D444A && buf[1] == 0xB0A6C0E9)
|
|
3704
|
+
return addr;
|
|
3723
3705
|
}
|
|
3706
|
+
return null;
|
|
3724
3707
|
}
|
|
3725
|
-
|
|
3708
|
+
/**
|
|
3709
|
+
* Start trying to connect to Jacdac in the background
|
|
3710
|
+
* and gracefull cancel as needed
|
|
3711
|
+
* @returns
|
|
3712
|
+
*/
|
|
3713
|
+
async startJacdacSetup(connectionId) {
|
|
3726
3714
|
this.xchgAddr = null;
|
|
3727
|
-
|
|
3728
|
-
|
|
3715
|
+
this.irqn = undefined;
|
|
3716
|
+
this.lastXchg = undefined;
|
|
3717
|
+
if (!this.usesCODAL) {
|
|
3718
|
+
log(`jacdac: CODAL disabled`);
|
|
3729
3719
|
return;
|
|
3730
3720
|
}
|
|
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");
|
|
3721
|
+
if (this.jacdacInHex === false) {
|
|
3722
|
+
log(`jacdac: jacdac not compiled in`);
|
|
3745
3723
|
return;
|
|
3746
3724
|
}
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3725
|
+
try {
|
|
3726
|
+
// allow jacdac to boot
|
|
3727
|
+
const now = pxt.U.now();
|
|
3728
|
+
await pxt.Util.delay(1000);
|
|
3729
|
+
let xchgRetry = 0;
|
|
3730
|
+
let xchg;
|
|
3731
|
+
while (xchg == null && xchgRetry++ < 3) {
|
|
3732
|
+
log(`jacdac: finding xchg address (retry ${xchgRetry})`);
|
|
3733
|
+
await pxt.Util.delay(500); // wait for the program to start and setup memory correctly
|
|
3734
|
+
if (connectionId != this.connectionId)
|
|
3735
|
+
return;
|
|
3736
|
+
xchg = await this.findJacdacXchgAddr(connectionId);
|
|
3737
|
+
}
|
|
3738
|
+
log(`jacdac: exchange address 0x${xchg ? xchg.toString(16) : "?"}; ${xchgRetry} retries; ${(pxt.U.now() - now) | 0}ms`);
|
|
3739
|
+
if (xchg == null) {
|
|
3740
|
+
log("jacdac: xchg address not found");
|
|
3741
|
+
this.jacdacInHex = false;
|
|
3742
|
+
pxt.tickEvent("hid.flash.jacdac.error.missingxchg");
|
|
3743
|
+
return;
|
|
3744
|
+
}
|
|
3745
|
+
if (connectionId != this.connectionId)
|
|
3746
|
+
return;
|
|
3747
|
+
const info = await this.readBytes(xchg, 16);
|
|
3748
|
+
if (info[12 + 2] != 0xff) {
|
|
3749
|
+
log("jacdac: invalid memory; try power-cycling the micro:bit");
|
|
3750
|
+
pxt.tickEvent("hid.flash.jacdac.error.invalidmemory");
|
|
3751
|
+
console.debug({ info, xchg });
|
|
3752
|
+
return;
|
|
3753
|
+
}
|
|
3754
|
+
// make sure connection is not outdated
|
|
3755
|
+
if (connectionId != this.connectionId)
|
|
3756
|
+
return;
|
|
3757
|
+
// clear initial lock
|
|
3758
|
+
await this.writeWord(xchg + 12, 0);
|
|
3759
|
+
// allow serial thread to use jacdac
|
|
3760
|
+
this.irqn = info[8];
|
|
3761
|
+
this.xchgAddr = xchg;
|
|
3762
|
+
log(`jacdac: exchange address 0x${this.xchgAddr.toString(16)}; irqn=${this.irqn}`);
|
|
3763
|
+
pxt.tickEvent("hid.flash.jacdac.connected");
|
|
3764
|
+
}
|
|
3765
|
+
catch (e) {
|
|
3766
|
+
if (connectionId != this.connectionId) {
|
|
3767
|
+
log(`jacdac: setup aborted`);
|
|
3768
|
+
return;
|
|
3769
|
+
}
|
|
3770
|
+
else
|
|
3771
|
+
throw e;
|
|
3754
3772
|
}
|
|
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
3773
|
}
|
|
3761
|
-
async triggerIRQ(
|
|
3762
|
-
const addr = 0xE000E200 + (irqn >> 5) * 4;
|
|
3763
|
-
await this.writeWord(addr, 1 << (irqn & 31));
|
|
3774
|
+
async triggerIRQ() {
|
|
3775
|
+
const addr = 0xE000E200 + (this.irqn >> 5) * 4;
|
|
3776
|
+
await this.writeWord(addr, 1 << (this.irqn & 31));
|
|
3764
3777
|
}
|
|
3765
3778
|
async jacdacProcess(hadSerial) {
|
|
3766
3779
|
if (this.xchgAddr == null) {
|
|
@@ -3778,7 +3791,7 @@ class DAPWrapper {
|
|
|
3778
3791
|
let inp = await this.readBytes(this.xchgAddr + 12, 256);
|
|
3779
3792
|
if (inp[2]) {
|
|
3780
3793
|
await this.writeWord(this.xchgAddr + 12, 0);
|
|
3781
|
-
await this.triggerIRQ(
|
|
3794
|
+
await this.triggerIRQ();
|
|
3782
3795
|
inp = inp.slice(0, inp[2] + 12);
|
|
3783
3796
|
this.onCustomEvent("jacdac", inp);
|
|
3784
3797
|
numev++;
|
|
@@ -3805,7 +3818,7 @@ class DAPWrapper {
|
|
|
3805
3818
|
await this.writeWords(this.xchgAddr + 12 + 256 + 4, new Uint32Array(bbody.buffer));
|
|
3806
3819
|
const bhead = this.currSend.buf.slice(0, 4);
|
|
3807
3820
|
await this.writeWords(this.xchgAddr + 12 + 256, new Uint32Array(bhead.buffer));
|
|
3808
|
-
await this.triggerIRQ(
|
|
3821
|
+
await this.triggerIRQ();
|
|
3809
3822
|
this.lastSend = Date.now();
|
|
3810
3823
|
numev++;
|
|
3811
3824
|
}
|
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;
|