DAPLinkV1 Device Stack
This document describes XRUSB’s CMSIS-DAP v1 (HID) device-class implementation: LibXR::USB::DapLinkV1Class<SwdPort>.
This class targets CMSIS-DAP v1 host toolchains that still use HID Report transport. Current mainline focuses on SWD, supports common DAP core commands, SWJ/SWD control sequences, and optional nRESET GPIO control.
Supported capabilities:
- CMSIS-DAP v1 HID transport
- SWD-only (
DAP_Connectsupports SWD only; JTAG is not implemented) - Optional nRESET control (inject via
GPIO* nreset_gpio) - HID IN/OUT + Feature Report transport path
- DAP_Transfer / DAP_TransferBlock (including AP posted-read pipeline)
1. Class and Construction
1.1 LibXR::USB::DapLinkV1Class<SwdPort>
This is a template class. The template parameter SwdPort provides the underlying SWD capability.
Constructor:
template <typename SwdPort>
explicit DapLinkV1Class(
SwdPort& swd_link,
LibXR::GPIO* nreset_gpio = nullptr,
Endpoint::EPNumber in_ep_num = Endpoint::EPNumber::EP_AUTO,
Endpoint::EPNumber out_ep_num = Endpoint::EPNumber::EP_AUTO);
Parameters:
swd_link: SWD link object referencenreset_gpio: optional nRESET GPIOin_ep_num/out_ep_num: HID IN/OUT endpoint numbers; auto allocation is supported
Common APIs:
SetInfoStrings(info): overrideDAP_InfostringsGetState(): read internal DAP stateIsInited(): whether bind/initialization has completed
1.2 InfoStrings
DAP_Info string set:
struct InfoStrings
{
const char* vendor;
const char* product;
const char* serial;
const char* firmware_ver;
const char* device_vendor;
const char* device_name;
const char* board_vendor;
const char* board_name;
const char* product_fw_ver;
};
2. Transport Model and HID Reports
DapLinkV1Class inherits from:
HID<sizeof(DAPLINK_V1_REPORT_DESC), DapLinkV1Def::MAX_REQUEST_SIZE,
DapLinkV1Def::MAX_RESPONSE_SIZE>
Current mainline constants:
MAX_REQUEST_SIZE = 64MAX_RESPONSE_SIZE = 64PACKET_COUNT_ADVERTISED = 1
The HID report descriptor defines:
- a 64-byte Input Report
- a 64-byte Output Report
- a 64-byte Feature Report
So this class uses HID report transport, not the Bulk transport model used by DAPLinkV2.
3. Lifecycle: Bind / Unbind
3.1 Bind
The bind stage mainly does the following:
- calls the HID base bind path and allocates IN/OUT endpoints
- initializes DAP runtime state:
debug_port = DISABLEDtransfer_abort = falseswj_clock_hz = 1MHz- default SWJ shadow: SWDIO=1, nRESET=1, SWCLK=0
- arms OUT reception to process host HID Output Reports
3.2 Unbind
The unbind stage mainly does the following:
- closes the SWD backend
- releases HID IN/OUT endpoints
- clears response-queue and shadow state
4. Key DAP_Info Fields
Current implementation behavior for key DAP_Info fields:
CAPABILITIES:DAP_CAP_SWDPACKET_COUNT:1PACKET_SIZE:64TIMESTAMP_CLOCK:1,000,000
Notes:
PACKET_SIZEmatches the fixed 64-byte HID v1 report size- unlike DAPLinkV2, there is no variable Bulk packet-size exposure here
5. Supported Command Scope
Current mainline covers a command family broadly similar to DAPLinkV2, but on a different transport:
DAP_InfoDAP_HostStatusDAP_Connect/DAP_DisconnectDAP_TransferConfigureDAP_TransferDAP_TransferBlockDAP_TransferAbortDAP_WriteABORTDAP_DelayDAP_ResetTargetDAP_SWJ_PinsDAP_SWJ_ClockDAP_SWJ_SequenceDAP_SWD_ConfigureDAP_SWD_Sequence
Implementation boundary:
- current mainline is still SWD-only; JTAG is not implemented
PACKET_COUNTis fixed at1, so there is no DAPLinkV2-style host-visible multi-packet response depth
6. Runtime Behavior
This class maintains:
- SWJ shadow pin state
- current
debug_port transfer_abortflag- a HID response queue whose depth matches
PACKET_COUNT_ADVERTISED
The request path is roughly:
- host sends a HID Output Report
- device parses it in
OnDataOutComplete() - response data is returned through HID Input / Feature Report paths
7. Usage Example
#include "daplink_v1.hpp"
#include "usb/device.hpp"
#include "debug/swd.hpp"
MySwdBackend swd(/* ... init ... */);
MyGpio nreset(/* ... optional ... */);
LibXR::USB::DapLinkV1Class<MySwdBackend> dap(swd, &nreset);
LibXR::USB::DapLinkV1Class<MySwdBackend>::InfoStrings info;
info.vendor = "XRobot";
info.product = "DAPLinkV1";
info.serial = "00000001";
info.firmware_ver = "1.0.0";
dap.SetInfoStrings(info);
// USB device class list: {{&dap}}
// usb_dev.Init();
// usb_dev.Start();
8. Difference from DAPLinkV2
DapLinkV1Class: HID transport,PACKET_SIZE=64,PACKET_COUNT=1DapLinkV2Class: Bulk transport, current mainline defaultPACKET_SIZE=512,PACKET_COUNT=4
If the host toolchain supports CMSIS-DAP v2 Bulk, DapLinkV2Class is generally preferred.
If compatibility with older host-side HID report paths is required, DapLinkV1Class is the appropriate class.