23 : jtag_(jtag), chain_(chain)
30 current_ir_valid_ =
false;
33 ErrorCode DpRead(uint8_t addr2b, uint32_t& val, JtagProtocol::Ack& ack)
36 const ErrorCode EC = Transfer(JtagProtocol::make_dp_req(
true, addr2b, 0u), resp);
42 ErrorCode DpWrite(uint8_t addr2b, uint32_t val, JtagProtocol::Ack& ack)
45 const ErrorCode EC = Transfer(JtagProtocol::make_dp_req(
false, addr2b, val), resp);
50 ErrorCode DpReadTxn(uint8_t addr2b, uint32_t& val, JtagProtocol::Ack& ack)
53 ErrorCode EC = Transfer(JtagProtocol::make_dp_req(
true, addr2b, 0u), resp);
59 if (resp.
ack != JtagProtocol::Ack::OK)
64 EC = Transfer(JtagProtocol::make_dp_req(
true, 3u, 0u), resp);
72 if ((addr2b & 0x03u) == 0u && val == 0u)
75 const ErrorCode id_ec = ReadIdCode(idcode);
76 if (id_ec ==
ErrorCode::OK && idcode != 0u && idcode != 0xFFFF'FFFFu)
79 ack = JtagProtocol::Ack::OK;
85 ErrorCode DpWriteTxn(uint8_t addr2b, uint32_t val, JtagProtocol::Ack& ack)
87 if ((addr2b & 0x03u) == 0u)
89 return WriteAbort(val, ack);
92 return DpWrite(addr2b, val, ack);
95 ErrorCode ApReadTxn(uint8_t addr2b, uint32_t& val, JtagProtocol::Ack& ack)
98 ErrorCode EC = Transfer(JtagProtocol::make_ap_req(
true, addr2b, 0u), resp);
104 if (resp.
ack != JtagProtocol::Ack::OK)
109 EC = Transfer(JtagProtocol::make_dp_req(
true, 3u, 0u), resp);
119 ErrorCode ApWriteTxn(uint8_t addr2b, uint32_t val, JtagProtocol::Ack& ack)
122 const ErrorCode EC = Transfer(JtagProtocol::make_ap_req(
false, addr2b, val), resp);
129 return ReadIdCodeWithIr(JtagProtocol::JTAG_IR_IDCODE, idcode);
132 ErrorCode ReadIdCodeWithIr(uint32_t ir, uint32_t& idcode)
140 uint64_t out_dr = 0u;
141 const ErrorCode EC2 = ShiftValueThroughChain(0u, 32u, out_dr);
146 idcode =
static_cast<uint32_t
>(out_dr & 0xFFFF'FFFFu);
150 ErrorCode WriteAbort(uint32_t data, JtagProtocol::Ack& ack)
152 const ErrorCode EC = SelectIr(JtagProtocol::JTAG_IR_ABORT);
155 ack = JtagProtocol::Ack::PROTOCOL;
159 uint64_t out_dr = 0u;
160 const ErrorCode EC2 = ShiftValueThroughChain(
161 JtagProtocol::PackDpDr(JtagProtocol::make_dp_req(
false, 0u, data)),
162 JtagProtocol::JTAG_DP_DR_LEN, out_dr);
165 ack = JtagProtocol::Ack::PROTOCOL;
172 ack = JtagProtocol::Ack::OK;
179 SelectIr(req.
port == JtagProtocol::Port::AP ? JtagProtocol::JTAG_IR_APACC
180 : JtagProtocol::JTAG_IR_DPACC);
183 resp.
ack = JtagProtocol::Ack::PROTOCOL;
187 uint64_t out_dr = 0u;
188 const ErrorCode EC2 = ShiftValueThroughChain(JtagProtocol::PackDpDr(req),
189 JtagProtocol::JTAG_DP_DR_LEN, out_dr);
192 resp.
ack = JtagProtocol::Ack::PROTOCOL;
196 JtagProtocol::UnpackDpDr(out_dr, resp);
201 static constexpr uint32_t DEFAULT_IR_BITS = 4u;
202 static constexpr uint32_t MAX_BITS = 512u;
203 static constexpr uint32_t MAX_BYTES = (MAX_BITS + 7u) / 8u;
205 uint32_t IrBits()
const
207 if (chain_ !=
nullptr && chain_->
ir_length !=
nullptr && chain_->
count > 0 &&
211 return (bits == 0u) ? DEFAULT_IR_BITS : bits;
213 return DEFAULT_IR_BITS;
216 uint32_t IrBeforeBits()
218 if (chain_ ==
nullptr)
224 JtagProtocol::UpdateChainCache(*chain_);
229 uint32_t IrAfterBits()
231 if (chain_ ==
nullptr)
237 JtagProtocol::UpdateChainCache(*chain_);
242 uint32_t DrBeforeBits()
244 if (chain_ ==
nullptr)
250 :
static_cast<uint32_t
>(chain_->
index);
253 uint32_t DrAfterBits()
255 if (chain_ ==
nullptr)
261 :
static_cast<uint32_t
>(chain_->
count - chain_->
index - 1u);
266 if (current_ir_valid_ && current_ir_ == ir)
271 const uint32_t ir_bits = IrBits();
272 const uint32_t pre = IrBeforeBits();
273 const uint32_t post = IrAfterBits();
274 const uint32_t total_bits = pre + ir_bits + post;
276 if (total_bits > MAX_BITS)
281 uint8_t buf[MAX_BYTES] = {};
282 PutOnes(buf, 0u, pre);
283 PutBits(buf, pre, ir, ir_bits);
284 PutOnes(buf, pre + ir_bits, post);
289 current_ir_valid_ =
true;
294 ErrorCode ShiftValueThroughChain(uint64_t in_value, uint32_t value_bits,
297 const uint32_t pre = DrBeforeBits();
298 const uint32_t post = DrAfterBits();
299 const uint32_t total_bits = pre + value_bits + post;
300 if (total_bits > MAX_BITS)
305 uint8_t tx[MAX_BYTES] = {};
306 uint8_t rx[MAX_BYTES] = {};
307 PutOnes(tx, 0u, pre);
308 PutBits64(tx, pre, in_value, value_bits);
309 PutOnes(tx, pre + value_bits, post);
317 out_value = GetBits64(rx, pre, value_bits);
321 static void PutOnes(uint8_t* buf, uint32_t bit_off, uint32_t bits)
323 for (uint32_t i = 0; i < bits; ++i)
325 const uint32_t idx = bit_off + i;
326 const uint32_t
byte = idx / 8u;
327 const uint32_t shift = idx & 7u;
328 buf[byte] =
static_cast<uint8_t
>(buf[byte] | (1u << shift));
332 static void PutBits(uint8_t* buf, uint32_t bit_off, uint32_t value, uint32_t bits)
334 for (uint32_t i = 0; i < bits; ++i)
336 const bool bit = ((value >> i) & 0x1u) != 0u;
337 const uint32_t idx = bit_off + i;
338 const uint32_t
byte = idx / 8u;
339 const uint32_t shift = idx & 7u;
342 buf[byte] =
static_cast<uint8_t
>(buf[byte] | (1u << shift));
346 buf[byte] =
static_cast<uint8_t
>(buf[byte] & ~(1u << shift));
351 static void PutBits64(uint8_t* buf, uint32_t bit_off, uint64_t value, uint32_t bits)
353 for (uint32_t i = 0; i < bits; ++i)
355 const bool bit = ((value >> i) & 0x1u) != 0u;
356 const uint32_t idx = bit_off + i;
357 const uint32_t
byte = idx / 8u;
358 const uint32_t shift = idx & 7u;
361 buf[byte] =
static_cast<uint8_t
>(buf[byte] | (1u << shift));
365 buf[byte] =
static_cast<uint8_t
>(buf[byte] & ~(1u << shift));
370 static uint64_t GetBits64(
const uint8_t* buf, uint32_t bit_off, uint32_t bits)
373 for (uint32_t i = 0; i < bits; ++i)
375 const uint32_t idx = bit_off + i;
376 const uint32_t
byte = idx / 8u;
377 const uint32_t shift = idx & 7u;
378 const uint64_t bit = (buf[byte] >> shift) & 0x1u;
387 uint32_t current_ir_ = 0u;
388 bool current_ir_valid_ =
false;