Understanding ARM Debug Interface: SWD

0. Introduction

The documentation from ARM is already very good, but it still lacks clarity on what to do immediately after powering on, which caused me some trouble during my first use. Today, I will provide a detailed overview to help more friends. By the way, the ARM_Cortex-M0/3 DesignStart series will continue to be updated, but may include other knowledge points in between.

1. Overview of SWD

SWD stands for Serial Wire Debug, which translates to “串行线调试” in Chinese. SWD is one of the two debug ports currently supported by ARM, the other being the JTAG Debug Port, which is the debug port commonly used on J-link (in JTAG mode). Based on the ARM CoreSight debugging architecture, SWD can read and write the chip’s registers by transmitting data packets. SWD is a two-wire protocol used to access the ARM debug interface. It is part of the ARM Debug Interface Architecture Specification and serves as a replacement for JTAG. The physical layer of SWD consists of two lines:

SWDIO: Bidirectional data line

SWCLK: Host-driven clock line

The following diagram is a simple connection diagram of SWD:

Understanding ARM Debug Interface: SWD

External devices (such as debug probes) can directly access the Serial Wire Debug Port (SW-DP) by connecting to SWDIO/SWCLK. SW-DP can access one or more Access Ports (AP), through which the remaining registers of the system can be accessed. An important AP for the Cortex M series CPU is the AHB-AP, which is the host on the internal AHB bus. In other words, the AHB-AP can access the memory map of the internal core. Since the internal flash, SRAM, debug components, and peripherals are all memory-mapped, the AHB-AP can control the entire device, including programming it. The entire SWD operation process is hierarchical, with the clock signal input from the SWCLK pin and the data signal input/output from the SWDIO pin. First, the Debugger operates on the SW-DP to determine the parameters of the AP registers, enabling operations on the Cortex Memory Map.

The following three screenshots illustrate the connection implementation of the ARM Debug Interface. As shown in the figure, the DAP consists of two parts: DP and MEM-AP (commonly referred to as AP). MEM-AP is a general term, encompassing APB/AHB/AXI-AP.

Understanding ARM Debug Interface: SWD

Understanding ARM Debug Interface: SWD

Understanding ARM Debug Interface: SWD

2. SWD Protocol

SWCLK is always driven by the host’s clock signal. Both parties will drive the SWDIO line to send data, with a high value on SWDIO indicating logic “1” and a low value indicating logic “0”. The protocol specifies three different phases when both parties drive the SWDIO line. Each transaction begins with a request sent by the host; the target then responds; finally, there is a data transfer phase. The control of the data phase depends on the type of request issued by the host. If the host issues a write request, the host will drive the SWDIO line. In the case of a read request, the target will drive the SWDIO line to transfer data from the target to the host. In all phases, the data is first transmitted LSB (Least Significant Bit). Whether the target samples data from the SWDIO line or drives data onto the SWDIO line, it occurs on the rising edge of the SWCLK clock.

2.1 SWD Commands

2.1.1 Host Sends Packet Request

The external host debugger sends a request to the DP, which is the target of this request.

The request sent by the host consists of 8 bits, as shown in the figure below:

Understanding ARM Debug Interface: SWD

Bit0: Start, fixed to 1.

Bit1: APnDP, 0 indicates access to DP registers, 1 indicates access to MEM-AP registers.

Bit2: RnW, 0 indicates a write request, 1 indicates a read request.

Bit[4:3]: Address value A[3:2], storing the address of the DP/AP registers.

Bit5: Parity, used to indicate the total number of odd bits in {APnDP, RnW, A[2:3]}.

Bit6: Stop, fixed to 0.

Bit7: Park, fixed to 1.

2.1.2 Target Returns ACK

The ACK value returned by the target consists of 3 bits: ACK[0:2]==001 indicates FAULT, ACK[0:2]==010 indicates WAIT, ACK[0:2]==100 indicates OK response.

2.1.3 Data Bit Transmission

Data consists of 32 bits of valid data + 1 bit of parity bit.

2.2 DAP Registers

During SWD communication, the main registers involved are two: one DP (Debug Port) and one AP (Access Port). To access the core registers, the access sequence is DP -> AP -> Core Register.

2.2.1 DP Registers

The DP registers are shown in the figure below, with the address indicated by ADDR[2:3] in the packet header. For details, please refer to the “ARM Debug Interface v5 Architecture Specification”.

Understanding ARM Debug Interface: SWD

The following diagram is a table created by a netizen based on ADI5’s description, which is easier to understand.

Understanding ARM Debug Interface: SWD

IDCODE Register

