libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
jtag_protocol.hpp
1// jtag_protocol.hpp
2#pragma once
3
4#include <cstdint>
5
6namespace LibXR::Debug::JtagProtocol
7{
11enum class Port : uint8_t
12{
13 DP = 0,
14 AP = 1,
15};
16
23enum class Ack : uint8_t
24{
25 NO_ACK = 0x0,
26 OK = 0x1,
27 WAIT = 0x2,
28 FAULT = 0x4,
29 PROTOCOL = 0x7,
30};
31
37struct Request
38{
39 Port port = Port::DP;
40 bool rnw =
41 true;
42 uint8_t addr2b = 0;
43 uint32_t wdata = 0;
44};
45
50{
51 Ack ack = Ack::PROTOCOL;
52 uint32_t rdata = 0;
53};
54
58inline constexpr uint32_t JTAG_IR_ABORT = 0x08u;
59inline constexpr uint32_t JTAG_IR_DPACC = 0x0Au;
60inline constexpr uint32_t JTAG_IR_APACC = 0x0Bu;
61inline constexpr uint32_t JTAG_IR_IDCODE = 0x0Eu;
62inline constexpr uint32_t JTAG_IR_BYPASS = 0x0Fu;
63
67inline constexpr uint8_t JTAG_SEQUENCE_TCK = 0x3Fu;
68inline constexpr uint8_t JTAG_SEQUENCE_TMS = 0x40u;
69inline constexpr uint8_t JTAG_SEQUENCE_TDO = 0x80u;
70
74inline constexpr uint32_t JTAG_DP_DR_LEN = 35u;
75
82constexpr Ack map_jtag_ack(uint8_t raw_ack)
83{
84 switch (raw_ack & 0x7u)
85 {
86 case 0x2:
87 return Ack::OK;
88 case 0x1:
89 return Ack::WAIT;
90 case 0x4:
91 return Ack::FAULT;
92 case 0x0:
93 return Ack::NO_ACK;
94 default:
95 return Ack::PROTOCOL;
96 }
97}
98
105{
106 uint8_t count = 0;
107 uint8_t index = 0;
108 const uint8_t* ir_length = nullptr;
109 const uint16_t* ir_before = nullptr;
110 const uint16_t* ir_after = nullptr;
111
112 // 运行期缓存(可选):用于减少每次 Shift 计算
113 uint32_t ir_before_bits_len = 0;
114 uint32_t ir_after_bits_len = 0;
115 uint32_t dr_before_bits_len = 0;
116 uint32_t dr_after_bits_len = 0;
117};
118
124inline void UpdateChainCache(ChainConfig& cfg)
125{
126 cfg.ir_before_bits_len = 0;
127 cfg.ir_after_bits_len = 0;
128 cfg.dr_before_bits_len = 0;
129 cfg.dr_after_bits_len = 0;
130
131 if (cfg.count == 0 || cfg.index >= cfg.count)
132 {
133 return;
134 }
135
136 if (cfg.ir_length != nullptr)
137 {
138 for (uint8_t i = 0; i < cfg.index; ++i)
139 {
140 cfg.ir_before_bits_len += cfg.ir_length[i];
141 }
142 for (uint8_t i = static_cast<uint8_t>(cfg.index + 1u); i < cfg.count; ++i)
143 {
144 cfg.ir_after_bits_len += cfg.ir_length[i];
145 }
146 }
147
148 cfg.dr_before_bits_len = cfg.index;
149 cfg.dr_after_bits_len = static_cast<uint32_t>(cfg.count - cfg.index - 1u);
150}
151
161inline uint64_t PackDpDr(const Request& req)
162{
163 const uint64_t RNW = req.rnw ? 1u : 0u;
164 const uint64_t A2 = static_cast<uint64_t>(req.addr2b & 0x1u);
165 const uint64_t A3 = static_cast<uint64_t>((req.addr2b >> 1) & 0x1u);
166 return (static_cast<uint64_t>(req.wdata) << 3) | (A3 << 2) | (A2 << 1) | RNW;
167}
168
174inline void UnpackDpDr(uint64_t dr_lsb_first, Response& resp)
175{
176 const uint8_t RAW_ACK = static_cast<uint8_t>(dr_lsb_first & 0x7u);
177 resp.ack = map_jtag_ack(RAW_ACK);
178 resp.rdata = static_cast<uint32_t>((dr_lsb_first >> 3) & 0xFFFF'FFFFu);
179}
180
184constexpr Request make_dp_req(bool rnw, uint8_t addr2b, uint32_t wdata = 0u)
185{
186 return Request{Port::DP, rnw, static_cast<uint8_t>(addr2b & 0x03u), wdata};
187}
188
192constexpr Request make_ap_req(bool rnw, uint8_t addr2b, uint32_t wdata = 0u)
193{
194 return Request{Port::AP, rnw, static_cast<uint8_t>(addr2b & 0x03u), wdata};
195}
196
197} // namespace LibXR::Debug::JtagProtocol
@ OK
操作成功 | Operation successful
JTAG 设备链配置 / JTAG device chain configuration.
const uint8_t * ir_length
各设备 IR 长度数组 / IR length array
uint8_t count
设备数(TDO 端为 index=0)/ Device count (TDO side index=0)
uint32_t ir_before_bits_len
前面设备 IR 总位数 / IR bits before
uint32_t ir_after_bits_len
后面设备 IR 总位数 / IR bits after
const uint16_t * ir_before
当前设备前的 bypass 位数 / Bypass bits before
uint32_t dr_after_bits_len
后面设备 DR 总位数 / DR bits after
const uint16_t * ir_after
当前设备后的 bypass 位数 / Bypass bits after
uint8_t index
当前设备索引 / Current device index
uint32_t dr_before_bits_len
前面设备 DR 总位数 / DR bits before
JTAG 传输请求 / JTAG transfer request.
uint32_t wdata
写数据(仅写请求有效)/ Write data (valid for write requests)
uint8_t addr2b
A[3:2] 两位地址编码(0..3)/ A[3:2] encoded as 0..3.
Port port
目标端口(DP/AP)/ Target port (DP/AP)
bool rnw
读写标志:true=读,false=写 / Read-not-write: true=read, false=write
JTAG 传输响应 / JTAG transfer response.
uint32_t rdata
读数据(仅读响应有效)/ Read data (valid for read responses)