/** * (c) 2026, Micro:bit Educational Foundation and contributors * * Derived from dapjs (https://github.com/ARMmbed/dapjs) which is * Copyright (c) Arm Limited 2018 * Copyright (c) Microsoft Corporation * * SPDX-License-Identifier: MIT * * CMSIS-DAP protocol layer. CmsisDapUsb handles the framing and validation of * CMSIS-DAP commands over USB. It sits between UsbTransport (raw packet I/O) * and ArmDebugSwd (SWD register access). Its responsibilities are: * * - Serialising all DAP commands through a single queue so concurrent * callers (serial polling, flash writes, SWD reads) don't interleave. * - Framing DAP_TRANSFER / DAP_TRANSFER_BLOCK requests and parsing their * responses, including structured error reporting. * - Providing named wrappers for the low-level DAP commands used during * SWD initialisation (SWJ_SEQUENCE, SWJ_CLOCK, etc.). * - Draining stale USB responses left over from a previous session. * * Protocol references: * - CMSIS-DAP: https://www.keil.com/pack/doc/CMSIS/DAP/html/group__DAP__Commands__gr.html * - ARM ADI: https://developer.arm.com/documentation/ihi0031/a/ */ import { DeviceError } from "../device.js"; import { Logging } from "../logging.js"; import { type Transport } from "./transport.js"; export declare const DP = 0; export declare const AP = 1; export declare const READ = 2; export declare const WRITE = 0; export declare const ABORT_ALL: number; export interface DapOperation { port: number; mode: number; register: number; value?: number; } /** * Base error for CMSIS-DAP protocol failures. * Extends DeviceError so existing catch blocks continue to work. */ export declare class DapError extends DeviceError { constructor(message: string); } /** * The response command byte didn't match the request. * This can indicate stale responses in the USB buffer from a previous * interrupted session, or a protocol-level error. */ export declare class DapResponseMismatchError extends DapError { constructor(expected: number, actual: number); } /** * DAP transfer or block transfer failed with a non-OK response. */ export declare class DapTransferError extends DapError { readonly response: number; readonly completedOps: number; readonly totalOps: number; constructor(response: number, completedOps: number, totalOps: number, prefix?: string); } export interface CmsisDap { readonly isOpen: boolean; readonly blockSize: number; /** Send a CMSIS-DAP command and validate the response. */ send(command: number, data?: Uint8Array): Promise; clearAbort(): Promise; swjSequence(data: Uint8Array): Promise; swjClock(frequency: number): Promise; connect(): Promise; disconnect(): Promise; configureTransfer(idleCycles: number, waitRetry: number, matchRetry: number): Promise; open(): Promise; close(): Promise; /** * Execute a batch of DAP transfer operations (DAP_TRANSFER command). * Returns the values read (one per READ operation in the batch). */ transfer(operations: DapOperation[]): Promise; /** Read a block of 32-bit values from a single register (DAP_TRANSFER_BLOCK). */ transferBlockRead(port: number, register: number, count: number): Promise; /** Write a block of 32-bit values to a single register (DAP_TRANSFER_BLOCK). */ transferBlockWrite(port: number, register: number, values: Uint32Array): Promise; /** * Drain stale responses from the USB buffer. * Sends probe commands and reads until the response matches, * discarding any stale responses from interrupted operations. */ drainStaleResponses(): Promise; } export declare class CmsisDapUsb implements CmsisDap { private transport; private logging; readonly blockSize: number; private sendQueue; constructor(transport: Transport, logging: Logging); get isOpen(): boolean; send(command: number, data?: Uint8Array): Promise; clearAbort(): Promise; swjSequence(data: Uint8Array): Promise; swjClock(frequency: number): Promise; connect(): Promise; disconnect(): Promise; configureTransfer(idleCycles: number, waitRetry: number, matchRetry: number): Promise; open(): Promise; close(): Promise; transfer(operations: DapOperation[]): Promise; transferBlockRead(port: number, register: number, count: number): Promise; transferBlockWrite(port: number, register: number, values: Uint32Array): Promise; drainStaleResponses(): Promise; }