IDCODE: Identification Code Register, used to identify SW-DP. The IDCODE register provides identification information about SW-DP. On devices with Cortex-M3 or Cortex-M4 cores, this register should be 0x2BA01477. For devices with Cortex-M0+ cores, this register should be 0x0BC11477.

ABORT Register

ABORT: Abort register, forces AP transactions to abort. During communication, if a sticky error occurs at position 1 (ack = 4). Writing 0b1 to ABORT will generate a DAP abort, forcing the current AP transaction to abort.

The main purpose of the ABORT register is to force the DAP to abort, and on SW-DP, it is also used to clear error and sticky flag conditions. Below is the definition of each bit of the AP ABORT register.

Understanding ARM Debug Interface: SWD

If you want to find the reason for the flag being set to 1. Generally:
For STICKYCMP or STICKYARR flags, you must find the accessed location to set the flag to 1.
For WDATAERR flags, you must resend the corrupted data.
For STICKYORUN flags, you must find the DP or AP transaction that caused the overflow. Then you must repeat the transaction starting from that point.
CTRL/STAT Register
CTRL/STAT: Control Status Register, used to control and obtain status information about DP.
SELECT: AHB-AP select register, selects the port (AP) to access and the bank address in AP and the bank address in DP.
RDBUFF Register

RDBUFF: Read Buffer Register, on SW-DP, RDBUFF shows the data captured during the last AP read, allowing repeated return values without generating a new AP access.

It is worth noting that after a bus reset, it is necessary to perform a switch operation between JTAG and SWD (send 0x79E7 or 0xE79E), then you must read the IDCODE first to determine the type of MCU before continuing with other operations.

2.2.2 AP (MEM-AP) Registers

MEM-AP provides DAP access to the memory subsystem. Since memory, peripherals, and debug components are all memory-mapped, MEM-AP can be used for programming and debugging Cortex M0/M3, etc.

Compared to DP registers, AP registers are much more complex. For details, please refer to the “ARM Debug Interface v5 Architecture Specification”.

Understanding ARM Debug Interface: SWD

The following diagram is a table created by a netizen based on ADI5’s description, which is easier to understand.

Understanding ARM Debug Interface: SWD

CSW Register

CSW: Control/Status Word Register, CSW configures and controls the memory system accessed through MEM-AP. size: 32bit-0b010; 16bit-0b001

TAR Register

TAR Register: Transfer Address Register, saves the memory address to be accessed. By setting b01 in the AddrInc field of the CSW register, the content of TAR can be automatically incremented upon successful access to DRW.

DRW Register

DRW: Data Read/Write Register, used to write or read data from the address specified in TAR. DRW directly maps the value passed in the AP access to one or more memory accesses at the address specified in TAR. When intending to write a value to a memory address, the address is first written to the TAR register, and then the value is written to DRW. When intending to read data from a memory address, the address is first written to TAR, and then the value is read from DRW.

IDR: Identification Register, IDR identifies the accessed port. To read this register, the APBANKSEL field should be set to 0xF. The IDR register can then be read using address 0x0C (ADDR[3:2]=b11). For devices with Cortex-M3 or Cortex-M4 cores, the IDR register should return the value 0x24770011. For devices with Cortex-M0+, it should return 0x0477003.

2.3 Debug and System Registers

The following screenshot shows the Cortex M3 debug registers. Using the debug registers, we can set the Core to halt mode and change Core registers such as SP or PC.

Understanding ARM Debug Interface: SWD

2.3.1 DHCSR Register

DHCSR=Debug Halting Control and Status Register

DHCSR controls the processor’s halt, single-step, and restart actions. When C_DEBUGEN is set to 1, halt debugging will be enabled. For more detailed information, please refer to the “ARM Cortex-Mx Authority Guide”.

Understanding ARM Debug Interface: SWD

2.3.2 DCRSR

DCRSR register = Debug Core Register Selector Register, provides debug access to the ARM core registers, special-purpose registers, and Floating-point extension registers. A write to DCRSR specifies the register to transfer.

Understanding ARM Debug Interface: SWD

2.3.3 DCRDR

Debug Core Register Data Register, DCRDR register provides debug access to the ARM core registers, special-purpose registers, and floating-point extension registers. DCRDR is the data register for these accesses.

2.3.4 DEMCR

Debug Exception and Monitor Control Register, DEMCR register manages vector catch

behavior and DebugMonitor handling when debugging. Bits [23:16] provide DebugMonitor exception control. Bits [15:0] provide Debug state, halting debug, control.

Understanding ARM Debug Interface: SWD

