32 static constexpr const char* DEFAULT_INTERFACE_STRING =
"XRUSB CMSIS-DAP v2";
62 SwdPort& swd_link,
LibXR::GPIO* nreset_gpio =
nullptr,
65 const char* interface_string = DEFAULT_INTERFACE_STRING)
76 InitWinUsbDescriptors();
149 UpdateWinUsbInterfaceFields();
172 desc_block_.
intf = {9,
173 static_cast<uint8_t
>(DescriptorType::INTERFACE),
183 static_cast<uint8_t
>(DescriptorType::ENDPOINT),
189 desc_block_.
ep_in = {7,
190 static_cast<uint8_t
>(DescriptorType::ENDPOINT),
196 SetData(
RawData{
reinterpret_cast<uint8_t*
>(&desc_block_),
sizeof(desc_block_)});
208 swj_shadow_ =
static_cast<uint8_t
>(DapLinkV2Def::DAP_SWJ_SWDIO_TMS |
209 DapLinkV2Def::DAP_SWJ_NRESET);
211 ResetResponseQueue();
212 ResetQueuedCommandState();
216 ArmOutTransferIfIdle();
227 ResetResponseQueue();
228 ResetQueuedCommandState();
253 swj_shadow_ =
static_cast<uint8_t
>(DapLinkV2Def::DAP_SWJ_SWDIO_TMS |
254 DapLinkV2Def::DAP_SWJ_NRESET);
296 return ConstRawData{
reinterpret_cast<const uint8_t*
>(&winusb_msos20_),
297 sizeof(winusb_msos20_)};
326 template <
typename E>
327 static constexpr uint8_t ToU8(E e)
329 return static_cast<uint8_t
>(e);
337 static inline ErrorCode BuildUnknownCmdResponse(uint8_t* resp, uint16_t cap,
340 if (!resp || cap < 1u)
351 static inline ErrorCode BuildCmdStatusResponse(uint8_t cmd, uint8_t status,
352 uint8_t* resp, uint16_t cap,
355 if (!resp || cap < 2u)
371 void InitWinUsbDescriptors()
373 winusb_msos20_.
set.wLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_.
set));
374 winusb_msos20_.
set.wDescriptorType =
375 LibXR::USB::WinUsbMsOs20::MS_OS_20_SET_HEADER_DESCRIPTOR;
376 winusb_msos20_.
set.dwWindowsVersion = 0x06030000;
377 winusb_msos20_.
set.wTotalLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_));
379 winusb_msos20_.
cfg.wLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_.
cfg));
380 winusb_msos20_.
cfg.wDescriptorType =
381 LibXR::USB::WinUsbMsOs20::MS_OS_20_SUBSET_HEADER_CONFIGURATION;
384 winusb_msos20_.
cfg.bConfigurationValue = 0u;
385 winusb_msos20_.
cfg.bReserved = 0;
386 winusb_msos20_.
cfg.wTotalLength =
static_cast<uint16_t
>(
387 sizeof(winusb_msos20_) - offsetof(WinUsbMsOs20DescSet, cfg));
389 winusb_msos20_.
func.wLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_.
func));
390 winusb_msos20_.
func.wDescriptorType =
391 LibXR::USB::WinUsbMsOs20::MS_OS_20_SUBSET_HEADER_FUNCTION;
392 winusb_msos20_.
func.bReserved = 0;
393 winusb_msos20_.
func.wTotalLength =
static_cast<uint16_t
>(
394 sizeof(winusb_msos20_) - offsetof(WinUsbMsOs20DescSet, func));
396 winusb_msos20_.
compat.wLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_.
compat));
397 winusb_msos20_.
compat.wDescriptorType =
398 LibXR::USB::WinUsbMsOs20::MS_OS_20_FEATURE_COMPATIBLE_ID;
400 winusb_msos20_.prop.
header.wDescriptorType =
401 LibXR::USB::WinUsbMsOs20::MS_OS_20_FEATURE_REG_PROPERTY;
402 winusb_msos20_.prop.
header.wPropertyDataType = LibXR::USB::WinUsbMsOs20::REG_MULTI_SZ;
403 winusb_msos20_.prop.
header.wPropertyNameLength =
404 LibXR::USB::WinUsbMsOs20::PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES;
407 LibXR::USB::WinUsbMsOs20::PROP_NAME_DEVICE_INTERFACE_GUIDS_UTF16,
408 LibXR::USB::WinUsbMsOs20::PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES);
412 const char GUID_STR[] =
"{CDB3B5AD-293B-4663-AA36-1AAE46463776}";
413 const size_t GUID_LEN =
sizeof(GUID_STR) - 1;
415 for (
size_t i = 0; i < GUID_LEN; ++i)
417 winusb_msos20_.prop.
data[i * 2] =
static_cast<uint8_t
>(GUID_STR[i]);
418 winusb_msos20_.prop.
data[i * 2 + 1] = 0x00;
422 winusb_msos20_.prop.
data[GUID_LEN * 2 + 0] = 0x00;
423 winusb_msos20_.prop.
data[GUID_LEN * 2 + 1] = 0x00;
424 winusb_msos20_.prop.
data[GUID_LEN * 2 + 2] = 0x00;
425 winusb_msos20_.prop.
data[GUID_LEN * 2 + 3] = 0x00;
428 winusb_msos20_.prop.
header.wLength =
429 static_cast<uint16_t
>(
sizeof(winusb_msos20_.prop));
436 void UpdateWinUsbInterfaceFields()
489 ArmOutTransferIfIdle();
491 const auto* req =
static_cast<const uint8_t*
>(data.
addr_);
492 const uint16_t REQ_LEN =
static_cast<uint16_t
>(data.
size_);
497 if (!HasDeferredResponseInEpBuffer() && IsResponseQueueEmpty() &&
499 CanBuildResponseDirectlyInEpBuffer())
502 if (tx_buff.addr_ && tx_buff.size_ > 0u)
504 auto* tx_buf =
static_cast<uint8_t*
>(tx_buff.addr_);
505 uint16_t out_len = 0u;
507 static_cast<uint16_t
>(tx_buff.size_), out_len);
511 if (StartInTransferFromCurrentBuffer(out_len))
516 if (!EnqueueResponse(tx_buf, out_len))
518 (void)SubmitNextQueuedResponseIfIdle();
519 (void)EnqueueResponse(tx_buf, out_len);
522 (void)SubmitNextQueuedResponseIfIdle();
523 ArmOutTransferIfIdle();
530 if (!HasDeferredResponseInEpBuffer() && IsResponseQueueEmpty() &&
532 CanBuildResponseDirectlyInEpBuffer())
535 if (tx_buff.addr_ && tx_buff.size_ > 0u)
537 auto* tx_buf =
static_cast<uint8_t*
>(tx_buff.addr_);
538 uint16_t out_len = 0u;
540 static_cast<uint16_t
>(tx_buff.size_), out_len);
544 SetDeferredResponseInEpBuffer(out_len);
545 ArmOutTransferIfIdle();
550 if (TryBuildAndEnqueueResponse(in_isr, req, REQ_LEN))
552 (void)SubmitDeferredResponseIfIdle();
553 (void)SubmitNextQueuedResponseIfIdle();
554 ArmOutTransferIfIdle();
560 (void)SubmitNextQueuedResponseIfIdle();
561 (void)TryBuildAndEnqueueResponse(in_isr, req, REQ_LEN);
563 (void)SubmitDeferredResponseIfIdle();
564 (void)SubmitNextQueuedResponseIfIdle();
565 ArmOutTransferIfIdle();
573 (void)SubmitDeferredResponseIfIdle();
574 (void)SubmitNextQueuedResponseIfIdle();
575 ArmOutTransferIfIdle();
584 constexpr uint16_t OPENOCD_SAFE_PS =
static_cast<uint16_t
>((255u * 5u) + 4u);
585 constexpr uint16_t RAW_PS =
586 (MaxDapPacketSize == 0u) ? DefaultDapPacketSize : MaxDapPacketSize;
587 return (RAW_PS > OPENOCD_SAFE_PS) ? OPENOCD_SAFE_PS : RAW_PS;
589 bool CanBuildResponseDirectlyInEpBuffer()
const
596 if (!tx_buff.addr_ || tx_buff.size_ == 0u)
603 bool StartInTransferFromCurrentBuffer(uint16_t len)
610 if (!tx_buff.addr_ || tx_buff.size_ == 0u)
614 uint16_t tx_len = len;
615 if (tx_len > tx_buff.size_)
617 tx_len =
static_cast<uint16_t
>(tx_buff.size_);
626 bool StartInTransferFromPayload(
const uint8_t* data, uint16_t len)
633 if (!tx_buff.addr_ || tx_buff.size_ == 0u)
637 uint16_t tx_len = len;
638 if (tx_len > MAX_DAP_PACKET_SIZE)
640 tx_len = MAX_DAP_PACKET_SIZE;
643 if (tx_len <= MAX_XFER && tx_len <=
static_cast<uint16_t
>(tx_buff.size_))
651 if (tx_len >
static_cast<uint16_t
>(
sizeof(in_tx_multi_storage_)))
653 tx_len =
static_cast<uint16_t
>(
sizeof(in_tx_multi_storage_));
655 if (tx_len > 0u && data != in_tx_multi_storage_)
659 in_tx_multi_buf_.
addr_ = in_tx_multi_storage_;
660 in_tx_multi_buf_.
size_ = tx_len;
675 if (len > RESP_SLOT_SIZE)
677 len = RESP_SLOT_SIZE;
686 static constexpr uint8_t NextRespQueueIndex(uint8_t idx)
688 return static_cast<uint8_t
>((idx + 1u) & (RESP_QUEUE_DEPTH - 1u));
691 void ResetResponseQueue()
696 deferred_in_resp_valid_ =
false;
697 deferred_in_resp_len_ = 0u;
700 bool HasDeferredResponseInEpBuffer()
const {
return deferred_in_resp_valid_; }
702 void SetDeferredResponseInEpBuffer(uint16_t len)
704 deferred_in_resp_len_ = len;
705 deferred_in_resp_valid_ =
true;
708 bool SubmitDeferredResponseIfIdle()
716 const uint16_t TX_LEN = deferred_in_resp_len_;
717 if (!StartInTransferFromCurrentBuffer(TX_LEN))
722 deferred_in_resp_valid_ =
false;
723 deferred_in_resp_len_ = 0u;
727 bool IsResponseQueueEmpty()
const {
return resp_q_count_ == 0u; }
729 bool IsResponseQueueFull()
const {
return resp_q_count_ >= RESP_QUEUE_DEPTH; }
731 void ResetQueuedCommandState()
733 queued_request_length_ = 0u;
734 queued_command_count_ = 0u;
750 uint16_t& cmd_len)
const
753 if (!req || avail < 1u)
758 const uint8_t CMD = req[0];
761 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::INFO):
763 return avail >= cmd_len;
764 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::HOST_STATUS):
766 return avail >= cmd_len;
767 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::CONNECT):
769 return avail >= cmd_len;
770 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::DISCONNECT):
772 return avail >= cmd_len;
773 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_CONFIGURE):
775 return avail >= cmd_len;
776 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_ABORT):
778 return avail >= cmd_len;
779 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::WRITE_ABORT):
781 return avail >= cmd_len;
782 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::DELAY):
784 return avail >= cmd_len;
785 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::RESET_TARGET):
787 return avail >= cmd_len;
788 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_PINS):
790 return avail >= cmd_len;
791 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_CLOCK):
793 return avail >= cmd_len;
794 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_CONFIGURE):
796 return avail >= cmd_len;
797 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_SEQUENCE):
803 const uint32_t BIT_COUNT = (req[1] == 0u) ? 256u :
static_cast<uint32_t
>(req[1]);
804 const uint32_t BYTE_COUNT = (BIT_COUNT + 7u) / 8u;
805 const uint32_t NEED = 2u + BYTE_COUNT;
810 cmd_len =
static_cast<uint16_t
>(NEED);
813 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_SEQUENCE):
819 const uint8_t SEQ_CNT = req[1];
821 for (uint32_t i = 0u; i < SEQ_CNT; ++i)
828 const uint8_t INFO = req[off++];
829 uint32_t cycles =
static_cast<uint32_t
>(INFO & 0x3Fu);
835 const bool MODE_IN = ((INFO & 0x80u) != 0u);
836 const uint32_t BYTES = (cycles + 7u) / 8u;
839 if (off + BYTES > avail)
846 cmd_len =
static_cast<uint16_t
>(off);
849 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER):
855 const uint8_t COUNT = req[2];
857 for (uint32_t i = 0u; i < COUNT; ++i)
864 const uint8_t RQ = req[off++];
866 const bool MATCH_VALUE =
867 ((RQ & LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_VALUE) != 0u);
868 if (!RNW || MATCH_VALUE)
870 if (off + 4u > avail)
877 cmd_len =
static_cast<uint16_t
>(off);
880 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_BLOCK):
892 need +=
static_cast<uint32_t
>(count) * 4u;
898 cmd_len =
static_cast<uint16_t
>(need);
903 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS):
904 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::EXECUTE_COMMANDS):
923 if (!resp || resp_cap < 1u)
928 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::EXECUTE_COMMANDS);
931 if (queued_command_count_ == 0u)
936 uint16_t req_off = 0u;
937 uint16_t resp_off = 1u;
938 for (uint32_t i = 0u; i < queued_command_count_; ++i)
940 if (req_off >= queued_request_length_)
945 uint16_t cmd_len = 0u;
947 &queued_request_buffer_[req_off],
948 static_cast<uint16_t
>(queued_request_length_ - req_off), cmd_len) ||
954 if (resp_off >= resp_cap)
959 uint16_t cmd_out = 0u;
961 in_isr, &queued_request_buffer_[req_off], cmd_len, &resp[resp_off],
962 static_cast<uint16_t
>(resp_cap - resp_off), cmd_out);
965 if (
static_cast<uint32_t
>(resp_off) +
static_cast<uint32_t
>(cmd_out) >
966 static_cast<uint32_t
>(resp_cap))
971 req_off =
static_cast<uint16_t
>(req_off + cmd_len);
972 resp_off =
static_cast<uint16_t
>(resp_off + cmd_out);
975 if (req_off != queued_request_length_)
984 bool TryBuildAndEnqueueResponse(
bool in_isr,
const uint8_t* req, uint16_t req_len)
986 if (!req || IsResponseQueueFull())
991 auto& slot = resp_q_[resp_q_tail_];
992 uint16_t out_len = 0u;
998 resp_q_tail_ = NextRespQueueIndex(resp_q_tail_);
1003 uint8_t OutstandingResponseCount()
const
1005 const uint8_t IN_FLIGHT =
1007 const uint8_t DEFERRED = deferred_in_resp_valid_ ? 1u : 0u;
1008 return static_cast<uint8_t
>(resp_q_count_ + IN_FLIGHT + DEFERRED);
1011 bool EnqueueResponse(
const uint8_t* data, uint16_t len)
1013 if (!data || IsResponseQueueFull())
1018 auto& slot = resp_q_[resp_q_tail_];
1026 resp_q_tail_ = NextRespQueueIndex(resp_q_tail_);
1031 bool SubmitNextQueuedResponseIfIdle()
1034 IsResponseQueueEmpty())
1038 auto& slot = resp_q_[resp_q_head_];
1039 if (!StartInTransferFromPayload(slot.payload, slot.len))
1043 resp_q_head_ = NextRespQueueIndex(resp_q_head_);
1048 void ArmOutTransferIfIdle()
1062 if (OutstandingResponseCount() >= MAX_OUTSTANDING_RESPONSES)
1068 if (out_rx_len == 0u)
1070 out_rx_len = DEFAULT_DAP_PACKET_SIZE;
1072 if (out_rx_len > MAX_DAP_PACKET_SIZE)
1074 out_rx_len = MAX_DAP_PACKET_SIZE;
1078 if (OUT_MAX_XFER == 0u)
1083 if (out_rx_len <= OUT_MAX_XFER)
1089 if (out_rx_len >
static_cast<uint16_t
>(
sizeof(out_req_multi_storage_)))
1091 out_rx_len =
static_cast<uint16_t
>(
sizeof(out_req_multi_storage_));
1096 out_req_multi_buf_.
addr_ = out_req_multi_storage_;
1097 out_req_multi_buf_.
size_ = out_rx_len;
1118 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1122 if (!req || !resp || req_len < 1u || resp_cap < 1u)
1124 if (resp && resp_cap >= 1u)
1131 const uint8_t CMD = req[0];
1135 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::INFO):
1136 return HandleInfo(in_isr, req, req_len, resp, resp_cap, out_len);
1137 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::HOST_STATUS):
1138 return HandleHostStatus(in_isr, req, req_len, resp, resp_cap, out_len);
1139 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::CONNECT):
1140 return HandleConnect(in_isr, req, req_len, resp, resp_cap, out_len);
1141 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::DISCONNECT):
1142 return HandleDisconnect(in_isr, req, req_len, resp, resp_cap, out_len);
1143 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_CONFIGURE):
1144 return HandleTransferConfigure(in_isr, req, req_len, resp, resp_cap, out_len);
1145 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER):
1146 return HandleTransfer(in_isr, req, req_len, resp, resp_cap, out_len);
1147 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_BLOCK):
1148 return HandleTransferBlock(in_isr, req, req_len, resp, resp_cap, out_len);
1149 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_ABORT):
1150 return HandleTransferAbort(in_isr, req, req_len, resp, resp_cap, out_len);
1151 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::WRITE_ABORT):
1152 return HandleWriteABORT(in_isr, req, req_len, resp, resp_cap, out_len);
1153 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::DELAY):
1154 return HandleDelay(in_isr, req, req_len, resp, resp_cap, out_len);
1155 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::RESET_TARGET):
1156 return HandleResetTarget(in_isr, req, req_len, resp, resp_cap, out_len);
1158 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_PINS):
1159 return HandleSWJPins(in_isr, req, req_len, resp, resp_cap, out_len);
1160 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_CLOCK):
1161 return HandleSWJClock(in_isr, req, req_len, resp, resp_cap, out_len);
1162 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_SEQUENCE):
1163 return HandleSWJSequence(in_isr, req, req_len, resp, resp_cap, out_len);
1164 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_CONFIGURE):
1165 return HandleSWDConfigure(in_isr, req, req_len, resp, resp_cap, out_len);
1166 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_SEQUENCE):
1167 return HandleSWDSequence(in_isr, req, req_len, resp, resp_cap, out_len);
1169 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS):
1171 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::EXECUTE_COMMANDS):
1175 (void)BuildUnknownCmdResponse(resp, resp_cap, out_len);
1189 if (!resp || resp_cap < 1u)
1203 ErrorCode HandleInfo(
bool ,
const uint8_t* req, uint16_t req_len,
1204 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1208 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::INFO);
1214 const uint8_t INFO_ID = req[1];
1216 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::INFO);
1220 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::VENDOR):
1221 return BuildInfoStringResponse(resp[0],
info_.vendor, resp, resp_cap, out_len);
1222 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::PRODUCT):
1223 return BuildInfoStringResponse(resp[0],
info_.product, resp, resp_cap, out_len);
1224 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::SERIAL_NUMBER):
1225 return BuildInfoStringResponse(resp[0],
info_.serial, resp, resp_cap, out_len);
1226 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::FIRMWARE_VERSION):
1227 return BuildInfoStringResponse(resp[0],
info_.firmware_ver, resp, resp_cap,
1230 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::DEVICE_VENDOR):
1231 return BuildInfoStringResponse(resp[0],
info_.device_vendor, resp, resp_cap,
1233 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::DEVICE_NAME):
1234 return BuildInfoStringResponse(resp[0],
info_.device_name, resp, resp_cap,
1236 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::BOARD_VENDOR):
1237 return BuildInfoStringResponse(resp[0],
info_.board_vendor, resp, resp_cap,
1239 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::BOARD_NAME):
1240 return BuildInfoStringResponse(resp[0],
info_.board_name, resp, resp_cap,
1242 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::PRODUCT_FIRMWARE_VERSION):
1243 return BuildInfoStringResponse(resp[0],
info_.product_fw_ver, resp, resp_cap,
1246 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::CAPABILITIES):
1247 return BuildInfoU8Response(resp[0],
LibXR::USB::DapLinkV2Def::DAP_CAP_SWD, resp,
1249 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::PACKET_COUNT):
1250 return BuildInfoU8Response(resp[0], PACKET_COUNT_EFFECTIVE, resp, resp_cap,
1252 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::PACKET_SIZE):
1255 return BuildInfoU16Response(resp[0], DAP_PS, resp, resp_cap, out_len);
1257 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::TIMESTAMP_CLOCK):
1258 return BuildInfoU32Response(resp[0], 1000000U, resp, resp_cap, out_len);
1267 ErrorCode BuildInfoStringResponse(uint8_t cmd,
const char* str, uint8_t* resp,
1268 uint16_t resp_cap, uint16_t& out_len)
1279 const size_t N_WITH_NUL = std::strlen(str) + 1;
1280 const size_t MAX_PAYLOAD = (resp_cap >= 2u) ? (resp_cap - 2u) : 0u;
1281 if (MAX_PAYLOAD == 0u)
1287 const size_t COPY_N = (N_WITH_NUL > MAX_PAYLOAD) ? MAX_PAYLOAD : N_WITH_NUL;
1291 resp[2 + COPY_N - 1] = 0x00;
1293 resp[1] =
static_cast<uint8_t
>(COPY_N);
1294 out_len =
static_cast<uint16_t
>(2u + COPY_N);
1298 ErrorCode BuildInfoU8Response(uint8_t cmd, uint8_t val, uint8_t* resp,
1299 uint16_t resp_cap, uint16_t& out_len)
1313 ErrorCode BuildInfoU16Response(uint8_t cmd, uint16_t val, uint8_t* resp,
1314 uint16_t resp_cap, uint16_t& out_len)
1331 ErrorCode BuildInfoU32Response(uint8_t cmd, uint32_t val, uint8_t* resp,
1332 uint16_t resp_cap, uint16_t& out_len)
1354 ErrorCode HandleHostStatus(
bool ,
const uint8_t* ,
1355 uint16_t , uint8_t* resp, uint16_t resp_cap,
1363 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::HOST_STATUS);
1364 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1369 ErrorCode HandleConnect(
bool ,
const uint8_t* req, uint16_t req_len,
1370 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1378 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::CONNECT);
1387 if (port == 0u || port == ToU8(LibXR::USB::DapLinkV2Def::Port::SWD))
1389 (void)
swd_.EnterSwd();
1394 ResetQueuedCommandState();
1396 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Port::SWD);
1400 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Port::DISABLED);
1407 ErrorCode HandleDisconnect(
bool ,
const uint8_t* ,
1408 uint16_t , uint8_t* resp, uint16_t resp_cap,
1420 ResetQueuedCommandState();
1422 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::DISCONNECT);
1423 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1428 ErrorCode HandleTransferConfigure(
bool ,
const uint8_t* req, uint16_t req_len,
1429 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1437 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_CONFIGURE);
1442 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1447 const uint8_t IDLE = req[1];
1449 uint16_t wait_retry = 0u;
1450 uint16_t match_retry = 0u;
1459 Debug::Swd::TransferPolicy pol =
swd_.GetTransferPolicy();
1460 pol.idle_cycles = IDLE;
1461 pol.wait_retry = wait_retry;
1462 swd_.SetTransferPolicy(pol);
1464 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1469 ErrorCode HandleTransferAbort(
bool ,
const uint8_t* ,
1470 uint16_t , uint8_t* resp, uint16_t resp_cap,
1479 SetTransferAbortFlag(
true);
1481 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_ABORT);
1482 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1487 ErrorCode HandleWriteABORT(
bool ,
const uint8_t* req, uint16_t req_len,
1488 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1496 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::WRITE_ABORT);
1500 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1505 uint32_t flags = 0u;
1508 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
1511 resp[1] = (EC ==
ErrorCode::OK && ack == LibXR::Debug::SwdProtocol::Ack::OK)
1512 ? ToU8(LibXR::USB::DapLinkV2Def::Status::OK)
1513 : ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1519 ErrorCode HandleDelay(
bool ,
const uint8_t* req, uint16_t req_len,
1520 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1528 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::DELAY);
1532 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1542 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1547 ErrorCode HandleResetTarget(
bool in_isr,
const uint8_t* , uint16_t ,
1548 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1550 if (!resp || resp_cap < 3u)
1556 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::RESET_TARGET);
1558 uint8_t execute = 0u;
1563 DelayUsIfAllowed(in_isr, 1000u);
1565 DelayUsIfAllowed(in_isr, 1000u);
1581 ErrorCode HandleSWJPins(
bool ,
const uint8_t* req, uint16_t req_len,
1582 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1584 if (!resp || resp_cap < 2u)
1590 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_PINS);
1593 if (!req || req_len < 7u)
1600 const uint8_t PIN_OUT = req[1];
1601 const uint8_t PIN_SEL = req[2];
1603 uint32_t wait_us = 0u;
1608 (PIN_OUT & PIN_SEL));
1611 if ((PIN_SEL & LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET) != 0u)
1613 const bool LEVEL_HIGH =
1614 ((PIN_OUT & LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET) != 0u);
1617 DriveReset(LEVEL_HIGH);
1621 auto read_pins = [&]() -> uint8_t
1629 pin_in |= LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET;
1633 pin_in =
static_cast<uint8_t
>(
1634 pin_in &
static_cast<uint8_t
>(
~LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET));
1644 uint8_t pin_in = 0u;
1646 if (wait_us == 0u || PIN_SEL == 0u)
1648 pin_in = read_pins();
1653 const uint8_t EXPECT =
static_cast<uint8_t
>(PIN_OUT & PIN_SEL);
1657 pin_in = read_pins();
1658 if ((pin_in & PIN_SEL) == EXPECT)
1671 ErrorCode HandleSWJClock(
bool ,
const uint8_t* req, uint16_t req_len,
1672 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1680 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_CLOCK);
1684 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1693 (void)
swd_.SetClockHz(hz);
1695 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1700 ErrorCode HandleSWJSequence(
bool ,
const uint8_t* req, uint16_t req_len,
1701 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1703 if (!resp || resp_cap < 2u)
1709 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_SEQUENCE);
1710 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1714 if (!req || req_len < 2u)
1716 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1720 const uint8_t RAW_COUNT = req[1];
1721 const uint32_t BIT_COUNT =
1722 (RAW_COUNT == 0u) ? 256u : static_cast<uint32_t>(RAW_COUNT);
1723 const uint32_t BYTE_COUNT = (BIT_COUNT + 7u) / 8u;
1725 if (2u + BYTE_COUNT > req_len)
1727 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1731 const uint8_t* data = &req[2];
1737 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1744 swj_shadow_ &
static_cast<uint8_t
>(
~LibXR::USB::DapLinkV2Def::DAP_SWJ_SWCLK_TCK));
1746 bool last_swdio =
false;
1747 if (BIT_COUNT != 0u)
1749 const uint32_t LAST_I = BIT_COUNT - 1u;
1750 last_swdio = (((data[LAST_I / 8u] >> (LAST_I & 7u)) & 0x01u) != 0u);
1755 swj_shadow_ |= LibXR::USB::DapLinkV2Def::DAP_SWJ_SWDIO_TMS;
1761 static_cast<uint8_t
>(
~LibXR::USB::DapLinkV2Def::DAP_SWJ_SWDIO_TMS));
1767 ErrorCode HandleSWDConfigure(
bool ,
const uint8_t* req, uint16_t req_len,
1768 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1776 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_CONFIGURE);
1778 if (req ==
nullptr || req_len < 2u)
1780 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1785 const uint8_t cfg = req[1];
1789 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1794 ErrorCode HandleSWDSequence(
bool ,
const uint8_t* req, uint16_t req_len,
1795 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1797 if (!req || !resp || resp_cap < 2u)
1803 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_SEQUENCE);
1820 const uint8_t SEQ_CNT = req[1];
1821 uint16_t req_off = 2u;
1822 uint16_t resp_off = 2u;
1824 for (uint32_t s = 0; s < SEQ_CNT; ++s)
1826 if (req_off >= req_len)
1833 const uint8_t INFO = req[req_off++];
1835 uint32_t cycles =
static_cast<uint32_t
>(INFO & 0x3Fu);
1841 const bool MODE_IN = ((INFO & 0x80u) != 0u);
1842 const uint16_t BYTES =
static_cast<uint16_t
>((cycles + 7u) / 8u);
1847 if (req_off + BYTES > req_len)
1854 const uint8_t* data = &req[req_off];
1855 req_off =
static_cast<uint16_t
>(req_off + BYTES);
1869 if (resp_off + BYTES > resp_cap)
1878 const ErrorCode EC =
swd_.SeqReadBits(cycles, &resp[resp_off]);
1886 resp_off =
static_cast<uint16_t
>(resp_off + BYTES);
1898 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1900 if (!req || req_len < 2u)
1902 return BuildCmdStatusResponse(
1903 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_ERROR, resp,
1907 const uint8_t NUM = req[1];
1910 return BuildCmdStatusResponse(
1911 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_OK, resp,
1915 uint16_t req_off = 2u;
1916 for (uint32_t i = 0u; i < NUM; ++i)
1918 if (req_off >= req_len)
1920 return BuildCmdStatusResponse(
1921 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_ERROR, resp,
1925 uint16_t cmd_len = 0u;
1927 static_cast<uint16_t
>(req_len - req_off), cmd_len) ||
1930 return BuildCmdStatusResponse(
1931 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_ERROR, resp,
1934 req_off =
static_cast<uint16_t
>(req_off + cmd_len);
1937 if (req_off != req_len)
1939 return BuildCmdStatusResponse(
1940 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_ERROR, resp,
1944 if (
static_cast<uint32_t
>(queued_request_length_) +
1945 static_cast<uint32_t
>(req_len - 2u) >
1946 static_cast<uint32_t
>(QUEUED_REQ_BUFFER_SIZE) ||
1947 static_cast<uint32_t
>(queued_command_count_) +
static_cast<uint32_t
>(NUM) >
1948 static_cast<uint32_t
>(QUEUED_CMD_COUNT_MAX))
1950 return BuildCmdStatusResponse(
1951 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_ERROR, resp,
1957 queued_request_length_ =
1958 static_cast<uint16_t
>(queued_request_length_ + (req_len - 2u));
1959 queued_command_count_ =
static_cast<uint16_t
>(queued_command_count_ + NUM);
1961 return BuildCmdStatusResponse(
1962 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_OK, resp, resp_cap,
1970 uint16_t , uint8_t* resp, uint16_t resp_cap,
1974 ResetQueuedCommandState();
1978 return BuildCmdStatusResponse(
1979 ToU8(LibXR::USB::DapLinkV2Def::CommandId::EXECUTE_COMMANDS),
DAP_ERROR, resp,
1991 uint8_t MapAckToDapResp(LibXR::Debug::SwdProtocol::Ack ack)
const
1993 static constexpr uint8_t ACK_MAP[8] = {7u, 1u, 2u, 7u, 4u, 7u, 7u, 7u};
1994 return ACK_MAP[
static_cast<uint8_t
>(ack) & 0x07u];
1997 static inline uint16_t LoadU16Le(
const uint8_t* p)
1999 return static_cast<uint16_t
>(
2000 static_cast<uint16_t
>(p[0]) |
2001 static_cast<uint16_t
>(
static_cast<uint16_t
>(p[1]) << 8u));
2004 static inline void StoreU16Le(uint8_t* p, uint16_t v)
2006 p[0] =
static_cast<uint8_t
>(v & 0xFFu);
2007 p[1] =
static_cast<uint8_t
>((v >> 8u) & 0xFFu);
2010 static inline uint32_t LoadU32Le(
const uint8_t* p)
2012 return static_cast<uint32_t
>(
2013 static_cast<uint32_t
>(p[0]) | (
static_cast<uint32_t
>(p[1]) << 8u) |
2014 (
static_cast<uint32_t
>(p[2]) << 16u) | (
static_cast<uint32_t
>(p[3]) << 24u));
2017 static inline void StoreU32Le(uint8_t* p, uint32_t v)
2019 p[0] =
static_cast<uint8_t
>(v & 0xFFu);
2020 p[1] =
static_cast<uint8_t
>((v >> 8u) & 0xFFu);
2021 p[2] =
static_cast<uint8_t
>((v >> 16u) & 0xFFu);
2022 p[3] =
static_cast<uint8_t
>((v >> 24u) & 0xFFu);
2034 if (resp.
ack == LibXR::Debug::SwdProtocol::Ack::WAIT)
2036 return swd_.TransferWithRetry(req, resp);
2039 if (resp.
ack == LibXR::Debug::SwdProtocol::Ack::FAULT)
2041 const auto POL =
swd_.GetTransferPolicy();
2042 if (POL.clear_sticky_on_fault)
2044 LibXR::Debug::SwdProtocol::Ack abort_ack =
2045 LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2046 (void)
swd_.WriteAbort(LibXR::Debug::SwdProtocol::DP_ABORT_STKCMPCLR |
2047 LibXR::Debug::SwdProtocol::DP_ABORT_STKERRCLR |
2048 LibXR::Debug::SwdProtocol::DP_ABORT_WDERRCLR |
2049 LibXR::Debug::SwdProtocol::DP_ABORT_ORUNERRCLR,
2057 ErrorCode DpReadRdbuffFast(uint32_t& val, LibXR::Debug::SwdProtocol::Ack& ack_out)
2060 const auto req = LibXR::Debug::SwdProtocol::make_dp_read_req(
2061 LibXR::Debug::SwdProtocol::DpReadReg::RDBUFF);
2062 const ErrorCode ec = TransferTxnFast(req, swd_resp);
2063 ack_out = swd_resp.
ack;
2068 if (swd_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK || !swd_resp.
parity_ok)
2072 val = swd_resp.
rdata;
2076 ErrorCode ApReadPostedFast(uint8_t addr2b, uint32_t& posted,
2077 LibXR::Debug::SwdProtocol::Ack& ack_out)
2080 const auto req = LibXR::Debug::SwdProtocol::make_ap_read_req(addr2b);
2081 const ErrorCode ec = TransferTxnFast(req, swd_resp);
2082 ack_out = swd_resp.
ack;
2087 if (swd_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK || !swd_resp.
parity_ok)
2091 posted = swd_resp.
rdata;
2106 ErrorCode HandleTransfer(
bool ,
const uint8_t* req, uint16_t req_len,
2107 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
2110 if (!req || !resp || resp_cap < 3u)
2115 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER);
2118 uint16_t resp_off = 3u;
2123 resp[2] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2131 resp[2] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2136 const uint8_t COUNT = req[2];
2137 uint16_t req_off = 3u;
2139 auto push_u32 = [&](uint32_t v) ->
bool
2141 if (resp_off + 4u > resp_cap)
2146 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
2150 auto push_timestamp = [&]() ->
bool
2156 auto ensure_space = [&](uint16_t bytes) ->
bool
2157 {
return (resp_off + bytes) <= resp_cap; };
2159 auto bytes_for_read = [&](
bool need_ts) -> uint16_t
2160 {
return static_cast<uint16_t
>(need_ts ? 8u : 4u); };
2162 uint8_t response_count = 0u;
2164 uint8_t response_value = 0u;
2167 bool check_write =
false;
2170 struct PendingApRead
2173 bool need_ts =
false;
2176 auto emit_read_with_ts = [&](
bool need_ts, uint32_t data) ->
bool
2180 if (!push_timestamp())
2185 if (!push_u32(data))
2195 auto complete_pending_by_rdbuff = [&]() ->
bool
2202 if (!ensure_space(bytes_for_read(pending.need_ts)))
2204 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2208 uint32_t rdata = 0u;
2209 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2210 const ErrorCode EC = DpReadRdbuffFast(rdata, ack);
2212 const uint8_t V = MapAckToDapResp(ack);
2213 if (V != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2220 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2224 if (!emit_read_with_ts(pending.need_ts, rdata))
2226 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2230 pending.valid =
false;
2231 pending.need_ts =
false;
2234 check_write =
false;
2237 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2243 auto flush_pending_if_any = [&]() ->
bool
2244 {
return pending.valid ? complete_pending_by_rdbuff() : true; };
2247 for (uint32_t i = 0; i < COUNT; ++i)
2249 if (req_off >= req_len)
2251 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2255 const uint8_t RQ = req[req_off++];
2262 const bool MATCH_VALUE =
2263 ((RQ & LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_VALUE) != 0u);
2264 const bool MATCH_MASK =
2265 ((RQ & LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_MASK) != 0u);
2268 if (TS && (MATCH_VALUE || MATCH_MASK))
2270 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2274 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2282 if (!flush_pending_if_any())
2287 if (req_off + 4u > req_len)
2289 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2293 uint32_t wdata = LoadU32Le(&req[req_off]);
2294 req_off =
static_cast<uint16_t
>(req_off + 4u);
2299 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2305 ec =
swd_.ApWriteTxn(ADDR2B, wdata, ack);
2309 ec =
swd_.DpWriteTxn(
static_cast<LibXR::Debug::SwdProtocol::DpWriteReg
>(ADDR2B),
2313 response_value = MapAckToDapResp(ack);
2314 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2320 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2326 if (!push_timestamp())
2328 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2345 if (!flush_pending_if_any())
2350 if (req_off + 4u > req_len)
2352 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2356 uint32_t match_val = LoadU32Le(&req[req_off]);
2357 req_off =
static_cast<uint16_t
>(req_off + 4u);
2359 uint32_t rdata = 0u;
2361 bool matched =
false;
2367 ec =
swd_.ApReadTxn(ADDR2B, rdata, ack);
2368 if (ec ==
ErrorCode::OK && ack == LibXR::Debug::SwdProtocol::Ack::OK)
2371 check_write =
false;
2376 ec =
swd_.DpReadTxn(
2377 static_cast<LibXR::Debug::SwdProtocol::DpReadReg
>(ADDR2B), rdata, ack);
2380 response_value = MapAckToDapResp(ack);
2381 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2387 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2404 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2412 static_cast<uint8_t
>(LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK |
2413 LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MISMATCH);
2418 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2427 if (!flush_pending_if_any())
2432 uint32_t rdata = 0u;
2433 ec =
swd_.DpReadTxn(
static_cast<LibXR::Debug::SwdProtocol::DpReadReg
>(ADDR2B),
2436 response_value = MapAckToDapResp(ack);
2437 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2443 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2447 if (!ensure_space(bytes_for_read(TS)))
2449 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2453 if (!emit_read_with_ts(TS, rdata))
2455 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2459 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2468 uint32_t dummy_posted = 0u;
2469 ec = ApReadPostedFast(ADDR2B, dummy_posted, ack);
2471 response_value = MapAckToDapResp(ack);
2472 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2478 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2484 pending.valid =
true;
2485 pending.need_ts = TS;
2489 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2495 if (!ensure_space(bytes_for_read(pending.need_ts)))
2497 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2501 uint32_t posted_prev = 0u;
2502 ec = ApReadPostedFast(ADDR2B, posted_prev, ack);
2504 const uint8_t CUR_V = MapAckToDapResp(ack);
2505 if (CUR_V != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK || ec !=
ErrorCode::OK)
2509 const uint8_t PROOR_FAIL =
2510 (CUR_V != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2512 :
LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2514 if (!complete_pending_by_rdbuff())
2522 response_value = PROOR_FAIL;
2528 if (!emit_read_with_ts(pending.need_ts, posted_prev))
2530 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2534 pending.valid =
true;
2535 pending.need_ts = TS;
2537 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2554 const uint8_t PRIOR_FAIL = response_value;
2556 if (!complete_pending_by_rdbuff())
2564 if (PRIOR_FAIL != 0u && PRIOR_FAIL != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2566 response_value = PRIOR_FAIL;
2573 if (response_value == LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK && check_write)
2575 uint32_t dummy = 0u;
2576 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2577 const ErrorCode EC = DpReadRdbuffFast(dummy, ack);
2578 const uint8_t V = MapAckToDapResp(ack);
2580 if (V != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2586 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2590 resp[1] = response_count;
2591 resp[2] = response_value;
2595 ErrorCode HandleTransferBlock(
bool ,
const uint8_t* req, uint16_t req_len,
2596 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
2600 if (!resp || resp_cap < 4u)
2606 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_BLOCK);
2612 if (!req || req_len < 5u)
2614 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2621 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2625 uint16_t count = 0u;
2626 count = LoadU16Le(&req[2]);
2628 const uint8_t DAP_RQ = req[4];
2631 if ((DAP_RQ & (LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_VALUE |
2632 LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_MASK)) != 0u)
2634 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2639 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2646 const uint16_t DONE0 = 0u;
2647 StoreU16Le(&resp[1], DONE0);
2648 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2660 uint16_t req_off = 5u;
2661 uint16_t resp_off = 4u;
2666 const uint32_t REQ_NEED =
2667 static_cast<uint32_t
>(req_off) + (
static_cast<uint32_t
>(count) * 4u);
2668 if (REQ_NEED > req_len)
2670 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2671 StoreU16Le(&resp[1], done);
2678 auto swd_req = LibXR::Debug::SwdProtocol::make_ap_write_req(ADDR2B, 0u);
2680 for (uint32_t i = 0; i < count; ++i)
2682 uint32_t wdata = LoadU32Le(&req[req_off]);
2683 req_off =
static_cast<uint16_t
>(req_off + 4u);
2684 swd_req.wdata = wdata;
2685 const ErrorCode ec = TransferTxnFast(swd_req, swd_resp);
2686 xresp = MapAckToDapResp(swd_resp.
ack);
2687 if (swd_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK)
2693 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2696 done =
static_cast<uint16_t
>(i + 1u);
2701 for (uint32_t i = 0; i < count; ++i)
2703 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2705 uint32_t wdata = LoadU32Le(&req[req_off]);
2706 req_off =
static_cast<uint16_t
>(req_off + 4u);
2707 ec =
swd_.DpWriteTxn(
static_cast<LibXR::Debug::SwdProtocol::DpWriteReg
>(ADDR2B),
2709 xresp = MapAckToDapResp(ack);
2710 if (ack != LibXR::Debug::SwdProtocol::Ack::OK)
2716 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2719 done =
static_cast<uint16_t
>(i + 1u);
2722 StoreU16Le(&resp[1], done);
2731 const uint32_t RESP_NEED =
2732 static_cast<uint32_t
>(resp_off) + (
static_cast<uint32_t
>(count) * 4u);
2733 if (RESP_NEED > resp_cap)
2735 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2736 StoreU16Le(&resp[1], done);
2743 for (uint32_t i = 0; i < count; ++i)
2745 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2747 uint32_t rdata = 0u;
2748 ec =
swd_.DpReadTxn(
static_cast<LibXR::Debug::SwdProtocol::DpReadReg
>(ADDR2B),
2750 xresp = MapAckToDapResp(ack);
2751 if (ack != LibXR::Debug::SwdProtocol::Ack::OK)
2757 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2760 StoreU32Le(&resp[resp_off], rdata);
2761 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
2762 done =
static_cast<uint16_t
>(i + 1u);
2764 StoreU16Le(&resp[1], done);
2772 const uint32_t RESP_NEED =
2773 static_cast<uint32_t
>(resp_off) + (
static_cast<uint32_t
>(count) * 4u);
2774 if (RESP_NEED > resp_cap)
2776 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2777 StoreU16Le(&resp[1], done);
2783 auto ap_read_req = LibXR::Debug::SwdProtocol::make_ap_read_req(ADDR2B);
2784 const auto rdbuff_req = LibXR::Debug::SwdProtocol::make_dp_read_req(
2785 LibXR::Debug::SwdProtocol::DpReadReg::RDBUFF);
2787 ErrorCode ec = TransferTxnFast(ap_read_req, ap_read_resp);
2788 xresp = MapAckToDapResp(ap_read_resp.
ack);
2789 if (ap_read_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK)
2795 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2800 for (uint32_t i = 1; i < count; ++i)
2802 ec = TransferTxnFast(ap_read_req, ap_read_resp);
2803 const uint8_t CUR = MapAckToDapResp(ap_read_resp.
ack);
2805 if (ap_read_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK ||
2809 if (resp_off + 4u <= resp_cap)
2812 const ErrorCode EC2 = TransferTxnFast(rdbuff_req, rdbuff_resp);
2813 const uint8_t V2 = MapAckToDapResp(rdbuff_resp.
ack);
2817 StoreU32Le(&resp[resp_off], rdbuff_resp.
rdata);
2818 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
2819 done =
static_cast<uint16_t
>(i);
2826 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2835 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2840 StoreU32Le(&resp[resp_off], ap_read_resp.
rdata);
2841 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
2842 done =
static_cast<uint16_t
>(i);
2849 const ErrorCode EC2 = TransferTxnFast(rdbuff_req, rdbuff_resp);
2850 const uint8_t V2 = MapAckToDapResp(rdbuff_resp.
ack);
2859 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2863 StoreU32Le(&resp[resp_off], rdbuff_resp.
rdata);
2864 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
2869 StoreU16Le(&resp[1], done);
2881 void DriveReset(
bool release)
2888 swj_shadow_ |= LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET;
2902 void DelayUsIfAllowed(
bool , uint32_t us)
2908 static constexpr uint16_t DEFAULT_DAP_PACKET_SIZE = DefaultDapPacketSize;
2909 static constexpr uint8_t PACKET_COUNT_ADVERTISED = AdvertisedPacketCount;
2910 static constexpr uint8_t PACKET_COUNT_EFFECTIVE =
2911 (PACKET_COUNT_ADVERTISED > 4u) ? 4u : PACKET_COUNT_ADVERTISED;
2912 static constexpr uint8_t MAX_OUTSTANDING_RESPONSES = PACKET_COUNT_EFFECTIVE;
2916 static constexpr uint16_t OPENOCD_SAFE_DAP_PACKET_SIZE =
2917 static_cast<uint16_t
>((255u * 5u) + 4u);
2920 static constexpr uint16_t MAX_DAP_PACKET_SIZE = MaxDapPacketSize;
2921 static constexpr uint16_t QUEUED_REQ_BUFFER_SIZE = QueuedRequestBufferSize;
2922 static constexpr uint16_t QUEUED_CMD_COUNT_MAX = QueuedCommandCountMax;
2923 static constexpr uint16_t RESP_SLOT_SIZE = MAX_DAP_PACKET_SIZE;
2924 static constexpr uint8_t RESP_QUEUE_DEPTH = PACKET_COUNT_EFFECTIVE;
2925 static constexpr uint16_t QUEUED_REQ_BUFFER_ALLOC_SIZE = QUEUED_REQ_BUFFER_SIZE;
2926 static_assert(PACKET_COUNT_ADVERTISED > 0u,
"PACKET_COUNT_ADVERTISED must be > 0");
2927 static_assert(PACKET_COUNT_EFFECTIVE > 0u,
"PACKET_COUNT_EFFECTIVE must be > 0");
2928 static_assert(MAX_DAP_PACKET_SIZE >= DEFAULT_DAP_PACKET_SIZE,
2929 "MAX_DAP_PACKET_SIZE must be >= DEFAULT_DAP_PACKET_SIZE");
2930 static_assert(MAX_DAP_PACKET_SIZE <= OPENOCD_SAFE_DAP_PACKET_SIZE,
2931 "MAX_DAP_PACKET_SIZE exceeds OpenOCD-safe limit");
2932 static_assert(((OPENOCD_SAFE_DAP_PACKET_SIZE - 4u) / 5u) <= 255u,
2933 "OPENOCD_SAFE_DAP_PACKET_SIZE too large for CMD_DAP_TFER u8 count");
2934 static_assert(QUEUED_REQ_BUFFER_SIZE > 0u,
"QUEUED_REQ_BUFFER_SIZE must be > 0");
2935 static_assert(QUEUED_CMD_COUNT_MAX > 0u,
"QUEUED_CMD_COUNT_MAX must be > 0");
2936 static_assert(RESP_SLOT_SIZE >= DEFAULT_DAP_PACKET_SIZE,
2937 "RESP_SLOT_SIZE must cover FS bulk packet size");
2938 static_assert((RESP_QUEUE_DEPTH & (RESP_QUEUE_DEPTH - 1u)) == 0u,
2939 "Response queue depth must be power-of-two");
2947 static_cast<uint16_t
>(LibXR::USB::WinUsbMsOs20::GUID_STR_UTF16_BYTES +
2953 uint8_t payload[RESP_SLOT_SIZE] = {};
2957 uint8_t resp_q_head_ = 0u;
2958 uint8_t resp_q_tail_ = 0u;
2959 uint8_t resp_q_count_ = 0u;
2960 bool deferred_in_resp_valid_ =
false;
2961 uint16_t deferred_in_resp_len_ = 0u;
2963 uint8_t queued_request_buffer_[QUEUED_REQ_BUFFER_ALLOC_SIZE] = {};
2964 uint16_t queued_request_length_ = 0u;
2965 uint16_t queued_command_count_ = 0u;
2967 uint8_t out_req_multi_storage_[MAX_DAP_PACKET_SIZE] = {};
2968 LibXR::RawData out_req_multi_buf_{out_req_multi_storage_, DEFAULT_DAP_PACKET_SIZE};
2969 uint8_t in_tx_multi_storage_[MAX_DAP_PACKET_SIZE] = {};
2970 LibXR::RawData in_tx_multi_buf_{in_tx_multi_storage_, DEFAULT_DAP_PACKET_SIZE};
2993 uint8_t
name[LibXR::USB::WinUsbMsOs20::
2994 PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES];
3009 DapLinkV2Def::DAP_SWJ_SWDIO_TMS |
3010 DapLinkV2Def::DAP_SWJ_NRESET);
3016 "XRDAP",
"XRobot",
"DAP_DEMO",
"0.1.0"};