Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ examples/
## this is generated by `npm pack`
*.tgz
package

dist/
vite.config.*
25 changes: 16 additions & 9 deletions lib/usb-device-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
*
* SPDX-License-Identifier: MIT
*/
import { CortexM, DAPLink, WebUSB } from "dapjs";
import * as dapjs from "dapjs";
// dapjs import faff needed for use from Node such as Vitest https://github.com/ARMmbed/dapjs/issues/118
import type { CortexM, DAPLink, WebUSB } from "dapjs";
const {
CortexM: CortexMValue,
DAPLink: DAPLinkValue,
WebUSB: WebUSBValue,
} = dapjs;
import { Logging } from "./logging.js";
import {
ApReg,
Expand Down Expand Up @@ -38,9 +45,9 @@ export class DAPWrapper {
public device: USBDevice,
private logging: Logging,
) {
this.transport = new WebUSB(this.device);
this.daplink = new DAPLink(this.transport);
this.cortexM = new CortexM(this.transport);
this.transport = new WebUSBValue(this.device);
this.daplink = new DAPLinkValue(this.transport);
this.cortexM = new CortexMValue(this.transport);
}

/**
Expand Down Expand Up @@ -82,9 +89,9 @@ export class DAPWrapper {
if (this.initialConnectionComplete) {
await this.disconnectAsync();

this.transport = new WebUSB(this.device);
this.daplink = new DAPLink(this.transport);
this.cortexM = new CortexM(this.transport);
this.transport = new WebUSBValue(this.device);
this.daplink = new DAPLinkValue(this.transport);
this.cortexM = new CortexMValue(this.transport);
} else {
this.initialConnectionComplete = true;
}
Expand Down Expand Up @@ -153,13 +160,13 @@ export class DAPWrapper {
// Changing the baud rate causes a micro:bit reset, so only do it if necessary
await this.daplink.setSerialBaudrate(115200);
}
this.daplink.addListener(DAPLink.EVENT_SERIAL_DATA, listener);
this.daplink.addListener(DAPLinkValue.EVENT_SERIAL_DATA, listener);
await this.daplink.startSerialRead(1);
}

stopSerial(listener: (data: string) => void): void {
this.daplink.stopSerialRead();
this.daplink.removeListener(DAPLink.EVENT_SERIAL_DATA, listener);
this.daplink.removeListener(DAPLinkValue.EVENT_SERIAL_DATA, listener);
}

async disconnectAsync(): Promise<void> {
Expand Down
40 changes: 16 additions & 24 deletions lib/usb-partial-flashing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@
* Latest Microsoft implementation is here:
* https://github.com/microsoft/pxt-microbit/blob/master/editor/flash.ts
*/
import { DAPLink } from "dapjs";

// dapjs import faff needed for Vitest https://github.com/ARMmbed/dapjs/issues/118
import * as dapjs from "dapjs";
const { DAPLink: DAPLinkValue } = dapjs;
import { Logging } from "./logging.js";
import { withTimeout, TimeoutError } from "./async-util.js";
import { DAPWrapper } from "./usb-device-wrapper.js";
Expand All @@ -55,8 +58,8 @@ import {
pageAlignBlocks,
read32FromUInt8Array,
} from "./usb-partial-flashing-utils.js";
import MemoryMap from "nrf-intel-hex";
import { BoardVersion } from "./device.js";
import MemoryMap from "nrf-intel-hex";

type ProgressCallback = (n: number, partial: boolean) => void;

Expand Down Expand Up @@ -205,7 +208,7 @@ export class PartialFlashing {
// Falls back to a full flash if partial flashing fails.
// Drawn from https://github.com/microsoft/pxt-microbit/blob/dec5b8ce72d5c2b4b0b20aafefce7474a6f0c7b2/editor/extension.tsx#L335
private async partialFlashAsync(
data: string | Uint8Array | MemoryMap.default,
data: string | Uint8Array | MemoryMap,
updateProgress: ProgressCallback,
): Promise<boolean> {
const flashBytes = this.convertDataToPaddedBytes(data);
Expand Down Expand Up @@ -251,15 +254,15 @@ export class PartialFlashing {

// Perform full flash of micro:bit's ROM using daplink.
async fullFlashAsync(
data: string | Uint8Array | MemoryMap.default,
data: string | Uint8Array | MemoryMap,
updateProgress: ProgressCallback,
) {
this.log("Full flash");

const fullFlashProgress = (progress: number) => {
updateProgress(progress, false);
};
this.dapwrapper.daplink.on(DAPLink.EVENT_PROGRESS, fullFlashProgress);
this.dapwrapper.daplink.on(DAPLinkValue.EVENT_PROGRESS, fullFlashProgress);
try {
data = this.convertDataToHexString(data);
await this.dapwrapper.transport.open();
Expand All @@ -270,7 +273,7 @@ export class PartialFlashing {
});
} finally {
this.dapwrapper.daplink.removeListener(
DAPLink.EVENT_PROGRESS,
DAPLinkValue.EVENT_PROGRESS,
fullFlashProgress,
);
}
Expand All @@ -279,7 +282,7 @@ export class PartialFlashing {
// Flash the micro:bit's ROM with the provided image, resetting the micro:bit first.
// Drawn from https://github.com/microsoft/pxt-microbit/blob/dec5b8ce72d5c2b4b0b20aafefce7474a6f0c7b2/editor/extension.tsx#L439
async flashAsync(
data: string | Uint8Array | MemoryMap.default,
data: string | Uint8Array | MemoryMap,
updateProgress: ProgressCallback,
): Promise<boolean> {
let resetPromise = (async () => {
Expand Down Expand Up @@ -321,7 +324,7 @@ export class PartialFlashing {
}

private convertDataToHexString(
data: string | Uint8Array | MemoryMap.default,
data: string | Uint8Array | MemoryMap,
): string {
if (typeof data === "string") {
return data;
Expand All @@ -333,7 +336,7 @@ export class PartialFlashing {
}

private convertDataToPaddedBytes(
data: string | Uint8Array | MemoryMap.default,
data: string | Uint8Array | MemoryMap,
): Uint8Array {
if (data instanceof Uint8Array) {
return data;
Expand All @@ -345,26 +348,15 @@ export class PartialFlashing {
}

private hexStringToPaddedBytes(hex: string): Uint8Array {
// Cludge for a packaging issue
const fromHex: (
hexText: string,
maxBlockSize?: number,
) => MemoryMap.default =
(MemoryMap as any).fromHex ?? MemoryMap.default.fromHex;

return this.memoryMapToPaddedBytes(fromHex(hex));
const m = MemoryMap.fromHex(hex);
return this.memoryMapToPaddedBytes(m);
}

private paddedBytesToHexString(data: Uint8Array): string {
// Cludge for a packaging issue
const fromPaddedUint8Array: (data: Uint8Array) => MemoryMap.default =
(MemoryMap as any).fromPaddedUint8Array ??
MemoryMap.default.fromPaddedUint8Array;

return fromPaddedUint8Array(data).asHexString();
return MemoryMap.fromPaddedUint8Array(data).asHexString();
}

private memoryMapToPaddedBytes(memoryMap: MemoryMap.default): Uint8Array {
private memoryMapToPaddedBytes(memoryMap: MemoryMap): Uint8Array {
const flashSize = {
V1: 256 * 1024,
V2: 512 * 1024,
Expand Down
Loading