2.3.5 AIRCR

Application Interrupt and Reset Control Register, AIRCR register sets or returns interrupt control data.

Understanding ARM Debug Interface: SWD

2.4 SWD Protocol Operation Timing

2.4.1 Successful Write Timing

As shown in the figure below, it is worth noting the trn (turnaround period), because we are using single-bus communication, where both write and read occur on the same line, and this trn occurs during the delay when switching from write to read.

Understanding ARM Debug Interface: SWD

2.3.2 Successful Read Timing

Understanding ARM Debug Interface: SWD

2.3.3 Response WAIT Timing

Understanding ARM Debug Interface: SWD

2.3.4 Response FAULT Timing

Understanding ARM Debug Interface: SWD

2.3.5 Protocol Error Response

Understanding ARM Debug Interface: SWD

2.3.6 Sticky Overrun Behavior

Understanding ARM Debug Interface: SWD

3. SWD Operation Steps

3.1 SWD Initialization Steps

  1. a) InitializeIO ports, set SWCLK and SWIO to output mode, keep SWDIO=1, ensuring that Host continuously sends at least 50 “1”, allowing Target to perform a Line Reset.
  2. b) Send JTAG to SWD command, 0x79E7 two bytes, then send a line reset operation again.
  3. c) Send at least two Idle signals, keeping SWDIO=0.
  4. d) Read the chip’s IDCODE, completing the SWD initialization operation. At this point, only the DP register group can be accessed, while the AP register group is still inaccessible. Note that after a reset, the IDCODE must be read once (located in DP register). Set the address to 00b, and read the DP operation to read the IDCODE, which varies depending on the core model; mine is 0x0BB11477.
The content in the ARM spec is shown in the figure below, for more details please refer to ARM Debug Interface v5 Architecture Specification ADIv5.0 to ADIv5.2“.

Understanding ARM Debug Interface: SWD

Understanding ARM Debug Interface: SWD

Understanding ARM Debug Interface: SWD

3.2 Accessing AP Registers via DP

  • 1) Write 0x50000000 to the CTRL/STAT register in DP (bits 28 and 30), enabling the debug port and its clock;

CSYSPWRUPREQ: System powerup request; CDBGPWRUPREQ: Debug powerup request

Understanding ARM Debug Interface: SWD

  • 2) Write to the SELECT register in DP to determine APBANK.
For example, writing the data as 0x000000F0 means APSEL=0x00, indicating AHB access; APBANKSEL=0xF indicates selecting the bank address of the current AP; DPBANKSEL=0x0 indicates DP.CTRL

Understanding ARM Debug Interface: SWD

Understanding ARM Debug Interface: SWD

3) Read the data from the IDR register (addr = 0xFC) and verify it

IDR is the IDCODE of the AP register, the IDR register is a read-only register, located at offset address 0xFC in the AP register space, and an IDR value of zero indicates that the AP does not exist. When reading the value of the IDR register, it is necessary to read it twice; the first time is a dummy read, and the second time the correct data is obtained. (The second time can also read from the RDBUFF register).

Understanding ARM Debug Interface: SWD

4) Write 0x00000002 to the CSW register, data_size: 32bit

Understanding ARM Debug Interface: SWD

Size:Access the size of the data type in MEM-AP, where: if the register’s data is 32bit, CSW.Size=’b010′; if the data being programmed is 16bit, CSW.Size=’b001′.

Understanding ARM Debug Interface: SWD

3.3 Read/Write Operations

If you want to write/read the values of the chip’s internal Flash/Sram/Register, you need to use two AP registers: TAR (Transfer Address Register) and DRW (Data Read/Write Register).

Understanding ARM Debug Interface: SWD

Understanding ARM Debug Interface: SWD

The screenshot above explains clearly that the address in the TAR register is not the address inside the AP, but the physical address in the chip system connected to the AP.

DRW register directly maps the AP access to one or more memory accesses inside the chip system. The AP access will not complete until the memory access is finished.

DRW register is R/W (readable and writable), and its offset in the MEM-AP register space is 0x0C.

In write mode, DRW writes the currently transmitted value to the address specified in TAR.

In read mode, DRW holds the current transmitted value read from the address specified in TAR.

3.2.1 Write Operation
1) Write the memory address value to be accessed in the TAR register (for example, addr = 0x08000000) 2) Write the data to be written to the chip’s memory in the DRW register (for example, data = 0x12345678)
3.2.2 Read Operation
1) Write the memory address value to be accessed in the TAR register (for example, addr = 0x08000000) 2) Read the data stored in memory from the DRW register 3) Read data from the RDBUFF register (DP) or read data from the DRW register (AP) the second time

