# J-Link over USB: What's on the Wire

<!-- SPDX-License-Identifier: Apache-2.0 -->
<!-- Copyright 2026 Jon Olson -->

## A working guide to discovery, bulk framing, probe commands, and what remains unknown

**Edition:** 1.0

**Research cutoff:** 2026-07-17

**Status:** Evidence-graded supporting documentation built from public sources
and bounded tests of one genuine probe with two DUTs. It is suitable for use
alongside a host implementation, but it is not a vendor specification or a claim
of vendor conformance.

**Intended use:** A vendorable reference for host software that communicates
with genuine or authorized OEM J-Link probes. Conservative implementation
boundaries are defined by the profiles in section 2.4 and the stable claim
register in section 31.

**Covers:** The vendor-specific USB bulk protocol spoken by genuine SEGGER
J-Link and J-Link OB debug probes. It does not cover the CDC-ACM virtual COM
port, J-Link Remote Server framing, Ethernet transport, firmware update
internals, or DUT-specific architecture and silicon.

---

> **Provenance and use.** This guide draws on public documentation, pinned
> public implementations, engineering discussions, and bounded experiments run
> for this guide. It is source-informed, not clean-room. The source ledger in
> section 28 says where each claim came from; sections 2.4 and 31 distinguish
> conservative host behavior from observed, research-only, decoder-only, and
> excluded material. Recording a fact is not the same as recommending that a
> host emit it.
>
> **Complete document.** This file contains the complete human-readable guide:
> wire grammars, evidence grades, implementation profiles, examples, source
> ledger, hardware observations, stable claim register, and redistribution
> notices. The source research project also maintains machine-readable
> provenance and validation material, but a consuming project does not need
> those files to vendor, read, cite, or use this guide as supporting
> implementation documentation. Keep section 32 with every copy.

## Contents

