44 static constexpr bool JTAG_ENABLED = DapLinkV2BuildConfig::kEnableJtag;
45 static constexpr const char* DEFAULT_INTERFACE_STRING =
"CMSIS-DAP v2";
77 const char* interface_string = DEFAULT_INTERFACE_STRING)
80 nreset_gpio_(nreset_gpio),
81 interface_string_(interface_string),
82 data_in_ep_num_(data_in_ep_num),
83 data_out_ep_num_(data_out_ep_num)
85 (void)swd_.SetClockHz(swj_clock_hz_);
88 InitWinUsbDescriptors();
102 return (local_interface_index == 0u) ? interface_string_ :
nullptr;
113 if constexpr (JTAG_ENABLED)
117 ResetJtagChainState();
118 if (jtag_ !=
nullptr)
149 auto ep = ep_data_in_;
161 auto ep = ep_data_out_;
176 interface_num_ = start_itf_num;
179 UpdateWinUsbInterfaceFields();
202 desc_block_.intf = {9,
203 static_cast<uint8_t
>(DescriptorType::INTERFACE),
212 desc_block_.ep_out = {7,
213 static_cast<uint8_t
>(DescriptorType::ENDPOINT),
214 static_cast<uint8_t
>(ep_data_out_->
GetAddress()),
219 desc_block_.ep_in = {7,
220 static_cast<uint8_t
>(DescriptorType::ENDPOINT),
221 static_cast<uint8_t
>(ep_data_in_->
GetAddress()),
226 SetData(
RawData{
reinterpret_cast<uint8_t*
>(&desc_block_),
sizeof(desc_block_)});
230 dap_state_.
debug_port = LibXR::USB::DapLinkV2Def::DebugPort::DISABLED;
231 dap_state_.transfer_abort =
false;
233 swj_clock_hz_ = 1'000'000u;
234 (void)swd_.SetClockHz(swj_clock_hz_);
235 if constexpr (JTAG_ENABLED)
237 if (jtag_ !=
nullptr)
244 last_nreset_level_high_ =
true;
245 swj_shadow_ =
static_cast<uint8_t
>(DapLinkV2Def::DAP_SWJ_SWDIO_TMS |
246 DapLinkV2Def::DAP_SWJ_NRESET);
248 ResetResponseQueue();
249 ResetQueuedCommandState();
250 ResetJtagChainState();
254 ArmOutTransferIfIdle();
265 ResetResponseQueue();
266 ResetQueuedCommandState();
268 dap_state_.
debug_port = LibXR::USB::DapLinkV2Def::DebugPort::DISABLED;
273 ep_data_in_->
Close();
275 endpoint_pool.
Release(ep_data_in_);
276 ep_data_in_ =
nullptr;
281 ep_data_out_->
Close();
283 endpoint_pool.
Release(ep_data_out_);
284 ep_data_out_ =
nullptr;
288 if constexpr (JTAG_ENABLED)
290 if (jtag_ !=
nullptr)
297 last_nreset_level_high_ =
true;
298 swj_shadow_ =
static_cast<uint8_t
>(DapLinkV2Def::DAP_SWJ_SWDIO_TMS |
299 DapLinkV2Def::DAP_SWJ_NRESET);
325 return (ep_data_in_ && ep_addr == ep_data_in_->
GetAddress()) ||
326 (ep_data_out_ && ep_addr == ep_data_out_->
GetAddress());
341 return ConstRawData{
reinterpret_cast<const uint8_t*
>(&winusb_msos20_),
342 sizeof(winusb_msos20_)};
360 return &winusb_msos20_cap_;
371 template <
typename E>
372 static constexpr uint8_t ToU8(E e)
374 return static_cast<uint8_t
>(e);
378 static constexpr uint8_t DAP_OK = 0x00u;
379 static constexpr uint8_t DAP_ERROR = 0xFFu;
382 static inline ErrorCode BuildUnknownCmdResponse(uint8_t* resp, uint16_t cap,
385 if (!resp || cap < 1u)
396 static inline ErrorCode BuildCmdStatusResponse(uint8_t cmd, uint8_t status,
397 uint8_t* resp, uint16_t cap,
400 if (!resp || cap < 2u)
416 void InitWinUsbDescriptors()
418 winusb_msos20_.set.wLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_.set));
419 winusb_msos20_.set.wDescriptorType =
420 LibXR::USB::WinUsbMsOs20::MS_OS_20_SET_HEADER_DESCRIPTOR;
421 winusb_msos20_.set.dwWindowsVersion = 0x06030000;
422 winusb_msos20_.set.wTotalLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_));
424 winusb_msos20_.cfg.wLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_.cfg));
425 winusb_msos20_.cfg.wDescriptorType =
426 LibXR::USB::WinUsbMsOs20::MS_OS_20_SUBSET_HEADER_CONFIGURATION;
429 winusb_msos20_.cfg.bConfigurationValue = 0u;
430 winusb_msos20_.cfg.bReserved = 0;
431 winusb_msos20_.cfg.wTotalLength =
static_cast<uint16_t
>(
432 sizeof(winusb_msos20_) - offsetof(WinUsbMsOs20DescSet, cfg));
434 winusb_msos20_.func.wLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_.func));
435 winusb_msos20_.func.wDescriptorType =
436 LibXR::USB::WinUsbMsOs20::MS_OS_20_SUBSET_HEADER_FUNCTION;
437 winusb_msos20_.func.bReserved = 0;
438 winusb_msos20_.func.wTotalLength =
static_cast<uint16_t
>(
439 sizeof(winusb_msos20_) - offsetof(WinUsbMsOs20DescSet, func));
441 winusb_msos20_.compat.wLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_.compat));
442 winusb_msos20_.compat.wDescriptorType =
443 LibXR::USB::WinUsbMsOs20::MS_OS_20_FEATURE_COMPATIBLE_ID;
445 winusb_msos20_.prop.
header.wDescriptorType =
446 LibXR::USB::WinUsbMsOs20::MS_OS_20_FEATURE_REG_PROPERTY;
447 winusb_msos20_.prop.
header.wPropertyDataType = LibXR::USB::WinUsbMsOs20::REG_MULTI_SZ;
448 winusb_msos20_.prop.
header.wPropertyNameLength =
449 LibXR::USB::WinUsbMsOs20::PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES;
452 LibXR::USB::WinUsbMsOs20::PROP_NAME_DEVICE_INTERFACE_GUIDS_UTF16,
453 LibXR::USB::WinUsbMsOs20::PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES);
457 const char GUID_STR[] =
"{CDB3B5AD-293B-4663-AA36-1AAE46463776}";
458 const size_t GUID_LEN =
sizeof(GUID_STR) - 1;
460 for (
size_t i = 0; i < GUID_LEN; ++i)
462 winusb_msos20_.prop.
data[i * 2] =
static_cast<uint8_t
>(GUID_STR[i]);
463 winusb_msos20_.prop.
data[i * 2 + 1] = 0x00;
467 winusb_msos20_.prop.
data[GUID_LEN * 2 + 0] = 0x00;
468 winusb_msos20_.prop.
data[GUID_LEN * 2 + 1] = 0x00;
469 winusb_msos20_.prop.
data[GUID_LEN * 2 + 2] = 0x00;
470 winusb_msos20_.prop.
data[GUID_LEN * 2 + 3] = 0x00;
473 winusb_msos20_.prop.
header.wLength =
474 static_cast<uint16_t
>(
sizeof(winusb_msos20_.prop));
477 winusb_msos20_cap_.SetVendorCode(WINUSB_VENDOR_CODE);
481 void UpdateWinUsbInterfaceFields()
484 winusb_msos20_.func.bFirstInterface = interface_num_;
498 static void OnDataOutCompleteStatic(
bool in_isr,
DapLinkV2Class* self,
501 if (self && self->inited_)
503 self->OnDataOutComplete(in_isr, data);
510 static void OnDataInCompleteStatic(
bool in_isr,
DapLinkV2Class* self,
513 if (self && self->inited_)
515 self->OnDataInComplete(in_isr, data);
526 if (!inited_ || !ep_data_in_ || !ep_data_out_)
531 const auto* req =
static_cast<const uint8_t*
>(data.
addr_);
532 const uint16_t REQ_LEN =
static_cast<uint16_t
>(data.
size_);
536 if (!HasDeferredResponseInEpBuffer() && IsResponseQueueEmpty() &&
538 CanBuildResponseDirectlyInEpBuffer())
541 if (tx_buff.addr_ && tx_buff.size_ > 0u)
543 auto* tx_buf =
static_cast<uint8_t*
>(tx_buff.addr_);
544 uint16_t out_len = 0u;
545 auto ans = ProcessOneCommand(in_isr, req, REQ_LEN, tx_buf,
546 static_cast<uint16_t
>(tx_buff.size_), out_len);
549 out_len = ClipResponseLength(out_len,
static_cast<uint16_t
>(tx_buff.size_));
550 if (StartInTransferFromCurrentBuffer(out_len))
555 if (!EnqueueResponse(tx_buf, out_len))
557 (void)SubmitNextQueuedResponseIfIdle();
558 (void)EnqueueResponse(tx_buf, out_len);
561 (void)SubmitNextQueuedResponseIfIdle();
562 ArmOutTransferIfIdle();
569 if (!HasDeferredResponseInEpBuffer() && IsResponseQueueEmpty() &&
571 CanBuildResponseDirectlyInEpBuffer())
574 if (tx_buff.addr_ && tx_buff.size_ > 0u)
576 auto* tx_buf =
static_cast<uint8_t*
>(tx_buff.addr_);
577 uint16_t out_len = 0u;
578 auto ans = ProcessOneCommand(in_isr, req, REQ_LEN, tx_buf,
579 static_cast<uint16_t
>(tx_buff.size_), out_len);
582 out_len = ClipResponseLength(out_len,
static_cast<uint16_t
>(tx_buff.size_));
583 SetDeferredResponseInEpBuffer(out_len);
584 ArmOutTransferIfIdle();
589 if (TryBuildAndEnqueueResponse(in_isr, req, REQ_LEN))
591 (void)SubmitDeferredResponseIfIdle();
592 (void)SubmitNextQueuedResponseIfIdle();
593 ArmOutTransferIfIdle();
598 (void)SubmitNextQueuedResponseIfIdle();
599 (void)TryBuildAndEnqueueResponse(in_isr, req, REQ_LEN);
601 (void)SubmitDeferredResponseIfIdle();
602 (void)SubmitNextQueuedResponseIfIdle();
603 ArmOutTransferIfIdle();
611 (void)SubmitDeferredResponseIfIdle();
612 (void)SubmitNextQueuedResponseIfIdle();
613 ArmOutTransferIfIdle();
620 uint16_t GetDapPacketSize()
const
622 constexpr uint16_t OPENOCD_SAFE_PS =
static_cast<uint16_t
>((255u * 5u) + 4u);
623 constexpr uint16_t RAW_PS =
624 (MaxDapPacketSize == 0u) ? DefaultDapPacketSize : MaxDapPacketSize;
625 return (RAW_PS > OPENOCD_SAFE_PS) ? OPENOCD_SAFE_PS : RAW_PS;
627 bool CanBuildResponseDirectlyInEpBuffer()
const
634 if (!tx_buff.addr_ || tx_buff.size_ == 0u)
638 return GetDapPacketSize() <=
static_cast<uint16_t
>(tx_buff.size_);
641 bool StartInTransferFromCurrentBuffer(uint16_t len)
648 if (!tx_buff.addr_ || tx_buff.size_ == 0u)
652 uint16_t tx_len = len;
653 if (tx_len > tx_buff.size_)
655 tx_len =
static_cast<uint16_t
>(tx_buff.size_);
664 bool StartInTransferFromPayload(
const uint8_t* data, uint16_t len)
666 if (!ep_data_in_ || !data)
671 if (!tx_buff.addr_ || tx_buff.size_ == 0u)
675 uint16_t tx_len = len;
676 if (tx_len > MAX_DAP_PACKET_SIZE)
678 tx_len = MAX_DAP_PACKET_SIZE;
680 const uint16_t MAX_XFER =
static_cast<uint16_t
>(ep_data_in_->
MaxTransferSize());
681 if (tx_len <= MAX_XFER && tx_len <=
static_cast<uint16_t
>(tx_buff.size_))
689 if (tx_len >
static_cast<uint16_t
>(
sizeof(in_tx_multi_storage_)))
691 tx_len =
static_cast<uint16_t
>(
sizeof(in_tx_multi_storage_));
693 if (tx_len > 0u && data != in_tx_multi_storage_)
697 in_tx_multi_buf_.
addr_ = in_tx_multi_storage_;
698 in_tx_multi_buf_.
size_ = tx_len;
705 uint16_t ClipResponseLength(uint16_t len, uint16_t cap)
const
707 const uint16_t DAP_PS = GetDapPacketSize();
712 if (len > RESP_SLOT_SIZE)
714 len = RESP_SLOT_SIZE;
723 static constexpr uint8_t NextRespQueueIndex(uint8_t idx)
725 return static_cast<uint8_t
>((idx + 1u) & (RESP_QUEUE_DEPTH - 1u));
728 void ResetResponseQueue()
733 deferred_in_resp_valid_ =
false;
734 deferred_in_resp_len_ = 0u;
737 bool HasDeferredResponseInEpBuffer()
const {
return deferred_in_resp_valid_; }
739 void SetDeferredResponseInEpBuffer(uint16_t len)
741 deferred_in_resp_len_ = len;
742 deferred_in_resp_valid_ =
true;
745 bool SubmitDeferredResponseIfIdle()
747 if (!deferred_in_resp_valid_ || !ep_data_in_ ||
753 const uint16_t TX_LEN = deferred_in_resp_len_;
754 if (!StartInTransferFromCurrentBuffer(TX_LEN))
759 deferred_in_resp_valid_ =
false;
760 deferred_in_resp_len_ = 0u;
764 bool IsResponseQueueEmpty()
const {
return resp_q_count_ == 0u; }
766 bool IsResponseQueueFull()
const {
return resp_q_count_ >= RESP_QUEUE_DEPTH; }
768 void ResetQueuedCommandState()
770 queued_request_length_ = 0u;
771 queued_command_count_ = 0u;
786 bool ParseQueuedCommandLength(
const uint8_t* req, uint16_t avail,
787 uint16_t& cmd_len)
const
790 if (!req || avail < 1u)
795 const uint8_t CMD = req[0];
798 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::INFO):
800 return avail >= cmd_len;
801 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::HOST_STATUS):
803 return avail >= cmd_len;
804 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::CONNECT):
806 return avail >= cmd_len;
807 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::DISCONNECT):
809 return avail >= cmd_len;
810 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_CONFIGURE):
812 return avail >= cmd_len;
813 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_ABORT):
815 return avail >= cmd_len;
816 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::WRITE_ABORT):
818 return avail >= cmd_len;
819 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::DELAY):
821 return avail >= cmd_len;
822 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::RESET_TARGET):
824 return avail >= cmd_len;
825 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_PINS):
827 return avail >= cmd_len;
828 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_CLOCK):
830 return avail >= cmd_len;
831 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_CONFIGURE):
833 return avail >= cmd_len;
834 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_SEQUENCE):
840 const uint32_t BIT_COUNT = (req[1] == 0u) ? 256u : static_cast<uint32_t>(req[1]);
841 const uint32_t BYTE_COUNT = (BIT_COUNT + 7u) / 8u;
842 const uint32_t NEED = 2u + BYTE_COUNT;
847 cmd_len =
static_cast<uint16_t
>(NEED);
850 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_SEQUENCE):
856 const uint8_t SEQ_CNT = req[1];
858 for (uint32_t i = 0u; i < SEQ_CNT; ++i)
865 const uint8_t INFO = req[off++];
866 uint32_t cycles =
static_cast<uint32_t
>(INFO & 0x3Fu);
872 const bool MODE_IN = ((INFO & 0x80u) != 0u);
873 const uint32_t BYTES = (cycles + 7u) / 8u;
876 if (off + BYTES > avail)
883 cmd_len =
static_cast<uint16_t
>(off);
886 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER):
892 const uint8_t COUNT = req[2];
894 for (uint32_t i = 0u; i < COUNT; ++i)
901 const uint8_t RQ = req[off++];
903 const bool MATCH_VALUE =
904 ((RQ & LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_VALUE) != 0u);
905 if (!RNW || MATCH_VALUE)
907 if (off + 4u > avail)
914 cmd_len =
static_cast<uint16_t
>(off);
917 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_BLOCK):
929 need +=
static_cast<uint32_t
>(count) * 4u;
935 cmd_len =
static_cast<uint16_t
>(need);
940 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS):
941 case ToU8(
LibXR::USB::DapLinkV2Def::CommandId::EXECUTE_COMMANDS):
956 bool TryExecuteQueuedCommandStream(
bool in_isr, uint8_t* resp, uint16_t resp_cap,
960 if (!resp || resp_cap < 1u)
965 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::EXECUTE_COMMANDS);
968 if (queued_command_count_ == 0u)
973 uint16_t req_off = 0u;
974 uint16_t resp_off = 1u;
975 for (uint32_t i = 0u; i < queued_command_count_; ++i)
977 if (req_off >= queued_request_length_)
982 uint16_t cmd_len = 0u;
983 if (!ParseQueuedCommandLength(
984 &queued_request_buffer_[req_off],
985 static_cast<uint16_t
>(queued_request_length_ - req_off), cmd_len) ||
991 if (resp_off >= resp_cap)
996 uint16_t cmd_out = 0u;
998 in_isr, &queued_request_buffer_[req_off], cmd_len, &resp[resp_off],
999 static_cast<uint16_t
>(resp_cap - resp_off), cmd_out);
1002 if (
static_cast<uint32_t
>(resp_off) +
static_cast<uint32_t
>(cmd_out) >
1003 static_cast<uint32_t
>(resp_cap))
1008 req_off =
static_cast<uint16_t
>(req_off + cmd_len);
1009 resp_off =
static_cast<uint16_t
>(resp_off + cmd_out);
1012 if (req_off != queued_request_length_)
1021 bool TryBuildAndEnqueueResponse(
bool in_isr,
const uint8_t* req, uint16_t req_len)
1023 if (!req || IsResponseQueueFull())
1028 auto& slot = resp_q_[resp_q_tail_];
1029 uint16_t out_len = 0u;
1031 ProcessOneCommand(in_isr, req, req_len, slot.payload, RESP_SLOT_SIZE, out_len);
1033 slot.len = ClipResponseLength(out_len, RESP_SLOT_SIZE);
1035 resp_q_tail_ = NextRespQueueIndex(resp_q_tail_);
1040 uint8_t OutstandingResponseCount()
const
1042 const uint8_t IN_FLIGHT =
1044 const uint8_t DEFERRED = deferred_in_resp_valid_ ? 1u : 0u;
1045 return static_cast<uint8_t
>(resp_q_count_ + IN_FLIGHT + DEFERRED);
1048 bool EnqueueResponse(
const uint8_t* data, uint16_t len)
1050 if (!data || IsResponseQueueFull())
1055 auto& slot = resp_q_[resp_q_tail_];
1056 const uint16_t CLIPPED = ClipResponseLength(len, RESP_SLOT_SIZE);
1063 resp_q_tail_ = NextRespQueueIndex(resp_q_tail_);
1068 bool SubmitNextQueuedResponseIfIdle()
1071 IsResponseQueueEmpty())
1075 auto& slot = resp_q_[resp_q_head_];
1076 if (!StartInTransferFromPayload(slot.payload, slot.len))
1080 resp_q_head_ = NextRespQueueIndex(resp_q_head_);
1085 void ArmOutTransferIfIdle()
1087 if (!inited_ || ep_data_out_ ==
nullptr || ep_data_in_ ==
nullptr)
1098 if (OutstandingResponseCount() >= MAX_OUTSTANDING_RESPONSES)
1103 uint16_t out_rx_len = GetDapPacketSize();
1104 if (out_rx_len == 0u)
1106 out_rx_len = DEFAULT_DAP_PACKET_SIZE;
1108 if (out_rx_len > MAX_DAP_PACKET_SIZE)
1110 out_rx_len = MAX_DAP_PACKET_SIZE;
1113 const uint16_t OUT_MAX_XFER =
static_cast<uint16_t
>(ep_data_out_->
MaxTransferSize());
1114 if (OUT_MAX_XFER == 0u)
1119 if (out_rx_len <= OUT_MAX_XFER)
1121 (void)ep_data_out_->
Transfer(out_rx_len);
1125 if (out_rx_len >
static_cast<uint16_t
>(
sizeof(out_req_multi_storage_)))
1127 out_rx_len =
static_cast<uint16_t
>(
sizeof(out_req_multi_storage_));
1132 out_req_multi_buf_.
addr_ = out_req_multi_storage_;
1133 out_req_multi_buf_.
size_ = out_rx_len;
1153 ErrorCode ProcessOneCommand(
bool in_isr,
const uint8_t* req, uint16_t req_len,
1154 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1158 if (!req || !resp || req_len < 1u || resp_cap < 1u)
1160 if (resp && resp_cap >= 1u)
1162 BuildNotSupportResponse(resp, resp_cap, out_len);
1167 const uint8_t CMD = req[0];
1171 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::INFO):
1172 return HandleInfo(in_isr, req, req_len, resp, resp_cap, out_len);
1173 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::HOST_STATUS):
1174 return HandleHostStatus(in_isr, req, req_len, resp, resp_cap, out_len);
1175 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::CONNECT):
1176 return HandleConnect(in_isr, req, req_len, resp, resp_cap, out_len);
1177 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::DISCONNECT):
1178 return HandleDisconnect(in_isr, req, req_len, resp, resp_cap, out_len);
1179 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_CONFIGURE):
1180 return HandleTransferConfigure(in_isr, req, req_len, resp, resp_cap, out_len);
1181 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER):
1182 return HandleTransfer(in_isr, req, req_len, resp, resp_cap, out_len);
1183 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_BLOCK):
1184 return HandleTransferBlock(in_isr, req, req_len, resp, resp_cap, out_len);
1185 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_ABORT):
1186 return HandleTransferAbort(in_isr, req, req_len, resp, resp_cap, out_len);
1187 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::WRITE_ABORT):
1188 return HandleWriteABORT(in_isr, req, req_len, resp, resp_cap, out_len);
1189 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::DELAY):
1190 return HandleDelay(in_isr, req, req_len, resp, resp_cap, out_len);
1191 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::RESET_TARGET):
1192 return HandleResetTarget(in_isr, req, req_len, resp, resp_cap, out_len);
1194 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_PINS):
1195 return HandleSWJPins(in_isr, req, req_len, resp, resp_cap, out_len);
1196 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_CLOCK):
1197 return HandleSWJClock(in_isr, req, req_len, resp, resp_cap, out_len);
1198 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_SEQUENCE):
1199 return HandleSWJSequence(in_isr, req, req_len, resp, resp_cap, out_len);
1200 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_CONFIGURE):
1201 return HandleSWDConfigure(in_isr, req, req_len, resp, resp_cap, out_len);
1202 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_SEQUENCE):
1203 return HandleSWDSequence(in_isr, req, req_len, resp, resp_cap, out_len);
1205 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::JTAG_SEQUENCE):
1206 if constexpr (JTAG_ENABLED)
1208 return HandleJTAGSequence(in_isr, req, req_len, resp, resp_cap, out_len);
1210 (void)BuildUnknownCmdResponse(resp, resp_cap, out_len);
1212 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::JTAG_CONFIGURE):
1213 if constexpr (JTAG_ENABLED)
1215 return HandleJTAGConfigure(in_isr, req, req_len, resp, resp_cap, out_len);
1217 (void)BuildUnknownCmdResponse(resp, resp_cap, out_len);
1219 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::JTAG_IDCODE):
1220 if constexpr (JTAG_ENABLED)
1222 return HandleJTAGIdCode(in_isr, req, req_len, resp, resp_cap, out_len);
1224 (void)BuildUnknownCmdResponse(resp, resp_cap, out_len);
1227 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS):
1228 return HandleQueueCommands(in_isr, req, req_len, resp, resp_cap, out_len);
1229 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::EXECUTE_COMMANDS):
1230 return HandleExecuteCommands(in_isr, req, req_len, resp, resp_cap, out_len);
1233 (void)BuildUnknownCmdResponse(resp, resp_cap, out_len);
1245 void BuildNotSupportResponse(uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1247 if (!resp || resp_cap < 1u)
1261 ErrorCode HandleInfo(
bool ,
const uint8_t* req, uint16_t req_len,
1262 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1266 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::INFO);
1272 const uint8_t INFO_ID = req[1];
1274 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::INFO);
1278 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::VENDOR):
1279 return BuildInfoStringResponse(resp[0], info_.vendor, resp, resp_cap, out_len);
1280 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::PRODUCT):
1281 return BuildInfoStringResponse(resp[0], info_.product, resp, resp_cap, out_len);
1282 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::SERIAL_NUMBER):
1283 return BuildInfoStringResponse(resp[0], info_.serial, resp, resp_cap, out_len);
1284 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::FIRMWARE_VERSION):
1285 return BuildInfoStringResponse(resp[0], info_.firmware_ver, resp, resp_cap,
1288 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::DEVICE_VENDOR):
1289 return BuildInfoStringResponse(resp[0], info_.device_vendor, resp, resp_cap,
1291 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::DEVICE_NAME):
1292 return BuildInfoStringResponse(resp[0], info_.device_name, resp, resp_cap,
1294 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::BOARD_VENDOR):
1295 return BuildInfoStringResponse(resp[0], info_.board_vendor, resp, resp_cap,
1297 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::BOARD_NAME):
1298 return BuildInfoStringResponse(resp[0], info_.board_name, resp, resp_cap,
1300 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::PRODUCT_FIRMWARE_VERSION):
1301 return BuildInfoStringResponse(resp[0], info_.product_fw_ver, resp, resp_cap,
1304 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::CAPABILITIES):
1307 if constexpr (JTAG_ENABLED)
1309 if (jtag_ !=
nullptr)
1314 return BuildInfoU8Response(resp[0], caps, resp, resp_cap, out_len);
1316 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::PACKET_COUNT):
1317 return BuildInfoU8Response(resp[0], PACKET_COUNT_EFFECTIVE, resp, resp_cap,
1319 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::PACKET_SIZE):
1321 const uint16_t DAP_PS = GetDapPacketSize();
1322 return BuildInfoU16Response(resp[0], DAP_PS, resp, resp_cap, out_len);
1324 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::TIMESTAMP_CLOCK):
1325 return BuildInfoU32Response(resp[0], 1000000U, resp, resp_cap, out_len);
1334 ErrorCode BuildInfoStringResponse(uint8_t cmd,
const char* str, uint8_t* resp,
1335 uint16_t resp_cap, uint16_t& out_len)
1346 const size_t N_WITH_NUL = std::strlen(str) + 1;
1347 const size_t MAX_PAYLOAD = (resp_cap >= 2u) ? (resp_cap - 2u) : 0u;
1348 if (MAX_PAYLOAD == 0u)
1354 const size_t COPY_N = (N_WITH_NUL > MAX_PAYLOAD) ? MAX_PAYLOAD : N_WITH_NUL;
1358 resp[2 + COPY_N - 1] = 0x00;
1360 resp[1] =
static_cast<uint8_t
>(COPY_N);
1361 out_len =
static_cast<uint16_t
>(2u + COPY_N);
1365 ErrorCode BuildInfoU8Response(uint8_t cmd, uint8_t val, uint8_t* resp,
1366 uint16_t resp_cap, uint16_t& out_len)
1380 ErrorCode BuildInfoU16Response(uint8_t cmd, uint16_t val, uint8_t* resp,
1381 uint16_t resp_cap, uint16_t& out_len)
1398 ErrorCode BuildInfoU32Response(uint8_t cmd, uint32_t val, uint8_t* resp,
1399 uint16_t resp_cap, uint16_t& out_len)
1421 ErrorCode HandleHostStatus(
bool ,
const uint8_t* ,
1422 uint16_t , uint8_t* resp, uint16_t resp_cap,
1430 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::HOST_STATUS);
1431 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1436 ErrorCode HandleConnect(
bool ,
const uint8_t* req, uint16_t req_len,
1437 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1445 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::CONNECT);
1453 if (port == 0u || port == ToU8(LibXR::USB::DapLinkV2Def::Port::SWD))
1455 (void)swd_.EnterSwd();
1456 (void)swd_.SetClockHz(swj_clock_hz_);
1458 dap_state_.
debug_port = LibXR::USB::DapLinkV2Def::DebugPort::SWD;
1460 ResetQueuedCommandState();
1462 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Port::SWD);
1464 else if (port == ToU8(LibXR::USB::DapLinkV2Def::Port::JTAG))
1466 if constexpr (!JTAG_ENABLED)
1468 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Port::DISABLED);
1472 if (jtag_ ==
nullptr)
1474 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Port::DISABLED);
1478 static constexpr uint8_t SWD_TO_JTAG_SEQUENCE[2] = {0x3Cu, 0xE7u};
1479 (void)swd_.SetClockHz(swj_clock_hz_);
1480 (void)swd_.LineReset();
1481 (void)swd_.SeqWriteBits(16u, SWD_TO_JTAG_SEQUENCE);
1482 (void)swd_.LineReset();
1486 dap_state_.
debug_port = LibXR::USB::DapLinkV2Def::DebugPort::JTAG;
1488 ResetQueuedCommandState();
1489 ResetJtagChainState();
1490 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Port::JTAG);
1496 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Port::DISABLED);
1503 ErrorCode HandleDisconnect(
bool ,
const uint8_t* ,
1504 uint16_t , uint8_t* resp, uint16_t resp_cap,
1514 if constexpr (JTAG_ENABLED)
1516 if (jtag_ !=
nullptr)
1521 dap_state_.
debug_port = LibXR::USB::DapLinkV2Def::DebugPort::DISABLED;
1523 ResetQueuedCommandState();
1525 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::DISCONNECT);
1526 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1531 ErrorCode HandleTransferConfigure(
bool ,
const uint8_t* req, uint16_t req_len,
1532 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1540 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_CONFIGURE);
1545 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1550 const uint8_t IDLE = req[1];
1552 uint16_t wait_retry = 0u;
1553 uint16_t match_retry = 0u;
1562 Debug::Swd::TransferPolicy pol = swd_.GetTransferPolicy();
1563 pol.idle_cycles = IDLE;
1564 pol.wait_retry = wait_retry;
1565 swd_.SetTransferPolicy(pol);
1567 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1572 ErrorCode HandleTransferAbort(
bool ,
const uint8_t* ,
1573 uint16_t , uint8_t* resp, uint16_t resp_cap,
1582 SetTransferAbortFlag(
true);
1584 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_ABORT);
1585 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1590 ErrorCode HandleWriteABORT(
bool in_isr,
const uint8_t* req, uint16_t req_len,
1591 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1599 if constexpr (JTAG_ENABLED)
1601 if (dap_state_.
debug_port == LibXR::USB::DapLinkV2Def::DebugPort::JTAG)
1603 return HandleJtagWriteAbort(in_isr, req, req_len, resp, resp_cap, out_len);
1607 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::WRITE_ABORT);
1611 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1616 uint32_t flags = 0u;
1619 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
1621 const ErrorCode EC = swd_.WriteAbortTxn(flags, ack);
1622 resp[1] = (EC ==
ErrorCode::OK && ack == LibXR::Debug::SwdProtocol::Ack::OK)
1623 ? ToU8(LibXR::USB::DapLinkV2Def::Status::OK)
1624 : ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1630 ErrorCode HandleDelay(
bool ,
const uint8_t* req, uint16_t req_len,
1631 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1639 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::DELAY);
1643 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1653 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1658 ErrorCode HandleResetTarget(
bool in_isr,
const uint8_t* , uint16_t ,
1659 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1661 if (!resp || resp_cap < 3u)
1667 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::RESET_TARGET);
1669 uint8_t execute = 0u;
1671 if (nreset_gpio_ !=
nullptr)
1674 DelayUsIfAllowed(in_isr, 1000u);
1676 DelayUsIfAllowed(in_isr, 1000u);
1691 ErrorCode HandleSWJPins(
bool ,
const uint8_t* req, uint16_t req_len,
1692 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1694 if (!resp || resp_cap < 2u)
1700 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_PINS);
1703 if (!req || req_len < 7u)
1710 const uint8_t PIN_OUT = req[1];
1711 const uint8_t PIN_SEL = req[2];
1713 uint32_t wait_us = 0u;
1717 swj_shadow_ =
static_cast<uint8_t
>((swj_shadow_ &
static_cast<uint8_t
>(~PIN_SEL)) |
1718 (PIN_OUT & PIN_SEL));
1721 if ((PIN_SEL & LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET) != 0u)
1723 const bool LEVEL_HIGH =
1724 ((PIN_OUT & LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET) != 0u);
1727 DriveReset(LEVEL_HIGH);
1731 auto read_pins = [&]() -> uint8_t
1733 uint8_t pin_in = swj_shadow_;
1735 if (nreset_gpio_ !=
nullptr)
1737 if (nreset_gpio_->
Read())
1739 pin_in |= LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET;
1743 pin_in =
static_cast<uint8_t
>(
1744 pin_in &
static_cast<uint8_t
>(
~LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET));
1754 uint8_t pin_in = 0u;
1756 if (wait_us == 0u || PIN_SEL == 0u)
1758 pin_in = read_pins();
1763 const uint8_t EXPECT =
static_cast<uint8_t
>(PIN_OUT & PIN_SEL);
1767 pin_in = read_pins();
1768 if ((pin_in & PIN_SEL) == EXPECT)
1781 ErrorCode HandleSWJClock(
bool ,
const uint8_t* req, uint16_t req_len,
1782 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1790 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_CLOCK);
1794 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1803 (void)swd_.SetClockHz(hz);
1804 if constexpr (JTAG_ENABLED)
1806 if (jtag_ !=
nullptr)
1812 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1817 ErrorCode HandleSWJSequence(
bool ,
const uint8_t* req, uint16_t req_len,
1818 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1820 if (!resp || resp_cap < 2u)
1826 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_SEQUENCE);
1827 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1831 if (!req || req_len < 2u)
1833 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1837 const uint8_t RAW_COUNT = req[1];
1838 const uint32_t BIT_COUNT =
1839 (RAW_COUNT == 0u) ? 256u : static_cast<uint32_t>(RAW_COUNT);
1840 const uint32_t BYTE_COUNT = (BIT_COUNT + 7u) / 8u;
1842 if (2u + BYTE_COUNT > req_len)
1844 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1848 const uint8_t* data = &req[2];
1851 const ErrorCode EC = swd_.SeqWriteBits(BIT_COUNT, data);
1854 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1860 swj_shadow_ =
static_cast<uint8_t
>(
1861 swj_shadow_ &
static_cast<uint8_t
>(
~LibXR::USB::DapLinkV2Def::DAP_SWJ_SWCLK_TCK));
1863 bool last_swdio =
false;
1864 if (BIT_COUNT != 0u)
1866 const uint32_t LAST_I = BIT_COUNT - 1u;
1867 last_swdio = (((data[LAST_I / 8u] >> (LAST_I & 7u)) & 0x01u) != 0u);
1872 swj_shadow_ |= LibXR::USB::DapLinkV2Def::DAP_SWJ_SWDIO_TMS;
1876 swj_shadow_ =
static_cast<uint8_t
>(
1878 static_cast<uint8_t
>(
~LibXR::USB::DapLinkV2Def::DAP_SWJ_SWDIO_TMS));
1884 ErrorCode HandleSWDConfigure(
bool ,
const uint8_t* req, uint16_t req_len,
1885 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1893 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_CONFIGURE);
1895 if (req ==
nullptr || req_len < 2u)
1897 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1902 const uint8_t cfg = req[1];
1906 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1911 ErrorCode HandleSWDSequence(
bool ,
const uint8_t* req, uint16_t req_len,
1912 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1914 if (!req || !resp || resp_cap < 2u)
1920 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_SEQUENCE);
1932 resp[1] = DAP_ERROR;
1937 const uint8_t SEQ_CNT = req[1];
1938 uint16_t req_off = 2u;
1939 uint16_t resp_off = 2u;
1941 for (uint32_t s = 0; s < SEQ_CNT; ++s)
1943 if (req_off >= req_len)
1945 resp[1] = DAP_ERROR;
1950 const uint8_t INFO = req[req_off++];
1952 uint32_t cycles =
static_cast<uint32_t
>(INFO & 0x3Fu);
1958 const bool MODE_IN = ((INFO & 0x80u) != 0u);
1959 const uint16_t BYTES =
static_cast<uint16_t
>((cycles + 7u) / 8u);
1964 if (req_off + BYTES > req_len)
1966 resp[1] = DAP_ERROR;
1971 const uint8_t* data = &req[req_off];
1972 req_off =
static_cast<uint16_t
>(req_off + BYTES);
1974 const ErrorCode EC = swd_.SeqWriteBits(cycles, data);
1977 resp[1] = DAP_ERROR;
1986 if (resp_off + BYTES > resp_cap)
1988 resp[1] = DAP_ERROR;
1995 const ErrorCode EC = swd_.SeqReadBits(cycles, &resp[resp_off]);
1998 resp[1] = DAP_ERROR;
2003 resp_off =
static_cast<uint16_t
>(resp_off + BYTES);
2011 ErrorCode HandleJTAGSequence(
bool ,
const uint8_t* req, uint16_t req_len,
2012 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
2014 if (!req || !resp || resp_cap < 2u)
2020 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::JTAG_SEQUENCE);
2024 if (jtag_ ==
nullptr)
2026 resp[1] = DAP_ERROR;
2032 resp[1] = DAP_ERROR;
2036 const uint8_t SEQ_CNT = req[1];
2037 uint16_t req_off = 2u;
2038 uint16_t resp_off = 2u;
2040 for (uint32_t s = 0; s < SEQ_CNT; ++s)
2042 if (req_off >= req_len)
2044 resp[1] = DAP_ERROR;
2049 const uint8_t INFO = req[req_off++];
2050 uint32_t cycles =
static_cast<uint32_t
>(INFO & 0x3Fu);
2056 const bool TMS = ((INFO & LibXR::Debug::JtagProtocol::JTAG_SEQUENCE_TMS) != 0u);
2057 const bool CAPTURE = ((INFO & LibXR::Debug::JtagProtocol::JTAG_SEQUENCE_TDO) != 0u);
2058 const uint16_t BYTES =
static_cast<uint16_t
>((cycles + 7u) / 8u);
2060 if (req_off + BYTES > req_len)
2062 resp[1] = DAP_ERROR;
2066 if (CAPTURE && (resp_off + BYTES > resp_cap))
2068 resp[1] = DAP_ERROR;
2073 const uint8_t* data = &req[req_off];
2074 uint8_t* out = CAPTURE ? &resp[resp_off] :
nullptr;
2083 resp[1] = DAP_ERROR;
2088 req_off =
static_cast<uint16_t
>(req_off + BYTES);
2091 resp_off =
static_cast<uint16_t
>(resp_off + BYTES);
2099 ErrorCode HandleJTAGConfigure(
bool ,
const uint8_t* req, uint16_t req_len,
2100 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
2102 if (!req || !resp || resp_cap < 2u)
2108 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::JTAG_CONFIGURE);
2112 if (jtag_ ==
nullptr)
2114 resp[1] = DAP_ERROR;
2120 resp[1] = DAP_ERROR;
2124 const uint8_t count = req[1];
2125 if (count > JTAG_MAX_DEVICES || req_len <
static_cast<uint16_t
>(2u + count))
2127 resp[1] = DAP_ERROR;
2134 for (uint32_t i = 0; i < count; ++i)
2136 const uint8_t len = req[
static_cast<uint16_t
>(2u + i)];
2137 jtag_ir_len_[i] = len;
2141 jtag_chain_.
count = count;
2144 jtag_chain_.
index = 0u;
2153 ErrorCode HandleJTAGIdCode(
bool ,
const uint8_t* req, uint16_t req_len,
2154 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
2156 if (!req || !resp || resp_cap < 6u)
2162 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::JTAG_IDCODE);
2163 resp[1] = DAP_ERROR;
2166 if (jtag_ ==
nullptr ||
2167 dap_state_.
debug_port != LibXR::USB::DapLinkV2Def::DebugPort::JTAG)
2177 const uint8_t index = req[1];
2178 if (index >= jtag_chain_.
count)
2183 jtag_chain_.
index = index;
2184 LibXR::Debug::JtagProtocol::UpdateChainCache(jtag_chain_);
2187 uint32_t idcode = 0u;
2190 (idcode == 0u || idcode == 0xFFFF'FFFFu || ((idcode & 0x1u) == 0u)) &&
2191 jtag_ir_len_[index] != 4u)
2193 uint32_t fallback_idcode = 0u;
2194 ec = dp.ReadIdCodeWithIr(0x01u, fallback_idcode);
2199 if (fallback_idcode != 0u && fallback_idcode != 0xFFFF'FFFFu &&
2200 ((fallback_idcode & 0x1u) != 0u))
2202 idcode = fallback_idcode;
2219 ErrorCode HandleQueueCommands(
bool ,
const uint8_t* req, uint16_t req_len,
2220 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
2222 if (!req || req_len < 2u)
2224 return BuildCmdStatusResponse(
2225 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS), DAP_ERROR, resp,
2229 const uint8_t NUM = req[1];
2232 return BuildCmdStatusResponse(
2233 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS), DAP_OK, resp,
2237 uint16_t req_off = 2u;
2238 for (uint32_t i = 0u; i < NUM; ++i)
2240 if (req_off >= req_len)
2242 return BuildCmdStatusResponse(
2243 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS), DAP_ERROR, resp,
2247 uint16_t cmd_len = 0u;
2248 if (!ParseQueuedCommandLength(&req[req_off],
2249 static_cast<uint16_t
>(req_len - req_off), cmd_len) ||
2252 return BuildCmdStatusResponse(
2253 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS), DAP_ERROR, resp,
2256 req_off =
static_cast<uint16_t
>(req_off + cmd_len);
2259 if (req_off != req_len)
2261 return BuildCmdStatusResponse(
2262 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS), DAP_ERROR, resp,
2266 if (
static_cast<uint32_t
>(queued_request_length_) +
2267 static_cast<uint32_t
>(req_len - 2u) >
2268 static_cast<uint32_t
>(QUEUED_REQ_BUFFER_SIZE) ||
2269 static_cast<uint32_t
>(queued_command_count_) +
static_cast<uint32_t
>(NUM) >
2270 static_cast<uint32_t
>(QUEUED_CMD_COUNT_MAX))
2272 return BuildCmdStatusResponse(
2273 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS), DAP_ERROR, resp,
2279 queued_request_length_ =
2280 static_cast<uint16_t
>(queued_request_length_ + (req_len - 2u));
2281 queued_command_count_ =
static_cast<uint16_t
>(queued_command_count_ + NUM);
2283 return BuildCmdStatusResponse(
2284 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS), DAP_OK, resp, resp_cap,
2291 ErrorCode HandleExecuteCommands(
bool in_isr,
const uint8_t* ,
2292 uint16_t , uint8_t* resp, uint16_t resp_cap,
2295 const bool ok = TryExecuteQueuedCommandStream(in_isr, resp, resp_cap, out_len);
2296 ResetQueuedCommandState();
2300 return BuildCmdStatusResponse(
2301 ToU8(LibXR::USB::DapLinkV2Def::CommandId::EXECUTE_COMMANDS), DAP_ERROR, resp,
2313 uint8_t MapAckToDapResp(LibXR::Debug::SwdProtocol::Ack ack)
const
2315 static constexpr uint8_t ACK_MAP[8] = {7u, 1u, 2u, 7u, 4u, 7u, 7u, 7u};
2316 return ACK_MAP[
static_cast<uint8_t
>(ack) & 0x07u];
2319 uint8_t MapAckToDapResp(LibXR::Debug::JtagProtocol::Ack ack)
const
2323 case LibXR::Debug::JtagProtocol::Ack::OK:
2325 case LibXR::Debug::JtagProtocol::Ack::WAIT:
2327 case LibXR::Debug::JtagProtocol::Ack::FAULT:
2329 case LibXR::Debug::JtagProtocol::Ack::NO_ACK:
2330 case LibXR::Debug::JtagProtocol::Ack::PROTOCOL:
2336 static inline uint16_t LoadU16Le(
const uint8_t* p)
2338 return static_cast<uint16_t
>(
2339 static_cast<uint16_t
>(p[0]) |
2340 static_cast<uint16_t
>(
static_cast<uint16_t
>(p[1]) << 8u));
2343 static inline void StoreU16Le(uint8_t* p, uint16_t v)
2345 p[0] =
static_cast<uint8_t
>(v & 0xFFu);
2346 p[1] =
static_cast<uint8_t
>((v >> 8u) & 0xFFu);
2349 static inline uint32_t LoadU32Le(
const uint8_t* p)
2351 return static_cast<uint32_t
>(
2352 static_cast<uint32_t
>(p[0]) | (
static_cast<uint32_t
>(p[1]) << 8u) |
2353 (
static_cast<uint32_t
>(p[2]) << 16u) | (
static_cast<uint32_t
>(p[3]) << 24u));
2356 static inline void StoreU32Le(uint8_t* p, uint32_t v)
2358 p[0] =
static_cast<uint8_t
>(v & 0xFFu);
2359 p[1] =
static_cast<uint8_t
>((v >> 8u) & 0xFFu);
2360 p[2] =
static_cast<uint8_t
>((v >> 16u) & 0xFFu);
2361 p[3] =
static_cast<uint8_t
>((v >> 24u) & 0xFFu);
2367 const ErrorCode EC0 = swd_.Transfer(req, resp);
2373 if (resp.
ack == LibXR::Debug::SwdProtocol::Ack::WAIT)
2375 return swd_.TransferWithRetry(req, resp);
2378 if (resp.
ack == LibXR::Debug::SwdProtocol::Ack::FAULT)
2380 const auto POL = swd_.GetTransferPolicy();
2381 if (POL.clear_sticky_on_fault)
2383 LibXR::Debug::SwdProtocol::Ack abort_ack =
2384 LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2385 (void)swd_.WriteAbort(LibXR::Debug::SwdProtocol::DP_ABORT_STKCMPCLR |
2386 LibXR::Debug::SwdProtocol::DP_ABORT_STKERRCLR |
2387 LibXR::Debug::SwdProtocol::DP_ABORT_WDERRCLR |
2388 LibXR::Debug::SwdProtocol::DP_ABORT_ORUNERRCLR,
2396 ErrorCode DpReadRdbuffFast(uint32_t& val, LibXR::Debug::SwdProtocol::Ack& ack_out)
2399 const auto req = LibXR::Debug::SwdProtocol::make_dp_read_req(
2400 LibXR::Debug::SwdProtocol::DpReadReg::RDBUFF);
2401 const ErrorCode ec = TransferTxnFast(req, swd_resp);
2402 ack_out = swd_resp.
ack;
2407 if (swd_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK || !swd_resp.
parity_ok)
2411 val = swd_resp.
rdata;
2415 ErrorCode CompletePendingApReadFast(uint32_t& val,
2416 LibXR::Debug::SwdProtocol::Ack& ack_out)
2418 return DpReadRdbuffFast(val, ack_out);
2421 ErrorCode CheckPostedApWriteFast(LibXR::Debug::SwdProtocol::Ack& ack_out)
2424 const auto req = LibXR::Debug::SwdProtocol::make_dp_read_req(
2425 LibXR::Debug::SwdProtocol::DpReadReg::CTRL_STAT);
2426 const ErrorCode ec = TransferTxnFast(req, swd_resp);
2427 ack_out = swd_resp.
ack;
2432 if (swd_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK || !swd_resp.
parity_ok)
2439 ErrorCode ApReadPostedFast(uint8_t addr2b, uint32_t& posted,
2440 LibXR::Debug::SwdProtocol::Ack& ack_out)
2443 const auto req = LibXR::Debug::SwdProtocol::make_ap_read_req(addr2b);
2444 const ErrorCode ec = TransferTxnFast(req, swd_resp);
2445 ack_out = swd_resp.
ack;
2450 if (swd_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK || !swd_resp.
parity_ok)
2454 posted = swd_resp.
rdata;
2458 void SetTransferAbortFlag(
bool on) { dap_state_.
transfer_abort = on; }
2467 ErrorCode HandleTransfer(
bool in_isr,
const uint8_t* req, uint16_t req_len,
2468 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
2471 if (!req || !resp || resp_cap < 3u)
2476 if constexpr (JTAG_ENABLED)
2478 if (dap_state_.
debug_port == LibXR::USB::DapLinkV2Def::DebugPort::JTAG)
2480 return HandleJtagTransfer(in_isr, req, req_len, resp, resp_cap, out_len);
2484 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER);
2487 uint16_t resp_off = 3u;
2492 resp[2] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2500 resp[2] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2505 const uint8_t COUNT = req[2];
2506 uint16_t req_off = 3u;
2508 auto push_u32 = [&](uint32_t v) ->
bool
2510 if (resp_off + 4u > resp_cap)
2515 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
2519 auto push_timestamp = [&]() ->
bool
2525 auto ensure_space = [&](uint16_t bytes) ->
bool
2526 {
return (resp_off + bytes) <= resp_cap; };
2528 auto bytes_for_read = [&](
bool need_ts) -> uint16_t
2529 {
return static_cast<uint16_t
>(need_ts ? 8u : 4u); };
2531 uint8_t response_count = 0u;
2533 uint8_t response_value = 0u;
2537 bool pending_ap_write =
false;
2540 struct PendingApRead
2543 bool need_ts =
false;
2546 auto emit_read_with_ts = [&](
bool need_ts, uint32_t data) ->
bool
2550 if (!push_timestamp())
2555 if (!push_u32(data))
2565 auto complete_pending_ap_read = [&]() ->
bool
2572 if (!ensure_space(bytes_for_read(pending.need_ts)))
2574 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2578 uint32_t rdata = 0u;
2579 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2580 const ErrorCode EC = CompletePendingApReadFast(rdata, ack);
2582 const uint8_t V = MapAckToDapResp(ack);
2583 if (V != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2590 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2594 if (!emit_read_with_ts(pending.need_ts, rdata))
2596 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2600 pending.valid =
false;
2601 pending.need_ts =
false;
2604 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2608 auto check_posted_ap_write_if_pending = [&]() ->
bool
2610 if (!pending_ap_write)
2614 LibXR::Debug::SwdProtocol::Ack check_ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2615 const ErrorCode check_ec = CheckPostedApWriteFast(check_ack);
2616 response_value = MapAckToDapResp(check_ack);
2617 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2623 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2626 pending_ap_write =
false;
2631 auto complete_pending_ap_read_if_any = [&]() ->
bool
2632 {
return pending.valid ? complete_pending_ap_read() : true; };
2634 auto close_posted_state = [&]() ->
bool
2635 {
return complete_pending_ap_read_if_any() && check_posted_ap_write_if_pending(); };
2638 for (uint32_t i = 0; i < COUNT; ++i)
2640 if (req_off >= req_len)
2642 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2646 const uint8_t RQ = req[req_off++];
2653 const bool MATCH_VALUE =
2654 ((RQ & LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_VALUE) != 0u);
2655 const bool MATCH_MASK =
2656 ((RQ & LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_MASK) != 0u);
2659 if (TS && (MATCH_VALUE || MATCH_MASK))
2661 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2665 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2673 if (!complete_pending_ap_read_if_any())
2678 if (req_off + 4u > req_len)
2680 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2684 uint32_t wdata = LoadU32Le(&req[req_off]);
2685 req_off =
static_cast<uint16_t
>(req_off + 4u);
2689 match_mask_ = wdata;
2690 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2696 ec = swd_.ApWriteTxn(ADDR2B, wdata, ack);
2700 ec = swd_.DpWriteTxn(
static_cast<LibXR::Debug::SwdProtocol::DpWriteReg
>(ADDR2B),
2704 response_value = MapAckToDapResp(ack);
2705 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2711 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2717 pending_ap_write =
true;
2722 if (!push_timestamp())
2724 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2739 if (!close_posted_state())
2744 if (req_off + 4u > req_len)
2746 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2750 uint32_t match_val = LoadU32Le(&req[req_off]);
2751 req_off =
static_cast<uint16_t
>(req_off + 4u);
2753 uint32_t rdata = 0u;
2755 bool matched =
false;
2761 ec = swd_.ApReadTxn(ADDR2B, rdata, ack);
2762 if (ec ==
ErrorCode::OK && ack == LibXR::Debug::SwdProtocol::Ack::OK)
2769 ec = swd_.DpReadTxn(
2770 static_cast<LibXR::Debug::SwdProtocol::DpReadReg
>(ADDR2B), rdata, ack);
2773 response_value = MapAckToDapResp(ack);
2774 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2780 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2784 if ((rdata & match_mask_) == (match_val & match_mask_))
2797 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2805 static_cast<uint8_t
>(LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK |
2806 LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MISMATCH);
2811 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2820 if (!close_posted_state())
2825 uint32_t rdata = 0u;
2826 ec = swd_.DpReadTxn(
static_cast<LibXR::Debug::SwdProtocol::DpReadReg
>(ADDR2B),
2829 response_value = MapAckToDapResp(ack);
2830 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2836 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2840 if (!ensure_space(bytes_for_read(TS)))
2842 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2846 if (!emit_read_with_ts(TS, rdata))
2848 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2852 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2858 if (!check_posted_ap_write_if_pending())
2868 uint32_t dummy_posted = 0u;
2869 ec = ApReadPostedFast(ADDR2B, dummy_posted, ack);
2871 response_value = MapAckToDapResp(ack);
2872 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2878 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2884 pending.valid =
true;
2885 pending.need_ts = TS;
2889 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2895 if (!ensure_space(bytes_for_read(pending.need_ts)))
2897 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2901 uint32_t posted_prev = 0u;
2902 ec = ApReadPostedFast(ADDR2B, posted_prev, ack);
2904 const uint8_t CUR_V = MapAckToDapResp(ack);
2905 if (CUR_V != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK || ec !=
ErrorCode::OK)
2909 const uint8_t PROOR_FAIL =
2910 (CUR_V != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2912 :
LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2914 if (!complete_pending_ap_read())
2922 response_value = PROOR_FAIL;
2928 if (!emit_read_with_ts(pending.need_ts, posted_prev))
2930 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2934 pending.valid =
true;
2935 pending.need_ts = TS;
2937 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2954 const uint8_t PRIOR_FAIL = response_value;
2956 if (!complete_pending_ap_read())
2964 if (PRIOR_FAIL != 0u && PRIOR_FAIL != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2966 response_value = PRIOR_FAIL;
2971 if (response_value == LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK &&
2972 !check_posted_ap_write_if_pending())
2976 resp[1] = response_count;
2977 resp[2] = response_value;
2981 ErrorCode HandleTransferBlock(
bool in_isr,
const uint8_t* req, uint16_t req_len,
2982 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
2984 if constexpr (JTAG_ENABLED)
2986 if (dap_state_.
debug_port == LibXR::USB::DapLinkV2Def::DebugPort::JTAG)
2988 return HandleJtagTransferBlock(in_isr, req, req_len, resp, resp_cap, out_len);
2994 if (!resp || resp_cap < 4u)
3000 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_BLOCK);
3006 if (!req || req_len < 5u)
3008 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3015 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3019 uint16_t count = 0u;
3020 count = LoadU16Le(&req[2]);
3022 const uint8_t DAP_RQ = req[4];
3025 if ((DAP_RQ & (LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_VALUE |
3026 LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_MASK)) != 0u)
3028 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3033 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3040 const uint16_t DONE0 = 0u;
3041 StoreU16Le(&resp[1], DONE0);
3042 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
3054 uint16_t req_off = 5u;
3055 uint16_t resp_off = 4u;
3060 const uint32_t REQ_NEED =
3061 static_cast<uint32_t
>(req_off) + (
static_cast<uint32_t
>(count) * 4u);
3062 if (REQ_NEED > req_len)
3064 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3065 StoreU16Le(&resp[1], done);
3072 auto swd_req = LibXR::Debug::SwdProtocol::make_ap_write_req(ADDR2B, 0u);
3074 for (uint32_t i = 0; i < count; ++i)
3076 uint32_t wdata = LoadU32Le(&req[req_off]);
3077 req_off =
static_cast<uint16_t
>(req_off + 4u);
3078 swd_req.wdata = wdata;
3079 const ErrorCode ec = TransferTxnFast(swd_req, swd_resp);
3080 xresp = MapAckToDapResp(swd_resp.
ack);
3081 if (swd_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK)
3087 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3090 done =
static_cast<uint16_t
>(i + 1u);
3092 if (xresp == LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK && done != 0u)
3094 LibXR::Debug::SwdProtocol::Ack check_ack =
3095 LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
3096 const ErrorCode check_ec = CheckPostedApWriteFast(check_ack);
3097 xresp = MapAckToDapResp(check_ack);
3098 if (check_ack == LibXR::Debug::SwdProtocol::Ack::OK &&
3101 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3107 for (uint32_t i = 0; i < count; ++i)
3109 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
3111 uint32_t wdata = LoadU32Le(&req[req_off]);
3112 req_off =
static_cast<uint16_t
>(req_off + 4u);
3113 ec = swd_.DpWriteTxn(
static_cast<LibXR::Debug::SwdProtocol::DpWriteReg
>(ADDR2B),
3115 xresp = MapAckToDapResp(ack);
3116 if (ack != LibXR::Debug::SwdProtocol::Ack::OK)
3122 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3125 done =
static_cast<uint16_t
>(i + 1u);
3128 StoreU16Le(&resp[1], done);
3137 const uint32_t RESP_NEED =
3138 static_cast<uint32_t
>(resp_off) + (
static_cast<uint32_t
>(count) * 4u);
3139 if (RESP_NEED > resp_cap)
3141 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3142 StoreU16Le(&resp[1], done);
3149 for (uint32_t i = 0; i < count; ++i)
3151 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
3153 uint32_t rdata = 0u;
3154 ec = swd_.DpReadTxn(
static_cast<LibXR::Debug::SwdProtocol::DpReadReg
>(ADDR2B),
3156 xresp = MapAckToDapResp(ack);
3157 if (ack != LibXR::Debug::SwdProtocol::Ack::OK)
3163 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3166 StoreU32Le(&resp[resp_off], rdata);
3167 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
3168 done =
static_cast<uint16_t
>(i + 1u);
3170 StoreU16Le(&resp[1], done);
3178 const uint32_t RESP_NEED =
3179 static_cast<uint32_t
>(resp_off) + (
static_cast<uint32_t
>(count) * 4u);
3180 if (RESP_NEED > resp_cap)
3182 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3183 StoreU16Le(&resp[1], done);
3189 auto ap_read_req = LibXR::Debug::SwdProtocol::make_ap_read_req(ADDR2B);
3191 ErrorCode ec = TransferTxnFast(ap_read_req, ap_read_resp);
3192 xresp = MapAckToDapResp(ap_read_resp.
ack);
3193 if (ap_read_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK)
3199 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3204 for (uint32_t i = 1; i < count; ++i)
3206 ec = TransferTxnFast(ap_read_req, ap_read_resp);
3207 const uint8_t CUR = MapAckToDapResp(ap_read_resp.
ack);
3209 if (ap_read_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK ||
3213 if (resp_off + 4u <= resp_cap)
3215 uint32_t rdbuff_data = 0u;
3216 LibXR::Debug::SwdProtocol::Ack rdbuff_ack =
3217 LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
3218 const ErrorCode ec2 = CompletePendingApReadFast(rdbuff_data, rdbuff_ack);
3219 const uint8_t v2 = MapAckToDapResp(rdbuff_ack);
3221 if (v2 == LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK && ec2 ==
ErrorCode::OK)
3223 StoreU32Le(&resp[resp_off], rdbuff_data);
3224 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
3225 done =
static_cast<uint16_t
>(i);
3232 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3241 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3246 StoreU32Le(&resp[resp_off], ap_read_resp.
rdata);
3247 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
3248 done =
static_cast<uint16_t
>(i);
3254 uint32_t rdbuff_data = 0u;
3255 LibXR::Debug::SwdProtocol::Ack rdbuff_ack =
3256 LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
3257 const ErrorCode ec2 = CompletePendingApReadFast(rdbuff_data, rdbuff_ack);
3258 const uint8_t v2 = MapAckToDapResp(rdbuff_ack);
3261 if (v2 != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
3267 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3271 StoreU32Le(&resp[resp_off], rdbuff_data);
3272 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
3277 StoreU16Le(&resp[1], done);
3284 ErrorCode HandleJtagTransfer(
bool ,
const uint8_t* req, uint16_t req_len,
3285 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
3288 if (!req || !resp || resp_cap < 3u)
3293 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER);
3296 uint16_t resp_off = 3u;
3298 if (req_len < 3u || jtag_ ==
nullptr || jtag_chain_.
count == 0u)
3300 resp[2] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3308 resp[2] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3313 const uint8_t TAP_INDEX = req[1];
3314 if (TAP_INDEX >= jtag_chain_.
count)
3316 resp[2] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3321 jtag_chain_.
index = TAP_INDEX;
3322 LibXR::Debug::JtagProtocol::UpdateChainCache(jtag_chain_);
3325 const uint8_t COUNT = req[2];
3326 uint16_t req_off = 3u;
3328 auto push_u32 = [&](uint32_t v) ->
bool
3330 if (resp_off + 4u > resp_cap)
3335 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
3339 auto push_timestamp = [&]() ->
bool
3345 auto ensure_space = [&](uint16_t bytes) ->
bool
3346 {
return (resp_off + bytes) <= resp_cap; };
3348 auto bytes_for_read = [&](
bool need_ts) -> uint16_t
3349 {
return static_cast<uint16_t
>(need_ts ? 8u : 4u); };
3351 auto idle_after_attempt = [&]()
3359 auto dp_read_retry = [&](uint8_t addr2b, uint32_t& val,
3360 LibXR::Debug::JtagProtocol::Ack& ack) ->
ErrorCode
3365 const ErrorCode ec = dp.DpReadTxn(addr2b, val, ack);
3366 idle_after_attempt();
3367 if (ack != LibXR::Debug::JtagProtocol::Ack::WAIT || retry == 0u ||
3376 auto dp_write_retry = [&](uint8_t addr2b, uint32_t val,
3377 LibXR::Debug::JtagProtocol::Ack& ack) ->
ErrorCode
3382 const ErrorCode ec = dp.DpWriteTxn(addr2b, val, ack);
3383 idle_after_attempt();
3384 if (ack != LibXR::Debug::JtagProtocol::Ack::WAIT || retry == 0u ||
3393 auto ap_read_retry = [&](uint8_t addr2b, uint32_t& val,
3394 LibXR::Debug::JtagProtocol::Ack& ack) ->
ErrorCode
3399 const ErrorCode ec = dp.ApReadTxn(addr2b, val, ack);
3400 idle_after_attempt();
3401 if (ack != LibXR::Debug::JtagProtocol::Ack::WAIT || retry == 0u ||
3410 auto ap_write_retry = [&](uint8_t addr2b, uint32_t val,
3411 LibXR::Debug::JtagProtocol::Ack& ack) ->
ErrorCode
3416 const ErrorCode ec = dp.ApWriteTxn(addr2b, val, ack);
3417 idle_after_attempt();
3418 if (ack != LibXR::Debug::JtagProtocol::Ack::WAIT || retry == 0u ||
3427 auto check_posted_ap_write_jtag =
3428 [&](LibXR::Debug::JtagProtocol::Ack& ack) ->
ErrorCode
3430 uint32_t ctrl_stat = 0u;
3431 return dp_read_retry(
3432 static_cast<uint8_t
>(LibXR::Debug::SwdProtocol::DpReadReg::CTRL_STAT),
3436 uint8_t response_count = 0u;
3437 uint8_t response_value = 0u;
3438 bool pending_ap_write =
false;
3440 auto emit_read_with_ts = [&](
bool need_ts, uint32_t data) ->
bool
3444 if (!push_timestamp())
3449 if (!push_u32(data))
3457 auto check_posted_ap_write_if_pending = [&]() ->
bool
3459 if (!pending_ap_write)
3464 LibXR::Debug::JtagProtocol::Ack ack = LibXR::Debug::JtagProtocol::Ack::PROTOCOL;
3465 const ErrorCode ec = check_posted_ap_write_jtag(ack);
3466 const uint8_t v = MapAckToDapResp(ack);
3468 if (v != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
3475 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3479 pending_ap_write =
false;
3483 auto should_check_pending_ap_write_at_tail = [&]() ->
bool
3485 return response_value == LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK ||
3487 static_cast<uint8_t
>(LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK |
3488 LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MISMATCH);
3491 for (uint32_t i = 0; i < COUNT; ++i)
3493 if (req_off >= req_len)
3495 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3499 const uint8_t RQ = req[req_off++];
3504 const bool MATCH_VALUE =
3505 ((RQ & LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_VALUE) != 0u);
3506 const bool MATCH_MASK =
3507 ((RQ & LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_MASK) != 0u);
3509 if (TS && (MATCH_VALUE || MATCH_MASK))
3511 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3515 LibXR::Debug::JtagProtocol::Ack ack = LibXR::Debug::JtagProtocol::Ack::PROTOCOL;
3520 if (req_off + 4u > req_len)
3522 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3526 uint32_t wdata = 0u;
3528 req_off =
static_cast<uint16_t
>(req_off + 4u);
3532 match_mask_ = wdata;
3533 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
3540 ec = ap_write_retry(ADDR2B, wdata, ack);
3544 ec = dp_write_retry(ADDR2B, wdata, ack);
3547 response_value = MapAckToDapResp(ack);
3548 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
3554 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3560 if (!push_timestamp())
3562 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3570 pending_ap_write =
true;
3577 if (!check_posted_ap_write_if_pending())
3582 if (req_off + 4u > req_len)
3584 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3588 uint32_t match_val = 0u;
3590 req_off =
static_cast<uint16_t
>(req_off + 4u);
3592 uint32_t rdata = 0u;
3594 bool matched =
false;
3600 ec = ap_read_retry(ADDR2B, rdata, ack);
3604 ec = dp_read_retry(ADDR2B, rdata, ack);
3607 response_value = MapAckToDapResp(ack);
3608 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
3614 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3618 if ((rdata & match_mask_) == (match_val & match_mask_))
3631 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
3639 static_cast<uint8_t
>(LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK |
3640 LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MISMATCH);
3650 if (!check_posted_ap_write_if_pending())
3655 uint32_t rdata = 0u;
3656 ec = dp_read_retry(ADDR2B, rdata, ack);
3658 response_value = MapAckToDapResp(ack);
3659 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
3665 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3669 if (!ensure_space(bytes_for_read(TS)))
3671 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3675 if (!emit_read_with_ts(TS, rdata))
3677 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3681 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
3685 uint32_t rdata = 0u;
3686 if (!check_posted_ap_write_if_pending())
3691 ec = ap_read_retry(ADDR2B, rdata, ack);
3693 response_value = MapAckToDapResp(ack);
3694 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
3700 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3704 if (!ensure_space(bytes_for_read(TS)))
3706 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3710 if (!emit_read_with_ts(TS, rdata))
3712 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3716 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
3726 if (pending_ap_write && should_check_pending_ap_write_at_tail())
3728 const uint8_t PRIOR_RESPONSE = response_value;
3729 if (check_posted_ap_write_if_pending())
3731 response_value = PRIOR_RESPONSE;
3735 resp[1] = response_count;
3736 resp[2] = response_value;
3741 ErrorCode HandleJtagTransferBlock(
bool ,
const uint8_t* req, uint16_t req_len,
3742 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
3744 if (!req || !resp || resp_cap < 4u)
3750 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_BLOCK);
3756 if (req_len < 5u || jtag_ ==
nullptr || jtag_chain_.
count == 0u)
3758 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3765 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3769 const uint8_t TAP_INDEX = req[1];
3770 if (TAP_INDEX >= jtag_chain_.
count)
3772 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3776 jtag_chain_.
index = TAP_INDEX;
3777 LibXR::Debug::JtagProtocol::UpdateChainCache(jtag_chain_);
3779 uint16_t count = 0u;
3781 const uint8_t DAP_RQ = req[4];
3783 if ((DAP_RQ & (LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_VALUE |
3784 LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_MASK)) != 0u)
3786 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3791 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3797 const uint16_t DONE0 = 0u;
3799 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
3805 auto idle_after_attempt = [&]()
3813 auto dp_read_retry = [&](uint8_t addr2b, uint32_t& val,
3814 LibXR::Debug::JtagProtocol::Ack& ack) ->
ErrorCode
3819 const ErrorCode ec = dp.DpReadTxn(addr2b, val, ack);
3820 idle_after_attempt();
3821 if (ack != LibXR::Debug::JtagProtocol::Ack::WAIT || retry == 0u ||
3830 auto dp_write_retry = [&](uint8_t addr2b, uint32_t val,
3831 LibXR::Debug::JtagProtocol::Ack& ack) ->
ErrorCode
3836 const ErrorCode ec = dp.DpWriteTxn(addr2b, val, ack);
3837 idle_after_attempt();
3838 if (ack != LibXR::Debug::JtagProtocol::Ack::WAIT || retry == 0u ||
3847 auto ap_read_retry = [&](uint8_t addr2b, uint32_t& val,
3848 LibXR::Debug::JtagProtocol::Ack& ack) ->
ErrorCode
3853 const ErrorCode ec = dp.ApReadTxn(addr2b, val, ack);
3854 idle_after_attempt();
3855 if (ack != LibXR::Debug::JtagProtocol::Ack::WAIT || retry == 0u ||
3864 auto ap_write_retry = [&](uint8_t addr2b, uint32_t val,
3865 LibXR::Debug::JtagProtocol::Ack& ack) ->
ErrorCode
3870 const ErrorCode ec = dp.ApWriteTxn(addr2b, val, ack);
3871 idle_after_attempt();
3872 if (ack != LibXR::Debug::JtagProtocol::Ack::WAIT || retry == 0u ||
3881 auto check_posted_ap_write_jtag =
3882 [&](LibXR::Debug::JtagProtocol::Ack& ack) ->
ErrorCode
3884 uint32_t ctrl_stat = 0u;
3885 return dp_read_retry(
3886 static_cast<uint8_t
>(LibXR::Debug::SwdProtocol::DpReadReg::CTRL_STAT),
3896 uint16_t req_off = 5u;
3897 uint16_t resp_off = 4u;
3901 for (uint32_t i = 0; i < count; ++i)
3903 if (req_off + 4u > req_len)
3905 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3909 uint32_t wdata = 0u;
3911 req_off =
static_cast<uint16_t
>(req_off + 4u);
3913 LibXR::Debug::JtagProtocol::Ack ack = LibXR::Debug::JtagProtocol::Ack::PROTOCOL;
3915 AP ? ap_write_retry(ADDR2B, wdata, ack) : dp_write_retry(ADDR2B, wdata, ack);
3917 xresp = MapAckToDapResp(ack);
3920 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3924 if (ack != LibXR::Debug::JtagProtocol::Ack::OK)
3931 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3935 done =
static_cast<uint16_t
>(i + 1u);
3938 if (AP && xresp == LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK && done > 0u)
3940 LibXR::Debug::JtagProtocol::Ack ack = LibXR::Debug::JtagProtocol::Ack::PROTOCOL;
3941 const ErrorCode ec = check_posted_ap_write_jtag(ack);
3942 const uint8_t v = MapAckToDapResp(ack);
3943 if (v != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
3949 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3959 for (uint32_t i = 0; i < count; ++i)
3961 if (resp_off + 4u > resp_cap)
3963 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3967 LibXR::Debug::JtagProtocol::Ack ack = LibXR::Debug::JtagProtocol::Ack::PROTOCOL;
3969 uint32_t rdata = 0u;
3973 ec = ap_read_retry(ADDR2B, rdata, ack);
3977 ec = dp_read_retry(ADDR2B, rdata, ack);
3980 xresp = MapAckToDapResp(ack);
3983 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3987 if (ack != LibXR::Debug::JtagProtocol::Ack::OK)
3994 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
3999 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
4000 done =
static_cast<uint16_t
>(i + 1u);
4009 ErrorCode HandleJtagWriteAbort(
bool ,
const uint8_t* req, uint16_t req_len,
4010 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
4012 if (!req || !resp || resp_cap < 2u)
4018 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::WRITE_ABORT);
4019 resp[1] = DAP_ERROR;
4022 if (req_len < 6u || jtag_ ==
nullptr || jtag_chain_.
count == 0u)
4027 const uint8_t TAP_INDEX = req[1];
4028 if (TAP_INDEX >= jtag_chain_.
count)
4033 jtag_chain_.
index = TAP_INDEX;
4034 LibXR::Debug::JtagProtocol::UpdateChainCache(jtag_chain_);
4036 uint32_t flags = 0u;
4040 LibXR::Debug::JtagProtocol::Ack ack = LibXR::Debug::JtagProtocol::Ack::PROTOCOL;
4041 const ErrorCode ec = dp.WriteAbort(flags, ack);
4042 if (ec ==
ErrorCode::OK && ack == LibXR::Debug::JtagProtocol::Ack::OK)
4054 void DriveReset(
bool release)
4056 last_nreset_level_high_ = release;
4061 swj_shadow_ |= LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET;
4065 swj_shadow_ =
static_cast<uint8_t
>(
4066 swj_shadow_ &
static_cast<uint8_t
>(
~LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET));
4069 if (nreset_gpio_ !=
nullptr)
4071 (void)nreset_gpio_->
Write(release);
4075 void ResetJtagChainState()
4077 if constexpr (JTAG_ENABLED)
4080 jtag_chain_.
count = 0u;
4081 jtag_chain_.
index = 0u;
4090 void DelayUsIfAllowed(
bool , uint32_t us)
4096 static constexpr uint16_t DEFAULT_DAP_PACKET_SIZE = DefaultDapPacketSize;
4097 static constexpr uint8_t PACKET_COUNT_ADVERTISED = AdvertisedPacketCount;
4098 static constexpr uint8_t PACKET_COUNT_EFFECTIVE =
4099 (PACKET_COUNT_ADVERTISED > 4u) ? 4u : PACKET_COUNT_ADVERTISED;
4100 static constexpr uint8_t MAX_OUTSTANDING_RESPONSES = PACKET_COUNT_EFFECTIVE;
4104 static constexpr uint16_t OPENOCD_SAFE_DAP_PACKET_SIZE =
4105 static_cast<uint16_t
>((255u * 5u) + 4u);
4106 static constexpr uint8_t JTAG_MAX_DEVICES = 16u;
4109 static constexpr uint16_t MAX_DAP_PACKET_SIZE = MaxDapPacketSize;
4110 static constexpr uint16_t QUEUED_REQ_BUFFER_SIZE = QueuedRequestBufferSize;
4111 static constexpr uint16_t QUEUED_CMD_COUNT_MAX = QueuedCommandCountMax;
4112 static constexpr uint16_t RESP_SLOT_SIZE = MAX_DAP_PACKET_SIZE;
4113 static constexpr uint8_t RESP_QUEUE_DEPTH = PACKET_COUNT_EFFECTIVE;
4114 static constexpr uint16_t QUEUED_REQ_BUFFER_ALLOC_SIZE = QUEUED_REQ_BUFFER_SIZE;
4115 static_assert(PACKET_COUNT_ADVERTISED > 0u,
"PACKET_COUNT_ADVERTISED must be > 0");
4116 static_assert(PACKET_COUNT_EFFECTIVE > 0u,
"PACKET_COUNT_EFFECTIVE must be > 0");
4117 static_assert(MAX_DAP_PACKET_SIZE >= DEFAULT_DAP_PACKET_SIZE,
4118 "MAX_DAP_PACKET_SIZE must be >= DEFAULT_DAP_PACKET_SIZE");
4119 static_assert(MAX_DAP_PACKET_SIZE <= OPENOCD_SAFE_DAP_PACKET_SIZE,
4120 "MAX_DAP_PACKET_SIZE exceeds OpenOCD-safe limit");
4121 static_assert(((OPENOCD_SAFE_DAP_PACKET_SIZE - 4u) / 5u) <= 255u,
4122 "OPENOCD_SAFE_DAP_PACKET_SIZE too large for CMD_DAP_TFER u8 count");
4123 static_assert(QUEUED_REQ_BUFFER_SIZE > 0u,
"QUEUED_REQ_BUFFER_SIZE must be > 0");
4124 static_assert(QUEUED_CMD_COUNT_MAX > 0u,
"QUEUED_CMD_COUNT_MAX must be > 0");
4125 static_assert(RESP_SLOT_SIZE >= DEFAULT_DAP_PACKET_SIZE,
4126 "RESP_SLOT_SIZE must cover FS bulk packet size");
4127 static_assert((RESP_QUEUE_DEPTH & (RESP_QUEUE_DEPTH - 1u)) == 0u,
4128 "Response queue depth must be power-of-two");
4130 static constexpr uint8_t WINUSB_VENDOR_CODE = 0x20;
4134 static constexpr uint16_t GUID_MULTI_SZ_UTF_16_BYTES =
4135 static_cast<uint16_t
>(LibXR::USB::WinUsbMsOs20::GUID_STR_UTF16_BYTES +
4141 uint8_t payload[RESP_SLOT_SIZE] = {};
4144 ResponseSlot resp_q_[RESP_QUEUE_DEPTH] = {};
4145 uint8_t resp_q_head_ = 0u;
4146 uint8_t resp_q_tail_ = 0u;
4147 uint8_t resp_q_count_ = 0u;
4148 bool deferred_in_resp_valid_ =
false;
4149 uint16_t deferred_in_resp_len_ = 0u;
4151 uint8_t queued_request_buffer_[QUEUED_REQ_BUFFER_ALLOC_SIZE] = {};
4152 uint16_t queued_request_length_ = 0u;
4153 uint16_t queued_command_count_ = 0u;
4155 uint8_t out_req_multi_storage_[MAX_DAP_PACKET_SIZE] = {};
4156 LibXR::RawData out_req_multi_buf_{out_req_multi_storage_, DEFAULT_DAP_PACKET_SIZE};
4157 uint8_t in_tx_multi_storage_[MAX_DAP_PACKET_SIZE] = {};
4158 LibXR::RawData in_tx_multi_buf_{in_tx_multi_storage_, DEFAULT_DAP_PACKET_SIZE};
4164 struct WinUsbMsOs20DescSet
4178 uint8_t
name[LibXR::USB::WinUsbMsOs20::
4179 PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES];
4182 uint8_t
data[GUID_MULTI_SZ_UTF_16_BYTES];
4192 uint8_t jtag_ir_len_[JTAG_MAX_DEVICES] = {};
4196 uint8_t swj_shadow_ =
4197 static_cast<uint8_t
>(DapLinkV2Def::DAP_SWJ_SWDIO_TMS |
4198 DapLinkV2Def::DAP_SWJ_NRESET);
4200 bool last_nreset_level_high_ =
true;
4203 InfoStrings info_{
"XRobot",
"DAPLinkV2",
"00000001",
"2.0.0",
"XRUSB",
4204 "XRDAP",
"XRobot",
"DAP_DEMO",
"0.1.0"};
4206 uint32_t swj_clock_hz_ = 1000000u;
4208 const char* interface_string_ =
nullptr;
4213 Endpoint* ep_data_in_ =
nullptr;
4214 Endpoint* ep_data_out_ =
nullptr;
4216 bool inited_ =
false;
4217 uint8_t interface_num_ = 0;
4224 struct DapLinkV2DescBlock
4226 InterfaceDescriptor intf;
4227 EndpointDescriptor ep_out;
4228 EndpointDescriptor ep_in;
4236 uint32_t match_mask_ = 0xFFFFFFFFu;