3.4 Notes During Read/Write:

Due to the special nature of reading AP registers, the returned data is the value from the last transmission. In other words, there are two ways to obtain the correct value of the AP register.

a) Send the read operation for the DRW register twice;

b) Send one read operation for the DRW register (reading the data from the previous cycle), then send one read operation for the RDBUFF register (reading the data you need)

In general, reading/writing DP registers has no latency and does not require two reads/writes. Reading AP registers has latency; the first time reading AP gets the previous cycle’s value, and the second time reading AP gets the desired value. Writing AP registers has no latency. For TAR and DRW, writing once is sufficient.

4. Programming SRAM via SWD

This section will demonstrate step-by-step how to program the internal SRAM via SWD.

4.1 Initialization

Before using SW-DP, an initialization sequence must be performed to establish communication and bring SW-DP into a known state.
  1. a) Send more than 50 cycles of SWCLK/TCK, SWDIO/TMS=1. This ensures that both SWD and JTAG are in a reset state.
  2. b) Send the 16-bit JTAG-to-SWD select sequence on SWDIOTMS
  3. c) Send more than 50 cycles of SWCLK/TCK, SWDIO/TMS=1. This ensures that if SWJ-DP is already in SWD mode, SWD will perform a line reset before sending the select sequence.
  4. d) Perform READID to verify that SW-DP has switched to SWD operation.

4.2 Halt CPU

Before programming the internal SRAM or FLASH, the CPU should first be reset and halted. This is mainly to set the CPU and peripherals to a known state and prevent the CPU from inadvertently running part of the code while programming.

The specific operation steps are as follows,

a)Write 0xA05F0001 to DHCSR, which enables halt debug.

b)Write 0x01 to DEMCR. This enables Reset Vector Catch.

c)Write 0xFA050004 to AIRCR. This resets the core.

Now, the core will halt at the first instruction, and all peripherals and registers (except debug registers) will be set to reset values.

4.3 Memory and Core Register Access.

4.3.1 Access Memory
  1. a) Set 32 bit width and auto increment in CSW register.

  2. b) Write memory address in TAR register

  3. c) Access DRW register for read/write data.

4.3.2 Access Core Registers

Read:

a) Set 32 bit width in CSW register
  1. b) Write DCRSR address into TAR register.

  2. c) Write core register index Rn into DRW register.

  3. d) Write DCRDR address into TAR register.

  4. e) Read core register value from DRW register.

Write:

a) Set 32 bit width in CSW register.
b) Write DCRDR address into TAR register.
c) Write core value into DRW register.
d) Write DCRSR address into TAR register.
e) Write core register index Rn and REGWnR = 1 into DRW register.

5 Notes During SWD Operations

5.1 Additional 8 Cycles of Clock After Data Transmission Completion

As shown in the screenshot below, this is mainly to ensure the stability of data transmission.

Understanding ARM Debug Interface: SWD

5.2 Errors in Invalid Request Packets

As shown in the figure below, generally, when this situation occurs, it is due to parity errors in the request packet sent by the HOST, which may be due to a bug in the HOST itself sending an incorrect parity bit, or it may be due to transmission errors during the sending process, with many possibilities for errors, but ultimately leading to one point: the host finds that the target did not drive the SWDIO line during the ACK phase, and due to the pull-up resistor, the host will ultimately see the received ACK as 3’b111. Once this error occurs, the host can only line reset the DAP, then read DPIDR, and establish a synchronization mechanism before continuing communication, essentially starting over.

Understanding ARM Debug Interface: SWD

5.3 Write Data Error WDATAERR

The DP will monitor this situation, leading to three consequences:
First, the write operation will not be triggered due to the detected parity error;
Second, the error flag WDATAERR will be set in the next two cycles;
Third, when the host initiates the next transmission, it will receive a Fault ACK in its ACK phase, i.e., ACK=3’b001.
Once an ACK is ACK_FAULT, it is necessary to immediately read the CTRL/STAT to check what caused the error; if it is found to be WDATAERR, the AP Abort register should be written to clear the error state, and the previous failed write operation should be initiated again.

Understanding ARM Debug Interface: SWD

5.4 STIKYERR

The possible reasons are: the Debug power domain has been powered down; or there was an error with the debug resources (e.g., core error); or there is a problem with the corresponding design logic;

Once this error is detected, debugging must be done carefully, modify the code, and then reconnect.

Writing articles is not easy. If you find this helpful, please give a thumbs up or treat me to a chicken leg!

Leave a Comment