1. [How the protocol fits together](#1-how-the-protocol-fits-together)
2. [What this covers](#2-what-this-covers)
3. [Sources, limits, and terms](#3-sources-limits-and-terms)
4. [Finding the probe and debug interface](#4-finding-the-probe-and-debug-interface)
5. [Bulk transport](#5-bulk-transport)
6. [Common encodings](#6-common-encodings)
7. [Starting a session](#7-starting-a-session)
8. [Operation-code index](#8-operation-code-index)
9. [Capability discovery](#9-capability-discovery)
10. [Probe identity, state, and limits](#10-probe-identity-state-and-limits)
11. [Target interface and electrical control](#11-target-interface-and-electrical-control)
12. [Unified JTAG/SWD scan operations](#12-unified-jtagswd-scan-operations)
13. [Historical target-assist operations](#13-historical-target-assist-operations)
14. [Persistent probe configuration](#14-persistent-probe-configuration)
15. [SWO capture service](#15-swo-capture-service)
16. [Connection-registration service](#16-connection-registration-service)
17. [Emulator communication channels](#17-emulator-communication-channels)
18. [On-probe file service](#18-on-probe-file-service)
19. [Silicon Labs C2 service](#19-silicon-labs-c2-service)
20. [Target SPI service](#20-target-spi-service)
21. [Errors and status values](#21-errors-and-status-values)
22. [State and side effects](#22-state-and-side-effects)
23. [Where the sources disagree](#23-where-the-sources-disagree)
24. [Building a host that survives real probes](#24-building-a-host-that-survives-real-probes)
25. [Wire examples](#25-wire-examples)
26. [Capturing the remaining unknowns](#26-capturing-the-remaining-unknowns)
27. [What the search did not turn up](#27-what-the-search-did-not-turn-up)
28. [Sources and evidence ledger](#28-sources-and-evidence-ledger)
29. [Hardware observations](#29-hardware-observations)
30. [Changing this guide](#30-changing-this-guide)
31. [Stable claim register](#31-stable-claim-register)
32. [Distribution, license, and notices](#32-distribution-license-and-notices)

## 1. How the protocol fits together

From the USB side, a J-Link probe presents a vendor-specific interface with one
bulk-OUT endpoint and one bulk-IN endpoint. The host sends a one-byte operation
code followed by operation-specific data. The probe returns only the response
defined for that operation. There is no universal response code, transaction
identifier, length field, checksum, or error envelope.

In other words, the protocol is simple but not self-framing. That is where most
of the trouble starts: the host has to know what it just asked for.

That simple design has several consequences:

1. The host must know the exact response shape before it reads.
2. A USB transfer boundary is not an application-message boundary. Either
   direction may be split across multiple bulk transfers.
3. Only one operation should be outstanding at a time.
4. A wrong response length can leave unread bytes in the endpoint and
   desynchronize every later operation.
5. USB short-packet and zero-length-packet behavior matters, especially when a
   response is an exact multiple of the bulk-IN endpoint's maximum packet size.
6. Capabilities and the available-interface mask are the protocol's real
   compatibility mechanism. Hardware version numbers and product IDs are useful
   hints, not substitutes.

The public record is useful, incomplete, and occasionally self-contradictory.
SEGGER published a 2010 reference manual for open-source J-Link support. Modern
open clients fill in later operation families, while OpenOCD developers recorded
places where vendor traffic used undocumented operations or contradicted the
manual. The public search turned up neither a reusable raw-USB corpus nor a
maintained Wireshark dissector.

A hardware campaign put an attached J-Link EDU Mini V2 through bounded tests
against Cortex-M and Cortex-A targets. Those sessions established exact
application bytes, host-visible USB completion boundaries, reset behavior,
recovery behavior, and several probe-specific quirks. They were not bus-level
packet captures. Each claim therefore says whether SEGGER documents it, public
code implements it, the campaign observed it, or the answer is still unknown.
Published editions remain available from the Trace landing page.

Target-level ADIv5, CoreSight, silicon, firmware, and SoC-integration findings
live in a separate research notebook. This guide keeps the probe behavior, USB
boundaries, and generic scan grammar.

## 2. What this covers

Ordinary USB handles device enumeration. This guide begins with finding and
claiming the J-Link application interface, then follows the bytes exchanged on
its bulk endpoints. Descriptor control transfers remain USB operations, not
J-Link application commands.

The word **probe** means the J-Link device. **Host** means the computer-side
client. **Target** means the system being debugged or programmed. **Operation**
means one application request and its associated response, if any.

The key words **MUST**, **MUST NOT**, **SHOULD**, **SHOULD NOT**, and **MAY**
express interoperability requirements for implementations built from this
reconstruction. They belong to this reconstruction; they are not SEGGER's
wording.

### 2.1 Byte notation

| Notation      | Meaning                                      |
| ------------- | -------------------------------------------- |
| `H→P`         | Bytes sent from host to probe on bulk OUT    |
| `P→H`         | Bytes sent from probe to host on bulk IN     |
| `u8`          | Unsigned 8-bit integer                       |
| `u16le`       | Unsigned 16-bit little-endian integer        |
| `u32le`       | Unsigned 32-bit little-endian integer        |
| `bytes[n]`    | Exactly `n` uninterpreted bytes              |
| `bits[n]`     | `ceil(n/8)` bytes containing `n` packed bits |
| `z`           | A byte that is reserved and is sent as zero  |
| `N(bits)`     | `ceil(bits / 8)`                             |
| `popcount(x)` | Number of one bits in `x`                    |

Hexadecimal wire bytes and one-byte code cells are lowercase without a `0x`
prefix, for example `05 a0 0f`. Decoded multi-byte scalar values use a `0x`
prefix, for example `0x00000fa0`.

### 2.2 Semantic operation names

Public implementations use different constant names, many inherited from vendor
terminology. This guide uses one stable namespace:

```text
probe.<subject>.<verb>       probe metadata and services
target.<subject>.<verb>      target-facing state
scan.<subject>.<verb>        clocked JTAG/SWD bit sequences
pin.<signal>.<verb>          direct probe-pin control
swo.<subject>.<verb>         Serial Wire Output capture
```

Names describe semantics, not the spelling of constants in any one codebase.
Numeric operation codes remain the wire identifiers.

### 2.3 Evidence grades

| Grade | Meaning                                                                                                           |
| ----- | ----------------------------------------------------------------------------------------------------------------- |
| `H`   | Described in SEGGER's historical RM08001-R7 manual (2010)                                                         |
| `V`   | Directly described by current vendor documentation outside RM08001-R7                                             |
| `S`   | Primary USB standard or authoritative capture-methodology documentation                                           |
| `C`   | Independently corroborated in multiple public records; related implementations alone do not qualify               |
| `I`   | Implemented or parsed in one current public codebase                                                              |
| `E`   | Only enumerated or named publicly; full wire layout is not available                                              |
| `O`   | Directly observed application bytes, descriptors, state, or host-visible completion in a bounded hardware session |
| `N`   | Inference derived from an observation but not directly exposed by the capture layer                               |
| `P`   | Project-authored scope, safety, or implementation policy; not behavior evidence                                   |
| `Q`   | A conflict, omission, or unresolved interpretation materially limits the claim                                    |

Grades combine, such as `H+I` or `H+Q`. This edition contains no `C` entries:
the known or possible ancestry among current implementations prevents their
agreement from counting as independent corroboration. An advertised capability
is still more authoritative for a particular probe than a table in this
document.

Evidence labels in the explanatory body summarize the sources discussed there.
They are not inherited by an operation family. The stable claim register makes
material propositions atomic and gives them durable identifiers. Only `O`
establishes direct observation; `N` marks an inference from a named observation
record. In particular, observation of `swo.clock.describe` does not observe SWO
start, stop, or data read.

### 2.4 Implementation profiles

Each claim in section 31 appears under one implementation profile:

| Profile              | Meaning                                                                                   |
| -------------------- | ----------------------------------------------------------------------------------------- |
| `core-host`          | Conservative behavior eligible for a genuine or authorized OEM probe host                 |
| `observed-extension` | Directly observed behavior whose probe and firmware scope must remain visible             |
| `research-only`      | Retained technical material not recommended for emission by the conservative host profile |
| `decoder-only`       | Useful to recognize in existing traffic, but never emitted                                |
| `excluded`           | Deliberately outside this guide's implementation scope                                    |

Profiles do not replace evidence grades, and neither dimension is a legal
conclusion. Where a retained claim says “this project,” it refers to the
conservative implementation policy under which this guide was developed; it does
not silently widen the consuming project's behavior. A consuming project may
adopt a narrower boundary. Widening one of these profiles calls for its own
evidence, safety review, and explicit project decision.

### 2.5 Using this guide with a host implementation

For a conservative host that controls genuine or authorized OEM probes:

1. Use `core-host` claims as the baseline implementation surface.
2. Use an `observed-extension` only when the observed probe, firmware, USB, and
   target scope remain visible and the implementation has a safe fallback.
3. Treat `research-only` and `decoder-only` material as recognition or
   investigation input, not permission to emit the operation.
4. Do not implement `excluded` material from this guide.
5. Cite stable `JLP-…` claim IDs in implementation comments, tests, or review
   records when a subtle wire rule would otherwise be easy to lose.
6. Preserve unknown values and raw bytes, and keep the session serialized and
   poisoned after ambiguous framing or completion.

This document is supporting engineering documentation, not generated source
code. A claim marked `Q`, an unresolved contradiction in section 23, or an
explicitly incomplete response grammar remains unresolved even when an operation
code is known.

## 3. Sources, limits, and terms

The main historical source is SEGGER's _Reference manual for J-Link USB
Protocol_, RM08001-R7, dated 2010-10-08. SEGGER published it to enable
open-source support for J-Link and OEM products; the same manual restricts use
for clone or compatible-emulator development. The exact consulted 358,017-byte
[archived vendor PDF](https://web.archive.org/web/20120903212701id_/http://www.segger.com/cms/admin/uploads/productDocs/RM08001_JLinkUSBProtocol.pdf)
has SHA-256 `0234b5812e541f4f16e4da4db91db67169a7cee826a4e8b73fbdfc7260652655`.
That source boundary matters. This guide neither redistributes nor relicenses
the manual, and the source ledger is not a legal-clearance opinion.

Current behavior was checked primarily against:

- [libjaylink](https://gitlab.zapb.de/libjaylink/libjaylink/-/tree/583faf19e11c6c4ef2551ae1572f6e416168a8f3),
  pinned at commit `583faf19e11c6c4ef2551ae1572f6e416168a8f3` (2026-03-12);
- [jaylink (Rust)](https://github.com/jonas-schievink/jaylink/tree/14bd3f4b8fb083bb477e64622e0e52bc440ce07d),
  pinned at commit `14bd3f4b8fb083bb477e64622e0e52bc440ce07d` (2023-01-31);
- [probe-rs](https://github.com/probe-rs/probe-rs/tree/71a89c84b39a76b775211871a5ca08d2ef52817c/probe-rs/src/probe/jlink),
  pinned at commit `71a89c84b39a76b775211871a5ca08d2ef52817c` (2026-07-15);
- [OpenOCD](https://github.com/openocd-org/openocd/tree/cb52502e88832386610add9781030f5380344063),
  pinned at commit `cb52502e88832386610add9781030f5380344063` (2026-07-06).
  Current OpenOCD delegates J-Link communication to libjaylink, so it is not
  independent corroboration for every detail. The pinned Rust jaylink source
  says it was inspired by libjaylink, and the pinned probe-rs source attributes
  at least one undocumented behavior to OpenOCD/libjaylink; those agreements are
  not automatically independent either.

These caveats are not theoretical. In an
[OpenOCD development discussion](https://sourceforge.net/p/openocd/mailman/openocd-devel/thread/20120529104315.4834.qmail%40stuge.se/),
developers reported undocumented operations and differences between captured
vendor traffic and the manual. A later
[OpenOCD correction](https://sourceforge.net/p/openocd/mailman/message/33585145/)
records a concrete interface-selection typo. Where the sources disagree, this
guide says so.

Section 29 records the hardware sessions. The harness used the active USB
descriptors and exact byte counts returned by the host's USB stack; the record
omits the probe serial number. The host controller did not expose a
packet-capture interface, so `O` establishes application bytes and host-visible
transfer boundaries, not packet timing, handshakes, or independent proof of an
inferred ZLP.

## 4. Finding the probe and debug interface

<!-- claim-coverage:JLP-USB-DISCOVERY-* -->

### 4.1 Device identification

SEGGER's USB vendor ID is:

```text
VID = 0x1366
```

The vendor ID alone is insufficient because SEGGER ships other USB functions. A
robust client SHOULD combine VID/PID recognition with descriptor inspection.

Historically observed J-Link application-protocol PIDs are:

```text
0x0101  0x0102  0x0103  0x0104  0x0105  0x0107  0x0108
```

That is a legacy set, not the complete current set. The attached genuine J-Link
EDU Mini V2 directly enumerated as `1366:1020` with manufacturer `SEGGER` and
product `J-Link`. This guide therefore admits `0x1020` as one presently
evidenced application PID under an exact VID/PID guard. It does not infer
neighboring PIDs or promote any public implementation range to a direct
observation.

`0x0106` is intentionally excluded by current clients because it denotes a CDC
serial-only function. On legacy devices, configurable “USB address” values 0
through 3 correspond to PIDs `0x0101` through `0x0104`.

The pinned libjaylink revision additionally recognizes:

```text
0x1010–0x1018
0x1020  0x1024  0x1025
0x1050–0x1059
0x1060–0x1069
```

Current probe-rs uses a broader implementation heuristic derived from SEGGER
udev rules: a new-format PID has bit `0x1000` set and at least one of the
legacy-driver bit `0x0010` or WinUSB-driver bit `0x0020` set. It explicitly
rejects `0x1008`, which is a CMSIS-DAP configuration. That rule is useful
discovery policy, not an immutable protocol rule. Descriptor inspection and an
allow/deny list remain prudent.

### 4.2 Application interface descriptor

Modern public clients find the application interface by these properties:

- interface class `0xff` (vendor-specific);
- interface subclass `0xff`;
- probe-rs additionally requires interface protocol `0xff`;
- one bulk-IN endpoint and one bulk-OUT endpoint;
- no assumption that this is USB interface number zero.

libjaylink accepts at least two endpoints and determines direction from each
endpoint descriptor. probe-rs is stricter and requires exactly two, both bulk. A
portable implementation SHOULD enumerate every alternate setting, locate the
vendor-specific pair, and reject ambiguous matches rather than selecting
arbitrarily.

Many current probes are composite devices. SEGGER's
[Virtual COM Port documentation](https://kb.segger.com/J-Link_Virtual_COM_Port)
describes a separate CDC-ACM function alongside the J-Link interface. A client
MUST claim only the vendor interface it uses and MUST NOT mistake the CDC
endpoints for protocol endpoints. VCOM and debug operation may run
simultaneously.

The observed EDU Mini V2 was not composite at the application-descriptor level:
it exposed one `ff/ff/ff` interface with exactly two bulk endpoints.
Product-family expectations therefore MUST NOT override descriptor enumeration.

### 4.3 Endpoint addresses

The historical manual gives two layouts:

| Probe generation                        |                Bulk IN |                Bulk OUT |
| --------------------------------------- | ---------------------: | ----------------------: |
| J-Link V3/V4                            | `0x81` (endpoint 1 IN) | `0x01` (endpoint 1 OUT) |
| J-Link V5 and later historical hardware | `0x81` (endpoint 1 IN) | `0x02` (endpoint 2 OUT) |

These are defaults, not discovery rules. The active USB descriptors are
authoritative. A host MUST use the endpoint addresses and `wMaxPacketSize`
reported by the selected interface.

### 4.4 Enumeration checklist

1. Match VID/PID conservatively.
2. Read the active configuration descriptor.
3. Locate an unambiguous vendor-specific interface with bulk IN and OUT.
4. Record interface number, endpoint addresses, transfer types, and both maximum
   packet sizes.
5. Detach a kernel driver only where the platform requires and permits it.
6. Claim the interface.
7. Do not issue application operations until all pending endpoint data from an
   earlier session has been ruled out or the device has been freshly
   opened/reset.

## 5. Bulk transport

<!-- claim-coverage:JLP-TRANSPORT-* -->

### 5.1 Host-driven half-duplex operation

The host initiates every operation. The normal sequence is:

```text
H→P  operation code || request body
P→H  response body, if that operation has one
```

There is no known unsolicited application message on the debug interface.
Streaming services such as SWO are still polled by explicit host operations.

A conforming host MUST keep at most one operation outstanding. This is both a
protocol property and a practical parser requirement: responses contain no
transaction ID and usually do not echo the request code.

### 5.2 No universal application framing

The first request byte selects the operation. Everything after it is
operation-specific. There is no universal:

- request length;
- response length;
- response operation code;
- sequence number;
- checksum or CRC;
- success/error header.

Some operation families define local length fields, TLVs, or status values.
Those local conventions MUST NOT be generalized to unrelated operations.

### 5.3 USB transfers are not messages

An operation body may be split across multiple OUT transfers, and a response may
arrive across multiple IN transfers. Public clients exercise both behaviors. For
example, an on-probe file write can send its operation header and file data as
distinct OUT transfers, while a registration reply can be read in an initial
fixed block followed by a calculated remainder.

Therefore:

- a capture analyzer MUST concatenate payload bytes by endpoint direction before
  parsing application fields;
- a client MUST continue until the operation-specific expected length is
  satisfied;
- neither a short host write nor an URB boundary should be treated as an
  operation delimiter unless that operation explicitly relies on it;
- parsers MUST account for zero-byte transfers and USB submission/completion
  records that describe the same transfer twice.

The observed `probe.version.read` response makes the point concrete. The probe
completed a two-byte IN transfer containing only the length, then completed a
second IN transfer containing exactly the declared body, even though the first
host buffer was large enough for both. A client that treats the first short
transfer as the entire response loses the body.

### 5.4 Maximum transfer sizes and timeout

The historical manual states these controller-era limits:

| Direction     | Historical maximum per USB transaction |
| ------------- | -------------------------------------: |
| Host to probe |                         `0xffff` bytes |
| Probe to host |                         `0x8000` bytes |

It also states that the probe aborts an operation if it cannot complete within
approximately five seconds, making large low-clock scans unsafe as a single
request. These figures SHOULD be treated as old-device upper bounds, not
guaranteed modern capacities. A host SHOULD divide long work into bounded chunks
and choose its own transfer timeout with margin. Current public clients use
shorter host-side USB timeouts (for example, 500 ms or repeated 1 s attempts),
showing that the two timeout concepts are distinct.

The scan bit count is only `u16le`, imposing a wire maximum of 65,535 bits per
scan even when memory permits. Actual limits can be much lower. Current probe-rs
uses 65,535 bits for a known J-Link EDU but only 504 bits for a J-Link
OB-K22-SiFive and as a conservative default. The `probe.workspace.read` result
does not reliably map to a universal scan limit.

### 5.5 Exact-packet responses and the ZLP trap

USB bulk transfers terminate by requested length or by a packet shorter than the
endpoint's maximum packet size. These are distinct cases. When the host requests
exactly a known application length, receipt of that length completes the host
transfer even if its last packet is full-sized; no separate terminator is
required. When the host submits more capacity and relies on USB short
termination, an exact-multiple response needs a following short packet, commonly
a zero-length packet (ZLP), to end that larger transfer.

The historical manual describes this for full-speed 64-byte packets and
recommends avoiding exact multiples where possible. Modern probe-rs generalizes
the workaround using the descriptor's actual maximum packet size: when expecting
an exact multiple, it submits an IN buffer one byte larger than the application
response. This consumes the transfer terminator without interpreting it as data.
Its code specifically notes that a naïve 256-byte configuration read can
otherwise leave the interface unusable. libjaylink instead performs larger
buffered reads and retains surplus application data, which also avoids a
narrowly sized transfer ending at the wrong point.

A robust host SHOULD:

1. obtain `mps_in` from the endpoint descriptor;
2. read exactly a known operation-specific application length and stop when that
   length is satisfied; or, if deliberately submitting surplus capacity and
   relying on USB termination, arrange to consume the short packet or ZLP;
3. expose exactly `expected_length` application bytes to the decoder;
4. never perform a speculative follow-up terminator read after all known
   application bytes have arrived;
5. never hard-code 64 except when deliberately supporting only full-speed legacy
   devices.

This is a USB transfer-completion issue, not an extra J-Link application byte.

On the observed full-speed probe, `probe.configuration.read` returned exactly
256 application bytes into a 2048-byte submitted IN buffer while `mps_in`
was 64. The transfer completed successfully at four maximum-size packets, and a
later version query returned normally with no stale endpoint data. This is
strong host-stack evidence that the 256-byte response was terminated by a ZLP.
It is not a raw packet-level capture, so the actual zero-length transaction is
described as an inference rather than a directly inspected packet.

The follow-up session created a second exact-packet case without reading
persistent data. A 512-bit SWD `scan.transfer.v3` request has 64 sample bytes
followed by one status byte. With a 65-byte application response expected, the
host received a successful 64-byte IN completion and then a distinct one-byte IN
completion containing status `00`. Because the first completion was shorter than
the submitted 65-byte capacity yet exactly one 64-byte maximum packet, this
strongly implies a ZLP between the sample field and the status field. It also
proves on this firmware that v3 sample and status fields are separate
host-visible USB transfers.

The campaign added two independent exact-multiple cases. An all-bit
`probe.counters.read` produced 128 bytes in one completed IN request whose
capacity was 129 bytes. A 512-bit JTAG `scan.transfer.v2` produced 64 sample
bytes in one completed IN request whose capacity was 65 bytes. Both successful
short completions strongly imply a terminating ZLP.

A later session repeated the v3 boundary test on a known-working JTAG target
while holding TMS high for all 512 clocks. One 132-byte `cf` request produced a
64-byte all-`ff` sample completion and then a distinct one-byte completion
containing status `00`; the subsequent version query succeeded. Together with
the 256-byte configuration read, SWD-v3 sample/status split, 128-byte counter
response, and JTAG-v2 sample response, this shows consistent exact-packet
termination across five observations on the same firmware.

A later sustained JTAG-DP MEM-AP read exposed the complementary case. A scan-v3
application response—including all expected sample bytes and its status
byte—ended at the 64-byte bulk-IN boundary. A subsequent one-byte terminator
read received no completion before its bounded command deadline. Closing the
poisoned handle, rediscovering, and reopening recovered without a physical probe
reset. This is host-visible completion evidence rather than a packet capture,
but it is enough to show that a host must not universally require a separately
observable ZLP after an exact known-length read.

As a conservative compatibility policy, a host MAY split only those scan-v3
requests whose known response would end on an exact packet multiple at the
preceding byte boundary. This makes both resulting responses non-exact and
avoids choosing one firmware behavior as universal.

### 5.6 Recovery after desynchronization

There is no public resynchronization marker. If a host sends an
unknown/malformed request, times out after a partial response, or reads the
wrong response length, it SHOULD assume the byte stream is desynchronized. The
safest recovery is:

1. stop issuing operations;
2. close and release the claimed interface;
3. reopen it, or reset/re-enumerate the device if stale data remains;
4. repeat capability/interface initialization.

Blindly scanning incoming bytes for a plausible operation code cannot work
because responses do not contain response codes.

## 6. Common encodings

<!-- claim-coverage:JLP-ENCODING-* -->

### 6.1 Integer byte order

Unless explicitly stated otherwise, multi-byte integers are little-endian. IPv4
addresses are the main exception: they appear as four network-order octets even
where surrounding scalar fields are little-endian. SPI serial data is shifted
most-significant bit first, which is distinct from the byte order of SPI
operation header fields.

### 6.2 Packed bit streams

JTAG and SWD scan buffers use this mapping:

```text
byte_index = floor(bit_index / 8)
bit_mask   = 1 << (bit_index mod 8)
```

Bit 0 is therefore the least-significant bit of byte 0 and is clocked first. `n`
bits occupy `N(n) = ceil(n/8)` bytes. The same packing applies to sampled reply
bits.

The sender SHOULD zero unused high bits in the final request byte. The receiver
MUST ignore unused high bits in the final reply byte.

### 6.3 Local TLV encoding

The SWO and file-service families use a small local TLV stream:

```text
[value_length:u8] [tag:u8] [value:value_length] ... [0x00]
```

The length precedes the tag. A zero length terminates the list and is not
followed by a tag. All presently known scalar TLV values have length four and
contain `u32le`.

This TLV convention applies only where explicitly specified.

## 7. Starting a session

<!-- claim-coverage:JLP-SESSION-*,JLP-INTERFACE-*,JLP-CLOCK-SET-* -->

```text
enumerate and claim vendor interface
        ↓
probe.version.read
        ↓
probe.capabilities.read-short
        ↓ if capability bit 31
probe.capabilities.read-long
        ↓
optional metadata/configuration reads
        ↓ if known device requires it
probe.connection.manage(register)
        ↓
target.interface.manage(query available)
        ↓
target.interface.manage(select explicitly)
        ↓
target.clock-rate.set
        ↓
scan / SWO / auxiliary operations
        ↓
stop streams, unregister, release interface
```

Some clients treat older probes without interface-selection capability as
JTAG-only. That is a compatibility assumption, not a universal wire fact.
Interface selection can reset the configured target clock, and probes can
remember a prior selection across reconnects; a host SHOULD explicitly select
the intended advertised interface and set the clock in that order on every
initialized session.

Connection registration is not a universally safe initialization step. Current
probe-rs enables it only for a known device that requires it because some other
devices fail on the operation. Treat it as a tested compatibility quirk, not
mandatory ceremony.

## 8. Operation-code index

<!-- claim-coverage:JLP-UNKNOWN-OPCODE-001 -->

The table is sorted by wire code. “Response” is the application payload size; it
excludes USB ZLPs. A row's profile is only a navigation summary: mixed families
are classified at individual claim or suboperation level. Evidence, including
`O`, is never inherited from a row.

|       Code | Semantic name                     | Request after code    | Response                         | Profile               | Claims                                              |
| ---------: | --------------------------------- | --------------------- | -------------------------------- | --------------------- | --------------------------------------------------- |
|       `01` | `probe.version.read`              | none                  | `2 + L`                          | core-host             | `JLP-VERSION-*`                                     |
|       `02` | `target.tap-reset.pulse`          | none                  | none                             | research-only         | `JLP-TAP-RESET-PULSE-001`                           |
|       `03` | `target.system-reset.pulse`       | none                  | none                             | research-only         | `JLP-SYSTEM-RESET-PULSE-001`                        |
|       `05` | `target.clock-rate.set`           | `u16le`               | none                             | core-host             | `JLP-CLOCK-SET-*`                                   |
|       `07` | `probe.signal-state.read`         | none                  | 8                                | core-host             | `JLP-SIGNAL-*`                                      |
|       `08` | `target.aux-power.set`            | `u8`                  | none                             | research-only         | `JLP-AUX-POWER-*`                                   |
|       `09` | `probe.connection.manage`         | suboperation + fields | variable                         | research-only         | `JLP-REGISTRATION-*`                                |
|       `15` | `spi.transfer`                    | suboperation + fields | variable                         | research-only         | `JLP-SPI-*`                                         |
|       `17` | `c2.transfer`                     | suboperation + fields | variable                         | research-only         | `JLP-C2-*`                                          |
|       `1e` | `probe.file.manage`               | suboperation + TLVs   | variable                         | research-only         | `JLP-FILE-*`                                        |
|       `c0` | `target.clock-rate.describe`      | none                  | 6                                | core-host             | `JLP-CLOCK-DESCRIBE-*`                              |
|       `c1` | `probe.hardware-fields.read`      | mask `u32le`          | `4 × popcount(mask)`             | mixed                 | `JLP-HARDWARE-FIELDS-*`, `JLP-HARDWARE-FIELD-BIT-*` |
|       `c2` | `probe.counters.read`             | mask `u32le`          | `4 × popcount(mask)`             | mixed                 | `JLP-COUNTERS-*`, `JLP-COUNTER-*`                   |
|       `c7` | `target.interface.manage`         | selector `u8`         | 4                                | mixed                 | `JLP-INTERFACE-*`                                   |
|       `c8` | `scan.clock-one`                  | none                  | 1                                | decoder-only          | `JLP-SCAN-CLOCK-ONE-*`                              |
|  `c9`–`cc` | persistent TMS/TDI control        | none                  | none                             | research-only         | `JLP-PIN-*`                                         |
|       `cd` | `scan.transfer.v1`                | scan body             | sampled bits                     | decoder-only          | `JLP-SCAN-V1-*`                                     |
|       `ce` | `scan.transfer.v2`                | scan body             | sampled bits                     | core-host             | `JLP-SCAN-V2-*`                                     |
|       `cf` | `scan.transfer.v3`                | scan body             | sampled bits + status            | core-host             | `JLP-SCAN-V3-*`                                     |
|       `d0` | `target.reset-and-halt.repeat`    | ARM7/9 sequence       | sampled bits                     | decoder-only          | `JLP-RESET-HALT-REPEAT-*`                           |
|       `d1` | `target.reset-and-halt.timed`     | ARM7/9 sequence       | sampled bits                     | decoder-only          | `JLP-RESET-HALT-TIMED-*`                            |
|       `d4` | `probe.workspace.read`            | none                  | 4                                | mixed                 | `JLP-WORKSPACE-*`                                   |
|       `d5` | `scan.transfer.write-only`        | scan body             | none                             | research-only         | `JLP-SCAN-WRITE-ONLY-*`                             |
|       `d6` | `scan.write-status.read-clear`    | none                  | 1                                | research-only         | `JLP-SCAN-WRITE-STATUS-*`                           |
|  `da`–`df` | persistent TCK/reset control      | none                  | none                             | research-only         | `JLP-PIN-*`                                         |
|       `e8` | `probe.capabilities.read-short`   | none                  | 4                                | core-host             | `JLP-CAP-SHORT-*`                                   |
|       `e9` | `target.cpu-capabilities.read`    | 4-byte selector       | 4                                | decoder-only          | `JLP-CPU-CAPABILITIES-*`                            |
|       `ea` | `target.cpu-operation`            | variable              | variable/incomplete              | decoder-only          | `JLP-CPU-OPERATION-*`                               |
|       `eb` | `swo.manage`                      | suboperation + TLVs   | variable                         | mixed by suboperation | `JLP-SWO-*`                                         |
|       `ed` | `probe.capabilities.read-long`    | none                  | 32                               | core-host             | `JLP-CAP-LONG-*`                                    |
|       `ee` | `probe.channel.transfer`          | suboperation + fields | variable                         | research-only         | `JLP-CHANNEL-*`                                     |
|       `f0` | `probe.hardware-version.read`     | none                  | 4                                | core-host             | `JLP-HARDWARE-VERSION-*`                            |
|       `f1` | `target.dcc.write`                | variable              | 1                                | decoder-only          | `JLP-DCC-*`                                         |
|       `f2` | `probe.configuration.read`        | none                  | 256                              | observed-extension    | `JLP-CONFIG-READ-*`                                 |
|       `f3` | `probe.configuration.write`       | 256 bytes             | none                             | research-only         | `JLP-CONFIG-WRITE-*`                                |
| `f4`, `f5` | generic target memory identifiers | undisclosed           | undisclosed                      | decoder-only          | `JLP-MEMORY-GENERIC-*`                              |
|       `f6` | `target.rtck.measure`             | none                  | documented 16; observed no reply | mixed, no emission    | `JLP-RTCK-*`                                        |
| `f7`, `f8` | historical ARM7/9 memory          | variable              | variable                         | decoder-only          | `JLP-MEMORY-ARM79-*`                                |

Unknown codes MUST NOT be sent merely because they are absent from this table.
The 2010 manual and modern public clients each cover operations the other does
not.

## 9. Capability discovery

<!-- claim-coverage:JLP-CAP-* -->

### 9.1 Short and long bitsets

`probe.capabilities.read-short` (`e8`) returns four bytes.
`probe.capabilities.read-long` (`ed`) returns 32 bytes. In either form,
capability bit `n` is:

```text
byte = response[floor(n / 8)]
mask = 1 << (n mod 8)
```

Thus bit 0 is the least-significant bit of response byte 0. The long form
extends the same bit-number namespace; its first four bytes SHOULD agree with
the short response. A host MUST issue `ed` only when short capability bit 31 is
set. It SHOULD retain unknown set bits for logs and future compatibility.

### 9.2 Known capability bits

| Bit | Semantic capability         | Associated operation or feature                              | Evidence |
| --: | --------------------------- | ------------------------------------------------------------ | -------- |
|   0 | protocol marker             | Historically “reserved”; appears always set                  | `H+I`    |
|   1 | hardware-version query      | `probe.hardware-version.read`                                | `H+I`    |
|   2 | DCC write                   | `target.dcc.write`                                           | `H+Q`    |
|   3 | adaptive target clock       | `target.clock-rate.set(0xffff)`                              | `H+I`    |
|   4 | configuration read          | `probe.configuration.read`                                   | `H+I`    |
|   5 | configuration write         | `probe.configuration.write`                                  | `H+I`    |
|   6 | trace family                | Historical trace support; exact operations not reconstructed | `H+E`    |
|   7 | generic memory write        | `target.memory.write-generic`                                | `H+E`    |
|   8 | generic memory read         | `target.memory.read-generic`                                 | `H+E`    |
|   9 | target-clock description    | `target.clock-rate.describe`                                 | `H+I`    |
|  10 | on-probe code execution     | Wire operation not publicly specified                        | `H+E`    |
|  11 | workspace query             | `probe.workspace.read`                                       | `H+I+Q`  |
|  12 | hardware-field query        | `probe.hardware-fields.read`                                 | `H+I`    |
|  13 | auxiliary target power      | `target.aux-power.set`                                       | `H+I`    |
|  14 | timed reset-and-halt        | `target.reset-and-halt.timed`                                | `H`      |
|  15 | reserved/unknown            | No stable public meaning                                     | `H`      |
|  16 | RTCK reaction measurement   | `target.rtck.measure`                                        | `H+I`    |
|  17 | target-interface management | `target.interface.manage`                                    | `H+I`    |
|  18 | ARM7/9 memory access        | `target.memory.{read,write}-arm79`                           | `H+Q`    |
|  19 | counters query              | `probe.counters.read`                                        | `H+I`    |
|  20 | DCC read                    | Operation layout not publicly specified here                 | `H+E`    |
|  21 | target CPU capabilities     | `target.cpu-capabilities.read`                               | `H`      |
|  22 | target CPU operation        | `target.cpu-operation`                                       | `H+Q`    |
|  23 | SWO capture                 | `swo.manage`                                                 | `H+I`    |
|  24 | extended DCC write          | Operation layout not publicly specified                      | `H+E`    |
|  25 | extended firmware update    | Deliberately not specified                                   | `H+E`    |
|  26 | on-probe file service       | `probe.file.manage`                                          | `H+I`    |
|  27 | connection registration     | `probe.connection.manage`                                    | `H+I`    |
|  28 | indicators                  | Operation layout not publicly specified                      | `H+E`    |
|  29 | network speed test          | Operation layout not publicly specified                      | `H+E`    |
|  30 | raw trace                   | Operation layout not publicly specified                      | `H+E`    |
|  31 | extended-capability query   | `probe.capabilities.read-long`                               | `H+I+Q`  |
|  32 | write-only scan             | `scan.transfer.write-only` and status query                  | `H+I`    |
|  33 | emulator communication      | `probe.channel.transfer`                                     | `H+I`    |
|  38 | Ethernet host transport     | Not the USB application transport                            | `I`      |
|  56 | target SPI                  | `spi.transfer`                                               | `I`      |

All unlisted bits from 34 through 255 are unknown in this edition. A host MUST
NOT infer that an operation is unsupported merely because this document lacks
its bit meaning; it SHOULD preserve the raw 256-bit response.

The historical short-capability table labels bit 31 reserved, while the same
manual's extended table and every modern client examined for this guide use it
to gate the long query. Only one meaning makes the exchange work:
“extended-capability query.”

### 9.3 Controlled observation

The EDU Mini V2 returned:

```text
H→P  e8
P→H  33 5a ea b8

H→P  ed
P→H  33 5a ea b8  1c 7c b0 66
     a1 40 0c 00  00 00 00 00
     00 00 00 00  00 00 00 00
     00 00 00 00  00 00 00 00
```

The first 32 long-response bits exactly equal the short response. Short bits set
were:

```text
0, 1, 4, 5, 9, 11, 12, 14, 17, 19, 21, 22, 23, 27, 28, 29, 31
```

The long response additionally set these currently unmapped bits:

```text
34, 35, 36, 42, 43, 44, 45, 46, 52, 53, 55,
57, 58, 61, 62, 64, 69, 71, 78, 82, 83
```

This is a useful firmware fingerprint, not a license to invent meanings for
those bits. A set bit is a clue, not a command: it reveals neither an operation
code nor whether the operation would be safe.

### 9.4 Historical example

```text
H→P  e8
P→H  bf 7f ff 3b
```

The reply is the little-endian bitset `0x3bff7fbf`. Decode it as individual
bits, not as a version number.

## 10. Probe identity, state, and limits

<!-- claim-coverage:JLP-VERSION-*,JLP-HARDWARE-*,JLP-SIGNAL-*,JLP-WORKSPACE-*,JLP-COUNTER-*,JLP-COUNTERS-*,JLP-RTCK-* -->

### 10.1 `probe.version.read` (`01`) — `core-host`

Request:

```text
H→P  01
```

Response:

```text
P→H  length:u16le
P→H  version_record:bytes[length]
```

The two lines describe application fields, not a requirement that they share a
USB transfer. `version_record` is a length-delimited record whose leading field
is normally a NUL-terminated ASCII firmware/build description. It can contain
additional NUL-terminated strings and padding. Clients SHOULD retain all
`length` bytes for diagnostics, display the bytes before the first NUL as the
primary version string, optionally expose later NUL-delimited fields, and
tolerate non-UTF-8 data by lossless escaping. They MUST NOT truncate the
application record merely because a NUL has been seen.

The historical manual's worked response prints only the low length byte even
though its field table and public implementations read `u16le`. A decoder MUST
consume both bytes. This is commonly the first application operation because it
works on old devices and provides useful identification.

The observed probe returned `70 00` as a dedicated two-byte IN transfer,
declaring 112 body bytes, followed by a dedicated 112-byte IN transfer. The
primary field was `J-Link EDU Mini V2 compiled Jun 25 2026 10:27:52`; the
remainder held a second copyright/URL string and zero padding. This directly
confirms the `u16le` header on that probe and disproves the narrower model of
“one string with at most one trailing NUL.”

### 10.2 `probe.hardware-version.read` (`f0`) — `core-host`

```text
H→P  f0
P→H  packed_version:u32le
```

The integer is decimal-packed as `TTMMmmrr`:

```text
type     = floor(value / 1,000,000) mod 100
major    = floor(value /    10,000) mod 100
minor    = floor(value /       100) mod 100
revision = value mod 100
```

Known historical type values are 0 J-Link, 1 J-Trace, 2 Flasher, and 3 J-Link
Pro. Modern public code does not enumerate every value. Unknown types MUST be
retained, not rejected.

Hardware versions do not form a reliable feature ladder across all J-Link OB
products. Use capability and interface queries for behavior selection.

The observed response was `20 4e 00 00`, or decimal 20,000: type 0, major 2,
minor 0, revision 0.

### 10.3 `probe.signal-state.read` (`07`) — `core-host`

```text
H→P  07
P→H  target_mv:u16le
      tck:u8
      tdi:u8
      tdo:u8
      tms:u8
      system_reset:u8
      tap_reset:u8
```

The response is eight bytes. Pin-state bytes are observed as Boolean values;
clients SHOULD treat zero as low and nonzero as high rather than require exactly
one. `target_mv` reports target reference voltage in millivolts.

The observed response was `dc 0c 00 01 01 01 01 ff`: 3292 mV, TCK low,
TDI/TDO/TMS/system-reset high, and tap-reset reported as `ff`. The noncanonical
`ff` directly validates the rule that every nonzero pin-state byte means high.

### 10.4 `probe.workspace.read` (`d4`) — claim-level `core-host` / `observed-extension`

```text
H→P  d4
P→H  workspace_bytes:u32le
```

Public sources disagree on the exact abstraction. The historical manual calls it
the maximum memory-block size. Rust clients use it as a chunking hint for SWD
memory operations. Current libjaylink calls it free memory and uses it when
sizing an SWO buffer. It also does not directly predict the maximum JTAG scan on
known devices.

The only safe reading is an **on-probe workspace ceiling or hint**. A host MAY
use it to lower operation sizes but MUST NOT assume that every operation accepts
a payload exactly that large. Per-operation field widths, observed device
limits, and conservative caps still apply.

The observed response was `58 2d 00 00`, or 11,608. This adds a device/firmware
datapoint but does not resolve which operation families the value predicts.

### 10.5 `probe.hardware-fields.read` (`c1`) — claim-level mixed profile

```text
H→P  c1  requested_mask:u32le
P→H  value:u32le × popcount(requested_mask)
```

One value is returned for each requested bit, in ascending bit-index order.
There are no field identifiers in the response. A host MUST retain the original
request mask while decoding. The historical manual states that requesting an
unknown field yields `0xffffffff` for that position.

| Bit | Returned value                       | Encoding/evidence                                                             |
| --: | ------------------------------------ | ----------------------------------------------------------------------------- |
|   0 | Auxiliary target-power state         | 0 off, nonzero on; `H+I`                                                      |
|   1 | Overcurrent trip reason              | 0 normal; 1 = 2 ms at 3000 mA; 2 = 10 ms at 1000 mA; 3 = 40 ms at 400 mA; `H` |
|   2 | Present target current               | milliamperes; `H+I`                                                           |
|   3 | Peak target current                  | milliamperes; `H+I`                                                           |
|   4 | Peak target current during operation | milliamperes; `H`                                                             |
|  10 | Longest interval over 3000 mA        | milliseconds; `H`                                                             |
|  11 | Longest interval over 1000 mA        | milliseconds; `H`                                                             |
|  12 | Longest interval over 400 mA         | milliseconds; `H`                                                             |
|  16 | Assigned IPv4 address                | four network-order octets; `I`                                                |
|  17 | IPv4 netmask                         | four network-order octets; `I`                                                |
|  18 | IPv4 gateway                         | four network-order octets; `I`                                                |
|  19 | IPv4 DNS server                      | four network-order octets; `I`                                                |
|  23 | USB supply voltage                   | millivolts; `I`                                                               |

Threshold semantics are reported as described by the historical source and may
vary with hardware. IPv4 values MUST be rendered from their four wire-order
octets, not byte-swapped as a host integer.

The observed request mask `0x00001c1f` (bits 0–4 and 10–12) returned eight zero
words: auxiliary power was off, no overcurrent condition or interval was
recorded, and all current readings were zero. A separate bit-23 request returned
`ff ff ff ff`. This directly confirms that an unsupported hardware field still
occupies its response position and uses the documented `0xffffffff` sentinel on
this probe.

### 10.6 `probe.counters.read` (`c2`) — claim-level mixed profile

```text
H→P  c2  requested_mask:u32le
P→H  value:u32le × popcount(requested_mask)
```

Values again follow set bits in ascending order.

| Bit | Counter                                                       |
| --: | ------------------------------------------------------------- |
|   0 | Milliseconds the probe has been connected/powered at a target |
|   1 | Number of target connect/disconnect events                    |

The historical source says the time counter resets or rolls after 24 hours.
Clients SHOULD treat both counters as wrapping diagnostics rather than durable
monotonic telemetry.

As with hardware fields, the historical source says an unknown requested counter
bit still consumes one response word containing `0xffffffff`.

Two observed `mask = 3` replies decoded to `(1,451,160 ms, 1 event)` and
`(1,456,330 ms, 1 event)`. The 5,170-unit increase over approximately 5.17
seconds directly supports millisecond units. After the target-facing experiments
the values were `(3,115,190 ms, 1 event)`: interface switching and SWD recovery
did not increment the physical target-connect count.

An observed `mask = 0xffffffff` request returned exactly 128 bytes. Bits 0
through 3 contained `4,241,480`, `1`, `0`, and `0`; bits 4 through 31 each
contained `0xffffffff`. Thus this firmware implements two additional counter
slots whose meanings remain unknown and applies the unsupported-field sentinel
to all 28 higher slots. The response proves positional expansion for a full
mask; a zero value alone does not justify assigning names to bits 2 and 3.

### 10.7 `target.rtck.measure` (`f6`) — `decoder-only`; observed hazard withheld

```text
H→P  f6
P→H  result:u32le
      minimum_ns:u32le
      maximum_ns:u32le
      average_ns:u32le
```

Known `result` values are 0 for success and 1 for no target reaction. Timing
values describe the reaction to adaptive return clock in nanoseconds. On nonzero
result, timing fields SHOULD be considered undefined unless a trace establishes
otherwise.

**Observed on the EDU Mini V2:** with JTAG selected and a DUT already shown to
expose SWD rather than a responding JTAG/RTCK path, the one-byte request `f6`
completed on bulk OUT but produced no IN response within one second. Immediate
and later `probe.version.read` attempts then timed out on bulk OUT even though
the USB device could still be opened and its interface claimed. Close/reopen did
not recover it. A host-side USB reset was followed by the device disappearing
from enumeration. Physical unplug/replug restored normal operation; section 29.9
records the recovery state. This is why `f6` is not a casual “let's see what
happens” query.

This behavior is narrower than a universal claim about `f6`: the probe might
have been waiting longer than the host timeout, and a reacting RTCK target was
not available for comparison. It nevertheless disproves the assumption that a
documented, nominally read-only query is necessarily liveness-safe. A client
SHOULD issue `target.rtck.measure` only with a known RTCK-capable setup, SHOULD
treat it as a potentially blocking target operation, and SHOULD have a
physical-reconnect recovery path. Returning a 16-byte `result = 1` failure
cannot be assumed on all probe/target combinations.

## 11. Target interface and electrical control

<!-- claim-coverage:JLP-INTERFACE-*,JLP-CLOCK-*,JLP-AUX-POWER-*,JLP-RESET-*,JLP-TAP-RESET-*,JLP-SYSTEM-RESET-*,JLP-PIN-*,JLP-SCAN-CLOCK-ONE-* -->

### 11.1 Interface selectors

The selector namespace is shared by the selection request and the bit positions
in the available-interface mask.

|  ID | Interface                      | Evidence |
| --: | ------------------------------ | -------- |
|   0 | JTAG (IEEE 1149.1)             | `H+I`    |
|   1 | SWD                            | `H+I`    |
|   2 | BDM3                           | `H+I`    |
|   3 | Renesas FINE                   | `H+I`    |
|   4 | PIC32 ICSP / two-wire JTAG     | `H+I`    |
|   5 | SPI                            | `I`      |
|   6 | Silicon Labs C2                | `I`      |
|   7 | cJTAG (IEEE 1149.7)            | `I`      |
|  10 | Microchip IS208x two-wire JTAG | `I`      |

Other values through 31 are unassigned in this edition.

### 11.2 `target.interface.manage` (`c7`) — claim-level mixed profile

```text
H→P  c7  selector:u8
P→H  result:u32le
```

Selector meanings:

|  Selector | Meaning of response                                                     |
| --------: | ----------------------------------------------------------------------- |
|      `ff` | Bit mask of available interfaces; bit `n` represents selector `n`       |
|      `fe` | Currently selected interface ID                                         |
| `00`–`1f` | Select that interface; response is the previously selected interface ID |

Before selecting an interface, the host MUST query availability and verify that
its bit is set. After selecting, it SHOULD set target clock rate again.

The historical prose says selection IDs are 1 through 31 and gives `c7 02` as an
SWD example, but its own table assigns JTAG 0 and SWD 1. Public implementations
and the OpenOCD correction agree that valid IDs include zero and that `c7 01`
selects SWD. That is the internally consistent wire behavior used here.

Some devices retain the selected interface across sessions. One Rust
implementation reports a probe hang when selecting FINE even though vendor
software sends the same bytes. Interface selection SHOULD therefore have a
recoverable timeout and a device-quirk mechanism.

In the initial read-only descriptor session, selector `ff` returned
`83 00 00 00`, advertising JTAG (bit 0), SWD (bit 1), and cJTAG (bit 7), while
selector `fe` returned `00 00 00 00`, reporting JTAG as current; that initial
tranche sent no interface-selection request. The later bounded follow-up
selected SWD and restored JTAG as described below and in section 29.7.

Example:

```text
H→P  c7 ff
P→H  03 00 00 00       # JTAG and SWD available

H→P  c7 01             # select SWD
P→H  00 00 00 00       # previous interface was JTAG
```

### 11.3 `target.clock-rate.describe` (`c0`) — `core-host`

```text
H→P  c0
P→H  base_hz:u32le  minimum_divisor:u16le
```

For the currently selected target interface, nominal rates are:

```text
rate_hz = base_hz / divisor
divisor is an integer >= minimum_divisor
```

`minimum_divisor` MUST NOT be zero. This describes the discrete rate family; it
does not guarantee every target will operate at every returned rate.

The observed response was `00 d8 b8 05 18 00`: a 96,000,000 Hz base and minimum
divisor 24, hence a nominal maximum of 4,000,000 Hz for the current JTAG
interface.

### 11.4 `target.clock-rate.set` (`05`) — `core-host`

```text
H→P  05  rate_khz:u16le
P→H  <none>
```

`rate_khz = 0xffff` requests adaptive clocking and MUST be used only when
capability bit 3 is set. Zero is rejected by current public clients. Because no
acknowledgement is returned, a transport-level successful OUT transfer is not
proof that the target accepted or can sustain the requested rate.

The follow-up session sent `05 64 00` after selecting SWD, requesting 100 kHz.
No response arrived or was expected; subsequent SWD transfers succeeded.
Re-selecting an interface was treated as invalidating that setting, so the
experiment reapplied it after every recovery toggle.

Examples:

```text
05 a0 0f    # 4000 kHz
05 ff ff    # adaptive clocking
```

### 11.5 Auxiliary target power (`08`) — `research-only`

```text
H→P  08  enable:u8
P→H  <none>
```

`enable` is 0 for off and 1 for on. The host MUST require capability bit 13.
This controls the probe's auxiliary target supply where hardware provides one;
it is not the target-reference voltage input. Enabling power can affect external
hardware and SHOULD be an explicit user policy.

### 11.6 Reset pulses

```text
02    target.tap-reset.pulse
03    target.system-reset.pulse
```

Both operations have no body and no response. The historical manual describes an
approximately 2 ms assertion followed by release. The TAP-reset operation
controls the dedicated TRST pin, not the five-TMS-clock JTAG reset sequence, and
may have no physical effect if the connector lacks TRST.

### 11.7 Persistent pin control

| Code | Semantic action                             | Response |
| ---: | ------------------------------------------- | -------- |
| `c9` | Drive TMS low                               | none     |
| `ca` | Drive TMS high                              | none     |
| `cb` | Drive TDI low                               | none     |
| `cc` | Drive TDI high                              | none     |
| `da` | Drive TCK low                               | none     |
| `db` | Drive TCK high                              | none     |
| `dc` | Assert system reset (normally active-low)   | none     |
| `dd` | Release system reset                        | none     |
| `de` | Assert TAP reset/TRST (normally active-low) | none     |
| `df` | Release TAP reset/TRST                      | none     |

Each request is the one-byte code alone. “Assert/release” is used instead of
inherited “clear/set” names so polarity is not confused with logical reset
state. A host using persistent control MUST restore safe released/high states on
orderly shutdown where appropriate, while recognizing that disconnects and
crashes can prevent cleanup.

### 11.8 `scan.clock-one` (`c8`) — `decoder-only`

```text
H→P  c8
P→H  sampled_pin:u8
```

The probe generates one TCK pulse, ending high, and returns one sampled pin
value. The historical manual labels the returned pin TDI, which is surprising
because TDI is normally host-driven and TDO is normally sampled. No public trace
in this research pass resolves whether the label is literal or a typo.
Implementations MUST NOT silently rename the sampled signal to TDO without
hardware validation.

## 12. Unified JTAG/SWD scan operations

<!-- claim-coverage:JLP-SCAN-* -->

### 12.1 Common scan body

Versions 2, 3, and write-only use:

```text
H→P  operation:u8
     z:u8
     bit_count:u16le
     control:bits[bit_count]
     drive:bits[bit_count]
```

Let `N = N(bit_count)`. The request length is `4 + 2N`. `bit_count` MUST be
nonzero. Reserved byte `z` MUST be zero.

The two bit buffers have interface-dependent semantics:

| Selected interface | `control` bit                                | `drive` bit                                 | sampled response bit     |
| ------------------ | -------------------------------------------- | ------------------------------------------- | ------------------------ |
| JTAG               | TMS                                          | TDI                                         | TDO                      |
| SWD                | Direction: 0 input/tri-state, 1 output/drive | SWDIO output value; ignored on input cycles | SWDIO sampled each cycle |

During SWD output cycles, sampled response bits are not specified and SHOULD be
ignored. During SWD input cycles, the host SHOULD send zero in the corresponding
drive bit.

The observed EDU Mini V2 firmware requires one additional probe-adapter rule
that is deliberately separate from architecture-neutral SWD turnaround. For a
12-bit request/ACK scan, direction `ff00` and drive `a500` produced raw sample
`0009`. Target input begins at bit 8: raw bits 8 through 10 are ACK `1,0,0` (OK,
LSB first), while raw bit 11 is already the first data bit that the neutral SWD
layer expects in the following scan. The next 42-bit input scan used direction
`00000000fc03`, drive `000000000000`, and returned raw sample `3b8ad8850300`.

On this bounded probe/firmware, the host adapter MUST delay each raw
target-driven sample by one logical target-input cycle and preserve the
displaced bit across consecutive scan-v3 operations. That stateful mapping
reconstructed DPIDR `0x0bb11477` and was subsequently validated by AP0 IDR,
CPUID, and a restored halt/resume round trip. Other probe families or firmware
MUST NOT inherit this rule without observation.

### 12.2 `scan.transfer.v1` (`cd`) — `decoder-only`

Legacy version 1 omits the reserved alignment byte:

```text
H→P  cd  bit_count:u16le  control:bits[bit_count]  drive:bits[bit_count]
P→H  sample:bits[bit_count]
```

The historical source marks it obsolete. New implementations SHOULD decode it
for traces but SHOULD NOT choose it when version 2 or 3 is known to work.

### 12.3 `scan.transfer.v2` (`ce`) — `core-host`

```text
H→P  ce  00  bit_count:u16le  control:bits[bit_count]  drive:bits[bit_count]
P→H  sample:bits[bit_count]
```

There is no status byte. The historical source marks version 2 obsolete on
then-current hardware version 5 and later, but current clients still keep it as
a fallback. Without a status byte, a USB-successful response cannot report
on-probe workspace exhaustion in-band.

On the observed probe in JTAG mode, a five-bit all-TMS-high request
`ce 00 05 00 1f 00` returned one byte `1f` and left the probe responsive. A
later 75-bit reset/IDCODE attempt returned sample bytes that matched the control
pattern and contained no valid JTAG IDCODE. Because the DUT was subsequently
proven to be SWD-only and no electrical loopback test was performed, this
observation establishes the v2 request/response length but does **not**
establish that v2 generally echoes TMS.

A later 512-bit v2 request held TMS high and TDI low for every clock, keeping
any compliant TAP in Test-Logic-Reset. It returned 64 bytes of `ff` in one
successful IN completion from a 65-byte-capacity request. This validates the
512-bit request and 64-byte response sizes and strongly implies a terminating
ZLP. The all-`ff` samples remain electrically ambiguous on this SWD-only DUT and
MUST NOT be generalized as a v2 echo rule.

On the later known-working Cortex-A JTAG chain, the same 75-clock reset/IDCODE
vector returned ten sample bytes `ff ef 08 40 d7 00 00 00 00 06`. Removing the
nine TAP-transition samples decoded one IDCODE `0x6ba00477` followed by zero
fill. This demonstrates that v2 returns genuine TDO samples on a responding
chain and resolves the earlier electrical ambiguity.

### 12.4 `scan.transfer.v3` (`cf`) — `core-host`

```text
H→P  cf  00  bit_count:u16le  control:bits[bit_count]  drive:bits[bit_count]
P→H  sample:bits[bit_count]  status:u8
```

Known status values:

| Status | Meaning                                             |
| -----: | --------------------------------------------------- |
|   `00` | Success                                             |
|   `06` | Insufficient on-probe memory/workspace              |
|  other | Operation-specific device error; preserve raw value |

The host MUST read the sample bytes even when status may be nonzero because the
status follows them. On error, sampled bytes SHOULD be considered undefined.

Example 9-bit request (`N = 2`):

```text
H→P  cf 00 09 00  00 01  a5 01
      |  |  |-----|  |---|  |---|
      op z bit_count control drive

P→H  xx xx 00
      sample status
```

The example illustrates layout only; it does not prescribe a meaningful JTAG
state-machine sequence.

Mode and target state materially affect this operation. On the earlier SWD-only
Cortex-M connection while JTAG was selected, five reset clocks returned one
sample byte followed by status `ff`. On the known-working Cortex-A JTAG chain,
the 75-clock IDCODE request differed from the successful v2 request only in
operation byte (`cf` instead of `ce`): its first ten response bytes were exactly
the same `ff ef 08 40 d7 00 00 00 00 06`, followed by a distinct one-byte `00`
status completion. A 512-clock all-TMS-high v3 request likewise returned 64
all-`ff` sample bytes and then status `00`. Implementations MUST therefore
select the intended interface before interpreting the two bit buffers, and
SHOULD preserve unknown nonzero status values such as `ff` rather than collapse
them into a generic USB error.

The observed v3 responses also settle a subtle framing point:
`sample:bits[bit_count]` and `status:u8` can be distinct USB transfers even when
a single host read could hold both. For 54-bit SWD requests, the probe returned
seven sample bytes and then one status byte. For the 75-bit JTAG request it
returned ten sample bytes and then one status byte. In both 512-bit SWD and JTAG
boundary cases it returned 64 sample bytes, an inferred terminating ZLP, and
then the status byte.

### 12.5 `scan.transfer.write-only` (`d5`) — `research-only`

```text
H→P  d5  00  bit_count:u16le  control:bits[bit_count]  drive:bits[bit_count]
P→H  <none>
```

This avoids returning sampled data and records failure in a sticky probe-side
result. The host SHOULD query and clear that result with `d6` at deliberate
synchronization points.

The historical operation index, capability table, and modern code agree on `d5`;
one detailed page in the manual prints `cf`. The outlier is treated as a typo,
and this guide uses `d5`.

### 12.6 `scan.write-status.read-clear` (`d6`) — `research-only`

```text
H→P  d6
P→H  status:u8
```

The operation returns the sticky result of preceding write-only scans and clears
it. The documented convention is `00` success and any nonzero byte an error; the
public record does not separately assign meanings to individual nonzero `d6`
values. A host SHOULD NOT assume the sticky status is scoped to a single
write-only request unless experiments demonstrate it; query it before and after
a batch when attribution matters.

### 12.7 Scan selection policy

A conservative host policy is:

1. Prefer version 3 for ordinary JTAG/SWD scanning.
2. Bound `bit_count` by `u16`, a tested per-device limit, operation overhead,
   and the five-second device work budget.
3. Fall back to version 2 only for a known compatibility need.
4. Use write-only only when capability bit 32 is set and returned samples are
   unnecessary.
5. Do not choose a version solely from hardware version. J-Link OB version
   numbering does not reliably follow the historical standalone-probe
   thresholds.

## 13. Historical target-assist operations

<!-- claim-coverage:JLP-RESET-HALT-*,JLP-DCC-*,JLP-CPU-*,JLP-MEMORY-* -->

This section contains operations described by the historical manual but not
exercised by the current public libraries inspected for this edition. They are
valuable for capture decoding, but a new client SHOULD treat them as
experimental until verified against genuine hardware.

### 13.1 `target.reset-and-halt.repeat` (`d0`) — `decoder-only`

```text
H→P  d0
     scan_bytes:u16le
     repeat_limit:u16le
     criterion_byte_offset:u16le
     criterion_mask:u16le
     criterion_value:u16le
     tms:bytes[scan_bytes]
     tdi:bytes[scan_bytes]

P→H  tdo:bytes[scan_bytes]
```

The probe releases target reset, repeatedly executes the supplied JTAG sequence,
and tests a returned value near `criterion_byte_offset`. It stops when:

```text
(observed_value & criterion_mask) == criterion_value
```

or after the repeat limit. The historical description is specific to ARM7 and
ARM9. It does not define alignment or out-of-range behavior for the 16-bit
criterion load; a host MUST keep the criterion entirely within the returned
buffer and SHOULD use an even offset unless traces prove unaligned access safe.

### 13.2 `target.reset-and-halt.timed` (`d1`) — `decoder-only`

```text
H→P  d1
     scan_bytes:u16le
     timeout_ms:u16le
     criterion_byte_offset:u16le
     criterion_mask:u16le
     criterion_value:u16le
     tms:bytes[scan_bytes]
     tdi:bytes[scan_bytes]

P→H  tdo:bytes[scan_bytes]
```

This has the same ARM7/9 behavior but replaces the repeat count with a
millisecond timeout. The response has no explicit success flag; the host must
evaluate the returned criterion itself.

These operations use a byte count, unlike the ordinary scan family's bit count.
Treating `scan_bytes` as bits would under-read the response and desynchronize
the session.

### 13.3 `target.dcc.write` (`f1`) — `decoder-only`

```text
H→P  f1
     initialization_bits:u16le
     status_bits:u16le
     data_bits:u16le
     status_bit_index:u16le
     timeout:u16le
     item_count:u16le
     jtag_program:bytes[B]
     data:bytes[item_count]

B = 2 × N(initialization_bits) + N(status_bits) + N(data_bits)

P→H  status:u8
```

Known response status values are 0 success and 1 timeout. The historical manual
labels nearly every semantic detail of the generated JTAG program “to be
determined” and says its generation is out of scope. The layout is useful for
recognizing traffic, but it is not enough to synthesize safe requests.

### 13.4 `target.cpu-capabilities.read` (`e9`) — `decoder-only`

```text
H→P  e9
     device_family:u8
     interface:u8
     00 00

P→H  capabilities:u32le
```

Known CPU capability bits are:

| Bit | Meaning                              |
| --: | ------------------------------------ |
|   0 | Marker; always one                   |
|   1 | CPU memory-write operation supported |
|   2 | CPU memory-read operation supported  |

The `interface` byte is a target-CPU selector defined by this operation's
historical API, not proven to be identical to every modern
`target.interface.manage` ID. Known examples use zero for JTAG.

### 13.5 `target.cpu-operation` (`ea`) — `decoder-only`

Request:

```text
H→P  ea
     operation:u8
     suboperation:u8
     device_family:u8
     interface:u8
     configuration_length:u16le
     configuration:bytes[configuration_length]
     address:u32le
     transfer_length:u32le
     write_data:bytes[transfer_length]    # write only
```

Known operation values:

|      Value | Meaning      |
| ---------: | ------------ |
| 100 (`64`) | Write memory |
| 101 (`65`) | Read memory  |

The manual specifies a `u32le` result where zero means success and a positive
value is the number of bytes not transferred:

```text
P→H  result:u32le
```

However, it does not say where read data appears relative to that result. A
literal response containing only the result cannot implement a read. The read
response therefore remains unknown. A client MUST NOT issue CPU read operations
until a trace or another primary source establishes the complete response
sequence.

### 13.6 Generic memory operations (`f4`, `f5`) — `decoder-only`

The public historical record assigns:

```text
f4  target.memory.write-generic
f5  target.memory.read-generic
```

and capability bits 7 and 8, but does not disclose a complete request or
response layout. These codes are identifiers only in this edition.

### 13.7 ARM7/9 memory write (`f7`) — `decoder-only`

```text
H→P  f7
     total_ir_bits:u8
     device_count:u8
     target_position:u8
     ir_pre_bits:u8
     is_arm9:u8
     is_big_endian:u8
     reserved:u16le
     suboperation:u8
     address:u32le
     length:u32le
     data:bytes[length]

P→H  status:u8
```

Known status values:

| Status | Meaning                |
| -----: | ---------------------- |
|      0 | Success                |
|      1 | Adaptive-clock timeout |
|      2 | Memory-access timeout  |
|      3 | Core error             |

`target_position` is the number of scan-chain devices before the target when
counted from TDO. `ir_pre_bits` is the combined instruction-register length
before the target. `is_arm9` and `is_big_endian` are Boolean bytes. The reserved
field is zero and the documented suboperation is normally 1.

Historical worked example, writing byte `ab` to address `0x12345678`:

```text
H→P  f7 04 01 00 00 00 00 00 00 01 78 56 34 12 01 00 00 00 ab
P→H  00
```

### 13.8 ARM7/9 memory read (`f8`) — `decoder-only`

The request is the write header without data:

```text
H→P  f8
     total_ir_bits:u8
     device_count:u8
     target_position:u8
     ir_pre_bits:u8
     is_arm9:u8
     is_big_endian:u8
     reserved:u16le
     suboperation:u8
     address:u32le
     length:u32le
```

The first response byte uses the same status table as the write operation. The
manual then describes both:

```text
data:bytes[length]
```

and, for an error path:

```text
error_address:u32le
failed_access_width:u32le
```

but gives overlapping conditions: its data condition includes success _or_ reads
no larger than 0x40, while its diagnostic condition includes failure _or_ reads
larger than 0x40. Those statements overlap for small failures and large
successes. The one-byte success example returns status in one transaction
followed by the data byte in another, confirming at least the small-success
case:

```text
H→P  f8 04 01 00 00 00 00 00 00 01 10 00 00 00 01 00 00 00
P→H  00
P→H  18
```

Large reads and all failure cases require capture validation before
implementation.

## 14. Persistent probe configuration

<!-- claim-coverage:JLP-CONFIG-* -->

### 14.1 Read and write operations

```text
probe.configuration.read (f2)
H→P  f2
P→H  configuration:bytes[256]

probe.configuration.write (f3)
H→P  f3  configuration:bytes[256]
P→H  <none>
```

The block is nonvolatile probe state. A host MUST require the corresponding
capability bit. A writer MUST first read the complete block, modify only known
bytes, and write all 256 bytes back unchanged elsewhere. It MUST NOT synthesize
reserved bytes from a table or assume erased bytes are always `ff` on every
firmware.

Because the read length is 256, it commonly triggers the exact-packet/ZLP issue
in section 5.5.

The controlled read submitted room for 2048 bytes and completed with exactly 256
application bytes. The contents were intentionally neither printed nor retained
in this artifact; only length, completion status, and transport behavior were
recorded.

### 14.2 Historical configuration map

|    Offset | Size | Meaning                        | Values                                                     |
| --------: | ---: | ------------------------------ | ---------------------------------------------------------- |
|      `00` |    1 | Legacy USB address             | 0–3; `ff` default                                          |
| `01`–`03` |    3 | Reserved                       | historically `ff`                                          |
| `04`–`07` |    4 | Default auxiliary target power | `u32le`: `0xffffffff` default/on if supported, 0 off, 1 on |
| `08`–`1f` |   24 | Reserved                       | historically `ff`                                          |
| `20`–`23` |    4 | Static IPv4 address            | network-order octets; all `ff` unset                       |
| `24`–`27` |    4 | IPv4 subnet mask               | network-order octets; all `ff` unset                       |
| `28`–`2f` |    8 | Reserved                       | historically `ff`                                          |
| `30`–`35` |    6 | MAC address                    | wire order; all `ff` unset                                 |
| `36`–`ff` |  202 | Reserved                       | historically `ff`                                          |

Changing legacy USB address can change the PID after re-enumeration. Modern
software should select probes by serial number instead. A configuration write
has no application acknowledgement and can change connectivity or target power
after reset; it SHOULD be exposed only through an explicit, verified
administrative action with a saved backup block.

## 15. SWO capture service

<!-- claim-coverage:JLP-SWO-* -->

All known SWO requests begin with operation `eb`, a suboperation, zero or more
local TLVs, and a zero terminator.

Current probe-rs requires SWD (interface 1) to be selected before starting
capture. Hardware with separate trace facilities may have broader combinations,
but a conservative client SHOULD select SWD, then restore target clock
configuration, unless the particular probe/interface pairing has been validated.

Known TLV tags:

| Tag | Length | Meaning                                        |
| --: | -----: | ---------------------------------------------- |
|   1 |      4 | Capture mode `u32le`; known mode 0 is UART/NRZ |
|   2 |      4 | Requested baud rate `u32le`                    |
|   3 |      4 | Requested read size `u32le`                    |
|   4 |      4 | On-probe capture-buffer size `u32le`           |

Unknown tags SHOULD be ignored by a decoder but MUST NOT be emitted without
evidence.

### 15.1 `swo.capture.start` — suboperation `64`

```text
H→P  eb 64
      04 01 mode:u32le
      04 02 baud:u32le
      04 04 buffer_size:u32le
      00

P→H  status_or_flags:u32le
```

The currently implemented mode is zero. Current libjaylink requires the response
to be zero; other code treats related SWO status words as bit flags. Until
traces establish otherwise, zero MUST mean success and any nonzero value SHOULD
fail the start while preserving the raw word.

The requested buffer MUST fit available on-probe workspace.
`probe.workspace.read` is a useful upper hint, not proof that the entire amount
is allocatable.

### 15.2 `swo.capture.stop` — suboperation `65`

```text
H→P  eb 65 00
P→H  status_or_flags:u32le
```

Zero is success. The host SHOULD stop capture before changing interfaces,
closing, or restarting SWO.

### 15.3 `swo.data.read` — suboperation `66`

```text
H→P  eb 66  04 03 requested:u32le  00
P→H  flags:u32le  actual:u32le  data:bytes[actual]
```

Known flag bit 0 indicates capture-buffer overrun. A host MUST check
`actual <= requested` before allocating or reading. Unknown flag bits MUST be
retained. Data is raw SWO bytes; decoding ITM, DWT, or other trace packets is a
higher layer.

Public Rust code warns that repeated undersized reads can reset at least some
probes. A host SHOULD select a read buffer comparable to the configured on-probe
buffer, poll frequently enough to avoid overrun, and drain all reported bytes.

### 15.4 `swo.clock.describe` — suboperation `6e`

```text
H→P  eb 6e  04 01 mode:u32le  00

P→H  total_length:u32le       # expected 28
      reserved:u32le
      base_hz:u32le
      minimum_divisor:u32le
      maximum_divisor:u32le
      minimum_prescaler:u32le
      maximum_prescaler:u32le
```

The first word is either response length 28 or, if its high bit is set, an error
word. Public code validates nonzero minimum divisor and ordered min/max ranges.
Two Rust clients compute the maximum rate as
`base_hz / minimum_divisor / max(1, minimum_prescaler)`, suggesting the general
candidate family `base_hz / divisor / max(1, prescaler)` over the advertised
integer ranges. That full combination rule was not independently demonstrated in
a public trace. A host SHOULD choose only values generated by a tested reference
client or verified on the particular probe.

Observed mode-0 request and response:

```text
H→P  eb 6e 04 01 00 00 00 00 00
P→H  1c 00 00 00  00 00 00 00  00 a2 4a 04  12 00 00 00
     ff 1f 00 00  00 00 00 00  00 00 00 00
```

This decodes to length 28, reserved zero, base 72,000,000 Hz, divisors 18
through 8191, and prescaler bounds both zero. Under the public clients'
`max(1, prescaler)` interpretation, the nominal maximum is 4 MHz. The entire
28-byte response arrived in one IN completion.

## 16. Connection-registration service

<!-- claim-coverage:JLP-REGISTRATION-* -->

`probe.connection.manage` uses operation `09` with these suboperations:

| Suboperation | Meaning                                 |
| -----------: | --------------------------------------- |
|         `64` | Register or refresh a client connection |
|         `65` | Unregister a client connection          |

### 16.1 Request

Both suboperations use the same 14-byte request:

```text
H→P  09
     suboperation:u8
     process_id:u32le
     host_id:bytes[4]
     interface_id:u8
     connection_id:u8
     handle:u16le
```

`host_id` is an IPv4 address as four network-order octets. USB clients normally
use `0.0.0.0`; current public examples also use zero for `process_id`,
`interface_id`, and `connection_id`. To register a new connection, send handle
zero. To unregister, send the nonzero handle returned by registration.

The semantic domains of `interface_id` and `connection_id` are not publicly
explained. They MUST NOT be equated with target-interface selectors merely
because one field shares the word “interface.”

### 16.2 Response

The reply has an eight-byte header, a table of fixed-size entries, and opaque
extra information:

```text
P→H  result_handle:u16le
     entry_count:u16le
     entry_size:u16le
     extra_size:u16le
     entries:bytes[entry_count × entry_size]
     extra:bytes[extra_size]
     padding:bytes[...]               # response is at least 76 bytes
```

Current public code requires:

```text
entry_count <= 16
entry_size  == 16
8 + entry_count × entry_size + extra_size <= 512
```

It first reads 76 bytes and then, if the calculated meaningful size is larger,
reads the remainder. A compatible decoder SHOULD accept and ignore padding
between the meaningful end and byte 76. It MUST bound all arithmetic before
reading.

Each 16-byte table entry is:

```text
process_id:u32le
host_id:bytes[4]                 # network-order IPv4 octets
interface_id:u8
connection_id:u8
handle:u16le
last_registration_ms:u32le      # relative to probe power-up
```

A new registration succeeds only if `result_handle` is nonzero **and** that
handle appears in the returned table. A nonzero returned handle alone is
insufficient when the table is full.

### 16.3 Compatibility policy

Capability bit 27 indicates service existence, but at least one current client
avoids registration on most probes because some devices do not tolerate the
request; it enables it for a known clone that requires a handle. Accordingly:

- do not register by default merely because bit 27 is set;
- maintain a tested allow/require quirk table;
- if registering, unregister during orderly close;
- do not assume a lost process has removed its table entry immediately.

## 17. Emulator communication channels

<!-- claim-coverage:JLP-CHANNEL-* -->

`probe.channel.transfer` uses operation `ee`. Public code commonly calls it
EMUCOM. “Channel” says what the wire abstraction actually is: a numbered byte
channel.

### 17.1 Status-word convention

For this family only, a `u32le` response with bit 31 clear is a byte count.
Known high-bit values are:

|                     Value/pattern | Meaning                                                          |
| --------------------------------: | ---------------------------------------------------------------- |
|                      `0x80000001` | Channel unsupported                                              |
| `0x81000000` plus available count | Requested amount unavailable; low 24 bits report available bytes |
|   any other value with bit 31 set | Device error                                                     |

The `0x81000000` form is documented by current public client code for reads. A
decoder MUST test the exact/patterned values before interpreting the word as a
length.

### 17.2 Channel read — suboperation `00`

```text
H→P  ee 00  channel:u32le  requested:u32le
P→H  status_or_actual:u32le
      data:bytes[actual]             # only when high bit is clear
```

The host MUST verify `actual <= requested`. A successful zero count is a valid
empty read.

### 17.3 Channel write — suboperation `01`

```text
H→P  ee 01  channel:u32le  length:u32le  data:bytes[length]
P→H  status_or_actual:u32le
```

On success, the returned value is the number of bytes accepted and MUST NOT
exceed `length`. Partial writes are possible and MUST be surfaced.

### 17.4 Channel allocation

Known channel zero is read-only and returns the probe's millisecond uptime as
four little-endian bytes. Channels below `0x00010000` are reserved. User-defined
channels begin at `0x00010000`. Availability and semantics beyond channel zero
depend on probe firmware or on-probe applications.

## 18. On-probe file service

<!-- claim-coverage:JLP-FILE-* -->

`probe.file.manage` uses operation `1e` and a local TLV header. Known
suboperations are:

| Suboperation | Semantic name       |
| -----------: | ------------------- |
|         `64` | `probe.file.read`   |
|         `65` | `probe.file.write`  |
|         `66` | `probe.file.size`   |
|         `67` | `probe.file.delete` |

Every request begins:

```text
1e  suboperation  00  TLVs...  00
```

Known TLV tags are:

| Tag | Value                                            |
| --: | ------------------------------------------------ |
|   1 | Filename bytes, length 1–255, no terminating NUL |
|   2 | File offset `u32le`                              |
|   3 | Data length `u32le`                              |

### 18.1 Family status convention

For this family only, a returned `u32le` with bit 31 set is a device error.
Otherwise it is a file size or actual byte count. Public code does not expose a
finer error taxonomy.

Filenames are raw bytes at the wire layer. A host SHOULD reject path traversal,
separators, control bytes, and platform-dependent encodings unless it
intentionally exposes the probe's full file namespace.

### 18.2 File read

```text
H→P  1e 64 00
      name_length 01 name:bytes[name_length]
      04 02 offset:u32le
      04 03 requested:u32le
      00

P→H  buffer:bytes[requested]
P→H  actual_or_error:u32le
```

The current public implementation always reads the requested-size buffer before
reading the final word, then treats only the first `actual` bytes as meaningful.
Bytes from `actual` through `requested - 1` are padding or undefined. The host
MUST validate `actual <= requested` and MUST NOT expose padding as file content.

That fixed-buffer ordering is implementation evidence, not capture-verified
failure behavior. A client that receives fewer than `requested` buffer bytes
before the status word cannot distinguish an early error word from file bytes
without additional framing; it SHOULD treat the session as ambiguous and recover
rather than guess.

### 18.3 File write

```text
H→P  1e 65 00
      name_length 01 name:bytes[name_length]
      04 02 offset:u32le
      04 03 length:u32le
      00
H→P  data:bytes[length]

P→H  actual_or_error:u32le
```

The header and data may be separate bulk OUT transfers. A successful count
smaller than `length` is a partial write and MUST be reported or retried
deliberately; it is not full success.

### 18.4 File size and delete

```text
H→P  1e 66 00  name_length 01 name 00
P→H  size_or_error:u32le

H→P  1e 67 00  name_length 01 name 00
P→H  status:u32le
```

For delete, any high-bit value is an error. Current public code accepts every
high-bit-clear value and does not interpret the low 31 bits; zero is the
ordinary success value, while positive values remain semantically unknown and
SHOULD be logged.

The pinned public library caps a single read or write at `0x100000` bytes (1
MiB). That is an implementation safety limit, not proven wire capacity. Large
files SHOULD be transferred in smaller offset-based pieces regardless.

## 19. Silicon Labs C2 service

<!-- claim-coverage:JLP-C2-* -->

`c2.transfer` uses operation `17` after selecting target interface 6.

Known suboperations:

| Value | Meaning                |
| ----: | ---------------------- |
|  `00` | Read data register     |
|  `01` | Write data register    |
|  `02` | Read address register  |
|  `03` | Write address register |

### 19.1 Reads

```text
H→P  17  suboperation  00  length:u16le
P→H  data:bytes[length]  status:u32le
```

For address-register read (`02`), length is exactly 1. Data-register reads use
`00`.

### 19.2 Writes

```text
H→P  17  suboperation  length:u16le  00  data:bytes[length]
P→H  status:u32le
```

For address-register write (`03`), length is exactly 1. Data-register writes use
`01`.

Known success status is zero; any nonzero word is an undifferentiated device
error. Current libjaylink limits a data-register operation to 64 bytes even
though the wire length field is 16 bits. That 64-byte value SHOULD be used as a
conservative default, not presented as a proven protocol maximum.

There is no separate public C2 capability bit in the sources inspected.
Availability is established by interface bit 6; the host MUST select it before
using operation `17`.

## 20. Target SPI service

<!-- claim-coverage:JLP-SPI-* -->

`spi.transfer` uses operation `15`, suboperation `01`, capability bit 56, and
target interface 5. The publicly implemented form makes the probe an SPI master
in mode 3 (`CPOL=1`, `CPHA=1`) and shifts each byte most-significant bit first.

### 20.1 Request and response

```text
H→P  15 01 00 00
     tx_section_length:u32le
     rx_section_length:u32le
     bit_count:u32le
     flags:u32le
     tx_data:bytes[tx_length]

P→H  rx_data:bytes[rx_length]
     transferred_bytes:u32le
```

In the observed public API:

```text
tx_section_length = tx_length + 8
rx_section_length = rx_length + 4
bit_count         = transfer_length_bytes × 8

tx_length = transfer_length_bytes when transmitting, otherwise 0
rx_length = transfer_length_bytes when receiving, otherwise 0
```

At least one of transmit or receive MUST be enabled. Both nonzero gives
full-duplex exchange; transmit zero gives receive-only clocks; receive zero
gives transmit-only. On success, `transferred_bytes` is expected to equal
`bit_count / 8`.

Although the wire carries a bit count, current public code exposes only
whole-byte operations. Non-byte-aligned transfers are not specified by this
edition.

### 20.2 Chip-select flags

Known flag values are composed from one start action and one end action:

| Mask/value | Action                                      |
| ---------: | ------------------------------------------- |
| start `00` | Leave chip select unchanged before transfer |
| start `02` | Drive chip select low before transfer       |
| start `03` | Drive chip select high before transfer      |
|   end `00` | Leave chip select unchanged after transfer  |
|   end `08` | Drive chip select low after transfer        |
|   end `0c` | Drive chip select high after transfer       |

This permits chip select to remain asserted across multiple operations. A host
MUST deliberately restore the intended final level after a multi-part
transaction and SHOULD do so during error cleanup if the probe remains
responsive.

## 21. Errors and status values

<!-- claim-coverage:JLP-VALIDATION-*,JLP-SCAN-V3-STATUS-*,JLP-SCAN-WRITE-STATUS-*,JLP-MEMORY-ARM79-STATUS-*,JLP-RTCK-STATUS-*,JLP-SWO-*,JLP-REGISTRATION-*,JLP-CHANNEL-*,JLP-FILE-*,JLP-C2-STATUS-*,JLP-SPI-* -->

There is no global status-code namespace. The same numeric value can have
unrelated meaning in another family.

| Family          | Status location       | Known convention                                                                             |
| --------------- | --------------------- | -------------------------------------------------------------------------------------------- |
| Scan v3         | trailing `u8`         | 0 success; 6 insufficient workspace                                                          |
| Write-only scan | later `d6` `u8`       | sticky, read-and-clear; 0 success                                                            |
| ARM7/9 memory   | leading/trailing `u8` | 0 success; 1 adaptive timeout; 2 memory timeout; 3 core error                                |
| DCC write       | `u8`                  | 0 success; 1 timeout                                                                         |
| CPU operation   | `u32le`               | 0 success; positive bytes not transferred                                                    |
| RTCK measure    | first `u32le`         | 0 success; 1 no reaction                                                                     |
| SWO             | `u32le`               | suboperation-dependent status or flags                                                       |
| Registration    | header and table      | nonzero handle plus matching table entry                                                     |
| Channel         | first `u32le`         | high bit error; otherwise count                                                              |
| File            | final `u32le`         | high bit error; otherwise count/size                                                         |
| C2              | trailing `u32le`      | 0 success; nonzero device error                                                              |
| SPI             | trailing `u32le`      | transferred-byte result count must equal `bit_count / 8`; it is not a documented status code |

For every variable-length reply, a host MUST validate the count against both the
request and a configured resource limit before allocating or reading. Length
arithmetic MUST be checked for overflow. Error-path payloads MUST be parsed by
that operation's rules, not by assuming a common header.

## 22. State and side effects

<!-- claim-coverage:JLP-STATE-*,JLP-CLEANUP-OWNERSHIP-001 -->

J-Link is not a stateless request/response service. The host should model at
least these state variables:

| State                     | Created/changed by | Cleared or consumed by                                      | Persistence notes                               |
| ------------------------- | ------------------ | ----------------------------------------------------------- | ----------------------------------------------- |
| Selected target interface | `c7` selection     | another `c7` selection                                      | May survive close/reconnect                     |
| Target clock rate         | `05`               | interface selection or another `05`                         | Set after every interface selection             |
| Direct pin levels         | `c9`–`df` family   | inverse pin operation, pulse, reset, or disconnect behavior | Crash can prevent cleanup                       |
| Write-only scan error     | `d5` failure       | `d6` read-and-clear                                         | Sticky across a batch; exact scope unproven     |
| SWO capture/buffer        | `eb 64`            | `eb 65`, probe reset, possible errors                       | Must be polled to avoid overrun                 |
| Connection handle         | `09 64`            | `09 65` or device policy                                    | Table is shared with other clients              |
| SPI chip-select level     | `15 01` flags      | later SPI flags or reset                                    | Can intentionally span operations               |
| Nonvolatile configuration | `f3`               | later `f3`                                                  | Survives power cycles; may change enumeration   |
| On-probe files            | `1e 65/67`         | write/delete                                                | Persistent behavior depends on firmware/storage |

An implementation SHOULD represent these explicitly rather than scatter them
across call sites. Cleanup should be best-effort and idempotent. It MUST NOT
perform surprising electrical or persistent cleanup—for example, turning off
user-requested target power—without a documented ownership policy.

## 23. Where the sources disagree

<!-- claim-coverage:JLP-VERSION-*,JLP-INTERFACE-*,JLP-CAP-*,JLP-WORKSPACE-*,JLP-SCAN-*,JLP-CPU-*,JLP-MEMORY-*,JLP-SWO-*,JLP-SESSION-REGISTRATION-001,JLP-VALIDATION-UNKNOWN-001 -->

| Topic                        | Public conflict                                                                                                                                       | Treatment in this guide                                                                                                                                              | What would settle it                                                           |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| Version length               | Historical worked example prints one length byte; field table and clients use `u16le`                                                                 | Consume two bytes; one current probe returned `70 00` as a dedicated transfer                                                                                        | Raw captures from old V3/V4 and additional current probes                      |
| Version body                 | Common summaries model one NUL-terminated version string; one observed body contained two strings plus padding                                        | Treat it as an opaque length-delimited record; the first field is the display string                                                                                 | Survey other products and firmware generations                                 |
| Interface ID range           | Manual says 1–31 while also defining JTAG as 0                                                                                                        | IDs 0–31 can be selected                                                                                                                                             | Boundary tests on modern genuine probes                                        |
| SWD selector                 | Manual example uses 2; table, code, and OpenOCD correction use 1                                                                                      | SWD is 1                                                                                                                                                             | No longer considered materially uncertain                                      |
| Long capability gate         | Historical short table calls bit 31 reserved; long table/clients need it as a gate                                                                    | Bit 31 means long-query support                                                                                                                                      | Survey bitsets across firmware generations                                     |
| Workspace value `d4`         | “Maximum memory block,” “free memory,” and operational chunk hint; observed value 11,608 does not distinguish them                                    | Treat as a workspace ceiling/hint                                                                                                                                    | Correlate with scan/SWD/SWO maximums                                           |
| One-clock sample `c8`        | Historical text names TDI, though TDO is the natural JTAG input                                                                                       | Preserve “sampled pin” ambiguity                                                                                                                                     | Electrical test or vendor capture                                              |
| Write-only scan code         | Detailed historical page prints `cf`; index, capability, and clients use `d5`                                                                         | Use `d5`                                                                                                                                                             | Consider resolved absent contrary trace                                        |
| ARM7/9 read response         | Data and diagnostic conditions overlap                                                                                                                | Only small-success path specified                                                                                                                                    | Large success and every failure combination                                    |
| CPU memory read              | Response result is given but returned data location is omitted                                                                                        | Read response unresolved                                                                                                                                             | Trace reference client using high-level CPU read                               |
| Scan capacity                | Historical buffers are 2 KiB; wire permits 65,535 bits; modern devices have smaller/larger quirks                                                     | Per-device conservative limit                                                                                                                                        | Matrix across standalone and OB hardware                                       |
| Exact-packet termination     | Historical text is fixed to 64-byte full-speed packets; observed host-visible completions include both inferred-ZLP and no-follow-up-completion cases | An exact known-length read ends when all application bytes arrive; a surplus-capacity read must consume USB termination; never perform a speculative terminator read | Raw packet captures across more probe, speed, and host-controller combinations |
| Version-based feature gating | Manual maps scan generations to hardware versions; OB numbering is inconsistent                                                                       | Gate by capabilities and tested quirks                                                                                                                               | Firmware/hardware survey                                                       |
| SWO result word              | Some clients treat nonzero as error; read path exposes overrun flags                                                                                  | Interpret per suboperation                                                                                                                                           | Start/stop failure and overrun captures                                        |
| Registration safety          | Capability advertises service, yet a current client avoids it on most probes                                                                          | Opt-in quirk, not universal initialization                                                                                                                           | Genuine multi-client behavior matrix                                           |

This table is not a choose-your-own-protocol menu. An implementation MUST NOT
erase an unresolved contradiction by choosing the convenient interpretation and
presenting it as established fact.

## 24. Building a host that survives real probes

<!-- claim-coverage:JLP-VALIDATION-*,JLP-TRANSACTION-*,JLP-STATE-*,JLP-CLEANUP-OWNERSHIP-001,JLP-UNKNOWN-*,JLP-ADMIN-AUTHORIZATION-001 -->

### 24.1 Transport abstraction

A useful transport API separates application expectations from USB mechanics:

```text
write_all(application_bytes)
read_application_exact(expected_length, in_endpoint_mps)
transaction(request, expected_response_length)
```

`read_application_exact` should arrange for correct short-packet/ZLP
consumption, return exactly the application length, and reject unexpected
nonzero surplus. It should not expose URB boundaries to operation decoders.

The transaction layer MUST serialize operations. Timeouts SHOULD name both the
USB action and the semantic operation in diagnostics. On any partial read or
ambiguous timeout, it SHOULD poison the session so ordinary calls cannot
continue until recovery.

### 24.2 Decoder discipline

Every operation decoder SHOULD follow this order:

1. Calculate the fixed minimum response size using checked arithmetic.
2. Read only the portion needed to obtain length/count fields.
3. Validate magic values, bounds, count relationships, and family-specific
   status.
4. Calculate the remainder with checked arithmetic.
5. Enforce a caller and implementation maximum.
6. Read the remainder.
7. Return unknown bits and raw status alongside interpreted fields.

Never allocate directly from a probe-provided `u32`. Never multiply an
unvalidated table count by an entry size. Never interpret a high-bit error word
as a 2+ GiB length.

### 24.3 Capability and quirk policy

A capability bit means the firmware claims a feature; it does not prove every
request shape or boundary works. The recommended decision order is:

1. capability/interface advertisement;
2. protocol field constraints;
3. known device/firmware quirks;
4. conservative implementation limit;
5. user override for controlled experiments.

Log the raw VID, PID, serial, descriptors, version string, hardware version,
short and long capabilities, selected interface, and chunk limits whenever a
compatibility decision changes behavior.

### 24.4 Electrical and persistent-operation safety

The following operations can reset, power, hold pins on, write target memory,
alter probe enumeration, or modify persistent storage:

```text
02 03 08 15 17 1e  c9–df  ea  f1 f3 f4 f7
```

This list is conservative, not exhaustive. A general-purpose analyzer SHOULD
default to read-only decoding. A client SHOULD require explicit user
authorization for target power and persistent configuration/file writes. Fuzzing
SHOULD exclude these families until performed on sacrificial hardware with
current limiting and a recovery plan.

### 24.5 Conformance levels

| Level               | Required behavior                                                                             |
| ------------------- | --------------------------------------------------------------------------------------------- |
| Transport decoder   | USB descriptor binding, directional reassembly, exact-packet/ZLP handling, opcode recognition |
| Discovery client    | Version, capabilities, hardware version/state, interface query                                |
| Basic debug client  | Explicit interface selection, rate setting, scan v3, bounded recovery                         |
| SWD/JTAG client     | Correct bit packing, direction semantics, per-device chunking, sticky scan handling           |
| Service client      | Family-specific validation for SWO, registration, channels, files, C2, or SPI                 |
| Experimental client | Evidence logging and explicit opt-in for unresolved/historical operations                     |

This guide does not cover enough of the protocol to support a claim of full
J-Link conformance. Important high-level memory, trace, firmware, indicator, and
network operations remain unspecified.

## 25. Wire examples

### 25.1 Version string

```text
H→P  01
P→H  0f 00  4a 2d 4c 69 6e 6b 20 65 78 61 6d 70 6c 65 00
```

This synthetic reply declares 15 record bytes whose first field is a
trailing-NUL version string. It is a format example, not an observed firmware
string; a real record may contain later NUL-delimited fields and padding.

### 25.2 Hardware state

Historical observed example:

```text
H→P  07
P→H  c3 0c 01 00 00 00 01 01
```

`0x0cc3 = 3267`, so target reference voltage is 3.267 V. TCK, system reset, and
TRST read high; TDI, TDO, and TMS read low.

### 25.3 Mask-ordered hardware fields

```text
H→P  c1 05 00 00 00
```

Mask `0x00000005` requests bits 0 and 2. The response contains two words in that
order:

```text
P→H  01 00 00 00  0c 00 00 00
```

Auxiliary target power is enabled and target current is 12 mA. There are no tags
in the response.

### 25.4 Target clock

```text
H→P  05 a0 0f       # 4000 kHz
```

The request has no application response. A subsequent state/query operation is a
new transaction, not an acknowledgement byte.

### 25.5 C2 address read

```text
H→P  17 02 00 01 00
P→H  7f 00 00 00 00
```

The address-register byte is `7f`; the trailing `u32le` status is zero.

### 25.6 Channel availability error

```text
H→P  ee 00 00 00 01 00 00 04 00 00
P→H  23 01 00 81
```

This asks user channel `0x00010000` for 1024 bytes. The synthetic reply is
`0x81000123`, meaning the requested amount is unavailable and 291 bytes are
presently available. It is not a 2.16 GiB successful length.

## 26. Capturing the remaining unknowns

This section describes experiments, not host-driver behavior, and contains the
capture procedure needed to extend this guide. Future editions should be driven
by reproducible captures in which one controlled action maps to one change on
the wire. A bucket of hex dumps is not a corpus.

### 26.1 Capture layer choices

Software capture records host-controller requests (URBs), not literal D+/D− or
SuperSpeed packets. That is usually the right layer for reconstructing
application bytes because it exposes complete bulk payloads and transfer status.

- On Linux, use usbmon and capture the relevant bus in Wireshark or dumpcap.
- On Windows, use USBPcap with Wireshark.
- On macOS, Wireshark documents the XHC20 interface where supported.
- Use a hardware USB analyzer when packet-level timing, retries, handshakes, bus
  resets, or exact ZLP behavior—not merely URB payloads—must be proven.

Wireshark's
[USB capture setup guide](https://wiki.wireshark.org/CaptureSetup/USB) explains
the platform mechanisms and the distinction between host-stack and hardware
capture.

### 26.2 Record complete experiment metadata

Every capture should include a machine-readable sidecar with:

```text
capture UUID and UTC time
host OS, kernel, USB backend, and capture tool versions
USB topology, bus/address, VID/PID, speed, and complete descriptors
probe serial number (redacted copy may also be published)
firmware version string and hardware version
short and long capability bytes
available and selected target interfaces
bulk endpoint addresses and maximum packet sizes
target board, voltage, scan chain, and wiring
reference-client product and exact version
single experiment action and expected effect
capture SHA-256
```

Without this metadata, two differing captures cannot be attributed to firmware,
hardware, target, driver, or experiment variation.

### 26.3 Minimal experiment matrix

Begin with a genuine probe and a noncritical target. Repeat each item in a fresh
capture:

1. Enumerate but do not open the reference client.
2. Open, remain idle, and close.
3. Query only probe information.
4. Query and select JTAG; repeat for SWD.
5. Set three target rates, varying only the rate.
6. Perform one JTAG scan with a recognizable single-bit pattern.
7. Perform one SWD read and one SWD write at a known address.
8. Assert and release each reset through the reference UI.
9. Start SWO, read no data, read known data, provoke a controlled overrun, stop.
10. Exercise registration with two simultaneous clients on hardware that
    supports it.
11. Read a small on-probe file; then vary offset and size one at a time.
12. Exercise C2 and SPI only on expendable, correctly wired targets.

For each request family, repeat with boundary sizes around:

```text
1, 7, 8, 9 bits
mps_in - 1, mps_in, mps_in + 1 bytes
255, 256, 257 bytes
known workspace/chunk boundary - 1, boundary, boundary + 1
```

Change one variable per capture. Repeat the same operation at least three times
to separate stable fields from counters, handles, timestamps, and uninitialized
padding.

### 26.4 Reconstructing application byte streams

For each captured USB device/interface:

1. Pair URB submission and completion records by URB identifier.
2. For OUT, take the payload from the record where the capture backend actually
   exposes it, normally submission.
3. For IN, take returned payload from completion.
4. Discard failed/cancelled transfers but record their status and timing.
5. Preserve successful zero-length transfers as transport events.
6. Concatenate application payload in time order separately for OUT and IN.
7. Use the single-outstanding-operation rule to alternate request decoding and
   expected response consumption.
8. Do not insert message boundaries at URB boundaries.

A capture tool should emit both a lossless event stream and a decoded view, for
example:

```json
{
  "time_ns": 123456,
  "direction": "host-to-probe",
  "endpoint": 2,
  "urb_id": "...",
  "payload_hex": "c7ff",
  "operation": "target.interface.manage",
  "fields": { "selector": 255 },
  "confidence": "H+I"
}
```

### 26.5 Inferring an unknown request

Use differential experiments rather than visual intuition:

1. Find the first stable request byte after a single reference-client action;
   treat it as a candidate operation code.
2. Repeat the action and mark volatile byte positions.
3. Change one scalar through asymmetric values such as `0x01`, `0x0102`, and
   `0x01020304` to expose width and endianness.
4. Change payload length across 255/256 and 65535 boundaries to locate length
   fields.
5. Use unequal sentinel regions (`11 22 33`, `a5 5a`) to find array ordering.
6. Test whether a zero byte terminates a TLV list or is merely reserved.
7. Compare success, target fault, timeout, and insufficient-buffer responses.
8. Validate the inferred grammar on a second firmware and a second probe family
   before promoting it from `I` to `C`.

Never infer a field solely from a familiar constant name in decompiled code. The
goal is a wire grammar supported by controlled variation.

### 26.6 Safe fault experiments

Fault behavior is essential because it reveals status fields, but fault
injection should be staged:

1. start with read-only queries and disconnected-target errors;
2. use a current-limited supply and sacrificial target;
3. test malformed volatile scans before persistent services;
4. cap every generated length below host/probe allocation limits;
5. watchdog the reference client and USB device for hangs;
6. preserve a known firmware-recovery path;
7. never fuzz firmware update, raw configuration write, target power, file
   deletion, or target memory write in the initial campaign.

Protocol discovery does not justify testing clones or bypassing product
restrictions. Use hardware and software for which the experimenter has
permission, and review the historical manual's terms.

### 26.7 Corpus layout

A public corpus should use a stable layout such as:

```text
captures/<probe-family>/<firmware>/<experiment-id>/
    raw.pcapng
    metadata.json
    descriptors.txt
    action.md
    decoded.jsonl
    decoder-version.txt
    SHA256SUMS
```

Raw captures are the evidence. Decoded files are replaceable interpretations.
Never publish only screenshots or console hex dumps.

### 26.8 Priority unknowns for captures

1. Full initialization traffic from current SEGGER software across standalone
   and OB probes.
2. The complete generic memory operations `f4` and `f5`.
3. CPU read response ordering for `ea`.
4. ARM7/9 read behavior for large successes and failures.
5. Exact sampled pin for `c8`.
6. Meaning and predictive value of workspace result `d4` by operation family.
7. ZLP/short-packet behavior at full-, high-, and SuperSpeed endpoint sizes.
8. Registration compatibility and opaque extra-response bytes.
9. SWO start/stop flags, prescaler semantics, and overrun behavior.
10. Additional extended capability bits and their operation codes.
11. Error responses to unknown operation codes and malformed lengths.
12. Whether any firmware supports multiple pipelined operations despite the
    unframed responses.

## 27. What the search did not turn up

The search covered code hosts, mailing-list archives, documentation mirrors,
Wireshark resources, Gists, and the wider web. It did **not** turn up a
maintained public J-Link USB dissector or a reusable raw `pcap`, `pcapng`, or
usbmon capture corpus. That is a result about this search, not a claim about the
entire internet.

One
[public debug log](https://gist.github.com/cstrahan/a9dfcf6c96a611aecbf3daeb97341c41)
contains real descriptors, VID/PID, firmware and hardware metadata, and
capability output. It supports high-level discovery behavior but is not a raw
USB trace: transfer boundaries, zero-length transfers, and unparsed bytes are
gone. Historical OpenOCD discussion says developers made comparison captures,
but the accessible thread contains no raw attachments suitable for a corpus.

The host-side records in section 29 do not close that gap. They establish
behavior for one probe, one firmware build, and the named target/host setups;
they provide neither raw packet records nor device diversity. Broader captures
are the only good way to separate copied client assumptions from behavior shared
across the product family.

## 28. Sources and evidence ledger

### 28.1 Vendor and historical material

| Source                                                                                                          | Used for                                                                        | Caveat                                                               |
| --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| [SEGGER RM08001-R7 manual mirror](https://manualzilla.com/doc/5922275/reference-manual-for-j-link-usb-protocol) | Transport model, encoding, historical operations, capability map, configuration | Dated 2010; incomplete; contains contradictions; review source terms |
| [SEGGER J-Link VCOM knowledge base](https://kb.segger.com/J-Link_Virtual_COM_Port)                              | Composite-device topology and simultaneous VCOM/debug use                       | Describes current product behavior, not operation bytes              |
| [SEGGER OpenOCD knowledge base](https://kb.segger.com/OpenOCD)                                                  | Current OpenOCD positioning and WinUSB context                                  | Product guidance, not a protocol specification                       |
| [SEGGER J-Link OB product page](https://www.segger.com/products/debug-probes/j-link/models/j-link-ob/)          | Scope of embedded/on-board probe family                                         | Marketing/product material                                           |
| [SEGGER J-Link downloads](https://www.segger.com/downloads/jlink/)                                              | Reference-software provenance and current release discovery                     | Version changes over time                                            |

### 28.2 Pinned implementation evidence

| Source file                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Principal evidence                                                                               |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| [libjaylink `discovery_usb.c`](https://gitlab.zapb.de/libjaylink/libjaylink/-/blob/583faf19e11c6c4ef2551ae1572f6e416168a8f3/libjaylink/discovery_usb.c)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | VID/PID list, legacy USB-address mapping                                                         |
| [libjaylink `transport_usb.c`](https://gitlab.zapb.de/libjaylink/libjaylink/-/blob/583faf19e11c6c4ef2551ae1572f6e416168a8f3/libjaylink/transport_usb.c)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Interface discovery, endpoint directions, buffering, timeout policy                              |
| [libjaylink `device.c`](https://gitlab.zapb.de/libjaylink/libjaylink/-/blob/583faf19e11c6c4ef2551ae1572f6e416168a8f3/libjaylink/device.c)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Identity, status, capabilities, hardware fields, config, registration                            |
| [libjaylink `target.c`](https://gitlab.zapb.de/libjaylink/libjaylink/-/blob/583faf19e11c6c4ef2551ae1572f6e416168a8f3/libjaylink/target.c)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Clock and interface operations                                                                   |
| [libjaylink `jtag.c`](https://gitlab.zapb.de/libjaylink/libjaylink/-/blob/583faf19e11c6c4ef2551ae1572f6e416168a8f3/libjaylink/jtag.c)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Scan v2/v3 and direct pins                                                                       |
| [libjaylink `swd.c`](https://gitlab.zapb.de/libjaylink/libjaylink/-/blob/583faf19e11c6c4ef2551ae1572f6e416168a8f3/libjaylink/swd.c)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | SWD direction/value interpretation                                                               |
| [libjaylink `swo.c`](https://gitlab.zapb.de/libjaylink/libjaylink/-/blob/583faf19e11c6c4ef2551ae1572f6e416168a8f3/libjaylink/swo.c)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | SWO TLVs and reply layouts                                                                       |
| [libjaylink `emucom.c`](https://gitlab.zapb.de/libjaylink/libjaylink/-/blob/583faf19e11c6c4ef2551ae1572f6e416168a8f3/libjaylink/emucom.c)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Channel operation and high-bit statuses                                                          |
| [libjaylink `fileio.c`](https://gitlab.zapb.de/libjaylink/libjaylink/-/blob/583faf19e11c6c4ef2551ae1572f6e416168a8f3/libjaylink/fileio.c)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | File TLVs, fixed requested read buffer, status convention                                        |
| [libjaylink `c2.c`](https://gitlab.zapb.de/libjaylink/libjaylink/-/blob/583faf19e11c6c4ef2551ae1572f6e416168a8f3/libjaylink/c2.c)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | C2 suboperations and layouts                                                                     |
| [libjaylink `spi.c`](https://gitlab.zapb.de/libjaylink/libjaylink/-/blob/583faf19e11c6c4ef2551ae1572f6e416168a8f3/libjaylink/spi.c)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | SPI mode, header, flags, reply count                                                             |
| [libjaylink `libjaylink.h`](https://gitlab.zapb.de/libjaylink/libjaylink/-/blob/583faf19e11c6c4ef2551ae1572f6e416168a8f3/libjaylink/libjaylink.h)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Public interface and capability/service enumerations                                             |
| [jaylink Rust `src/lib.rs`](https://github.com/jonas-schievink/jaylink/blob/14bd3f4b8fb083bb477e64622e0e52bc440ce07d/src/lib.rs)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | Historical operation cross-check, initialization, scans, SWO; explicitly inspired by libjaylink  |
| [jaylink Rust `src/capabilities.rs`](https://github.com/jonas-schievink/jaylink/blob/14bd3f4b8fb083bb477e64622e0e52bc440ce07d/src/capabilities.rs)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | Capability namespace and bit-31 correction                                                       |
| [jaylink Rust `src/interface.rs`](https://github.com/jonas-schievink/jaylink/blob/14bd3f4b8fb083bb477e64622e0e52bc440ce07d/src/interface.rs)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Interface IDs, persistence notes, FINE quirk                                                     |
| [probe-rs J-Link module](https://github.com/probe-rs/probe-rs/blob/71a89c84b39a76b775211871a5ca08d2ef52817c/probe-rs/src/probe/jlink/mod.rs)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Descriptor matching, PID heuristic, MPS/ZLP workaround, chunk quirks, registration policy        |
| [probe-rs `capabilities.rs`](https://github.com/probe-rs/probe-rs/blob/71a89c84b39a76b775211871a5ca08d2ef52817c/probe-rs/src/probe/jlink/capabilities.rs), [`swo.rs`](https://github.com/probe-rs/probe-rs/blob/71a89c84b39a76b775211871a5ca08d2ef52817c/probe-rs/src/probe/jlink/swo.rs), [`connection.rs`](https://github.com/probe-rs/probe-rs/blob/71a89c84b39a76b775211871a5ca08d2ef52817c/probe-rs/src/probe/jlink/connection.rs), [`config.rs`](https://github.com/probe-rs/probe-rs/blob/71a89c84b39a76b775211871a5ca08d2ef52817c/probe-rs/src/probe/jlink/config.rs), and [`interface.rs`](https://github.com/probe-rs/probe-rs/blob/71a89c84b39a76b775211871a5ca08d2ef52817c/probe-rs/src/probe/jlink/interface.rs) | Exact supporting modules cited by claims in this guide                                           |
| [OpenOCD `src/jtag/drivers/jlink.c`](https://github.com/openocd-org/openocd/blob/cb52502e88832386610add9781030f5380344063/src/jtag/drivers/jlink.c)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Current adapter integration; directly delegates wire behavior to libjaylink                      |
| [Debian libjaylink 0.4.0 source](https://sources.debian.org/src/libjaylink/0.4.0-1/libjaylink/)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | Same project lineage as libjaylink; useful as a packaged snapshot, not independent corroboration |

### 28.3 Historical engineering discussion and capture methodology

| Source                                                                                                                                 | Used for                                                                           |
| -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| [OpenOCD J-Link protocol thread](https://sourceforge.net/p/openocd/mailman/openocd-devel/thread/20120529104315.4834.qmail%40stuge.se/) | Direct evidence that the public manual was incomplete and vendor captures differed |
| [OpenOCD interface-selector correction](https://sourceforge.net/p/openocd/mailman/message/33585145/)                                   | Confirmation that JTAG ID 0 is selectable and the historical range text is a typo  |
| [Wireshark USB capture setup](https://wiki.wireshark.org/CaptureSetup/USB)                                                             | Host capture methods and limitations                                               |
| [Public J-Link debug log](https://gist.github.com/cstrahan/a9dfcf6c96a611aecbf3daeb97341c41)                                           | Real-world descriptor/metadata corroboration, explicitly not raw capture evidence  |

### 28.4 Direct observation evidence

| Source                                                                 | Used for                                                                                                                                                                                  | Caveat                                                                                                                                        |
| ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| Controlled attached-probe session, 2026-07-15                          | USB descriptor profile; exact host-visible request/response bytes and transfer boundaries for documented read-only operations; liveness check after configuration read                    | One J-Link EDU Mini V2 and firmware; serial redacted; no raw host-controller packet capture; configuration contents suppressed                |
| Controlled attached-probe/DUT follow-up, 2026-07-15 through 2026-07-16 | Hardware fields and counters; JTAG/SWD mode behavior; SWO clock description; exact-packet scan boundaries; target-link versus probe-liveness behavior; RTCK lockup and reconnect recovery | Same probe and host; one Cortex-M0 DUT; no raw packet capture; target-specific decodes are outside this guide                                 |
| Controlled Cortex-A JTAG continuation, 2026-07-16                      | Successful v2/v3 JTAG samples; exact-packet response boundary; generic-scan transport of JTAG-DP transactions; state restoration and probe liveness                                       | Same probe and host; one Cortex-A-class DUT at 1.8 V; no raw packet capture; target architecture and component decodes are outside this guide |

### 28.5 Target-architecture sources

Arm architecture, CoreSight, silicon, firmware, and target-algorithm sources
formerly cataloged here moved with their findings to separate target research.
They are deliberately outside this USB-protocol guide.

## 29. Hardware observations

### 29.1 Method and safety boundary

These staged sessions used a genuine probe attached to the research host. The
harness read descriptors through ordinary USB control requests, claimed the
application interface in user space, and kept one operation outstanding at a
time. It recorded each application OUT payload and each host-visible IN
completion length. The fixed read-only list below describes the initial session;
later subsections mark every place where the safety boundary widened.

Because a stalled target-facing operation can leave the probe waiting for a
physical replug, the initial session sent only documented, read-only operation
codes:

```text
01  probe.version.read
07  probe.signal-state.read
c0  target.clock-rate.describe
c7  target.interface.manage, selectors ff and fe only
d4  probe.workspace.read
e8  probe.capabilities.read-short
ed  probe.capabilities.read-long
f0  probe.hardware-version.read
f2  probe.configuration.read
```

No interface was selected, no clock was changed, no reset or pin-drive operation
was issued, no target power was changed, no scan was performed, no
registration/file/channel service was entered, no persistent state was written,
and no unknown operation was tried. Configuration bytes were not displayed or
retained in this artifact. The USB serial number is intentionally omitted.

The host did not expose a usable host-controller capture interface. The record
therefore establishes bytes and completions as seen through the USB API, not
token-level packets, ACK/NAK traffic, microframe timing, or bus-level proof of a
ZLP.

### 29.2 USB descriptor profile

| Field                        | Observed value                                                                       |
| ---------------------------- | ------------------------------------------------------------------------------------ |
| Product                      | J-Link EDU Mini V2                                                                   |
| VID:PID                      | `1366:1020`                                                                          |
| Link speed                   | Full speed, 12 Mbit/s                                                                |
| `bcdUSB`                     | `0x0200`                                                                             |
| `bcdDevice`                  | `0x0100`                                                                             |
| Endpoint-zero maximum packet | 64 bytes                                                                             |
| Configurations               | 1                                                                                    |
| Active configuration         | value 1; total descriptor length 32 bytes                                            |
| Power attributes             | `0x80`, bus-powered; `bMaxPower = 50`, or 100 mA in USB 2.0 units                    |
| Application interface        | number 0, alternate 0, class/subclass/protocol `ff/ff/ff`                            |
| Interface endpoints          | exactly 2                                                                            |
| Bulk IN                      | `0x81`, maximum packet 64, interval 1                                                |
| Bulk OUT                     | `0x02`, maximum packet 64, interval 1                                                |
| Application topology         | one vendor-specific interface; no CDC-ACM/VCOM interface in the active configuration |

This profile validates descriptor-driven discovery and one common endpoint
layout. It does not make interface zero, OUT endpoint `0x02`, or 64-byte packets
universal.

### 29.3 Host-visible transaction transcript

The transaction order below is not a recommended initialization sequence; it is
an evidence log. `IN #n` denotes a distinct completed host USB read.

| Request | Host-visible response                                                               | Decode                                                    |
| ------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------- |
| `01`    | IN #1: `70 00`; IN #2: exactly 112 bytes                                            | `u16le` length 112, followed by a length-delimited record |
| `e8`    | `33 5a ea b8`                                                                       | short capability bitset `0xb8ea5a33`                      |
| `ed`    | 32 bytes beginning `33 5a ea b8 1c 7c b0 66 a1 40 0c 00`, then 20 zero bytes        | long bitset; first 32 bits equal the short response       |
| `f0`    | `20 4e 00 00`                                                                       | packed value 20,000: type 0, version 2.0.0                |
| `d4`    | `58 2d 00 00`                                                                       | workspace value 11,608                                    |
| `c7 ff` | `83 00 00 00`                                                                       | interfaces advertised: JTAG, SWD, cJTAG                   |
| `c7 fe` | `00 00 00 00`                                                                       | current interface: JTAG                                   |
| `c0`    | `00 d8 b8 05 18 00`                                                                 | base 96 MHz, minimum divisor 24, nominal maximum 4 MHz    |
| `07`    | `dc 0c 00 01 01 01 01 ff`                                                           | 3292 mV; TCK low; TDI/TDO/TMS/system-reset/tap-reset high |
| `f2`    | one successful IN completion of exactly 256 bytes from a 2048-byte submitted buffer | configuration length confirmed; contents suppressed       |

The 112-byte version record began with:

```text
J-Link EDU Mini V2 compiled Jun 25 2026 10:27:52\0
```

It continued with a second NUL-terminated copyright/URL field and zero padding.
The first response read had capacity for substantially more than two bytes, yet
the probe ended it after the `70 00` header. A second IN request was therefore
required for the body. This is observed transfer behavior, not merely a client
implementation choice.

The complete capability bytes and set-bit lists appear in section 9.3. Unknown
extended bits are preserved there without names.

### 29.4 Exact-packet inference and liveness check

The configuration read gave the cleanest view yet of exact-packet behavior. The
host requested up to 2048 IN bytes. The USB API reported successful completion
at 256 bytes, exactly four 64-byte maximum packets and less than the submitted
capacity. Normal bulk-transfer termination therefore strongly implies that the
probe sent a following zero-length packet. Because no packet capture was
available, this document does not label the unseen ZLP itself as directly
observed.

Immediately after that read, a complete two-stage `probe.version.read` succeeded
again. This verifies that no configuration bytes or inferred terminator remained
to poison the next application transaction, and that the probe was responsive at
the end of the session.

### 29.5 Follow-up method and risk ladder

The follow-up used a purpose-built libusb harness with no generic/raw-command
mode. Every operation was compiled into an allow list with a fixed request and
an exact or locally validated response grammar. The harness used a one-second
USB timeout, allowed only one outstanding operation, released the interface
after each test, reopened it after 100 ms, and ran a complete two-stage
`probe.version.read` liveness check. It never retried a failed state-changing
operation automatically.

Tests proceeded in these tiers:

1. probe-only hardware fields, counters, signal state, clock description, and
   SWO clock description;
2. five JTAG TAP-reset clocks and a bounded 64-bit IDCODE attempt on the
   already-selected interface;
3. advertised interface selection to SWD, a 100 kHz request, link activation,
   and target-debug reads;
4. architecturally defined target-debug recovery and selection writes, followed
   by identification reads;
5. bounded, read-only target-bus reads with address state saved and restored;
6. a 512-clock SWD line-reset boundary test designed to produce 64 sample bytes
   plus one status byte.

Through tier 6, the session did not assert probe or DUT reset pins, change
target power, halt the core, write target memory, change target-bus access
configuration, erase/program flash, enter registration/file/channel services,
start SWO capture, or send an unknown J-Link operation code. The small set of
target-debug selection, recovery, and address writes was saved or restored.

The campaign later requested every counter bit, performed bounded
target-component identification reads, and exercised a 512-bit v2 scan while
holding the JTAG TAP reset condition. The risk ladder eventually found the
command that justified it: the documented RTCK measurement unexpectedly wedged
the probe. Section 29.9 records the containment, failed automated recovery, and
subsequent physical-reconnect recovery.

After reconnect, the ladder continued with explicitly reversible halt/resume,
target-memory, core-register, and read-only vendor-ROM experiments. These later
tiers still did not assert reset, change target power, change target-bus access
configuration, erase or program flash, invoke a write-capable ROM command, or
expose target RAM contents in this artifact. A failed workspace or core-register
restoration was defined to leave the core halted rather than resume corrupted
application state. Target-specific ladders and restoration details remain
outside this USB-protocol release.

### 29.6 Probe telemetry and probe-only services

| Observation                        | Request                      | Response/result                                                                                                                                             |
| ---------------------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Basic hardware fields              | `c1 1f 1c 00 00`             | 32 zero bytes: auxiliary power off, no current or overcurrent history                                                                                       |
| USB-voltage field probe            | `c1 00 00 80 00`             | `ff ff ff ff`, validating the unsupported-field sentinel                                                                                                    |
| Counters, first sample             | `c2 03 00 00 00`             | 1,451,160 ms and one target-connect event                                                                                                                   |
| Counters, second sample            | same, about 5.17 s later     | 1,456,330 ms and one event; delta exactly 5,170 units                                                                                                       |
| Counters, after DUT tests          | same                         | 3,115,190 ms and one event; no physical disconnect was registered                                                                                           |
| Counters, after physical reconnect | same                         | 97,850 ms and one event; later 2,042,710 ms and one event, confirming the elapsed field restarted with probe power while the event counter restarted at one |
| All counter slots                  | `c2 ff ff ff ff`             | One 128-byte IN completion: bits 0..3 were 4,241,480, 1, 0, 0; bits 4..31 were `0xffffffff`                                                                 |
| SWO clock description              | `eb 6e 04 01 00 00 00 00 00` | 28-byte success: 72 MHz base, divisor 18..8191, prescaler 0..0                                                                                              |

The target reference reading ranged from 3292 to 3297 mV. Auxiliary target power
and measured auxiliary current remained zero, consistent with an externally
powered DUT. Every probe-only query and every post-operation version check
succeeded.

### 29.7 JTAG/SWD operation and USB boundaries

The starting selected interface was JTAG (0). JTAG v2 accepted five all-TMS-high
clocks and returned one sample byte. A bounded IDCODE scan produced no valid ID
and cannot distinguish an SWD-only target from electrical loopback or other
nonresponding-chain behavior. JTAG v3 returned its sample byte followed by
status `ff`; the probe remained responsive, and no larger JTAG v3 request was
sent.

Selecting advertised interface SWD (1) returned previous interface 0. Querying
current interface then returned 1. The host requested 100 kHz and sent the
standard 136-bit JTAG-to-SWD activation sequence. The probe returned 17 sample
bytes and status `00` as two separate IN completions.

Every 54-bit SWD transfer likewise returned seven sample bytes and then a
one-byte `00` probe status. The earlier source-informed decode placed the ACK at
the first input-direction bit and produced valid target values within each
monolithic scan. Later split-call HIL exposed the stricter probe-adapter
boundary described in section 12.1: target-input samples require a one-cycle
logical delay whose displaced bit survives into the next scan call. This is not
an extra architecture-level SWD turnaround cycle, and it is established only for
the recorded probe/firmware.

For the exact-packet test, a 512-bit request contained 504 high SWDIO clocks and
eight low idle clocks. The response was:

```text
IN #1: 64 sample bytes, all zero
IN #2: 00 status
```

The first host read had capacity for the entire 65-byte application response.
Its successful completion at exactly one 64-byte maximum packet therefore
strongly implies a terminating ZLP before the separate status transfer.

After restoring the probe to JTAG, a 512-bit v2 request held all control bits
high and all drive bits low. It returned one 64-byte sample completion
containing only `ff`; the host read capacity was 65 bytes. This provides the
same ZLP inference for v2, which has no trailing status field.

### 29.8 Generic scan transport validation

The Cortex-M follow-up used ordinary 54-bit `scan.transfer.v3` requests to carry
complete SWD reads and writes. Each request produced seven packed sample bytes
and a separate status byte. Target ACK and parity checks validated the
control/drive/sample indexing, while reversible target operations established
that the same J-Link wrapper carries both target reads and target writes. No
separate J-Link high-level memory operation was required.

The later JTAG follow-up used `scan.transfer.v2` to carry complete architected
target-debug transactions in bounded 40-clock vectors. The returned sample bytes
contained both TAP-transition samples and the target data-register samples. This
establishes the generic scan operation's expressive power across both observed
target interfaces; target-register, component, silicon, and restoration decodes
remain outside this USB-protocol release.

### 29.9 Failure behavior, automated recovery, and cleanup

Two deliberately contained SWD target-link failures produced no valid target
ACK. In both cases the probe continued to answer complete version queries.
Close/reopen did not by itself restore the target link, but an
advertised-interface toggle, clock reapplication, and link-activation sequence
recovered it without a USB reset, probe power cycle, target reset, or physical
replug. This demonstrates that target-protocol failure and probe USB liveness
are separate failure domains. Target-specific ACK, sticky-bit, and restoration
sequences remain outside this USB-protocol release.

The later RTCK experiment failed at a different layer: it took the probe down
with it. Immediately beforehand, the continuation had restored target-debug
state, selected the original JTAG interface, observed both reset pins
deasserted, measured 3295 mV, and passed repeated version checks. The `f6` OUT
transfer then succeeded, but its expected 16-byte response never arrived within
one second. The immediate close/reopen liveness check and a later standalone
version attempt both timed out on bulk OUT. A host-side USB device-reset attempt
did not restore application traffic and was followed by the device disappearing
from enumeration. No DUT reset, target-power change, or additional J-Link
application command was issued.

A physical unplug/replug recovered the same probe. It re-enumerated with the
same descriptors and firmware string, reported 3319 mV with both reset pins
deasserted, selected JTAG as its current interface, and reported counters of
97,850 ms and one connect event. A fresh version query and later target scans
succeeded. Physical reconnect is therefore a demonstrated recovery for this
exact lockup, while host USB reset is not.

### 29.10 Reversible target-write continuation

The Cortex-M continuation exercised halt/resume, one SRAM word, one core
register, and one read-only vendor-ROM call. All target traffic still used
ordinary 54-bit `scan.transfer.v3` requests with the same seven-sample-byte plus
one-status-byte response grammar as reads. Saved target state was read back
after restoration, the core resumed, both reset pins remained deasserted, and a
final close/reopen probe-version query succeeded.

A later Cortex-M0 reset qualification used the one-byte persistent pin
operations directly. With approximately 3.32 V target reference, signal-state
records changed raw nRESET from `01` to `00` after `dc` and back to `01` after
`dd`; both transitions were observed within 5 ms. Cleanup issued `dd`
unconditionally, closed and reopened the probe, issued `dd` again, confirmed
nRESET high, and completed the two-stage version query. A pre-armed Armv6-M
reset-vector catch then halted the actual DUT in its boot-ROM reset handler with
the observed boot vectors, after which the harness restored debug registers and
resumed execution. This is bounded evidence for the documented `dc`/`dd` pin
semantics on this probe, firmware, and wiring, not a universal reset guarantee.

The source research archive identifies this campaign as
`OBS-EDU-MINI-V2-CORTEXM-RESET-20260717-006`. This guide retains the wire
exchanges, signal changes, qualification boundary, negative SWD/TRST results,
and cleanup that matter to a reader. It intentionally does not embed harness
binaries, private execution logs, or target-specific artifacts. The physical
reset claims remain `research-only`; direct evidence grade does not by itself
change host-emission policy.

The stricter connect-under-reset qualification did **not** pass. A valid SWD DP
session returned IDCODE `0x0bb11477` before assertion, but direct DP reads
returned no target ACK while nRESET was observed low, both with and without a
fresh JTAG-to-SWD activation sequence. Post-release attempts at 1, 5, 20, and
100 ms likewise did not restore target ACK, although every probe-version query
succeeded. Physical nRESET, physical TRST, and their cleanup operations
therefore remain outside the conservative `core-host` profile. During the TRST
trial, raw signal byte `ff` did not change after `de` or `df`; without a wired,
responding JTAG target this proves neither physical TRST assertion nor target
behavior.

This validates the scan wrapper and probe liveness across target writes. Core
registers, addresses, silicon identity, ROM ABI, and restoration recipes are
target-specific and remain outside this USB-protocol release.

### 29.11 Cortex-A JTAG scan continuation

In a later session, the same probe was moved to a known-working Cortex-A-class
JTAG target. Target reference voltage remained between 1807 and 1810 mV, both
reset inputs remained deasserted, JTAG was already selected, and the requested
scan clock was 100 kHz. The continuation began again at the bottom of the risk
ladder: signal state, five TMS-high TAP-reset clocks, IDCODE,
instruction-register length, BYPASS length, DP-local reads, AP-local reads, and
only then bounded memory-bus reads.

A 75-clock reset/IDCODE vector returned the same ten sample bytes through v2 and
v3: `ff ef 08 40 d7 00 00 00 00 06`. The v3 response then supplied a separate
status `00`. Target-architecture decoding confirmed that these were genuine TDO
samples from a responding chain. This is important negative evidence for the
earlier nonresponding JTAG attempt: its v3 status `ff` was associated with that
failed attempt, not a fixed trailer byte.

A later 512-clock v3 request held TMS high and TDI low throughout. Its exact
host-visible boundary was:

```text
H→P  132 bytes: cf 00 00 02 || 64 bytes ff || 64 bytes 00
P→H  IN #1: 64 sample bytes, all ff
     IN #2: one status byte, 00
```

The TAP remained in Test-Logic-Reset, neither physical reset input was asserted,
and the close/reopen version check succeeded.

The generic JTAG v2 scan operation then carried successful target-debug
transactions in bounded 40-clock vectors without a higher-level J-Link memory
operation. Returned bytes included the requested target samples plus the
surrounding TAP-transition samples. The harness bounded target WAIT handling,
restored target-debug selection and power state after every command, reset only
the JTAG TAP, and completed fresh two-stage probe-version queries. Target
instruction/data-register assignments, access ports, addresses, ROM tables, and
components remain outside this USB-protocol release.

#### 29.11.1 Target-specific results

The observed TAP identity, JTAG-DP grammar, AP enumeration, ROM-table
termination, architectural presence-bit anomalies, component identities, and
final target-debug state remain together in a separate research notebook.
Keeping them outside this release avoids presenting one SoC integration as part
of the J-Link USB protocol.

### 29.12 Generalization limits

These observations improve field and transfer grammars but do not establish
universal firmware behavior. In particular:

- only one probe model, firmware build, USB speed, and host stack were
  exercised;
- one Cortex-M0 DUT was exercised over SWD and one Cortex-A-class DUT was
  exercised over a known-working JTAG chain;
- bounded target reads and reversible target writes validated scan transport
  without asserting reset, changing target power, or erasing/programming flash;
- no raw bus timing or packet metadata was captured;
- the capability fingerprint proves which bits were set, not what unknown bits
  mean;
- the workspace result remains semantically ambiguous;
- the RTCK failure was observed only without a known reacting RTCK target, and
  its internal wait state is unknown;
- the earlier `ff` JTAG v3 status was distinguished from the `00` success status
  on a known-working JTAG target, but broader status/error sampling is still
  required;
- all target identities, access-port maps, component tables, and
  silicon-specific behavior are outside this guide's implementation scope;
- no claim is made about high-speed, SuperSpeed, composite, legacy V3/V4, J-Link
  OB, or non-USB transports.

## 30. Changing this guide

### 30.1 What future editions must preserve

Future edits should preserve three separations:

1. **Wire fact versus interpretation.** Store raw bytes and status values even
   when a friendly meaning is known.
2. **Probe behavior versus client policy.** A 1 MiB file cap or 504-bit scan
   chunk in a client is not automatically a protocol maximum.
3. **Documentation versus observation.** Promote a claim only when its evidence
   grade changes, and link the capture or pinned code responsible.

A future capture-backed edition should add, for every operation:

```text
first-seen probe and firmware
last-verified probe and firmware
request grammar
success response grammar
each observed failure grammar
state prerequisites and state transitions
boundary tests
capture IDs and byte offsets
```

That would turn this reconstruction into a falsifiable, evolving protocol
specification rather than another list of inherited constant names.

## 31. Stable claim register

This register is the claim index. It gives each material wire or implementation
proposition a durable anchor and groups it by the profiles defined in section
2.4. The linked sections provide the evidence, limitations, byte grammar, and
operational context. Where retained claim wording says “this project,” it means
the conservative policy under which this guide was developed.

### 31.1 `core-host`

<a id="jlp-scope-usb-001"></a>
<!-- claim:JLP-SCOPE-USB-001 -->

**JLP-SCOPE-USB-001 — USB application scope.** The host USB stack performs
device enumeration; this specification includes application-interface discovery,
selection and claiming requirements, plus subsequent bulk application traffic.
(detailed explanation: §2)

<a id="jlp-usb-discovery-001"></a>
<!-- claim:JLP-USB-DISCOVERY-001 -->

**JLP-USB-DISCOVERY-001 — Vendor identifier.** The historical SEGGER USB vendor
identifier is 0x1366. (detailed explanation: §4)

<a id="jlp-usb-discovery-002"></a>
<!-- claim:JLP-USB-DISCOVERY-002 -->

**JLP-USB-DISCOVERY-002 — Legacy application products.** The legacy application
PID set is 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0107, and 0x0108. (detailed
explanation: §4)

<a id="jlp-usb-discovery-003"></a>
<!-- claim:JLP-USB-DISCOVERY-003 -->

**JLP-USB-DISCOVERY-003 — CDC-only legacy product.** PID 0x0106 is treated as a
CDC/VCOM product rather than the debug application interface. (detailed
explanation: §4)

<a id="jlp-usb-discovery-007"></a>
<!-- claim:JLP-USB-DISCOVERY-007 -->

**JLP-USB-DISCOVERY-007 — Vendor-class interface.** The application interface
normally uses vendor class and subclass 0xff/0xff. (detailed explanation: §4)

<a id="jlp-usb-discovery-009"></a>
<!-- claim:JLP-USB-DISCOVERY-009 -->

**JLP-USB-DISCOVERY-009 — Bulk endpoint pair.** Binding requires one bulk-IN and
one bulk-OUT endpoint in the selected alternate setting. (detailed explanation:
§4)

<a id="jlp-usb-discovery-010"></a>
<!-- claim:JLP-USB-DISCOVERY-010 -->

**JLP-USB-DISCOVERY-010 — Nonzero interface number.** The application interface
is not required to have interface number zero. (detailed explanation: §4)

<a id="jlp-usb-discovery-011"></a>
<!-- claim:JLP-USB-DISCOVERY-011 -->

**JLP-USB-DISCOVERY-011 — Alternate-setting inspection.** A host inspects all
alternate settings and rejects ambiguous application-interface matches.
(detailed explanation: §4)

<a id="jlp-usb-discovery-012"></a>
<!-- claim:JLP-USB-DISCOVERY-012 -->

**JLP-USB-DISCOVERY-012 — VCOM separation.** CDC/VCOM endpoints must not be
bound as debug-application endpoints. (detailed explanation: §4)

<a id="jlp-usb-discovery-013"></a>
<!-- claim:JLP-USB-DISCOVERY-013 -->

**JLP-USB-DISCOVERY-013 — Descriptor precedence.** Active descriptors take
precedence over product-family expectations. (detailed explanation: §4)

<a id="jlp-usb-discovery-014"></a>
<!-- claim:JLP-USB-DISCOVERY-014 -->

**JLP-USB-DISCOVERY-014 — Descriptor endpoint parameters.** Endpoint addresses
and both maximum packet sizes come from the selected descriptors. (detailed
explanation: §4)

<a id="jlp-transport-sequence-001"></a>
<!-- claim:JLP-TRANSPORT-SEQUENCE-001 -->

**JLP-TRANSPORT-SEQUENCE-001 — Host initiation.** The host initiates each
application operation. (detailed explanation: §5)

<a id="jlp-transport-sequence-002"></a>
<!-- claim:JLP-TRANSPORT-SEQUENCE-002 -->

**JLP-TRANSPORT-SEQUENCE-002 — Single outstanding operation.** At most one
application operation is outstanding on a session. (detailed explanation: §5)

<a id="jlp-transport-framing-001"></a>
<!-- claim:JLP-TRANSPORT-FRAMING-001 -->

**JLP-TRANSPORT-FRAMING-001 — Operation-code prefix.** The first request byte is
the operation code. (detailed explanation: §5)

<a id="jlp-transport-framing-002"></a>
<!-- claim:JLP-TRANSPORT-FRAMING-002 -->

**JLP-TRANSPORT-FRAMING-002 — No universal envelope.** The application protocol
has no universal request or response envelope. (detailed explanation: §5)

<a id="jlp-transport-framing-003"></a>
<!-- claim:JLP-TRANSPORT-FRAMING-003 -->

**JLP-TRANSPORT-FRAMING-003 — Family-local framing.** A length, status, or TLV
convention is local to the operation family that defines it. (detailed
explanation: §5)

<a id="jlp-transport-reassembly-001"></a>
<!-- claim:JLP-TRANSPORT-REASSEMBLY-001 -->

**JLP-TRANSPORT-REASSEMBLY-001 — Split application fields.** An application
field may span multiple USB bulk transfers. (detailed explanation: §5)

<a id="jlp-transport-reassembly-002"></a>
<!-- claim:JLP-TRANSPORT-REASSEMBLY-002 -->

**JLP-TRANSPORT-REASSEMBLY-002 — Transfer boundary semantics.** A host-visible
USB transfer boundary is not an application-message delimiter. (detailed
explanation: §5)

<a id="jlp-transport-exact-read-001"></a>
<!-- claim:JLP-TRANSPORT-EXACT-READ-001 -->

**JLP-TRANSPORT-EXACT-READ-001 — Operation-specific read length.** The host
continues reading until the operation-specific application length is satisfied
or an error makes completion ambiguous. (detailed explanation: §5)

<a id="jlp-transport-chunk-001"></a>
<!-- claim:JLP-TRANSPORT-CHUNK-001 -->

**JLP-TRANSPORT-CHUNK-001 — Conservative chunking.** Long work is chunked below
wire-field, device-workspace, target, and time-budget limits. (detailed
explanation: §5)

<a id="jlp-transport-zlp-001"></a>
<!-- claim:JLP-TRANSPORT-ZLP-001 -->

**JLP-TRANSPORT-ZLP-001 — Exact-packet termination.** An exact-multiple bulk-IN
application field may complete by the host's exact known application length or,
when the host relies on USB short termination, by a short packet or zero-length
packet. (detailed explanation: §5)

<a id="jlp-transport-zlp-002"></a>
<!-- claim:JLP-TRANSPORT-ZLP-002 -->

**JLP-TRANSPORT-ZLP-002 — Descriptor packet size.** Exact-packet logic uses the
selected bulk-IN descriptor's maximum packet size rather than a hard-coded
value. (detailed explanation: §5)

<a id="jlp-transport-zlp-003"></a>
<!-- claim:JLP-TRANSPORT-ZLP-003 -->

**JLP-TRANSPORT-ZLP-003 — Terminator consumption.** A known-length read may end
after exactly the expected application bytes; a read relying on USB termination
allows or separately consumes any terminator without delivering it as
application data. (detailed explanation: §5)

<a id="jlp-transport-zlp-004"></a>
<!-- claim:JLP-TRANSPORT-ZLP-004 -->

**JLP-TRANSPORT-ZLP-004 — Application-byte delivery.** The operation decoder
receives exactly the expected application bytes and never a USB zero-length
terminator. (detailed explanation: §5)

<a id="jlp-transport-exact-packet-avoidance-001"></a>
<!-- claim:JLP-TRANSPORT-EXACT-PACKET-AVOIDANCE-001 -->

**JLP-TRANSPORT-EXACT-PACKET-AVOIDANCE-001 — Conservative exact-packet scan
avoidance.** A host may conservatively split scan-v3 work at a preceding byte
boundary so each known application response is not an exact multiple of the
selected bulk-IN maximum packet size. (detailed explanation: §5)

<a id="jlp-transport-recovery-001"></a>
<!-- claim:JLP-TRANSPORT-RECOVERY-001 -->

**JLP-TRANSPORT-RECOVERY-001 — Ambiguous-session poisoning.** Partial or
ambiguous operation completion poisons the session for further application
traffic. (detailed explanation: §5)

<a id="jlp-transport-recovery-002"></a>
<!-- claim:JLP-TRANSPORT-RECOVERY-002 -->

**JLP-TRANSPORT-RECOVERY-002 — Recovery sequence.** Recovery stops new
operations, closes the interface, reopens, reinitializes state, and verifies a
known-safe query before reuse. (detailed explanation: §5)

<a id="jlp-encoding-endian-001"></a>
<!-- claim:JLP-ENCODING-ENDIAN-001 -->

**JLP-ENCODING-ENDIAN-001 — Default integer byte order.** Multi-byte integers
are little-endian unless a field explicitly says otherwise. (detailed
explanation: §6)

<a id="jlp-encoding-bits-001"></a>
<!-- claim:JLP-ENCODING-BITS-001 -->

**JLP-ENCODING-BITS-001 — Packed-bit position.** Packed bit n occupies bit n
modulo 8 of byte floor(n divided by 8). (detailed explanation: §6)

<a id="jlp-encoding-bits-002"></a>
<!-- claim:JLP-ENCODING-BITS-002 -->

**JLP-ENCODING-BITS-002 — Packed-bit length.** A packed stream of n bits
occupies ceil(n/8) bytes. (detailed explanation: §6)

<a id="jlp-encoding-bits-003"></a>
<!-- claim:JLP-ENCODING-BITS-003 -->

**JLP-ENCODING-BITS-003 — Unused request bits.** A sender zeros unused high bits
in the final packed request byte. (detailed explanation: §6)

<a id="jlp-encoding-bits-004"></a>
<!-- claim:JLP-ENCODING-BITS-004 -->

**JLP-ENCODING-BITS-004 — Unused response bits.** A receiver ignores unused high
bits in the final packed response byte. (detailed explanation: §6)

<a id="jlp-session-order-001"></a>
<!-- claim:JLP-SESSION-ORDER-001 -->

**JLP-SESSION-ORDER-001 — Conservative session order.** A core session discovers
descriptors and capabilities before selecting a target interface, then reapplies
target clock before target-active work. (detailed explanation: §7)

<a id="jlp-session-interface-001"></a>
<!-- claim:JLP-SESSION-INTERFACE-001 -->

**JLP-SESSION-INTERFACE-001 — Explicit session interface.** A capable host
explicitly selects the intended advertised interface and sets its clock in that
order for each initialized session. (detailed explanation: §7)

<a id="jlp-cap-short-request-001"></a>
<!-- claim:JLP-CAP-SHORT-REQUEST-001 -->

**JLP-CAP-SHORT-REQUEST-001 — Short-capability request.**
probe.capabilities.read-short is the one-byte request e8. (detailed explanation:
§9.1)

<a id="jlp-cap-short-response-001"></a>
<!-- claim:JLP-CAP-SHORT-RESPONSE-001 -->

**JLP-CAP-SHORT-RESPONSE-001 — Short-capability response.** The short-capability
response is exactly four bytes. (detailed explanation: §9.1)

<a id="jlp-cap-long-request-001"></a>
<!-- claim:JLP-CAP-LONG-REQUEST-001 -->

**JLP-CAP-LONG-REQUEST-001 — Long-capability request.**
probe.capabilities.read-long is the one-byte request ed. (detailed explanation:
§9.1)

<a id="jlp-cap-long-response-001"></a>
<!-- claim:JLP-CAP-LONG-RESPONSE-001 -->

**JLP-CAP-LONG-RESPONSE-001 — Long-capability response.** The long-capability
response is exactly 32 bytes. (detailed explanation: §9.1)

<a id="jlp-cap-bit-order-001"></a>
<!-- claim:JLP-CAP-BIT-ORDER-001 -->

**JLP-CAP-BIT-ORDER-001 — Capability bit order.** Capability bit n is bit n
modulo 8 of byte floor(n divided by 8). (detailed explanation: §9.1)

<a id="jlp-cap-long-prefix-001"></a>
<!-- claim:JLP-CAP-LONG-PREFIX-001 -->

**JLP-CAP-LONG-PREFIX-001 — Long-prefix agreement.** The first four
long-capability bytes should agree with the short-capability response;
disagreement is preserved and reported. (detailed explanation: §9.1)

<a id="jlp-cap-long-gate-001"></a>
<!-- claim:JLP-CAP-LONG-GATE-001 -->

**JLP-CAP-LONG-GATE-001 — Long-query gate.** The host emits the long-capability
query only when short capability bit 31 is set. (detailed explanation: §9.1)

<a id="jlp-cap-unknown-preserve-001"></a>
<!-- claim:JLP-CAP-UNKNOWN-PRESERVE-001 -->

**JLP-CAP-UNKNOWN-PRESERVE-001 — Unknown capability preservation.** Unknown
capability bits are retained without invented semantic names. (detailed
explanation: §9.1)

<a id="jlp-cap-missing-meaning-001"></a>
<!-- claim:JLP-CAP-MISSING-MEANING-001 -->

**JLP-CAP-MISSING-MEANING-001 — Missing-map neutrality.** Absence of a
capability-bit meaning from this edition is not evidence that a device lacks an
operation. (detailed explanation: §9.1)

<a id="jlp-cap-bit-001"></a>
<!-- claim:JLP-CAP-BIT-001 -->

**JLP-CAP-BIT-001 — Capability bit 1.** Capability bit 1 is cataloged as
hardware-version query; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-003"></a>
<!-- claim:JLP-CAP-BIT-003 -->

**JLP-CAP-BIT-003 — Capability bit 3.** Capability bit 3 is cataloged as
adaptive target clock; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-004"></a>
<!-- claim:JLP-CAP-BIT-004 -->

**JLP-CAP-BIT-004 — Capability bit 4.** Capability bit 4 is cataloged as
configuration read; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-009"></a>
<!-- claim:JLP-CAP-BIT-009 -->

**JLP-CAP-BIT-009 — Capability bit 9.** Capability bit 9 is cataloged as
target-clock description; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-011"></a>
<!-- claim:JLP-CAP-BIT-011 -->

**JLP-CAP-BIT-011 — Capability bit 11.** Capability bit 11 is cataloged as
workspace query; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-012"></a>
<!-- claim:JLP-CAP-BIT-012 -->

**JLP-CAP-BIT-012 — Capability bit 12.** Capability bit 12 is cataloged as
hardware-field query; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-017"></a>
<!-- claim:JLP-CAP-BIT-017 -->

**JLP-CAP-BIT-017 — Capability bit 17.** Capability bit 17 is cataloged as
target-interface management; this label does not by itself authorize the
associated operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-019"></a>
<!-- claim:JLP-CAP-BIT-019 -->

**JLP-CAP-BIT-019 — Capability bit 19.** Capability bit 19 is cataloged as
counters query; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-031"></a>
<!-- claim:JLP-CAP-BIT-031 -->

**JLP-CAP-BIT-031 — Capability bit 31.** Capability bit 31 is cataloged as
long-capability query; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-version-request-001"></a>
<!-- claim:JLP-VERSION-REQUEST-001 -->

**JLP-VERSION-REQUEST-001 — Probe version request.** The request is one byte 01.
(detailed explanation: §10.1)

<a id="jlp-version-response-001"></a>
<!-- claim:JLP-VERSION-RESPONSE-001 -->

**JLP-VERSION-RESPONSE-001 — Probe version response.** The response is a u16le
byte length followed by exactly that many record bytes. (detailed explanation:
§10.1)

<a id="jlp-hardware-version-request-001"></a>
<!-- claim:JLP-HARDWARE-VERSION-REQUEST-001 -->

**JLP-HARDWARE-VERSION-REQUEST-001 — Hardware version request.** The request is
one byte f0. (detailed explanation: §10.2)

<a id="jlp-hardware-version-response-001"></a>
<!-- claim:JLP-HARDWARE-VERSION-RESPONSE-001 -->

**JLP-HARDWARE-VERSION-RESPONSE-001 — Hardware version response.** The response
is one u32le decimal-packed hardware version. (detailed explanation: §10.2)

<a id="jlp-signal-state-request-001"></a>
<!-- claim:JLP-SIGNAL-STATE-REQUEST-001 -->

**JLP-SIGNAL-STATE-REQUEST-001 — Signal state request.** The request is one
byte 07. (detailed explanation: §10.3)

<a id="jlp-signal-state-response-001"></a>
<!-- claim:JLP-SIGNAL-STATE-RESPONSE-001 -->

**JLP-SIGNAL-STATE-RESPONSE-001 — Signal state response.** The response is
target millivolts as u16le followed by six one-byte signal states. (detailed
explanation: §10.3)

<a id="jlp-workspace-request-001"></a>
<!-- claim:JLP-WORKSPACE-REQUEST-001 -->

**JLP-WORKSPACE-REQUEST-001 — Probe workspace request.** The request is one byte
d4. (detailed explanation: §10.4)

<a id="jlp-workspace-response-001"></a>
<!-- claim:JLP-WORKSPACE-RESPONSE-001 -->

**JLP-WORKSPACE-RESPONSE-001 — Probe workspace response.** The response is one
u32le workspace value. (detailed explanation: §10.4)

<a id="jlp-hardware-fields-request-001"></a>
<!-- claim:JLP-HARDWARE-FIELDS-REQUEST-001 -->

**JLP-HARDWARE-FIELDS-REQUEST-001 — Hardware fields request.** The request is c1
followed by a u32le requested-field mask. (detailed explanation: §10.5)

<a id="jlp-hardware-fields-response-001"></a>
<!-- claim:JLP-HARDWARE-FIELDS-RESPONSE-001 -->

**JLP-HARDWARE-FIELDS-RESPONSE-001 — Hardware fields response.** The response
has one u32le word for each set mask bit in ascending bit order. (detailed
explanation: §10.5)

<a id="jlp-counters-request-001"></a>
<!-- claim:JLP-COUNTERS-REQUEST-001 -->

**JLP-COUNTERS-REQUEST-001 — Probe counters request.** The request is c2
followed by a u32le requested-counter mask. (detailed explanation: §10.6)

<a id="jlp-counters-response-001"></a>
<!-- claim:JLP-COUNTERS-RESPONSE-001 -->

**JLP-COUNTERS-RESPONSE-001 — Probe counters response.** The response has one
u32le word for each set mask bit in ascending bit order. (detailed explanation:
§10.6)

<a id="jlp-version-record-001"></a>
<!-- claim:JLP-VERSION-RECORD-001 -->

**JLP-VERSION-RECORD-001 — Version record retention.** The host retains all
declared version-record bytes and does not stop application decoding at the
first NUL. (detailed explanation: §10.1)

<a id="jlp-version-primary-field-001"></a>
<!-- claim:JLP-VERSION-PRIMARY-FIELD-001 -->

**JLP-VERSION-PRIMARY-FIELD-001 — Primary version field.** The primary display
field is the bytes before the first NUL, with lossless escaping for non-UTF-8
data. (detailed explanation: §10.1)

<a id="jlp-hardware-version-decimal-001"></a>
<!-- claim:JLP-HARDWARE-VERSION-DECIMAL-001 -->

**JLP-HARDWARE-VERSION-DECIMAL-001 — Decimal-packed hardware version.** The
packed hardware integer is split into two decimal digits each for type, major,
minor, and revision. (detailed explanation: §10.2)

<a id="jlp-hardware-type-unknown-001"></a>
<!-- claim:JLP-HARDWARE-TYPE-UNKNOWN-001 -->

**JLP-HARDWARE-TYPE-UNKNOWN-001 — Unknown hardware type.** Unknown hardware-type
values are preserved rather than rejected. (detailed explanation: §10.2)

<a id="jlp-signal-boolean-001"></a>
<!-- claim:JLP-SIGNAL-BOOLEAN-001 -->

**JLP-SIGNAL-BOOLEAN-001 — Noncanonical signal high.** A signal-state byte of
zero is low and any nonzero value is high. (detailed explanation: §10.3)

<a id="jlp-workspace-policy-001"></a>
<!-- claim:JLP-WORKSPACE-POLICY-001 -->

**JLP-WORKSPACE-POLICY-001 — Workspace as ceiling or hint.** The workspace value
may lower operation sizes but is not a universal per-operation maximum.
(detailed explanation: §10.4)

<a id="jlp-hardware-fields-order-001"></a>
<!-- claim:JLP-HARDWARE-FIELDS-ORDER-001 -->

**JLP-HARDWARE-FIELDS-ORDER-001 — Hardware-field ordering.** Hardware-field
response words correspond to requested bits in ascending bit-index order.
(detailed explanation: §10.5)

<a id="jlp-counters-order-001"></a>
<!-- claim:JLP-COUNTERS-ORDER-001 -->

**JLP-COUNTERS-ORDER-001 — Counter ordering.** Counter response words correspond
to requested bits in ascending bit-index order. (detailed explanation: §10.6)

<a id="jlp-counter-bit-001"></a>
<!-- claim:JLP-COUNTER-BIT-001 -->

**JLP-COUNTER-BIT-001 — Connect-event counter.** Counter bit 1 reports target
connect/disconnect events. (detailed explanation: §10.6)

<a id="jlp-counter-wrap-001"></a>
<!-- claim:JLP-COUNTER-WRAP-001 -->

**JLP-COUNTER-WRAP-001 — Counter wrap.** Counter values are wrapping diagnostics
rather than durable monotonic telemetry. (detailed explanation: §10.6)

<a id="jlp-hardware-field-bit-000"></a>
<!-- claim:JLP-HARDWARE-FIELD-BIT-000 -->

**JLP-HARDWARE-FIELD-BIT-000 — Hardware field bit 0.** Hardware-field mask bit 0
selects auxiliary target-power state. (detailed explanation: §10.5)

<a id="jlp-hardware-field-bit-002"></a>
<!-- claim:JLP-HARDWARE-FIELD-BIT-002 -->

**JLP-HARDWARE-FIELD-BIT-002 — Hardware field bit 2.** Hardware-field mask bit 2
selects present target current in milliamperes. (detailed explanation: §10.5)

<a id="jlp-hardware-field-bit-003"></a>
<!-- claim:JLP-HARDWARE-FIELD-BIT-003 -->

**JLP-HARDWARE-FIELD-BIT-003 — Hardware field bit 3.** Hardware-field mask bit 3
selects peak target current in milliamperes. (detailed explanation: §10.5)

<a id="jlp-interface-id-000"></a>
<!-- claim:JLP-INTERFACE-ID-000 -->

**JLP-INTERFACE-ID-000 — Interface selector 0.** Interface selector 0 denotes
JTAG. (detailed explanation: §11.1)

<a id="jlp-interface-id-001"></a>
<!-- claim:JLP-INTERFACE-ID-001 -->

**JLP-INTERFACE-ID-001 — Interface selector 1.** Interface selector 1 denotes
SWD. (detailed explanation: §11.1)

<a id="jlp-interface-available-request-001"></a>
<!-- claim:JLP-INTERFACE-AVAILABLE-REQUEST-001 -->

**JLP-INTERFACE-AVAILABLE-REQUEST-001 — Available-interface request.** The
available-interface request is c7 ff. (detailed explanation: §11.2)

<a id="jlp-interface-available-response-001"></a>
<!-- claim:JLP-INTERFACE-AVAILABLE-RESPONSE-001 -->

**JLP-INTERFACE-AVAILABLE-RESPONSE-001 — Available-interface response.** The
response to c7 ff is a u32le mask whose bit n represents selector n. (detailed
explanation: §11.2)

<a id="jlp-interface-current-request-001"></a>
<!-- claim:JLP-INTERFACE-CURRENT-REQUEST-001 -->

**JLP-INTERFACE-CURRENT-REQUEST-001 — Current-interface request.** The
current-interface request is c7 fe. (detailed explanation: §11.2)

<a id="jlp-interface-current-response-001"></a>
<!-- claim:JLP-INTERFACE-CURRENT-RESPONSE-001 -->

**JLP-INTERFACE-CURRENT-RESPONSE-001 — Current-interface response.** The
response to c7 fe is the selected interface ID in a u32le word. (detailed
explanation: §11.2)

<a id="jlp-interface-select-request-001"></a>
<!-- claim:JLP-INTERFACE-SELECT-REQUEST-001 -->

**JLP-INTERFACE-SELECT-REQUEST-001 — Interface-selection request.** An
interface-selection request is c7 followed by the one-byte interface ID.
(detailed explanation: §11.2)

<a id="jlp-interface-select-response-001"></a>
<!-- claim:JLP-INTERFACE-SELECT-RESPONSE-001 -->

**JLP-INTERFACE-SELECT-RESPONSE-001 — Interface-selection response.** The
selection response is the previous interface ID in a u32le word. (detailed
explanation: §11.2)

<a id="jlp-interface-select-gate-001"></a>
<!-- claim:JLP-INTERFACE-SELECT-GATE-001 -->

**JLP-INTERFACE-SELECT-GATE-001 — Availability gate.** The host queries the
available mask and verifies a selector bit before selection. (detailed
explanation: §11.2)

<a id="jlp-interface-clock-order-001"></a>
<!-- claim:JLP-INTERFACE-CLOCK-ORDER-001 -->

**JLP-INTERFACE-CLOCK-ORDER-001 — Clock reapplication.** The host reapplies
target clock configuration after changing the selected interface. (detailed
explanation: §11.2)

<a id="jlp-interface-quirk-001"></a>
<!-- claim:JLP-INTERFACE-QUIRK-001 -->

**JLP-INTERFACE-QUIRK-001 — Selection timeout guard.** Interface selection uses
a recoverable timeout and per-device guard because advertised or vendor-used
selectors may still hang. (detailed explanation: §11.2)

<a id="jlp-clock-describe-request-001"></a>
<!-- claim:JLP-CLOCK-DESCRIBE-REQUEST-001 -->

**JLP-CLOCK-DESCRIBE-REQUEST-001 — Target-clock description request.** The
request is one byte c0. (detailed explanation: §11.3)

<a id="jlp-clock-describe-response-001"></a>
<!-- claim:JLP-CLOCK-DESCRIBE-RESPONSE-001 -->

**JLP-CLOCK-DESCRIBE-RESPONSE-001 — Target-clock description response.** The
response is base_hz:u32le followed by minimum_divisor:u16le. (detailed
explanation: §11.3)

<a id="jlp-clock-describe-formula-001"></a>
<!-- claim:JLP-CLOCK-DESCRIBE-FORMULA-001 -->

**JLP-CLOCK-DESCRIBE-FORMULA-001 — Target-clock formula.** Nominal interface
rates are base_hz divided by an integer divisor not smaller than
minimum_divisor. (detailed explanation: §11.3)

<a id="jlp-clock-describe-validate-001"></a>
<!-- claim:JLP-CLOCK-DESCRIBE-VALIDATE-001 -->

**JLP-CLOCK-DESCRIBE-VALIDATE-001 — Clock-description validation.** A zero
minimum divisor is invalid and every derived rate uses checked arithmetic.
(detailed explanation: §11.3)

<a id="jlp-clock-set-request-001"></a>
<!-- claim:JLP-CLOCK-SET-REQUEST-001 -->

**JLP-CLOCK-SET-REQUEST-001 — Target-clock set request.** The request is 05
followed by rate_khz:u16le. (detailed explanation: §11.4)

<a id="jlp-clock-set-response-001"></a>
<!-- claim:JLP-CLOCK-SET-RESPONSE-001 -->

**JLP-CLOCK-SET-RESPONSE-001 — Target-clock set response.** The operation has no
application response. (detailed explanation: §11.4)

<a id="jlp-clock-set-adaptive-001"></a>
<!-- claim:JLP-CLOCK-SET-ADAPTIVE-001 -->

**JLP-CLOCK-SET-ADAPTIVE-001 — Adaptive clock request.** rate_khz 0xffff
requests adaptive clocking and is emitted only when capability bit 3 is set.
(detailed explanation: §11.4)

<a id="jlp-clock-set-noack-001"></a>
<!-- claim:JLP-CLOCK-SET-NOACK-001 -->

**JLP-CLOCK-SET-NOACK-001 — Clock set has no acknowledgement.** A successful OUT
completion is not proof that the target accepted or can sustain the requested
rate. (detailed explanation: §11.4)

<a id="jlp-clock-set-zero-001"></a>
<!-- claim:JLP-CLOCK-SET-ZERO-001 -->

**JLP-CLOCK-SET-ZERO-001 — Zero-rate client guard.** This project rejects a
requested target rate of zero before emission. (detailed explanation: §11.4)

<a id="jlp-scan-common-request-001"></a>
<!-- claim:JLP-SCAN-COMMON-REQUEST-001 -->

**JLP-SCAN-COMMON-REQUEST-001 — Common scan body.** Scan v2 and v3 requests
contain opcode, zero reserved byte, u16le bit count, packed control bits, then
packed drive bits. (detailed explanation: §12.1)

<a id="jlp-scan-bitcount-001"></a>
<!-- claim:JLP-SCAN-BITCOUNT-001 -->

**JLP-SCAN-BITCOUNT-001 — Scan bit count.** The scan bit count is nonzero and no
greater than 65535 wire bits. (detailed explanation: §12.1)

<a id="jlp-scan-reserved-001"></a>
<!-- claim:JLP-SCAN-RESERVED-001 -->

**JLP-SCAN-RESERVED-001 — Scan reserved byte.** The reserved scan byte is
emitted as zero. (detailed explanation: §12.1)

<a id="jlp-scan-jtag-buffers-001"></a>
<!-- claim:JLP-SCAN-JTAG-BUFFERS-001 -->

**JLP-SCAN-JTAG-BUFFERS-001 — JTAG scan roles.** In JTAG mode, control is TMS,
drive is TDI, and the returned sample is TDO. (detailed explanation: §12.1)

<a id="jlp-scan-swd-buffers-001"></a>
<!-- claim:JLP-SCAN-SWD-BUFFERS-001 -->

**JLP-SCAN-SWD-BUFFERS-001 — SWD scan roles.** In SWD mode, control is
direction, drive is SWDIO output, and the returned sample is SWDIO. (detailed
explanation: §12.1)

<a id="jlp-scan-swd-output-sample-001"></a>
<!-- claim:JLP-SCAN-SWD-OUTPUT-SAMPLE-001 -->

**JLP-SCAN-SWD-OUTPUT-SAMPLE-001 — SWD output samples.** Returned samples during
SWD output cycles are undefined and ignored. (detailed explanation: §12.1)

<a id="jlp-scan-swd-input-drive-001"></a>
<!-- claim:JLP-SCAN-SWD-INPUT-DRIVE-001 -->

**JLP-SCAN-SWD-INPUT-DRIVE-001 — SWD input drive bits.** The host sends zero
drive bits during SWD input cycles. (detailed explanation: §12.1)

<a id="jlp-scan-v2-request-001"></a>
<!-- claim:JLP-SCAN-V2-REQUEST-001 -->

**JLP-SCAN-V2-REQUEST-001 — Scan v2 request.** The request is ce, 00, u16le bit
count, packed control bits, then packed drive bits. (detailed explanation:
§12.3)

<a id="jlp-scan-v2-response-001"></a>
<!-- claim:JLP-SCAN-V2-RESPONSE-001 -->

**JLP-SCAN-V2-RESPONSE-001 — Scan v2 response.** The response is exactly one
packed sample bit per requested clock. (detailed explanation: §12.3)

<a id="jlp-scan-v2-no-status-001"></a>
<!-- claim:JLP-SCAN-V2-NO-STATUS-001 -->

**JLP-SCAN-V2-NO-STATUS-001 — Scan v2 no status.** Scan v2 has no application
status byte. (detailed explanation: §12.3)

<a id="jlp-scan-v3-request-001"></a>
<!-- claim:JLP-SCAN-V3-REQUEST-001 -->

**JLP-SCAN-V3-REQUEST-001 — Scan v3 request.** The request is cf, 00, u16le bit
count, packed control bits, then packed drive bits. (detailed explanation:
§12.4)

<a id="jlp-scan-v3-response-001"></a>
<!-- claim:JLP-SCAN-V3-RESPONSE-001 -->

**JLP-SCAN-V3-RESPONSE-001 — Scan v3 response.** The response is the packed
sample stream followed by one status byte. (detailed explanation: §12.4)

<a id="jlp-scan-v3-status-success-001"></a>
<!-- claim:JLP-SCAN-V3-STATUS-SUCCESS-001 -->

**JLP-SCAN-V3-STATUS-SUCCESS-001 — Scan v3 success.** Scan v3 status 00 means
success. (detailed explanation: §12.4)

<a id="jlp-scan-v3-status-workspace-001"></a>
<!-- claim:JLP-SCAN-V3-STATUS-WORKSPACE-001 -->

**JLP-SCAN-V3-STATUS-WORKSPACE-001 — Scan v3 workspace status.** The historical
and public-client meaning of scan v3 status 06 is insufficient on-probe memory
or workspace. (detailed explanation: §12.4)

<a id="jlp-scan-v3-unknown-status-001"></a>
<!-- claim:JLP-SCAN-V3-UNKNOWN-STATUS-001 -->

**JLP-SCAN-V3-UNKNOWN-STATUS-001 — Unknown scan v3 status.** Any other scan v3
status is preserved as a raw family-local value. (detailed explanation: §12.4)

<a id="jlp-scan-v3-sample-before-status-001"></a>
<!-- claim:JLP-SCAN-V3-SAMPLE-BEFORE-STATUS-001 -->

**JLP-SCAN-V3-SAMPLE-BEFORE-STATUS-001 — Scan v3 sample ordering.** The host
consumes the complete sample stream before reading or interpreting the following
status byte. (detailed explanation: §12.4)

<a id="jlp-scan-selection-v3-001"></a>
<!-- claim:JLP-SCAN-SELECTION-V3-001 -->

**JLP-SCAN-SELECTION-V3-001 — Prefer scan v3.** The core host prefers scan v3
for ordinary JTAG and SWD scanning. (detailed explanation: §12.7)

<a id="jlp-scan-selection-bound-001"></a>
<!-- claim:JLP-SCAN-SELECTION-BOUND-001 -->

**JLP-SCAN-SELECTION-BOUND-001 — Bound scan work.** Every scan is bounded by the
u16 field, tested device limits, workspace, transport overhead, and work budget.
(detailed explanation: §12.7)

<a id="jlp-scan-selection-v2-fallback-001"></a>
<!-- claim:JLP-SCAN-SELECTION-V2-FALLBACK-001 -->

**JLP-SCAN-SELECTION-V2-FALLBACK-001 — Scan v2 fallback.** The core host uses
scan v2 only for a recorded compatibility need. (detailed explanation: §12.7)

<a id="jlp-swo-clock-range-validation-001"></a>
<!-- claim:JLP-SWO-CLOCK-RANGE-VALIDATION-001 -->

**JLP-SWO-CLOCK-RANGE-VALIDATION-001 — SWO clock range validation.** The host
rejects zero minimum divisors and inverted advertised bounds. (detailed
explanation: §15.4)

<a id="jlp-validation-count-001"></a>
<!-- claim:JLP-VALIDATION-COUNT-001 -->

**JLP-VALIDATION-COUNT-001 — Probe count validation.** Every probe-supplied
count is validated against the request, remaining bytes, and a configured limit.
(detailed explanation: §24)

<a id="jlp-validation-overflow-001"></a>
<!-- claim:JLP-VALIDATION-OVERFLOW-001 -->

**JLP-VALIDATION-OVERFLOW-001 — Checked length arithmetic.** Every length sum,
product, and allocation uses checked arithmetic. (detailed explanation: §24)

<a id="jlp-validation-status-001"></a>
<!-- claim:JLP-VALIDATION-STATUS-001 -->

**JLP-VALIDATION-STATUS-001 — Family-local status.** A status value is
interpreted only within the operation family that defines it. (detailed
explanation: §24)

<a id="jlp-validation-unknown-001"></a>
<!-- claim:JLP-VALIDATION-UNKNOWN-001 -->

**JLP-VALIDATION-UNKNOWN-001 — Unknown-value preservation.** Unknown bits,
selectors, tags, fields, and raw status values are preserved without invented
semantics. (detailed explanation: §24)

<a id="jlp-transaction-serialize-001"></a>
<!-- claim:JLP-TRANSACTION-SERIALIZE-001 -->

**JLP-TRANSACTION-SERIALIZE-001 — Operation serialization.** Application
operations on one session are serialized. (detailed explanation: §24)

<a id="jlp-transaction-poison-001"></a>
<!-- claim:JLP-TRANSACTION-POISON-001 -->

**JLP-TRANSACTION-POISON-001 — Poison after ambiguity.** Partial or ambiguous
completion poisons the session until recovery. (detailed explanation: §24)

<a id="jlp-state-interface-001"></a>
<!-- claim:JLP-STATE-INTERFACE-001 -->

**JLP-STATE-INTERFACE-001 — Interface state.** Selected target interface is
session state that may persist on the probe. (detailed explanation: §24)

<a id="jlp-state-clock-001"></a>
<!-- claim:JLP-STATE-CLOCK-001 -->

**JLP-STATE-CLOCK-001 — Clock state.** Target clock configuration is state and
is reapplied after interface changes. (detailed explanation: §24)

<a id="jlp-state-pins-001"></a>
<!-- claim:JLP-STATE-PINS-001 -->

**JLP-STATE-PINS-001 — Persistent pin state.** Persistent pin operations outlive
the request and require explicit ownership. (detailed explanation: §24)

<a id="jlp-state-scan-sticky-001"></a>
<!-- claim:JLP-STATE-SCAN-STICKY-001 -->

**JLP-STATE-SCAN-STICKY-001 — Sticky scan state.** Write-only scan status is
probe state cleared by its query operation. (detailed explanation: §24)

<a id="jlp-state-swo-001"></a>
<!-- claim:JLP-STATE-SWO-001 -->

**JLP-STATE-SWO-001 — SWO capture state.** SWO start establishes capture state
that should be stopped before reconfiguration or close. (detailed explanation:
§24)

<a id="jlp-state-registration-001"></a>
<!-- claim:JLP-STATE-REGISTRATION-001 -->

**JLP-STATE-REGISTRATION-001 — Registration state.** Connection registration
creates service state that is explicitly unregistered when used. (detailed
explanation: §24)

<a id="jlp-state-spi-cs-001"></a>
<!-- claim:JLP-STATE-SPI-CS-001 -->

**JLP-STATE-SPI-CS-001 — SPI chip-select state.** SPI chip-select ownership can
span a request and requires cleanup. (detailed explanation: §24)

<a id="jlp-state-config-001"></a>
<!-- claim:JLP-STATE-CONFIG-001 -->

**JLP-STATE-CONFIG-001 — Persistent configuration state.** Configuration write
mutates nonvolatile probe state. (detailed explanation: §24)

<a id="jlp-state-files-001"></a>
<!-- claim:JLP-STATE-FILES-001 -->

**JLP-STATE-FILES-001 — On-probe file state.** File write and delete mutate
on-probe persistent state. (detailed explanation: §24)

<a id="jlp-cleanup-ownership-001"></a>
<!-- claim:JLP-CLEANUP-OWNERSHIP-001 -->

**JLP-CLEANUP-OWNERSHIP-001 — Cleanup ownership.** Only the component that
intentionally acquires protocol or electrical state performs its cleanup.
(detailed explanation: §24)

<a id="jlp-unknown-opcode-001"></a>
<!-- claim:JLP-UNKNOWN-OPCODE-001 -->

**JLP-UNKNOWN-OPCODE-001 — Unknown operation emission.** Unknown operation codes
are never emitted. (detailed explanation: §24)

<a id="jlp-unknown-tag-001"></a>
<!-- claim:JLP-UNKNOWN-TAG-001 -->

**JLP-UNKNOWN-TAG-001 — Unknown tag emission.** Unknown operation-family tags
are never emitted. (detailed explanation: §24)

<a id="jlp-admin-authorization-001"></a>
<!-- claim:JLP-ADMIN-AUTHORIZATION-001 -->

**JLP-ADMIN-AUTHORIZATION-001 — Administrative authorization.** Electrical,
reset, target-writing, destructive, and persistent actions require explicit
ownership and authorization. (detailed explanation: §24)

### 31.2 `observed-extension`

<a id="jlp-usb-discovery-016"></a>
<!-- claim:JLP-USB-DISCOVERY-016 -->

**JLP-USB-DISCOVERY-016 — Observed current application product.** The presently
evidenced application PID set includes 0x1020 for the observed J-Link EDU Mini
V2; this observation admits no other current PID. (detailed explanation: §4)

<a id="jlp-scan-swd-sample-carry-001"></a>
<!-- claim:JLP-SCAN-SWD-SAMPLE-CARRY-001 -->

**JLP-SCAN-SWD-SAMPLE-CARRY-001 — Observed SWD target-sample carry.** On the
observed EDU Mini V2 firmware, each raw sample obtained while the target drives
SWDIO is delayed by one logical target-input cycle, with the displaced bit
carried across consecutive scan-v3 operations. (detailed explanation: §12.1)

<a id="jlp-usb-discovery-008"></a>
<!-- claim:JLP-USB-DISCOVERY-008 -->

**JLP-USB-DISCOVERY-008 — Protocol-byte heuristic.** Requiring interface
protocol 0xff is a stricter client heuristic, not necessary evidence of the
application interface. (detailed explanation: §4)

<a id="jlp-hardware-fields-unsupported-001"></a>
<!-- claim:JLP-HARDWARE-FIELDS-UNSUPPORTED-001 -->

**JLP-HARDWARE-FIELDS-UNSUPPORTED-001 — Unsupported hardware field.** An
unsupported requested hardware field still occupies one response word and may
use 0xffffffff. (detailed explanation: §10.5)

<a id="jlp-counters-unsupported-001"></a>
<!-- claim:JLP-COUNTERS-UNSUPPORTED-001 -->

**JLP-COUNTERS-UNSUPPORTED-001 — Unsupported counter slot.** An unsupported
requested counter slot still occupies one response word and uses 0xffffffff on
the observed firmware. (detailed explanation: §10.6)

<a id="jlp-counter-bit-000"></a>
<!-- claim:JLP-COUNTER-BIT-000 -->

**JLP-COUNTER-BIT-000 — Connected-time counter.** Counter bit 0 reports
connected or powered-at-target time in milliseconds on the documented and
observed setup. (detailed explanation: §10.6)

<a id="jlp-rtck-lockup-001"></a>
<!-- claim:JLP-RTCK-LOCKUP-001 -->

**JLP-RTCK-LOCKUP-001 — Bounded RTCK lockup.** On the recorded non-reacting
setup, f6 completed OUT, produced no IN reply in the observation window, wedged
the probe, and required physical reconnect. (detailed explanation: §10.7)

<a id="jlp-config-read-request-001"></a>
<!-- claim:JLP-CONFIG-READ-REQUEST-001 -->

**JLP-CONFIG-READ-REQUEST-001 — Configuration-read request.** The request is one
byte f2. (detailed explanation: §14.1)

<a id="jlp-config-read-response-001"></a>
<!-- claim:JLP-CONFIG-READ-RESPONSE-001 -->

**JLP-CONFIG-READ-RESPONSE-001 — Configuration-read response.** The response is
exactly 256 configuration bytes. (detailed explanation: §14.1)

<a id="jlp-config-read-zlp-001"></a>
<!-- claim:JLP-CONFIG-READ-ZLP-001 -->

**JLP-CONFIG-READ-ZLP-001 — Configuration-read exact packet.** A 256-byte
configuration response is handled with the exact-packet completion rule.
(detailed explanation: §14.1)

<a id="jlp-swo-clock-request-001"></a>
<!-- claim:JLP-SWO-CLOCK-REQUEST-001 -->

**JLP-SWO-CLOCK-REQUEST-001 — SWO clock-description request.** The request is eb
6e, a four-byte mode TLV, and a zero terminator. (detailed explanation: §15.4)

<a id="jlp-swo-clock-response-001"></a>
<!-- claim:JLP-SWO-CLOCK-RESPONSE-001 -->

**JLP-SWO-CLOCK-RESPONSE-001 — SWO clock-description response.** A normal
response is seven u32le words: length 28, reserved, base_hz, divisor bounds, and
prescaler bounds. (detailed explanation: §15.4)

### 31.3 `research-only`

<a id="jlp-usb-discovery-005"></a>
<!-- claim:JLP-USB-DISCOVERY-005 -->

**JLP-USB-DISCOVERY-005 — Modern implementation PID ranges.** The pinned
libjaylink revision recognizes additional 0x10xx product ranges. (detailed
explanation: §4)

<a id="jlp-usb-discovery-006"></a>
<!-- claim:JLP-USB-DISCOVERY-006 -->

**JLP-USB-DISCOVERY-006 — PID heuristic status.** A new-format PID test used by
one client is an implementation heuristic, not a universal protocol rule.
(detailed explanation: §4)

<a id="jlp-encoding-ipv4-001"></a>
<!-- claim:JLP-ENCODING-IPV4-001 -->

**JLP-ENCODING-IPV4-001 — IPv4 octet order.** IPv4 values are four network-order
octets rather than little-endian host integers. (detailed explanation: §6)

<a id="jlp-encoding-tlv-001"></a>
<!-- claim:JLP-ENCODING-TLV-001 -->

**JLP-ENCODING-TLV-001 — Local TLV order.** In identified local-TLV families,
each item is length, tag, then value. (detailed explanation: §6)

<a id="jlp-encoding-tlv-002"></a>
<!-- claim:JLP-ENCODING-TLV-002 -->

**JLP-ENCODING-TLV-002 — TLV terminator.** A zero length terminates a local TLV
list and has no following tag. (detailed explanation: §6)

<a id="jlp-encoding-tlv-003"></a>
<!-- claim:JLP-ENCODING-TLV-003 -->

**JLP-ENCODING-TLV-003 — TLV scope.** Local TLV framing applies only to
operation families that explicitly define it. (detailed explanation: §6)

<a id="jlp-session-registration-001"></a>
<!-- claim:JLP-SESSION-REGISTRATION-001 -->

**JLP-SESSION-REGISTRATION-001 — Registration is not universal initialization.**
Connection registration is an opt-in compatibility quirk rather than a universal
session step. (detailed explanation: §7)

<a id="jlp-cap-bit-005"></a>
<!-- claim:JLP-CAP-BIT-005 -->

**JLP-CAP-BIT-005 — Capability bit 5.** Capability bit 5 is cataloged as
configuration write; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-013"></a>
<!-- claim:JLP-CAP-BIT-013 -->

**JLP-CAP-BIT-013 — Capability bit 13.** Capability bit 13 is cataloged as
auxiliary target power; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-023"></a>
<!-- claim:JLP-CAP-BIT-023 -->

**JLP-CAP-BIT-023 — Capability bit 23.** Capability bit 23 is cataloged as SWO
service; this label does not by itself authorize the associated operation.
(detailed explanation: §9.2)

<a id="jlp-cap-bit-026"></a>
<!-- claim:JLP-CAP-BIT-026 -->

**JLP-CAP-BIT-026 — Capability bit 26.** Capability bit 26 is cataloged as
on-probe file service; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-027"></a>
<!-- claim:JLP-CAP-BIT-027 -->

**JLP-CAP-BIT-027 — Capability bit 27.** Capability bit 27 is cataloged as
connection registration; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-032"></a>
<!-- claim:JLP-CAP-BIT-032 -->

**JLP-CAP-BIT-032 — Capability bit 32.** Capability bit 32 is cataloged as
write-only scan; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-033"></a>
<!-- claim:JLP-CAP-BIT-033 -->

**JLP-CAP-BIT-033 — Capability bit 33.** Capability bit 33 is cataloged as
emulator communication channels; this label does not by itself authorize the
associated operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-038"></a>
<!-- claim:JLP-CAP-BIT-038 -->

**JLP-CAP-BIT-038 — Capability bit 38.** Capability bit 38 is cataloged as
Ethernet host-transport capability; this label does not by itself authorize the
associated operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-056"></a>
<!-- claim:JLP-CAP-BIT-056 -->

**JLP-CAP-BIT-056 — Capability bit 56.** Capability bit 56 is cataloged as
target SPI service; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-hardware-field-bit-016"></a>
<!-- claim:JLP-HARDWARE-FIELD-BIT-016 -->

**JLP-HARDWARE-FIELD-BIT-016 — Hardware field bit 16.** Hardware-field mask bit
16 selects assigned IPv4 address as four wire-order octets. (detailed
explanation: §10.5)

<a id="jlp-hardware-field-bit-017"></a>
<!-- claim:JLP-HARDWARE-FIELD-BIT-017 -->

**JLP-HARDWARE-FIELD-BIT-017 — Hardware field bit 17.** Hardware-field mask bit
17 selects IPv4 netmask as four wire-order octets. (detailed explanation: §10.5)

<a id="jlp-hardware-field-bit-018"></a>
<!-- claim:JLP-HARDWARE-FIELD-BIT-018 -->

**JLP-HARDWARE-FIELD-BIT-018 — Hardware field bit 18.** Hardware-field mask bit
18 selects IPv4 gateway as four wire-order octets. (detailed explanation: §10.5)

<a id="jlp-hardware-field-bit-019"></a>
<!-- claim:JLP-HARDWARE-FIELD-BIT-019 -->

**JLP-HARDWARE-FIELD-BIT-019 — Hardware field bit 19.** Hardware-field mask bit
19 selects IPv4 DNS server as four wire-order octets. (detailed explanation:
§10.5)

<a id="jlp-hardware-field-bit-023"></a>
<!-- claim:JLP-HARDWARE-FIELD-BIT-023 -->

**JLP-HARDWARE-FIELD-BIT-023 — Hardware field bit 23.** Hardware-field mask bit
23 selects USB supply voltage in millivolts. (detailed explanation: §10.5)

<a id="jlp-interface-id-005"></a>
<!-- claim:JLP-INTERFACE-ID-005 -->

**JLP-INTERFACE-ID-005 — Interface selector 5.** Interface selector 5 denotes
SPI. (detailed explanation: §11.1)

<a id="jlp-interface-id-006"></a>
<!-- claim:JLP-INTERFACE-ID-006 -->

**JLP-INTERFACE-ID-006 — Interface selector 6.** Interface selector 6 denotes
Silicon Labs C2. (detailed explanation: §11.1)

<a id="jlp-interface-id-007"></a>
<!-- claim:JLP-INTERFACE-ID-007 -->

**JLP-INTERFACE-ID-007 — Interface selector 7.** Interface selector 7 denotes
cJTAG. (detailed explanation: §11.1)

<a id="jlp-interface-id-010"></a>
<!-- claim:JLP-INTERFACE-ID-010 -->

**JLP-INTERFACE-ID-010 — Interface selector 10.** Interface selector 10 denotes
Microchip IS208x two-wire JTAG. (detailed explanation: §11.1)

<a id="jlp-aux-power-request-001"></a>
<!-- claim:JLP-AUX-POWER-REQUEST-001 -->

**JLP-AUX-POWER-REQUEST-001 — Auxiliary-power request.** The request is 08
followed by one byte: zero off or one on; there is no application response.
(detailed explanation: §11.5)

<a id="jlp-aux-power-gate-001"></a>
<!-- claim:JLP-AUX-POWER-GATE-001 -->

**JLP-AUX-POWER-GATE-001 — Auxiliary-power capability gate.** The host emits
auxiliary-power control only when capability bit 13 is set. (detailed
explanation: §11.5)

<a id="jlp-tap-reset-pulse-001"></a>
<!-- claim:JLP-TAP-RESET-PULSE-001 -->

**JLP-TAP-RESET-PULSE-001 — TAP reset pulse.** The one-byte request 02 asserts
then releases the dedicated TAP reset pin and has no application response.
(detailed explanation: §11.6)

<a id="jlp-system-reset-pulse-001"></a>
<!-- claim:JLP-SYSTEM-RESET-PULSE-001 -->

**JLP-SYSTEM-RESET-PULSE-001 — System reset pulse.** The one-byte request 03
asserts then releases system reset and has no application response. (detailed
explanation: §11.6)

<a id="jlp-pin-tms-low-001"></a>
<!-- claim:JLP-PIN-TMS-LOW-001 -->

**JLP-PIN-TMS-LOW-001 — Persistent pin TMS low.** The one-byte request c9
performs persistent TMS low and has no application response. (detailed
explanation: §11.7)

<a id="jlp-pin-tms-high-001"></a>
<!-- claim:JLP-PIN-TMS-HIGH-001 -->

**JLP-PIN-TMS-HIGH-001 — Persistent pin TMS high.** The one-byte request ca
performs persistent TMS high and has no application response. (detailed
explanation: §11.7)

<a id="jlp-pin-tdi-low-001"></a>
<!-- claim:JLP-PIN-TDI-LOW-001 -->

**JLP-PIN-TDI-LOW-001 — Persistent pin TDI low.** The one-byte request cb
performs persistent TDI low and has no application response. (detailed
explanation: §11.7)

<a id="jlp-pin-tdi-high-001"></a>
<!-- claim:JLP-PIN-TDI-HIGH-001 -->

**JLP-PIN-TDI-HIGH-001 — Persistent pin TDI high.** The one-byte request cc
performs persistent TDI high and has no application response. (detailed
explanation: §11.7)

<a id="jlp-pin-tck-low-001"></a>
<!-- claim:JLP-PIN-TCK-LOW-001 -->

**JLP-PIN-TCK-LOW-001 — Persistent pin TCK low.** The one-byte request da
performs persistent TCK low and has no application response. (detailed
explanation: §11.7)

<a id="jlp-pin-tck-high-001"></a>
<!-- claim:JLP-PIN-TCK-HIGH-001 -->

**JLP-PIN-TCK-HIGH-001 — Persistent pin TCK high.** The one-byte request db
performs persistent TCK high and has no application response. (detailed
explanation: §11.7)

<a id="jlp-pin-system-reset-assert-001"></a>
<!-- claim:JLP-PIN-SYSTEM-RESET-ASSERT-001 -->

**JLP-PIN-SYSTEM-RESET-ASSERT-001 — Persistent pin system reset assert.** The
one-byte request dc performs persistent system reset assert and has no
application response. (detailed explanation: §11.7)

<a id="jlp-pin-system-reset-release-001"></a>
<!-- claim:JLP-PIN-SYSTEM-RESET-RELEASE-001 -->

**JLP-PIN-SYSTEM-RESET-RELEASE-001 — Persistent pin system reset release.** The
one-byte request dd performs persistent system reset release and has no
application response. (detailed explanation: §11.7)

<a id="jlp-pin-tap-reset-assert-001"></a>
<!-- claim:JLP-PIN-TAP-RESET-ASSERT-001 -->

**JLP-PIN-TAP-RESET-ASSERT-001 — Persistent pin TAP reset assert.** The one-byte
request de performs persistent TAP reset assert and has no application response.
(detailed explanation: §11.7)

<a id="jlp-pin-tap-reset-release-001"></a>
<!-- claim:JLP-PIN-TAP-RESET-RELEASE-001 -->

**JLP-PIN-TAP-RESET-RELEASE-001 — Persistent pin TAP reset release.** The
one-byte request df performs persistent TAP reset release and has no application
response. (detailed explanation: §11.7)

<a id="jlp-pin-cleanup-001"></a>
<!-- claim:JLP-PIN-CLEANUP-001 -->

**JLP-PIN-CLEANUP-001 — Persistent-pin cleanup.** An owner of persistent pin
state performs best-effort restoration to an explicitly chosen safe state.
(detailed explanation: §11.7)

<a id="jlp-scan-write-only-request-001"></a>
<!-- claim:JLP-SCAN-WRITE-ONLY-REQUEST-001 -->

**JLP-SCAN-WRITE-ONLY-REQUEST-001 — Write-only scan request.** The request is
d5, 00, u16le bit count, packed control bits, then packed drive bits, and has no
immediate response. (detailed explanation: §12.5)

<a id="jlp-scan-write-only-sticky-001"></a>
<!-- claim:JLP-SCAN-WRITE-ONLY-STICKY-001 -->

**JLP-SCAN-WRITE-ONLY-STICKY-001 — Write-only sticky result.** Write-only scan
failure is retained in probe-side sticky state for later query. (detailed
explanation: §12.5)

<a id="jlp-scan-write-status-request-001"></a>
<!-- claim:JLP-SCAN-WRITE-STATUS-REQUEST-001 -->

**JLP-SCAN-WRITE-STATUS-REQUEST-001 — Write-status request.** The one-byte
request d6 reads and clears write-only scan status. (detailed explanation:
§12.6)

<a id="jlp-scan-write-status-response-001"></a>
<!-- claim:JLP-SCAN-WRITE-STATUS-RESPONSE-001 -->

**JLP-SCAN-WRITE-STATUS-RESPONSE-001 — Write-status response.** The response is
one status byte, with zero documented as success. (detailed explanation: §12.6)

<a id="jlp-scan-write-status-clear-001"></a>
<!-- claim:JLP-SCAN-WRITE-STATUS-CLEAR-001 -->

**JLP-SCAN-WRITE-STATUS-CLEAR-001 — Write-status clearing.** Reading d6 clears
the sticky write-only scan result. (detailed explanation: §12.6)

<a id="jlp-scan-selection-write-only-gate-001"></a>
<!-- claim:JLP-SCAN-SELECTION-WRITE-ONLY-GATE-001 -->

**JLP-SCAN-SELECTION-WRITE-ONLY-GATE-001 — Write-only scan gate.** Write-only
scan remains disabled unless capability bit 32 is set and direct observation or
a recorded policy exception exists. (detailed explanation: §12.7)

<a id="jlp-config-write-request-001"></a>
<!-- claim:JLP-CONFIG-WRITE-REQUEST-001 -->

**JLP-CONFIG-WRITE-REQUEST-001 — Configuration-write request.** The request is
f3 followed by all 256 configuration bytes. (detailed explanation: §14.1)

<a id="jlp-config-write-response-001"></a>
<!-- claim:JLP-CONFIG-WRITE-RESPONSE-001 -->

**JLP-CONFIG-WRITE-RESPONSE-001 — Configuration-write response.** Configuration
write has no application acknowledgement. (detailed explanation: §14.1)

<a id="jlp-config-write-gate-001"></a>
<!-- claim:JLP-CONFIG-WRITE-GATE-001 -->

**JLP-CONFIG-WRITE-GATE-001 — Configuration capability gate.** Configuration
read or write is emitted only when its corresponding capability bit is set.
(detailed explanation: §14.1)

<a id="jlp-config-write-preserve-001"></a>
<!-- claim:JLP-CONFIG-WRITE-PRESERVE-001 -->

**JLP-CONFIG-WRITE-PRESERVE-001 — Configuration-byte preservation.** A writer
modifies only known intended bytes and preserves every other byte from a fresh
full-block read. (detailed explanation: §14.1)

<a id="jlp-config-write-backup-001"></a>
<!-- claim:JLP-CONFIG-WRITE-BACKUP-001 -->

**JLP-CONFIG-WRITE-BACKUP-001 — Configuration backup.** A configuration writer
retains a verified backup and recovery plan before emission. (detailed
explanation: §14.1)

<a id="jlp-config-write-admin-001"></a>
<!-- claim:JLP-CONFIG-WRITE-ADMIN-001 -->

**JLP-CONFIG-WRITE-ADMIN-001 — Configuration administrative boundary.**
Configuration write is excluded from ordinary host-driver APIs and requires an
explicit administrative action. (detailed explanation: §14.1)

<a id="jlp-swo-request-prefix-001"></a>
<!-- claim:JLP-SWO-REQUEST-PREFIX-001 -->

**JLP-SWO-REQUEST-PREFIX-001 — SWO request prefix.** Known SWO requests begin
with eb, a suboperation, local TLVs, and a zero-length terminator. (detailed
explanation: §15)

<a id="jlp-swo-tlv-mode-001"></a>
<!-- claim:JLP-SWO-TLV-MODE-001 -->

**JLP-SWO-TLV-MODE-001 — SWO mode TLV.** SWO TLV tag 1 carries a four-byte mode;
known mode zero is UART/NRZ. (detailed explanation: §15)

<a id="jlp-swo-tlv-baud-001"></a>
<!-- claim:JLP-SWO-TLV-BAUD-001 -->

**JLP-SWO-TLV-BAUD-001 — SWO baud TLV.** SWO TLV tag 2 carries a u32le requested
baud. (detailed explanation: §15)

<a id="jlp-swo-tlv-read-size-001"></a>
<!-- claim:JLP-SWO-TLV-READ-SIZE-001 -->

**JLP-SWO-TLV-READ-SIZE-001 — SWO read-size TLV.** SWO TLV tag 3 carries a u32le
requested read size. (detailed explanation: §15)

<a id="jlp-swo-tlv-buffer-size-001"></a>
<!-- claim:JLP-SWO-TLV-BUFFER-SIZE-001 -->

**JLP-SWO-TLV-BUFFER-SIZE-001 — SWO buffer-size TLV.** SWO TLV tag 4 carries a
u32le on-probe buffer size. (detailed explanation: §15)

<a id="jlp-swo-unknown-tag-001"></a>
<!-- claim:JLP-SWO-UNKNOWN-TAG-001 -->

**JLP-SWO-UNKNOWN-TAG-001 — Unknown SWO tag.** Unknown SWO tags may be decoded
but are never emitted by this project. (detailed explanation: §15)

<a id="jlp-swo-start-request-001"></a>
<!-- claim:JLP-SWO-START-REQUEST-001 -->

**JLP-SWO-START-REQUEST-001 — SWO capture start request.** The request is eb 64
with mode, baud, and buffer-size TLVs, then a zero terminator. (detailed
explanation: §15.1)

<a id="jlp-swo-start-response-001"></a>
<!-- claim:JLP-SWO-START-RESPONSE-001 -->

**JLP-SWO-START-RESPONSE-001 — SWO capture start response.** The response is one
u32le status or flags word. (detailed explanation: §15.1)

<a id="jlp-swo-stop-request-001"></a>
<!-- claim:JLP-SWO-STOP-REQUEST-001 -->

**JLP-SWO-STOP-REQUEST-001 — SWO capture stop request.** The request is eb 65
followed by a zero terminator. (detailed explanation: §15.2)

<a id="jlp-swo-stop-response-001"></a>
<!-- claim:JLP-SWO-STOP-RESPONSE-001 -->

**JLP-SWO-STOP-RESPONSE-001 — SWO capture stop response.** The response is one
u32le status or flags word. (detailed explanation: §15.2)

<a id="jlp-swo-read-request-001"></a>
<!-- claim:JLP-SWO-READ-REQUEST-001 -->

**JLP-SWO-READ-REQUEST-001 — SWO data read request.** The request is eb 66 with
a requested-size TLV and zero terminator. (detailed explanation: §15.3)

<a id="jlp-swo-read-response-001"></a>
<!-- claim:JLP-SWO-READ-RESPONSE-001 -->

**JLP-SWO-READ-RESPONSE-001 — SWO data read response.** The response is
flags:u32le, actual:u32le, then exactly actual data bytes. (detailed
explanation: §15.3)

<a id="jlp-swo-start-zero-success-001"></a>
<!-- claim:JLP-SWO-START-ZERO-SUCCESS-001 -->

**JLP-SWO-START-ZERO-SUCCESS-001 — SWO start zero status.** A zero start
response means success; nonzero values are preserved and fail the start.
(detailed explanation: §15.1)

<a id="jlp-swo-start-buffer-guard-001"></a>
<!-- claim:JLP-SWO-START-BUFFER-GUARD-001 -->

**JLP-SWO-START-BUFFER-GUARD-001 — SWO buffer guard.** The requested SWO buffer
is bounded by workspace and tested probe limits. (detailed explanation: §15.1)

<a id="jlp-swo-stop-zero-success-001"></a>
<!-- claim:JLP-SWO-STOP-ZERO-SUCCESS-001 -->

**JLP-SWO-STOP-ZERO-SUCCESS-001 — SWO stop zero status.** A zero stop response
means success. (detailed explanation: §15.2)

<a id="jlp-swo-read-overrun-001"></a>
<!-- claim:JLP-SWO-READ-OVERRUN-001 -->

**JLP-SWO-READ-OVERRUN-001 — SWO overrun flag.** SWO read flag bit zero
indicates capture-buffer overrun. (detailed explanation: §15.3)

<a id="jlp-swo-read-bounds-001"></a>
<!-- claim:JLP-SWO-READ-BOUNDS-001 -->

**JLP-SWO-READ-BOUNDS-001 — SWO read bounds.** The host checks actual is no
greater than requested before allocation or data read. (detailed explanation:
§15.3)

<a id="jlp-swo-read-polling-001"></a>
<!-- claim:JLP-SWO-READ-POLLING-001 -->

**JLP-SWO-READ-POLLING-001 — SWO polling guard.** The host uses a bounded read
size and polling cadence that avoids known undersized-read and overrun hazards.
(detailed explanation: §15.3)

<a id="jlp-swo-clock-error-word-001"></a>
<!-- claim:JLP-SWO-CLOCK-ERROR-WORD-001 -->

**JLP-SWO-CLOCK-ERROR-WORD-001 — SWO clock error word.** A high bit in the first
SWO clock-description word is treated by public clients as an error indication.
(detailed explanation: §15.4)

<a id="jlp-swo-clock-rate-candidate-001"></a>
<!-- claim:JLP-SWO-CLOCK-RATE-CANDIDATE-001 -->

**JLP-SWO-CLOCK-RATE-CANDIDATE-001 — SWO candidate-rate formula.** The candidate
rate family base_hz/divisor/max(1,prescaler) is source-derived and not directly
verified across the advertised range. (detailed explanation: §15.4)

<a id="jlp-registration-subop-register-001"></a>
<!-- claim:JLP-REGISTRATION-SUBOP-REGISTER-001 -->

**JLP-REGISTRATION-SUBOP-REGISTER-001 — Connection registration subop
register.** Suboperation 64 registers or refreshes a client connection.
(detailed explanation: §16)

<a id="jlp-registration-subop-unregister-001"></a>
<!-- claim:JLP-REGISTRATION-SUBOP-UNREGISTER-001 -->

**JLP-REGISTRATION-SUBOP-UNREGISTER-001 — Connection registration subop
unregister.** Suboperation 65 unregisters a client connection. (detailed
explanation: §16)

<a id="jlp-registration-request-001"></a>
<!-- claim:JLP-REGISTRATION-REQUEST-001 -->

**JLP-REGISTRATION-REQUEST-001 — Connection registration request.** A request is
exactly 14 bytes: 09, suboperation:u8, process_id:u32le, host_id:bytes[4],
interface_id:u8, connection_id:u8, and handle:u16le in that order. (detailed
explanation: §16)

<a id="jlp-registration-handle-001"></a>
<!-- claim:JLP-REGISTRATION-HANDLE-001 -->

**JLP-REGISTRATION-HANDLE-001 — Connection registration handle.** The request
handle, response result_handle, and table-entry handle are all u16le values.
(detailed explanation: §16)

<a id="jlp-registration-response-001"></a>
<!-- claim:JLP-REGISTRATION-RESPONSE-001 -->

**JLP-REGISTRATION-RESPONSE-001 — Connection registration response.** The
response begins with the eight-byte header result_handle:u16le,
entry_count:u16le, entry_size:u16le, extra_size:u16le, followed by entry_count ×
entry_size entry bytes and extra_size extra bytes. (detailed explanation: §16)

<a id="jlp-registration-entry-001"></a>
<!-- claim:JLP-REGISTRATION-ENTRY-001 -->

**JLP-REGISTRATION-ENTRY-001 — Connection registration entry.** Each 16-byte
entry is process_id:u32le, host_id:bytes[4], interface_id:u8, connection_id:u8,
handle:u16le, and last_registration_ms:u32le in that order. (detailed
explanation: §16)

<a id="jlp-registration-bounds-001"></a>
<!-- claim:JLP-REGISTRATION-BOUNDS-001 -->

**JLP-REGISTRATION-BOUNDS-001 — Connection registration bounds.** A response is
rejected unless entry_count is at most 16, entry_size is exactly 16, and 8 +
entry_count × entry_size + extra_size is at most 512 under checked arithmetic.
(detailed explanation: §16)

<a id="jlp-registration-success-001"></a>
<!-- claim:JLP-REGISTRATION-SUCCESS-001 -->

**JLP-REGISTRATION-SUCCESS-001 — Connection registration success.** A new
registration succeeds only when result_handle is nonzero and an entry with the
same handle appears in the returned table. (detailed explanation: §16)

<a id="jlp-registration-padding-001"></a>
<!-- claim:JLP-REGISTRATION-PADDING-001 -->

**JLP-REGISTRATION-PADDING-001 — Connection registration padding.**
Probe-to-host bytes between the meaningful response end and the 76-byte minimum
are bounded, semantically ignored padding; no zero value is required. (detailed
explanation: §16)

<a id="jlp-registration-compatibility-001"></a>
<!-- claim:JLP-REGISTRATION-COMPATIBILITY-001 -->

**JLP-REGISTRATION-COMPATIBILITY-001 — Connection registration compatibility.**
IPv4-shaped fields and interface IDs in this USB operation do not import Remote
Server/TCP framing. (detailed explanation: §16)

<a id="jlp-channel-status-count-001"></a>
<!-- claim:JLP-CHANNEL-STATUS-COUNT-001 -->

**JLP-CHANNEL-STATUS-COUNT-001 — Emulator communication channel status count.**
The family status word may carry an available byte count. (detailed explanation:
§17)

<a id="jlp-channel-status-unsupported-001"></a>
<!-- claim:JLP-CHANNEL-STATUS-UNSUPPORTED-001 -->

**JLP-CHANNEL-STATUS-UNSUPPORTED-001 — Emulator communication channel status
unsupported.** The exact u32le value 0x80000001 denotes an unsupported channel
service. (detailed explanation: §17)

<a id="jlp-channel-status-unavailable-001"></a>
<!-- claim:JLP-CHANNEL-STATUS-UNAVAILABLE-001 -->

**JLP-CHANNEL-STATUS-UNAVAILABLE-001 — Emulator communication channel status
unavailable.** A read result with high byte 0x81 denotes requested data
unavailable, and its low 24 bits report the available byte count. (detailed
explanation: §17)

<a id="jlp-channel-read-request-001"></a>
<!-- claim:JLP-CHANNEL-READ-REQUEST-001 -->

**JLP-CHANNEL-READ-REQUEST-001 — Emulator communication channel read request.**
Read suboperation 00 carries channel and requested-count fields. (detailed
explanation: §17)

<a id="jlp-channel-read-response-001"></a>
<!-- claim:JLP-CHANNEL-READ-RESPONSE-001 -->

**JLP-CHANNEL-READ-RESPONSE-001 — Emulator communication channel read
response.** A channel-read response starts with status_or_actual:u32le and, only
when bit 31 is clear, continues with exactly actual data bytes where actual does
not exceed requested. (detailed explanation: §17)

<a id="jlp-channel-write-request-001"></a>
<!-- claim:JLP-CHANNEL-WRITE-REQUEST-001 -->

**JLP-CHANNEL-WRITE-REQUEST-001 — Emulator communication channel write
request.** Write suboperation 01 carries channel, count, and data bytes.
(detailed explanation: §17)

<a id="jlp-channel-write-response-001"></a>
<!-- claim:JLP-CHANNEL-WRITE-RESPONSE-001 -->

**JLP-CHANNEL-WRITE-RESPONSE-001 — Emulator communication channel write
response.** A channel-write response is status_or_actual:u32le; a high-bit-clear
value is the accepted byte count and must not exceed the requested length.
(detailed explanation: §17)

<a id="jlp-channel-zero-001"></a>
<!-- claim:JLP-CHANNEL-ZERO-001 -->

**JLP-CHANNEL-ZERO-001 — Emulator communication channel zero.** Zero-length
channel transfers are handled without inventing data. (detailed explanation:
§17)

<a id="jlp-channel-user-range-001"></a>
<!-- claim:JLP-CHANNEL-USER-RANGE-001 -->

**JLP-CHANNEL-USER-RANGE-001 — Emulator communication channel user range.** The
public implementation's user-channel range is client policy, not a universal
wire limit. (detailed explanation: §17)

<a id="jlp-file-suboperations-001"></a>
<!-- claim:JLP-FILE-SUBOPERATIONS-001 -->

**JLP-FILE-SUBOPERATIONS-001 — On-probe file suboperations.** Suboperations 64,
65, 66, and 67 identify read, write, size, and delete. (detailed explanation:
§18)

<a id="jlp-file-tlv-name-001"></a>
<!-- claim:JLP-FILE-TLV-NAME-001 -->

**JLP-FILE-TLV-NAME-001 — On-probe file tlv name.** The filename TLV is
name_length:u8, tag 01, then 1–255 raw filename bytes without a terminating NUL.
(detailed explanation: §18)

<a id="jlp-file-tlv-offset-001"></a>
<!-- claim:JLP-FILE-TLV-OFFSET-001 -->

**JLP-FILE-TLV-OFFSET-001 — On-probe file tlv offset.** The file-offset TLV is
exactly 04 02 followed by offset:u32le. (detailed explanation: §18)

<a id="jlp-file-tlv-length-001"></a>
<!-- claim:JLP-FILE-TLV-LENGTH-001 -->

**JLP-FILE-TLV-LENGTH-001 — On-probe file tlv length.** The file-length TLV is
exactly 04 03 followed by length:u32le. (detailed explanation: §18)

<a id="jlp-file-status-001"></a>
<!-- claim:JLP-FILE-STATUS-001 -->

**JLP-FILE-STATUS-001 — On-probe file status.** File-service status is
interpreted only within the file family. (detailed explanation: §18)

<a id="jlp-file-read-request-001"></a>
<!-- claim:JLP-FILE-READ-REQUEST-001 -->

**JLP-FILE-READ-REQUEST-001 — On-probe file read request.** A file-read request
identifies name, offset, and length. (detailed explanation: §18)

<a id="jlp-file-read-response-001"></a>
<!-- claim:JLP-FILE-READ-RESPONSE-001 -->

**JLP-FILE-READ-RESPONSE-001 — On-probe file read response.** A file-read
response supplies requested buffer bytes before actual_or_error:u32le; when the
high bit is clear, only the first actual bytes are content and actual must not
exceed requested. (detailed explanation: §18)

<a id="jlp-file-read-padding-001"></a>
<!-- claim:JLP-FILE-READ-PADDING-001 -->

**JLP-FILE-READ-PADDING-001 — On-probe file read padding.** Any family padding
is consumed without becoming file data. (detailed explanation: §18)

<a id="jlp-file-write-request-001"></a>
<!-- claim:JLP-FILE-WRITE-REQUEST-001 -->

**JLP-FILE-WRITE-REQUEST-001 — On-probe file write request.** A file-write
request identifies name, offset, and length. (detailed explanation: §18)

<a id="jlp-file-write-data-transfer-001"></a>
<!-- claim:JLP-FILE-WRITE-DATA-TRANSFER-001 -->

**JLP-FILE-WRITE-DATA-TRANSFER-001 — On-probe file write data transfer.** After
the terminated file-write TLV header, the host sends exactly length data bytes;
the header and data may occupy distinct bulk OUT transfers. (detailed
explanation: §18)

<a id="jlp-file-write-response-001"></a>
<!-- claim:JLP-FILE-WRITE-RESPONSE-001 -->

**JLP-FILE-WRITE-RESPONSE-001 — On-probe file write response.** A file-write
response is actual_or_error:u32le; a high-bit-clear value is the written byte
count and must not exceed length. (detailed explanation: §18)

<a id="jlp-file-size-001"></a>
<!-- claim:JLP-FILE-SIZE-001 -->

**JLP-FILE-SIZE-001 — On-probe file size.** File-size suboperation 66 returns
one size_or_error:u32le word; a clear high bit denotes the size and a set high
bit denotes a device error. (detailed explanation: §18)

<a id="jlp-file-delete-001"></a>
<!-- claim:JLP-FILE-DELETE-001 -->

**JLP-FILE-DELETE-001 — On-probe file delete.** The delete suboperation mutates
persistent on-probe state. (detailed explanation: §18)

<a id="jlp-file-name-guard-001"></a>
<!-- claim:JLP-FILE-NAME-GUARD-001 -->

**JLP-FILE-NAME-GUARD-001 — On-probe file name guard.** A host bounds and
validates file-name length before emission. (detailed explanation: §18)

<a id="jlp-file-client-chunk-001"></a>
<!-- claim:JLP-FILE-CLIENT-CHUNK-001 -->

**JLP-FILE-CLIENT-CHUNK-001 — On-probe file client chunk.** A client chunks file
transfers below declared and tested limits. (detailed explanation: §18)

<a id="jlp-c2-interface-gate-001"></a>
<!-- claim:JLP-C2-INTERFACE-GATE-001 -->

**JLP-C2-INTERFACE-GATE-001 — Silicon Labs C2 interface gate.** The service is
used only with the C2 target interface selected. (detailed explanation: §19)

<a id="jlp-c2-suboperations-001"></a>
<!-- claim:JLP-C2-SUBOPERATIONS-001 -->

**JLP-C2-SUBOPERATIONS-001 — Silicon Labs C2 suboperations.** Suboperations 00
through 03 identify data read, data write, address read, and address write.
(detailed explanation: §19)

<a id="jlp-c2-read-request-001"></a>
<!-- claim:JLP-C2-READ-REQUEST-001 -->

**JLP-C2-READ-REQUEST-001 — Silicon Labs C2 read request.** A C2 read request is
17, register-selecting suboperation:u8, reserved 00, and length:u16le;
address-register suboperation 02 requires length one. (detailed explanation:
§19)

<a id="jlp-c2-read-response-001"></a>
<!-- claim:JLP-C2-READ-RESPONSE-001 -->

**JLP-C2-READ-RESPONSE-001 — Silicon Labs C2 read response.** A C2 read response
is data:bytes[length] followed by status:u32le; address-register reads return
one data byte while data-register reads are variable length. (detailed
explanation: §19)

<a id="jlp-c2-write-request-001"></a>
<!-- claim:JLP-C2-WRITE-REQUEST-001 -->

**JLP-C2-WRITE-REQUEST-001 — Silicon Labs C2 write request.** A C2 write request
is 17, register-selecting suboperation:u8, length:u16le, reserved 00, and
data:bytes[length]; address-register suboperation 03 requires length one.
(detailed explanation: §19)

<a id="jlp-c2-write-response-001"></a>
<!-- claim:JLP-C2-WRITE-RESPONSE-001 -->

**JLP-C2-WRITE-RESPONSE-001 — Silicon Labs C2 write response.** A C2 write
response is exactly status:u32le, where zero is success and every nonzero value
is an undifferentiated device error. (detailed explanation: §19)

<a id="jlp-c2-status-001"></a>
<!-- claim:JLP-C2-STATUS-001 -->

**JLP-C2-STATUS-001 — Silicon Labs C2 status.** C2 status is interpreted only
within the C2 service. (detailed explanation: §19)

<a id="jlp-c2-client-limit-001"></a>
<!-- claim:JLP-C2-CLIENT-LIMIT-001 -->

**JLP-C2-CLIENT-LIMIT-001 — Silicon Labs C2 client limit.** The pinned client
limits C2 data-register transfers to 64 bytes although the wire length field is
u16le; 64 is client policy, not a proven protocol maximum. (detailed
explanation: §19)

<a id="jlp-spi-interface-gate-001"></a>
<!-- claim:JLP-SPI-INTERFACE-GATE-001 -->

**JLP-SPI-INTERFACE-GATE-001 — Target SPI interface gate.** The service is used
only with the SPI target interface selected. (detailed explanation: §20)

<a id="jlp-spi-mode-001"></a>
<!-- claim:JLP-SPI-MODE-001 -->

**JLP-SPI-MODE-001 — Target SPI mode.** The pinned public implementation fixes
SPI mode 3 and MSB-first shifting; neither mode nor clock is encoded as a
request field. (detailed explanation: §20)

<a id="jlp-spi-request-001"></a>
<!-- claim:JLP-SPI-REQUEST-001 -->

**JLP-SPI-REQUEST-001 — Target SPI request.** The SPI request is 15 01 00 00,
tx_section_length:u32le, rx_section_length:u32le, bit_count:u32le, flags:u32le,
then tx_data:bytes[tx_length] in that order. (detailed explanation: §20)

<a id="jlp-spi-response-001"></a>
<!-- claim:JLP-SPI-RESPONSE-001 -->

**JLP-SPI-RESPONSE-001 — Target SPI response.** The SPI response is
rx_data:bytes[rx_length] followed by transferred_bytes:u32le; the final word is
a result count, not a documented status code. (detailed explanation: §20)

<a id="jlp-spi-length-relationships-001"></a>
<!-- claim:JLP-SPI-LENGTH-RELATIONSHIPS-001 -->

**JLP-SPI-LENGTH-RELATIONSHIPS-001 — Target SPI length relationships.** For the
pinned whole-byte API, tx_section_length equals tx_length plus 8. (detailed
explanation: §20)

<a id="jlp-spi-rx-section-length-001"></a>
<!-- claim:JLP-SPI-RX-SECTION-LENGTH-001 -->

**JLP-SPI-RX-SECTION-LENGTH-001 — Target SPI receive-section length.** For the
pinned whole-byte API, rx_section_length equals rx_length plus 4. (detailed
explanation: §20)

<a id="jlp-spi-bit-count-001"></a>
<!-- claim:JLP-SPI-BIT-COUNT-001 -->

**JLP-SPI-BIT-COUNT-001 — Target SPI bit count.** For the pinned whole-byte API,
bit_count equals transfer_length_bytes multiplied by 8. (detailed explanation:
§20)

<a id="jlp-spi-direction-modes-001"></a>
<!-- claim:JLP-SPI-DIRECTION-MODES-001 -->

**JLP-SPI-DIRECTION-MODES-001 — Target SPI direction modes.** Direction and
duplex modes are interpreted only within the SPI family. (detailed explanation:
§20)

<a id="jlp-spi-count-validation-001"></a>
<!-- claim:JLP-SPI-COUNT-VALIDATION-001 -->

**JLP-SPI-COUNT-VALIDATION-001 — Target SPI count validation.** Every
SPI-supplied or requested count is bounded with checked arithmetic. (detailed
explanation: §20)

<a id="jlp-spi-cs-start-001"></a>
<!-- claim:JLP-SPI-CS-START-001 -->

**JLP-SPI-CS-START-001 — Target SPI cs start.** A request flag can begin
chip-select ownership. (detailed explanation: §20)

<a id="jlp-spi-cs-end-001"></a>
<!-- claim:JLP-SPI-CS-END-001 -->

**JLP-SPI-CS-END-001 — Target SPI cs end.** A request flag can end chip-select
ownership. (detailed explanation: §20)

<a id="jlp-spi-cs-cleanup-001"></a>
<!-- claim:JLP-SPI-CS-CLEANUP-001 -->

**JLP-SPI-CS-CLEANUP-001 — Target SPI cs cleanup.** A failed operation performs
best-effort chip-select cleanup when ownership was acquired. (detailed
explanation: §20)

### 31.4 `decoder-only`

<a id="jlp-usb-discovery-004"></a>
<!-- claim:JLP-USB-DISCOVERY-004 -->

**JLP-USB-DISCOVERY-004 — Legacy address mapping.** Historical logical USB
addresses 0 through 3 map to PIDs 0x0101 through 0x0104. (detailed explanation:
§4)

<a id="jlp-usb-discovery-015"></a>
<!-- claim:JLP-USB-DISCOVERY-015 -->

**JLP-USB-DISCOVERY-015 — Historical endpoint defaults.** Historical endpoint
layouts are decoding defaults only and do not override active descriptors.
(detailed explanation: §4)

<a id="jlp-transport-capture-001"></a>
<!-- claim:JLP-TRANSPORT-CAPTURE-001 -->

**JLP-TRANSPORT-CAPTURE-001 — Directional capture reassembly.** A decoder
reassembles each endpoint direction independently and preserves successful
zero-length events when the capture layer exposes them. (detailed explanation:
§5)

<a id="jlp-transport-limit-001"></a>
<!-- claim:JLP-TRANSPORT-LIMIT-001 -->

**JLP-TRANSPORT-LIMIT-001 — Historical OUT limit.** The historical manual gives
0xffff bytes as a host-to-probe application-transfer upper figure. (detailed
explanation: §5)

<a id="jlp-transport-limit-002"></a>
<!-- claim:JLP-TRANSPORT-LIMIT-002 -->

**JLP-TRANSPORT-LIMIT-002 — Historical IN limit.** The historical manual gives
0x8000 bytes as a probe-to-host application-transfer upper figure. (detailed
explanation: §5)

<a id="jlp-transport-timeout-001"></a>
<!-- claim:JLP-TRANSPORT-TIMEOUT-001 -->

**JLP-TRANSPORT-TIMEOUT-001 — Historical work budget.** The historical probe
work budget is approximately five seconds rather than a universal host timeout.
(detailed explanation: §5)

<a id="jlp-encoding-tlv-unknown-001"></a>
<!-- claim:JLP-ENCODING-TLV-UNKNOWN-001 -->

**JLP-ENCODING-TLV-UNKNOWN-001 — Unknown TLV emission.** Unknown TLV tags may be
preserved by decoders but are never emitted. (detailed explanation: §6)

<a id="jlp-session-legacy-jtag-001"></a>
<!-- claim:JLP-SESSION-LEGACY-JTAG-001 -->

**JLP-SESSION-LEGACY-JTAG-001 — Legacy JTAG assumption.** Treating probes
without interface management as JTAG-only is a client compatibility assumption,
not a universal wire fact. (detailed explanation: §7)

<a id="jlp-cap-bit-000"></a>
<!-- claim:JLP-CAP-BIT-000 -->

**JLP-CAP-BIT-000 — Capability bit 0.** Capability bit 0 is cataloged as
protocol marker; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-002"></a>
<!-- claim:JLP-CAP-BIT-002 -->

**JLP-CAP-BIT-002 — Capability bit 2.** Capability bit 2 is cataloged as DCC
write; this label does not by itself authorize the associated operation.
(detailed explanation: §9.2)

<a id="jlp-cap-bit-006"></a>
<!-- claim:JLP-CAP-BIT-006 -->

**JLP-CAP-BIT-006 — Capability bit 6.** Capability bit 6 is cataloged as
historical trace family; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-007"></a>
<!-- claim:JLP-CAP-BIT-007 -->

**JLP-CAP-BIT-007 — Capability bit 7.** Capability bit 7 is cataloged as generic
memory write; this label does not by itself authorize the associated operation.
(detailed explanation: §9.2)

<a id="jlp-cap-bit-008"></a>
<!-- claim:JLP-CAP-BIT-008 -->

**JLP-CAP-BIT-008 — Capability bit 8.** Capability bit 8 is cataloged as generic
memory read; this label does not by itself authorize the associated operation.
(detailed explanation: §9.2)

<a id="jlp-cap-bit-014"></a>
<!-- claim:JLP-CAP-BIT-014 -->

**JLP-CAP-BIT-014 — Capability bit 14.** Capability bit 14 is cataloged as timed
reset-and-halt; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-015"></a>
<!-- claim:JLP-CAP-BIT-015 -->

**JLP-CAP-BIT-015 — Capability bit 15.** Capability bit 15 is cataloged as
reserved or unknown; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-016"></a>
<!-- claim:JLP-CAP-BIT-016 -->

**JLP-CAP-BIT-016 — Capability bit 16.** Capability bit 16 is cataloged as RTCK
reaction measurement; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-018"></a>
<!-- claim:JLP-CAP-BIT-018 -->

**JLP-CAP-BIT-018 — Capability bit 18.** Capability bit 18 is cataloged as
historical ARM7/9 memory access; this label does not by itself authorize the
associated operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-020"></a>
<!-- claim:JLP-CAP-BIT-020 -->

**JLP-CAP-BIT-020 — Capability bit 20.** Capability bit 20 is cataloged as DCC
read identifier; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-021"></a>
<!-- claim:JLP-CAP-BIT-021 -->

**JLP-CAP-BIT-021 — Capability bit 21.** Capability bit 21 is cataloged as
target CPU capabilities; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-022"></a>
<!-- claim:JLP-CAP-BIT-022 -->

**JLP-CAP-BIT-022 — Capability bit 22.** Capability bit 22 is cataloged as
target CPU operation; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-024"></a>
<!-- claim:JLP-CAP-BIT-024 -->

**JLP-CAP-BIT-024 — Capability bit 24.** Capability bit 24 is cataloged as
extended DCC write identifier; this label does not by itself authorize the
associated operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-028"></a>
<!-- claim:JLP-CAP-BIT-028 -->

**JLP-CAP-BIT-028 — Capability bit 28.** Capability bit 28 is cataloged as
indicator identifier; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-030"></a>
<!-- claim:JLP-CAP-BIT-030 -->

**JLP-CAP-BIT-030 — Capability bit 30.** Capability bit 30 is cataloged as raw
trace identifier; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-hardware-field-bit-001"></a>
<!-- claim:JLP-HARDWARE-FIELD-BIT-001 -->

**JLP-HARDWARE-FIELD-BIT-001 — Hardware field bit 1.** Hardware-field mask bit 1
selects overcurrent trip reason. (detailed explanation: §10.5)

<a id="jlp-hardware-field-bit-004"></a>
<!-- claim:JLP-HARDWARE-FIELD-BIT-004 -->

**JLP-HARDWARE-FIELD-BIT-004 — Hardware field bit 4.** Hardware-field mask bit 4
selects peak operation current in milliamperes. (detailed explanation: §10.5)

<a id="jlp-hardware-field-bit-010"></a>
<!-- claim:JLP-HARDWARE-FIELD-BIT-010 -->

**JLP-HARDWARE-FIELD-BIT-010 — Hardware field bit 10.** Hardware-field mask bit
10 selects longest interval above 3000 mA in milliseconds. (detailed
explanation: §10.5)

<a id="jlp-hardware-field-bit-011"></a>
<!-- claim:JLP-HARDWARE-FIELD-BIT-011 -->

**JLP-HARDWARE-FIELD-BIT-011 — Hardware field bit 11.** Hardware-field mask bit
11 selects longest interval above 1000 mA in milliseconds. (detailed
explanation: §10.5)

<a id="jlp-hardware-field-bit-012"></a>
<!-- claim:JLP-HARDWARE-FIELD-BIT-012 -->

**JLP-HARDWARE-FIELD-BIT-012 — Hardware field bit 12.** Hardware-field mask bit
12 selects longest interval above 400 mA in milliseconds. (detailed explanation:
§10.5)

<a id="jlp-rtck-request-001"></a>
<!-- claim:JLP-RTCK-REQUEST-001 -->

**JLP-RTCK-REQUEST-001 — RTCK request.** target.rtck.measure is the one-byte
request f6. (detailed explanation: §10.7)

<a id="jlp-rtck-response-001"></a>
<!-- claim:JLP-RTCK-RESPONSE-001 -->

**JLP-RTCK-RESPONSE-001 — RTCK response.** The documented response is four u32le
words: result, minimum_ns, maximum_ns, and average_ns. (detailed explanation:
§10.7)

<a id="jlp-rtck-status-001"></a>
<!-- claim:JLP-RTCK-STATUS-001 -->

**JLP-RTCK-STATUS-001 — RTCK status meanings.** The historical result values are
zero for success and one for no target reaction. (detailed explanation: §10.7)

<a id="jlp-interface-id-002"></a>
<!-- claim:JLP-INTERFACE-ID-002 -->

**JLP-INTERFACE-ID-002 — Interface selector 2.** Interface selector 2 denotes
BDM3. (detailed explanation: §11.1)

<a id="jlp-interface-id-003"></a>
<!-- claim:JLP-INTERFACE-ID-003 -->

**JLP-INTERFACE-ID-003 — Interface selector 3.** Interface selector 3 denotes
Renesas FINE. (detailed explanation: §11.1)

<a id="jlp-interface-id-004"></a>
<!-- claim:JLP-INTERFACE-ID-004 -->

**JLP-INTERFACE-ID-004 — Interface selector 4.** Interface selector 4 denotes
PIC32 ICSP or two-wire JTAG. (detailed explanation: §11.1)

<a id="jlp-reset-pulse-duration-001"></a>
<!-- claim:JLP-RESET-PULSE-DURATION-001 -->

**JLP-RESET-PULSE-DURATION-001 — Historical reset duration.** The historical
manual describes an approximately two-millisecond assertion, not a universal
timing guarantee. (detailed explanation: §11.6)

<a id="jlp-scan-clock-one-request-001"></a>
<!-- claim:JLP-SCAN-CLOCK-ONE-REQUEST-001 -->

**JLP-SCAN-CLOCK-ONE-REQUEST-001 — Single-clock request.** The request is one
byte c8. (detailed explanation: §11.8)

<a id="jlp-scan-clock-one-response-001"></a>
<!-- claim:JLP-SCAN-CLOCK-ONE-RESPONSE-001 -->

**JLP-SCAN-CLOCK-ONE-RESPONSE-001 — Single-clock response.** The documented
response is one sampled-pin byte. (detailed explanation: §11.8)

<a id="jlp-scan-clock-one-signal-001"></a>
<!-- claim:JLP-SCAN-CLOCK-ONE-SIGNAL-001 -->

**JLP-SCAN-CLOCK-ONE-SIGNAL-001 — Single-clock sampled signal.** The identity of
the sampled signal remains unresolved and must not be silently renamed.
(detailed explanation: §11.8)

<a id="jlp-scan-v1-request-001"></a>
<!-- claim:JLP-SCAN-V1-REQUEST-001 -->

**JLP-SCAN-V1-REQUEST-001 — Scan v1 request.** The request is cd, u16le bit
count, packed control bits, then packed drive bits, without the v2/v3 reserved
byte. (detailed explanation: §12.2)

<a id="jlp-scan-v1-response-001"></a>
<!-- claim:JLP-SCAN-V1-RESPONSE-001 -->

**JLP-SCAN-V1-RESPONSE-001 — Scan v1 response.** The response is one packed
sample bit per requested clock. (detailed explanation: §12.2)

<a id="jlp-reset-halt-repeat-request-001"></a>
<!-- claim:JLP-RESET-HALT-REPEAT-REQUEST-001 -->

**JLP-RESET-HALT-REPEAT-REQUEST-001 — Repeated reset-and-halt request.** The
request contains five u16le control fields followed by equal-length TMS and TDI
byte arrays. (detailed explanation: §13.1)

<a id="jlp-reset-halt-repeat-response-001"></a>
<!-- claim:JLP-RESET-HALT-REPEAT-RESPONSE-001 -->

**JLP-RESET-HALT-REPEAT-RESPONSE-001 — Repeated reset-and-halt response.** The
response is one TDO byte for each requested scan byte. (detailed explanation:
§13.1)

<a id="jlp-reset-halt-timed-request-001"></a>
<!-- claim:JLP-RESET-HALT-TIMED-REQUEST-001 -->

**JLP-RESET-HALT-TIMED-REQUEST-001 — Timed reset-and-halt request.** The request
contains scan byte count, timeout, criterion fields, and equal-length TMS and
TDI arrays. (detailed explanation: §13.2)

<a id="jlp-reset-halt-timed-response-001"></a>
<!-- claim:JLP-RESET-HALT-TIMED-RESPONSE-001 -->

**JLP-RESET-HALT-TIMED-RESPONSE-001 — Timed reset-and-halt response.** The
response is one TDO byte for each requested scan byte. (detailed explanation:
§13.2)

<a id="jlp-dcc-write-request-001"></a>
<!-- claim:JLP-DCC-WRITE-REQUEST-001 -->

**JLP-DCC-WRITE-REQUEST-001 — Historical DCC write request.** The request
contains six u16le controls, a derived-length JTAG program, and item bytes.
(detailed explanation: §13.3)

<a id="jlp-dcc-write-response-001"></a>
<!-- claim:JLP-DCC-WRITE-RESPONSE-001 -->

**JLP-DCC-WRITE-RESPONSE-001 — Historical DCC write response.** The response is
one status byte: zero success or one timeout. (detailed explanation: §13.3)

<a id="jlp-cpu-capabilities-request-001"></a>
<!-- claim:JLP-CPU-CAPABILITIES-REQUEST-001 -->

**JLP-CPU-CAPABILITIES-REQUEST-001 — Target CPU capabilities request.** The
request is e9, device-family byte, interface byte, and two zero bytes. (detailed
explanation: §13.4)

<a id="jlp-cpu-capabilities-response-001"></a>
<!-- claim:JLP-CPU-CAPABILITIES-RESPONSE-001 -->

**JLP-CPU-CAPABILITIES-RESPONSE-001 — Target CPU capabilities response.** The
response is one u32le CPU-capability mask. (detailed explanation: §13.4)

<a id="jlp-cpu-operation-request-001"></a>
<!-- claim:JLP-CPU-OPERATION-REQUEST-001 -->

**JLP-CPU-OPERATION-REQUEST-001 — Historical CPU operation request.** The
request contains operation, suboperation, target selectors, configuration length
and bytes, u32le address and length, plus write data when applicable. (detailed
explanation: §13.5)

<a id="jlp-cpu-operation-response-001"></a>
<!-- claim:JLP-CPU-OPERATION-RESPONSE-001 -->

**JLP-CPU-OPERATION-RESPONSE-001 — Historical CPU operation response.** The
documented write response is a u32le result; the read-data placement is
unresolved. (detailed explanation: §13.5)

<a id="jlp-memory-arm79-write-request-001"></a>
<!-- claim:JLP-MEMORY-ARM79-WRITE-REQUEST-001 -->

**JLP-MEMORY-ARM79-WRITE-REQUEST-001 — ARM7/9 memory write request.** The
request contains chain metadata, flags, zero reserved field, suboperation, u32le
address and length, and write bytes. (detailed explanation: §13.7)

<a id="jlp-memory-arm79-write-response-001"></a>
<!-- claim:JLP-MEMORY-ARM79-WRITE-RESPONSE-001 -->

**JLP-MEMORY-ARM79-WRITE-RESPONSE-001 — ARM7/9 memory write response.** The
response is one status byte. (detailed explanation: §13.7)

<a id="jlp-memory-arm79-read-request-001"></a>
<!-- claim:JLP-MEMORY-ARM79-READ-REQUEST-001 -->

**JLP-MEMORY-ARM79-READ-REQUEST-001 — ARM7/9 memory read request.** The request
is the ARM7/9 memory header without write data. (detailed explanation: §13.8)

<a id="jlp-memory-arm79-read-response-001"></a>
<!-- claim:JLP-MEMORY-ARM79-READ-RESPONSE-001 -->

**JLP-MEMORY-ARM79-READ-RESPONSE-001 — ARM7/9 memory read response.** A small
successful read returns status zero then data; large-read and error layouts
remain unresolved. (detailed explanation: §13.8)

<a id="jlp-reset-halt-repeat-criterion-001"></a>
<!-- claim:JLP-RESET-HALT-REPEAT-CRITERION-001 -->

**JLP-RESET-HALT-REPEAT-CRITERION-001 — Repeated halt criterion.** The repeated
operation stops when the masked returned criterion equals the requested value or
the repeat limit is reached. (detailed explanation: §13.1)

<a id="jlp-reset-halt-timed-criterion-001"></a>
<!-- claim:JLP-RESET-HALT-TIMED-CRITERION-001 -->

**JLP-RESET-HALT-TIMED-CRITERION-001 — Timed halt criterion.** The timed
operation returns no explicit success flag; the host evaluates the returned
criterion. (detailed explanation: §13.2)

<a id="jlp-dcc-program-length-001"></a>
<!-- claim:JLP-DCC-PROGRAM-LENGTH-001 -->

**JLP-DCC-PROGRAM-LENGTH-001 — DCC program length.** The historical DCC
JTAG-program length is twice ceil(initialization_bits/8) plus
ceil(status_bits/8) plus ceil(data_bits/8). (detailed explanation: §13.3)

<a id="jlp-cpu-capability-bits-001"></a>
<!-- claim:JLP-CPU-CAPABILITY-BITS-001 -->

**JLP-CPU-CAPABILITY-BITS-001 — CPU capability bits.** Historical CPU-capability
bits 0, 1, and 2 mean marker, CPU write, and CPU read respectively. (detailed
explanation: §13.4)

<a id="jlp-cpu-operation-read-unresolved-001"></a>
<!-- claim:JLP-CPU-OPERATION-READ-UNRESOLVED-001 -->

**JLP-CPU-OPERATION-READ-UNRESOLVED-001 — CPU read response unresolved.** The
historical source does not establish where CPU read data appears relative to its
result word. (detailed explanation: §13.5)

<a id="jlp-memory-generic-write-code-001"></a>
<!-- claim:JLP-MEMORY-GENERIC-WRITE-CODE-001 -->

**JLP-MEMORY-GENERIC-WRITE-CODE-001 — Generic memory-write identifier.**
Operation code f4 is publicly enumerated as generic memory write, but its
grammar is not established. (detailed explanation: §13.6)

<a id="jlp-memory-generic-read-code-001"></a>
<!-- claim:JLP-MEMORY-GENERIC-READ-CODE-001 -->

**JLP-MEMORY-GENERIC-READ-CODE-001 — Generic memory-read identifier.** Operation
code f5 is publicly enumerated as generic memory read, but its grammar is not
established. (detailed explanation: §13.6)

<a id="jlp-memory-arm79-status-001"></a>
<!-- claim:JLP-MEMORY-ARM79-STATUS-001 -->

**JLP-MEMORY-ARM79-STATUS-001 — ARM7/9 memory status.** Historical status values
0 through 3 mean success, adaptive-clock timeout, memory-access timeout, and
core error. (detailed explanation: §13.7)

<a id="jlp-memory-arm79-read-unresolved-001"></a>
<!-- claim:JLP-MEMORY-ARM79-READ-UNRESOLVED-001 -->

**JLP-MEMORY-ARM79-READ-UNRESOLVED-001 — ARM7/9 read response conflict.**
Large-read and failure response conditions overlap in the historical prose and
remain unresolved. (detailed explanation: §13.8)

<a id="jlp-config-usb-address-001"></a>
<!-- claim:JLP-CONFIG-USB-ADDRESS-001 -->

**JLP-CONFIG-USB-ADDRESS-001 — Historical configuration usb address.** In the
historical 256-byte configuration map, offset 0x00 is the legacy USB address.
(detailed explanation: §14.2)

<a id="jlp-config-aux-power-001"></a>
<!-- claim:JLP-CONFIG-AUX-POWER-001 -->

**JLP-CONFIG-AUX-POWER-001 — Historical configuration aux power.** In the
historical 256-byte configuration map, offsets 0x04 through 0x07 are the default
auxiliary-power setting. (detailed explanation: §14.2)

<a id="jlp-config-ipv4-address-001"></a>
<!-- claim:JLP-CONFIG-IPV4-ADDRESS-001 -->

**JLP-CONFIG-IPV4-ADDRESS-001 — Historical configuration ipv4 address.** In the
historical 256-byte configuration map, offsets 0x20 through 0x23 are the static
IPv4 address. (detailed explanation: §14.2)

<a id="jlp-config-ipv4-netmask-001"></a>
<!-- claim:JLP-CONFIG-IPV4-NETMASK-001 -->

**JLP-CONFIG-IPV4-NETMASK-001 — Historical configuration ipv4 netmask.** In the
historical 256-byte configuration map, offsets 0x24 through 0x27 are the IPv4
subnet mask. (detailed explanation: §14.2)

<a id="jlp-config-mac-001"></a>
<!-- claim:JLP-CONFIG-MAC-001 -->

**JLP-CONFIG-MAC-001 — Historical configuration mac.** In the historical
256-byte configuration map, offsets 0x30 through 0x35 are the MAC address.
(detailed explanation: §14.2)

<a id="jlp-config-reserved-001"></a>
<!-- claim:JLP-CONFIG-RESERVED-001 -->

**JLP-CONFIG-RESERVED-001 — Historical configuration reserved.** In the
historical 256-byte configuration map, all remaining listed ranges are
historical reserved bytes, not synthesis defaults. (detailed explanation: §14.2)

<a id="jlp-config-reenumeration-001"></a>
<!-- claim:JLP-CONFIG-REENUMERATION-001 -->

**JLP-CONFIG-REENUMERATION-001 — Configuration re-enumeration.** Changing the
legacy USB address can change the PID after re-enumeration. (detailed
explanation: §14.2)

### 31.5 `excluded`

<a id="jlp-scope-remote-001"></a>
<!-- claim:JLP-SCOPE-REMOTE-001 -->

**JLP-SCOPE-REMOTE-001 — Remote Server exclusion.** J-Link Remote Server and TCP
framing are outside this USB specification. (detailed explanation: §2)

<a id="jlp-scope-target-001"></a>
<!-- claim:JLP-SCOPE-TARGET-001 -->

**JLP-SCOPE-TARGET-001 — Target-algorithm separation.** Arm, JTAG, SWD,
SWO-decoder, and silicon algorithms carried inside generic scan payloads are not
J-Link USB wire claims. (detailed explanation: §2)

<a id="jlp-scope-emulator-001"></a>
<!-- claim:JLP-SCOPE-EMULATOR-001 -->

**JLP-SCOPE-EMULATOR-001 — Public emulator exclusion.** A public deployable
J-Link-compatible emulator is outside this project's implementation boundary.
(detailed explanation: §2)

<a id="jlp-cap-bit-010"></a>
<!-- claim:JLP-CAP-BIT-010 -->

**JLP-CAP-BIT-010 — Capability bit 10.** Capability bit 10 is cataloged as
on-probe code execution; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-025"></a>
<!-- claim:JLP-CAP-BIT-025 -->

**JLP-CAP-BIT-025 — Capability bit 25.** Capability bit 25 is cataloged as
extended firmware update; this label does not by itself authorize the associated
operation. (detailed explanation: §9.2)

<a id="jlp-cap-bit-029"></a>
<!-- claim:JLP-CAP-BIT-029 -->

**JLP-CAP-BIT-029 — Capability bit 29.** Capability bit 29 is cataloged as
network speed-test identifier; this label does not by itself authorize the
associated operation. (detailed explanation: §9.2)

## 32. Distribution, license, and notices

This file is designed to be vendored intact—for example as
`docs/probes/JLINK_USB_PROTOCOL.md`—as supporting documentation for a J-Link
host implementation. No companion file is required to interpret its notation,
wire grammars, evidence grades, implementation profiles, source ledger,
observations, or stable claim IDs.

The source research project may retain additional machine-readable provenance,
transcripts, conformance vectors, validators, and release checksums. Those
materials are useful for auditing the upstream edition but are not a dependency
of a consuming project's documentation tree. This guide is documentation rather
than generated code. After a project adopts a profile or claim, a disagreement
among this guide, the implementation, and its tests is a defect to resolve or an
explicit downstream deviation to record—not a reason to silently prefer one copy
of the rule.

When vendoring the file, retain the title, edition and research-cutoff metadata,
stable claim anchors, and this section. Record substantive downstream edits so
readers can distinguish the upstream edition from a local fork. A consuming
project can link its code and tests to the `JLP-…` identifiers without importing
the source research catalog.

The following notice is embedded so that the applicable terms and boundaries
travel with a one-file distribution.

### 32.1 Copyright and license

**SPDX-License-Identifier:** `Apache-2.0`

Copyright 2026 Jon Olson

Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at <https://www.apache.org/licenses/LICENSE-2.0>.

Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations.

The license applies only to the copyrightable original expression, selection,
arrangement, and editorial contributions for which Jon Olson can grant rights.
It does not relicense cited manuals, standards, source code, discussions, logs,
trademarks, product rights, or other third-party material, all of which remain
subject to their own terms. Facts and wire behavior may not be copyrightable in
a given jurisdiction.

### 32.2 Full Apache License, Version 2.0

The complete license text is included here so that a one-file distribution
carries the license itself, rather than only a link to it.

<details>
<summary>Apache License, Version 2.0</summary>

```text
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

```

</details>

### 32.3 Affiliation and marks

J-Link is used here to identify SEGGER products and their interoperability
surface. This project is not affiliated with, sponsored by, or endorsed by
SEGGER. JTAG, SWD, and SWO are used as technical terms. The Apache License does
not grant rights to SEGGER trademarks or products, and this guide grants no
right to present another product as a SEGGER product.

---

**End of edition 1.0.**
