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 static constexpr uint8_t kConfigurationValue = 1u;
375 winusb_msos20_.
set.wLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_.
set));
376 winusb_msos20_.
set.wDescriptorType =
377 LibXR::USB::WinUsbMsOs20::MS_OS_20_SET_HEADER_DESCRIPTOR;
378 winusb_msos20_.
set.dwWindowsVersion = 0x06030000;
379 winusb_msos20_.
set.wTotalLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_));
381 winusb_msos20_.
cfg.wLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_.
cfg));
382 winusb_msos20_.
cfg.wDescriptorType =
383 LibXR::USB::WinUsbMsOs20::MS_OS_20_SUBSET_HEADER_CONFIGURATION;
385 winusb_msos20_.
cfg.bConfigurationValue = kConfigurationValue;
386 winusb_msos20_.
cfg.bReserved = 0;
387 winusb_msos20_.
cfg.wTotalLength =
static_cast<uint16_t
>(
388 sizeof(winusb_msos20_) - offsetof(WinUsbMsOs20DescSet, cfg));
390 winusb_msos20_.
func.wLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_.
func));
391 winusb_msos20_.
func.wDescriptorType =
392 LibXR::USB::WinUsbMsOs20::MS_OS_20_SUBSET_HEADER_FUNCTION;
393 winusb_msos20_.
func.bReserved = 0;
394 winusb_msos20_.
func.wTotalLength =
static_cast<uint16_t
>(
395 sizeof(winusb_msos20_) - offsetof(WinUsbMsOs20DescSet, func));
397 winusb_msos20_.
compat.wLength =
static_cast<uint16_t
>(
sizeof(winusb_msos20_.
compat));
398 winusb_msos20_.
compat.wDescriptorType =
399 LibXR::USB::WinUsbMsOs20::MS_OS_20_FEATURE_COMPATIBLE_ID;
401 winusb_msos20_.prop.
header.wDescriptorType =
402 LibXR::USB::WinUsbMsOs20::MS_OS_20_FEATURE_REG_PROPERTY;
403 winusb_msos20_.prop.
header.wPropertyDataType = LibXR::USB::WinUsbMsOs20::REG_MULTI_SZ;
404 winusb_msos20_.prop.
header.wPropertyNameLength =
405 LibXR::USB::WinUsbMsOs20::PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES;
408 LibXR::USB::WinUsbMsOs20::PROP_NAME_DEVICE_INTERFACE_GUIDS_UTF16,
409 LibXR::USB::WinUsbMsOs20::PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES);
413 const char GUID_STR[] =
"{CDB3B5AD-293B-4663-AA36-1AAE46463776}";
414 const size_t GUID_LEN =
sizeof(GUID_STR) - 1;
416 for (
size_t i = 0; i < GUID_LEN; ++i)
418 winusb_msos20_.prop.
data[i * 2] =
static_cast<uint8_t
>(GUID_STR[i]);
419 winusb_msos20_.prop.
data[i * 2 + 1] = 0x00;
423 winusb_msos20_.prop.
data[GUID_LEN * 2 + 0] = 0x00;
424 winusb_msos20_.prop.
data[GUID_LEN * 2 + 1] = 0x00;
425 winusb_msos20_.prop.
data[GUID_LEN * 2 + 2] = 0x00;
426 winusb_msos20_.prop.
data[GUID_LEN * 2 + 3] = 0x00;
429 winusb_msos20_.prop.
header.wLength =
430 static_cast<uint16_t
>(
sizeof(winusb_msos20_.prop));
437 void UpdateWinUsbInterfaceFields()
490 ArmOutTransferIfIdle();
492 const auto* req =
static_cast<const uint8_t*
>(data.
addr_);
493 const uint16_t REQ_LEN =
static_cast<uint16_t
>(data.
size_);
498 if (!HasDeferredResponseInEpBuffer() && IsResponseQueueEmpty() &&
500 CanBuildResponseDirectlyInEpBuffer())
503 if (tx_buff.addr_ && tx_buff.size_ > 0u)
505 auto* tx_buf =
static_cast<uint8_t*
>(tx_buff.addr_);
506 uint16_t out_len = 0u;
508 static_cast<uint16_t
>(tx_buff.size_), out_len);
512 if (StartInTransferFromCurrentBuffer(out_len))
517 if (!EnqueueResponse(tx_buf, out_len))
519 (void)SubmitNextQueuedResponseIfIdle();
520 (void)EnqueueResponse(tx_buf, out_len);
523 (void)SubmitNextQueuedResponseIfIdle();
524 ArmOutTransferIfIdle();
531 if (!HasDeferredResponseInEpBuffer() && IsResponseQueueEmpty() &&
533 CanBuildResponseDirectlyInEpBuffer())
536 if (tx_buff.addr_ && tx_buff.size_ > 0u)
538 auto* tx_buf =
static_cast<uint8_t*
>(tx_buff.addr_);
539 uint16_t out_len = 0u;
541 static_cast<uint16_t
>(tx_buff.size_), out_len);
545 SetDeferredResponseInEpBuffer(out_len);
546 ArmOutTransferIfIdle();
551 if (TryBuildAndEnqueueResponse(in_isr, req, REQ_LEN))
553 (void)SubmitDeferredResponseIfIdle();
554 (void)SubmitNextQueuedResponseIfIdle();
555 ArmOutTransferIfIdle();
561 (void)SubmitNextQueuedResponseIfIdle();
562 (void)TryBuildAndEnqueueResponse(in_isr, req, REQ_LEN);
564 (void)SubmitDeferredResponseIfIdle();
565 (void)SubmitNextQueuedResponseIfIdle();
566 ArmOutTransferIfIdle();
574 (void)SubmitDeferredResponseIfIdle();
575 (void)SubmitNextQueuedResponseIfIdle();
576 ArmOutTransferIfIdle();
585 constexpr uint16_t OPENOCD_SAFE_PS =
static_cast<uint16_t
>((255u * 5u) + 4u);
586 constexpr uint16_t RAW_PS =
587 (MaxDapPacketSize == 0u) ? DefaultDapPacketSize : MaxDapPacketSize;
588 return (RAW_PS > OPENOCD_SAFE_PS) ? OPENOCD_SAFE_PS : RAW_PS;
590 bool CanBuildResponseDirectlyInEpBuffer()
const
597 if (!tx_buff.addr_ || tx_buff.size_ == 0u)
604 bool StartInTransferFromCurrentBuffer(uint16_t len)
611 if (!tx_buff.addr_ || tx_buff.size_ == 0u)
615 uint16_t tx_len = len;
616 if (tx_len > tx_buff.size_)
618 tx_len =
static_cast<uint16_t
>(tx_buff.size_);
627 bool StartInTransferFromPayload(
const uint8_t* data, uint16_t len)
634 if (!tx_buff.addr_ || tx_buff.size_ == 0u)
638 uint16_t tx_len = len;
639 if (tx_len > MAX_DAP_PACKET_SIZE)
641 tx_len = MAX_DAP_PACKET_SIZE;
644 if (tx_len <= MAX_XFER && tx_len <=
static_cast<uint16_t
>(tx_buff.size_))
652 if (tx_len >
static_cast<uint16_t
>(
sizeof(in_tx_multi_storage_)))
654 tx_len =
static_cast<uint16_t
>(
sizeof(in_tx_multi_storage_));
656 if (tx_len > 0u && data != in_tx_multi_storage_)
660 in_tx_multi_buf_.
addr_ = in_tx_multi_storage_;
661 in_tx_multi_buf_.
size_ = tx_len;
676 if (len > RESP_SLOT_SIZE)
678 len = RESP_SLOT_SIZE;
687 static constexpr uint8_t NextRespQueueIndex(uint8_t idx)
689 return static_cast<uint8_t
>((idx + 1u) & (RESP_QUEUE_DEPTH - 1u));
692 void ResetResponseQueue()
697 deferred_in_resp_valid_ =
false;
698 deferred_in_resp_len_ = 0u;
701 bool HasDeferredResponseInEpBuffer()
const {
return deferred_in_resp_valid_; }
703 void SetDeferredResponseInEpBuffer(uint16_t len)
705 deferred_in_resp_len_ = len;
706 deferred_in_resp_valid_ =
true;
709 bool SubmitDeferredResponseIfIdle()
717 const uint16_t TX_LEN = deferred_in_resp_len_;
718 if (!StartInTransferFromCurrentBuffer(TX_LEN))
723 deferred_in_resp_valid_ =
false;
724 deferred_in_resp_len_ = 0u;
728 bool IsResponseQueueEmpty()
const {
return resp_q_count_ == 0u; }
730 bool IsResponseQueueFull()
const {
return resp_q_count_ >= RESP_QUEUE_DEPTH; }
732 void ResetQueuedCommandState()
734 queued_request_length_ = 0u;
735 queued_command_count_ = 0u;
751 uint16_t& cmd_len)
const
754 if (!req || avail < 1u)
759 const uint8_t CMD = req[0];
762 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::INFO):
764 return avail >= cmd_len;
765 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::HOST_STATUS):
767 return avail >= cmd_len;
768 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::CONNECT):
770 return avail >= cmd_len;
771 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::DISCONNECT):
773 return avail >= cmd_len;
774 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_CONFIGURE):
776 return avail >= cmd_len;
777 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_ABORT):
779 return avail >= cmd_len;
780 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::WRITE_ABORT):
782 return avail >= cmd_len;
783 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::DELAY):
785 return avail >= cmd_len;
786 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::RESET_TARGET):
788 return avail >= cmd_len;
789 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_PINS):
791 return avail >= cmd_len;
792 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_CLOCK):
794 return avail >= cmd_len;
795 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_CONFIGURE):
797 return avail >= cmd_len;
798 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_SEQUENCE):
804 const uint32_t BIT_COUNT = (req[1] == 0u) ? 256u :
static_cast<uint32_t
>(req[1]);
805 const uint32_t BYTE_COUNT = (BIT_COUNT + 7u) / 8u;
806 const uint32_t NEED = 2u + BYTE_COUNT;
811 cmd_len =
static_cast<uint16_t
>(NEED);
814 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_SEQUENCE):
820 const uint8_t SEQ_CNT = req[1];
822 for (uint32_t i = 0u; i < SEQ_CNT; ++i)
829 const uint8_t INFO = req[off++];
830 uint32_t cycles =
static_cast<uint32_t
>(INFO & 0x3Fu);
836 const bool MODE_IN = ((INFO & 0x80u) != 0u);
837 const uint32_t BYTES = (cycles + 7u) / 8u;
840 if (off + BYTES > avail)
847 cmd_len =
static_cast<uint16_t
>(off);
850 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER):
856 const uint8_t COUNT = req[2];
858 for (uint32_t i = 0u; i < COUNT; ++i)
865 const uint8_t RQ = req[off++];
867 const bool MATCH_VALUE =
868 ((RQ & LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_VALUE) != 0u);
869 if (!RNW || MATCH_VALUE)
871 if (off + 4u > avail)
878 cmd_len =
static_cast<uint16_t
>(off);
881 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_BLOCK):
893 need +=
static_cast<uint32_t
>(count) * 4u;
899 cmd_len =
static_cast<uint16_t
>(need);
904 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS):
905 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::EXECUTE_COMMANDS):
924 if (!resp || resp_cap < 1u)
929 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::EXECUTE_COMMANDS);
932 if (queued_command_count_ == 0u)
937 uint16_t req_off = 0u;
938 uint16_t resp_off = 1u;
939 for (uint32_t i = 0u; i < queued_command_count_; ++i)
941 if (req_off >= queued_request_length_)
946 uint16_t cmd_len = 0u;
948 &queued_request_buffer_[req_off],
949 static_cast<uint16_t
>(queued_request_length_ - req_off), cmd_len) ||
955 if (resp_off >= resp_cap)
960 uint16_t cmd_out = 0u;
962 in_isr, &queued_request_buffer_[req_off], cmd_len, &resp[resp_off],
963 static_cast<uint16_t
>(resp_cap - resp_off), cmd_out);
966 if (
static_cast<uint32_t
>(resp_off) +
static_cast<uint32_t
>(cmd_out) >
967 static_cast<uint32_t
>(resp_cap))
972 req_off =
static_cast<uint16_t
>(req_off + cmd_len);
973 resp_off =
static_cast<uint16_t
>(resp_off + cmd_out);
976 if (req_off != queued_request_length_)
985 bool TryBuildAndEnqueueResponse(
bool in_isr,
const uint8_t* req, uint16_t req_len)
987 if (!req || IsResponseQueueFull())
992 auto& slot = resp_q_[resp_q_tail_];
993 uint16_t out_len = 0u;
999 resp_q_tail_ = NextRespQueueIndex(resp_q_tail_);
1004 uint8_t OutstandingResponseCount()
const
1006 const uint8_t IN_FLIGHT =
1008 const uint8_t DEFERRED = deferred_in_resp_valid_ ? 1u : 0u;
1009 return static_cast<uint8_t
>(resp_q_count_ + IN_FLIGHT + DEFERRED);
1012 bool EnqueueResponse(
const uint8_t* data, uint16_t len)
1014 if (!data || IsResponseQueueFull())
1019 auto& slot = resp_q_[resp_q_tail_];
1027 resp_q_tail_ = NextRespQueueIndex(resp_q_tail_);
1032 bool SubmitNextQueuedResponseIfIdle()
1035 IsResponseQueueEmpty())
1039 auto& slot = resp_q_[resp_q_head_];
1040 if (!StartInTransferFromPayload(slot.payload, slot.len))
1044 resp_q_head_ = NextRespQueueIndex(resp_q_head_);
1049 void ArmOutTransferIfIdle()
1063 if (OutstandingResponseCount() >= MAX_OUTSTANDING_RESPONSES)
1069 if (out_rx_len == 0u)
1071 out_rx_len = DEFAULT_DAP_PACKET_SIZE;
1073 if (out_rx_len > MAX_DAP_PACKET_SIZE)
1075 out_rx_len = MAX_DAP_PACKET_SIZE;
1079 if (OUT_MAX_XFER == 0u)
1084 if (out_rx_len <= OUT_MAX_XFER)
1090 if (out_rx_len >
static_cast<uint16_t
>(
sizeof(out_req_multi_storage_)))
1092 out_rx_len =
static_cast<uint16_t
>(
sizeof(out_req_multi_storage_));
1097 out_req_multi_buf_.
addr_ = out_req_multi_storage_;
1098 out_req_multi_buf_.
size_ = out_rx_len;
1119 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1123 if (!req || !resp || req_len < 1u || resp_cap < 1u)
1125 if (resp && resp_cap >= 1u)
1132 const uint8_t CMD = req[0];
1136 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::INFO):
1137 return HandleInfo(in_isr, req, req_len, resp, resp_cap, out_len);
1138 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::HOST_STATUS):
1139 return HandleHostStatus(in_isr, req, req_len, resp, resp_cap, out_len);
1140 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::CONNECT):
1141 return HandleConnect(in_isr, req, req_len, resp, resp_cap, out_len);
1142 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::DISCONNECT):
1143 return HandleDisconnect(in_isr, req, req_len, resp, resp_cap, out_len);
1144 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_CONFIGURE):
1145 return HandleTransferConfigure(in_isr, req, req_len, resp, resp_cap, out_len);
1146 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER):
1147 return HandleTransfer(in_isr, req, req_len, resp, resp_cap, out_len);
1148 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_BLOCK):
1149 return HandleTransferBlock(in_isr, req, req_len, resp, resp_cap, out_len);
1150 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_ABORT):
1151 return HandleTransferAbort(in_isr, req, req_len, resp, resp_cap, out_len);
1152 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::WRITE_ABORT):
1153 return HandleWriteABORT(in_isr, req, req_len, resp, resp_cap, out_len);
1154 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::DELAY):
1155 return HandleDelay(in_isr, req, req_len, resp, resp_cap, out_len);
1156 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::RESET_TARGET):
1157 return HandleResetTarget(in_isr, req, req_len, resp, resp_cap, out_len);
1159 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_PINS):
1160 return HandleSWJPins(in_isr, req, req_len, resp, resp_cap, out_len);
1161 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_CLOCK):
1162 return HandleSWJClock(in_isr, req, req_len, resp, resp_cap, out_len);
1163 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_SEQUENCE):
1164 return HandleSWJSequence(in_isr, req, req_len, resp, resp_cap, out_len);
1165 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_CONFIGURE):
1166 return HandleSWDConfigure(in_isr, req, req_len, resp, resp_cap, out_len);
1167 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_SEQUENCE):
1168 return HandleSWDSequence(in_isr, req, req_len, resp, resp_cap, out_len);
1170 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS):
1172 case ToU8(LibXR::USB::DapLinkV2Def::CommandId::EXECUTE_COMMANDS):
1176 (void)BuildUnknownCmdResponse(resp, resp_cap, out_len);
1190 if (!resp || resp_cap < 1u)
1204 ErrorCode HandleInfo(
bool ,
const uint8_t* req, uint16_t req_len,
1205 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1209 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::INFO);
1215 const uint8_t INFO_ID = req[1];
1217 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::INFO);
1221 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::VENDOR):
1222 return BuildInfoStringResponse(resp[0],
info_.vendor, resp, resp_cap, out_len);
1223 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::PRODUCT):
1224 return BuildInfoStringResponse(resp[0],
info_.product, resp, resp_cap, out_len);
1225 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::SERIAL_NUMBER):
1226 return BuildInfoStringResponse(resp[0],
info_.serial, resp, resp_cap, out_len);
1227 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::FIRMWARE_VERSION):
1228 return BuildInfoStringResponse(resp[0],
info_.firmware_ver, resp, resp_cap,
1231 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::DEVICE_VENDOR):
1232 return BuildInfoStringResponse(resp[0],
info_.device_vendor, resp, resp_cap,
1234 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::DEVICE_NAME):
1235 return BuildInfoStringResponse(resp[0],
info_.device_name, resp, resp_cap,
1237 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::BOARD_VENDOR):
1238 return BuildInfoStringResponse(resp[0],
info_.board_vendor, resp, resp_cap,
1240 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::BOARD_NAME):
1241 return BuildInfoStringResponse(resp[0],
info_.board_name, resp, resp_cap,
1243 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::PRODUCT_FIRMWARE_VERSION):
1244 return BuildInfoStringResponse(resp[0],
info_.product_fw_ver, resp, resp_cap,
1247 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::CAPABILITIES):
1248 return BuildInfoU8Response(resp[0],
LibXR::USB::DapLinkV2Def::DAP_CAP_SWD, resp,
1250 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::PACKET_COUNT):
1251 return BuildInfoU8Response(resp[0], PACKET_COUNT_EFFECTIVE, resp, resp_cap,
1253 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::PACKET_SIZE):
1256 return BuildInfoU16Response(resp[0], DAP_PS, resp, resp_cap, out_len);
1258 case ToU8(LibXR::USB::DapLinkV2Def::InfoId::TIMESTAMP_CLOCK):
1259 return BuildInfoU32Response(resp[0], 1000000U, resp, resp_cap, out_len);
1268 ErrorCode BuildInfoStringResponse(uint8_t cmd,
const char* str, uint8_t* resp,
1269 uint16_t resp_cap, uint16_t& out_len)
1280 const size_t N_WITH_NUL = std::strlen(str) + 1;
1281 const size_t MAX_PAYLOAD = (resp_cap >= 2u) ? (resp_cap - 2u) : 0u;
1282 if (MAX_PAYLOAD == 0u)
1288 const size_t COPY_N = (N_WITH_NUL > MAX_PAYLOAD) ? MAX_PAYLOAD : N_WITH_NUL;
1292 resp[2 + COPY_N - 1] = 0x00;
1294 resp[1] =
static_cast<uint8_t
>(COPY_N);
1295 out_len =
static_cast<uint16_t
>(2u + COPY_N);
1299 ErrorCode BuildInfoU8Response(uint8_t cmd, uint8_t val, uint8_t* resp,
1300 uint16_t resp_cap, uint16_t& out_len)
1314 ErrorCode BuildInfoU16Response(uint8_t cmd, uint16_t val, uint8_t* resp,
1315 uint16_t resp_cap, uint16_t& out_len)
1332 ErrorCode BuildInfoU32Response(uint8_t cmd, uint32_t val, uint8_t* resp,
1333 uint16_t resp_cap, uint16_t& out_len)
1355 ErrorCode HandleHostStatus(
bool ,
const uint8_t* ,
1356 uint16_t , uint8_t* resp, uint16_t resp_cap,
1364 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::HOST_STATUS);
1365 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1370 ErrorCode HandleConnect(
bool ,
const uint8_t* req, uint16_t req_len,
1371 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1379 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::CONNECT);
1388 if (port == 0u || port == ToU8(LibXR::USB::DapLinkV2Def::Port::SWD))
1390 (void)
swd_.EnterSwd();
1395 ResetQueuedCommandState();
1397 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Port::SWD);
1401 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Port::DISABLED);
1408 ErrorCode HandleDisconnect(
bool ,
const uint8_t* ,
1409 uint16_t , uint8_t* resp, uint16_t resp_cap,
1421 ResetQueuedCommandState();
1423 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::DISCONNECT);
1424 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1429 ErrorCode HandleTransferConfigure(
bool ,
const uint8_t* req, uint16_t req_len,
1430 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1438 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_CONFIGURE);
1443 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1448 const uint8_t IDLE = req[1];
1450 uint16_t wait_retry = 0u;
1451 uint16_t match_retry = 0u;
1460 Debug::Swd::TransferPolicy pol =
swd_.GetTransferPolicy();
1461 pol.idle_cycles = IDLE;
1462 pol.wait_retry = wait_retry;
1463 swd_.SetTransferPolicy(pol);
1465 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1470 ErrorCode HandleTransferAbort(
bool ,
const uint8_t* ,
1471 uint16_t , uint8_t* resp, uint16_t resp_cap,
1480 SetTransferAbortFlag(
true);
1482 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_ABORT);
1483 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1488 ErrorCode HandleWriteABORT(
bool ,
const uint8_t* req, uint16_t req_len,
1489 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1497 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::WRITE_ABORT);
1501 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1506 uint32_t flags = 0u;
1509 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
1512 resp[1] = (EC ==
ErrorCode::OK && ack == LibXR::Debug::SwdProtocol::Ack::OK)
1513 ? ToU8(LibXR::USB::DapLinkV2Def::Status::OK)
1514 : ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1520 ErrorCode HandleDelay(
bool ,
const uint8_t* req, uint16_t req_len,
1521 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1529 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::DELAY);
1533 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1543 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1548 ErrorCode HandleResetTarget(
bool in_isr,
const uint8_t* , uint16_t ,
1549 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1551 if (!resp || resp_cap < 3u)
1557 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::RESET_TARGET);
1559 uint8_t execute = 0u;
1564 DelayUsIfAllowed(in_isr, 1000u);
1566 DelayUsIfAllowed(in_isr, 1000u);
1582 ErrorCode HandleSWJPins(
bool ,
const uint8_t* req, uint16_t req_len,
1583 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1585 if (!resp || resp_cap < 2u)
1591 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_PINS);
1594 if (!req || req_len < 7u)
1601 const uint8_t PIN_OUT = req[1];
1602 const uint8_t PIN_SEL = req[2];
1604 uint32_t wait_us = 0u;
1609 (PIN_OUT & PIN_SEL));
1612 if ((PIN_SEL & LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET) != 0u)
1614 const bool LEVEL_HIGH =
1615 ((PIN_OUT & LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET) != 0u);
1618 DriveReset(LEVEL_HIGH);
1622 auto read_pins = [&]() -> uint8_t
1630 pin_in |= LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET;
1634 pin_in =
static_cast<uint8_t
>(
1635 pin_in &
static_cast<uint8_t
>(
~LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET));
1645 uint8_t pin_in = 0u;
1647 if (wait_us == 0u || PIN_SEL == 0u)
1649 pin_in = read_pins();
1654 const uint8_t EXPECT =
static_cast<uint8_t
>(PIN_OUT & PIN_SEL);
1658 pin_in = read_pins();
1659 if ((pin_in & PIN_SEL) == EXPECT)
1672 ErrorCode HandleSWJClock(
bool ,
const uint8_t* req, uint16_t req_len,
1673 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1681 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_CLOCK);
1685 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1694 (void)
swd_.SetClockHz(hz);
1696 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1701 ErrorCode HandleSWJSequence(
bool ,
const uint8_t* req, uint16_t req_len,
1702 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1704 if (!resp || resp_cap < 2u)
1710 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWJ_SEQUENCE);
1711 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1715 if (!req || req_len < 2u)
1717 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1721 const uint8_t RAW_COUNT = req[1];
1722 const uint32_t BIT_COUNT =
1723 (RAW_COUNT == 0u) ? 256u : static_cast<uint32_t>(RAW_COUNT);
1724 const uint32_t BYTE_COUNT = (BIT_COUNT + 7u) / 8u;
1726 if (2u + BYTE_COUNT > req_len)
1728 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1732 const uint8_t* data = &req[2];
1738 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1745 swj_shadow_ &
static_cast<uint8_t
>(
~LibXR::USB::DapLinkV2Def::DAP_SWJ_SWCLK_TCK));
1747 bool last_swdio =
false;
1748 if (BIT_COUNT != 0u)
1750 const uint32_t LAST_I = BIT_COUNT - 1u;
1751 last_swdio = (((data[LAST_I / 8u] >> (LAST_I & 7u)) & 0x01u) != 0u);
1756 swj_shadow_ |= LibXR::USB::DapLinkV2Def::DAP_SWJ_SWDIO_TMS;
1762 static_cast<uint8_t
>(
~LibXR::USB::DapLinkV2Def::DAP_SWJ_SWDIO_TMS));
1768 ErrorCode HandleSWDConfigure(
bool ,
const uint8_t* req, uint16_t req_len,
1769 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1777 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_CONFIGURE);
1779 if (req ==
nullptr || req_len < 2u)
1781 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::ERROR);
1786 const uint8_t cfg = req[1];
1790 resp[1] = ToU8(LibXR::USB::DapLinkV2Def::Status::OK);
1795 ErrorCode HandleSWDSequence(
bool ,
const uint8_t* req, uint16_t req_len,
1796 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1798 if (!req || !resp || resp_cap < 2u)
1804 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::SWD_SEQUENCE);
1821 const uint8_t SEQ_CNT = req[1];
1822 uint16_t req_off = 2u;
1823 uint16_t resp_off = 2u;
1825 for (uint32_t s = 0; s < SEQ_CNT; ++s)
1827 if (req_off >= req_len)
1834 const uint8_t INFO = req[req_off++];
1836 uint32_t cycles =
static_cast<uint32_t
>(INFO & 0x3Fu);
1842 const bool MODE_IN = ((INFO & 0x80u) != 0u);
1843 const uint16_t BYTES =
static_cast<uint16_t
>((cycles + 7u) / 8u);
1848 if (req_off + BYTES > req_len)
1855 const uint8_t* data = &req[req_off];
1856 req_off =
static_cast<uint16_t
>(req_off + BYTES);
1870 if (resp_off + BYTES > resp_cap)
1879 const ErrorCode EC =
swd_.SeqReadBits(cycles, &resp[resp_off]);
1887 resp_off =
static_cast<uint16_t
>(resp_off + BYTES);
1899 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
1901 if (!req || req_len < 2u)
1903 return BuildCmdStatusResponse(
1904 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_ERROR, resp,
1908 const uint8_t NUM = req[1];
1911 return BuildCmdStatusResponse(
1912 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_OK, resp,
1916 uint16_t req_off = 2u;
1917 for (uint32_t i = 0u; i < NUM; ++i)
1919 if (req_off >= req_len)
1921 return BuildCmdStatusResponse(
1922 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_ERROR, resp,
1926 uint16_t cmd_len = 0u;
1928 static_cast<uint16_t
>(req_len - req_off), cmd_len) ||
1931 return BuildCmdStatusResponse(
1932 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_ERROR, resp,
1935 req_off =
static_cast<uint16_t
>(req_off + cmd_len);
1938 if (req_off != req_len)
1940 return BuildCmdStatusResponse(
1941 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_ERROR, resp,
1945 if (
static_cast<uint32_t
>(queued_request_length_) +
1946 static_cast<uint32_t
>(req_len - 2u) >
1947 static_cast<uint32_t
>(QUEUED_REQ_BUFFER_SIZE) ||
1948 static_cast<uint32_t
>(queued_command_count_) +
static_cast<uint32_t
>(NUM) >
1949 static_cast<uint32_t
>(QUEUED_CMD_COUNT_MAX))
1951 return BuildCmdStatusResponse(
1952 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_ERROR, resp,
1958 queued_request_length_ =
1959 static_cast<uint16_t
>(queued_request_length_ + (req_len - 2u));
1960 queued_command_count_ =
static_cast<uint16_t
>(queued_command_count_ + NUM);
1962 return BuildCmdStatusResponse(
1963 ToU8(LibXR::USB::DapLinkV2Def::CommandId::QUEUE_COMMANDS),
DAP_OK, resp, resp_cap,
1971 uint16_t , uint8_t* resp, uint16_t resp_cap,
1975 ResetQueuedCommandState();
1979 return BuildCmdStatusResponse(
1980 ToU8(LibXR::USB::DapLinkV2Def::CommandId::EXECUTE_COMMANDS),
DAP_ERROR, resp,
1992 uint8_t MapAckToDapResp(LibXR::Debug::SwdProtocol::Ack ack)
const
1994 static constexpr uint8_t ACK_MAP[8] = {7u, 1u, 2u, 7u, 4u, 7u, 7u, 7u};
1995 return ACK_MAP[
static_cast<uint8_t
>(ack) & 0x07u];
1998 static inline uint16_t LoadU16Le(
const uint8_t* p)
2000 return static_cast<uint16_t
>(
2001 static_cast<uint16_t
>(p[0]) |
2002 static_cast<uint16_t
>(
static_cast<uint16_t
>(p[1]) << 8u));
2005 static inline void StoreU16Le(uint8_t* p, uint16_t v)
2007 p[0] =
static_cast<uint8_t
>(v & 0xFFu);
2008 p[1] =
static_cast<uint8_t
>((v >> 8u) & 0xFFu);
2011 static inline uint32_t LoadU32Le(
const uint8_t* p)
2013 return static_cast<uint32_t
>(
2014 static_cast<uint32_t
>(p[0]) | (
static_cast<uint32_t
>(p[1]) << 8u) |
2015 (
static_cast<uint32_t
>(p[2]) << 16u) | (
static_cast<uint32_t
>(p[3]) << 24u));
2018 static inline void StoreU32Le(uint8_t* p, uint32_t v)
2020 p[0] =
static_cast<uint8_t
>(v & 0xFFu);
2021 p[1] =
static_cast<uint8_t
>((v >> 8u) & 0xFFu);
2022 p[2] =
static_cast<uint8_t
>((v >> 16u) & 0xFFu);
2023 p[3] =
static_cast<uint8_t
>((v >> 24u) & 0xFFu);
2035 if (resp.
ack == LibXR::Debug::SwdProtocol::Ack::WAIT)
2037 return swd_.TransferWithRetry(req, resp);
2040 if (resp.
ack == LibXR::Debug::SwdProtocol::Ack::FAULT)
2042 const auto POL =
swd_.GetTransferPolicy();
2043 if (POL.clear_sticky_on_fault)
2045 LibXR::Debug::SwdProtocol::Ack abort_ack =
2046 LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2047 (void)
swd_.WriteAbort(LibXR::Debug::SwdProtocol::DP_ABORT_STKCMPCLR |
2048 LibXR::Debug::SwdProtocol::DP_ABORT_STKERRCLR |
2049 LibXR::Debug::SwdProtocol::DP_ABORT_WDERRCLR |
2050 LibXR::Debug::SwdProtocol::DP_ABORT_ORUNERRCLR,
2058 ErrorCode DpReadRdbuffFast(uint32_t& val, LibXR::Debug::SwdProtocol::Ack& ack_out)
2061 const auto req = LibXR::Debug::SwdProtocol::make_dp_read_req(
2062 LibXR::Debug::SwdProtocol::DpReadReg::RDBUFF);
2063 const ErrorCode ec = TransferTxnFast(req, swd_resp);
2064 ack_out = swd_resp.
ack;
2069 if (swd_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK || !swd_resp.
parity_ok)
2073 val = swd_resp.
rdata;
2077 ErrorCode ApReadPostedFast(uint8_t addr2b, uint32_t& posted,
2078 LibXR::Debug::SwdProtocol::Ack& ack_out)
2081 const auto req = LibXR::Debug::SwdProtocol::make_ap_read_req(addr2b);
2082 const ErrorCode ec = TransferTxnFast(req, swd_resp);
2083 ack_out = swd_resp.
ack;
2088 if (swd_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK || !swd_resp.
parity_ok)
2092 posted = swd_resp.
rdata;
2107 ErrorCode HandleTransfer(
bool ,
const uint8_t* req, uint16_t req_len,
2108 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
2111 if (!req || !resp || resp_cap < 3u)
2116 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER);
2119 uint16_t resp_off = 3u;
2124 resp[2] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2132 resp[2] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2137 const uint8_t COUNT = req[2];
2138 uint16_t req_off = 3u;
2140 auto push_u32 = [&](uint32_t v) ->
bool
2142 if (resp_off + 4u > resp_cap)
2147 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
2151 auto push_timestamp = [&]() ->
bool
2157 auto ensure_space = [&](uint16_t bytes) ->
bool
2158 {
return (resp_off + bytes) <= resp_cap; };
2160 auto bytes_for_read = [&](
bool need_ts) -> uint16_t
2161 {
return static_cast<uint16_t
>(need_ts ? 8u : 4u); };
2163 uint8_t response_count = 0u;
2165 uint8_t response_value = 0u;
2168 bool check_write =
false;
2171 struct PendingApRead
2174 bool need_ts =
false;
2177 auto emit_read_with_ts = [&](
bool need_ts, uint32_t data) ->
bool
2181 if (!push_timestamp())
2186 if (!push_u32(data))
2196 auto complete_pending_by_rdbuff = [&]() ->
bool
2203 if (!ensure_space(bytes_for_read(pending.need_ts)))
2205 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2209 uint32_t rdata = 0u;
2210 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2211 const ErrorCode EC = DpReadRdbuffFast(rdata, ack);
2213 const uint8_t V = MapAckToDapResp(ack);
2214 if (V != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2221 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2225 if (!emit_read_with_ts(pending.need_ts, rdata))
2227 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2231 pending.valid =
false;
2232 pending.need_ts =
false;
2235 check_write =
false;
2238 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2244 auto flush_pending_if_any = [&]() ->
bool
2245 {
return pending.valid ? complete_pending_by_rdbuff() : true; };
2248 for (uint32_t i = 0; i < COUNT; ++i)
2250 if (req_off >= req_len)
2252 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2256 const uint8_t RQ = req[req_off++];
2263 const bool MATCH_VALUE =
2264 ((RQ & LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_VALUE) != 0u);
2265 const bool MATCH_MASK =
2266 ((RQ & LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_MASK) != 0u);
2269 if (TS && (MATCH_VALUE || MATCH_MASK))
2271 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2275 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2283 if (!flush_pending_if_any())
2288 if (req_off + 4u > req_len)
2290 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2294 uint32_t wdata = LoadU32Le(&req[req_off]);
2295 req_off =
static_cast<uint16_t
>(req_off + 4u);
2300 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2306 ec =
swd_.ApWriteTxn(ADDR2B, wdata, ack);
2310 ec =
swd_.DpWriteTxn(
static_cast<LibXR::Debug::SwdProtocol::DpWriteReg
>(ADDR2B),
2314 response_value = MapAckToDapResp(ack);
2315 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2321 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2327 if (!push_timestamp())
2329 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2346 if (!flush_pending_if_any())
2351 if (req_off + 4u > req_len)
2353 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2357 uint32_t match_val = LoadU32Le(&req[req_off]);
2358 req_off =
static_cast<uint16_t
>(req_off + 4u);
2360 uint32_t rdata = 0u;
2362 bool matched =
false;
2368 ec =
swd_.ApReadTxn(ADDR2B, rdata, ack);
2369 if (ec ==
ErrorCode::OK && ack == LibXR::Debug::SwdProtocol::Ack::OK)
2372 check_write =
false;
2377 ec =
swd_.DpReadTxn(
2378 static_cast<LibXR::Debug::SwdProtocol::DpReadReg
>(ADDR2B), rdata, ack);
2381 response_value = MapAckToDapResp(ack);
2382 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2388 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2405 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2413 static_cast<uint8_t
>(LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK |
2414 LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MISMATCH);
2419 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2428 if (!flush_pending_if_any())
2433 uint32_t rdata = 0u;
2434 ec =
swd_.DpReadTxn(
static_cast<LibXR::Debug::SwdProtocol::DpReadReg
>(ADDR2B),
2437 response_value = MapAckToDapResp(ack);
2438 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2444 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2448 if (!ensure_space(bytes_for_read(TS)))
2450 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2454 if (!emit_read_with_ts(TS, rdata))
2456 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2460 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2469 uint32_t dummy_posted = 0u;
2470 ec = ApReadPostedFast(ADDR2B, dummy_posted, ack);
2472 response_value = MapAckToDapResp(ack);
2473 if (response_value != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2479 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2485 pending.valid =
true;
2486 pending.need_ts = TS;
2490 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2496 if (!ensure_space(bytes_for_read(pending.need_ts)))
2498 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2502 uint32_t posted_prev = 0u;
2503 ec = ApReadPostedFast(ADDR2B, posted_prev, ack);
2505 const uint8_t CUR_V = MapAckToDapResp(ack);
2506 if (CUR_V != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK || ec !=
ErrorCode::OK)
2510 const uint8_t PROOR_FAIL =
2511 (CUR_V != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2513 :
LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2515 if (!complete_pending_by_rdbuff())
2523 response_value = PROOR_FAIL;
2529 if (!emit_read_with_ts(pending.need_ts, posted_prev))
2531 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2535 pending.valid =
true;
2536 pending.need_ts = TS;
2538 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2555 const uint8_t PRIOR_FAIL = response_value;
2557 if (!complete_pending_by_rdbuff())
2565 if (PRIOR_FAIL != 0u && PRIOR_FAIL != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2567 response_value = PRIOR_FAIL;
2574 if (response_value == LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK && check_write)
2576 uint32_t dummy = 0u;
2577 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2578 const ErrorCode EC = DpReadRdbuffFast(dummy, ack);
2579 const uint8_t V = MapAckToDapResp(ack);
2581 if (V != LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK)
2587 response_value = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2591 resp[1] = response_count;
2592 resp[2] = response_value;
2596 ErrorCode HandleTransferBlock(
bool ,
const uint8_t* req, uint16_t req_len,
2597 uint8_t* resp, uint16_t resp_cap, uint16_t& out_len)
2601 if (!resp || resp_cap < 4u)
2607 resp[0] = ToU8(LibXR::USB::DapLinkV2Def::CommandId::TRANSFER_BLOCK);
2613 if (!req || req_len < 5u)
2615 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2622 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2626 uint16_t count = 0u;
2627 count = LoadU16Le(&req[2]);
2629 const uint8_t DAP_RQ = req[4];
2632 if ((DAP_RQ & (LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_VALUE |
2633 LibXR::USB::DapLinkV2Def::DAP_TRANSFER_MATCH_MASK)) != 0u)
2635 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2640 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2647 const uint16_t DONE0 = 0u;
2648 StoreU16Le(&resp[1], DONE0);
2649 resp[3] = LibXR::USB::DapLinkV2Def::DAP_TRANSFER_OK;
2661 uint16_t req_off = 5u;
2662 uint16_t resp_off = 4u;
2667 const uint32_t REQ_NEED =
2668 static_cast<uint32_t
>(req_off) + (
static_cast<uint32_t
>(count) * 4u);
2669 if (REQ_NEED > req_len)
2671 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2672 StoreU16Le(&resp[1], done);
2679 auto swd_req = LibXR::Debug::SwdProtocol::make_ap_write_req(ADDR2B, 0u);
2681 for (uint32_t i = 0; i < count; ++i)
2683 uint32_t wdata = LoadU32Le(&req[req_off]);
2684 req_off =
static_cast<uint16_t
>(req_off + 4u);
2685 swd_req.wdata = wdata;
2686 const ErrorCode ec = TransferTxnFast(swd_req, swd_resp);
2687 xresp = MapAckToDapResp(swd_resp.
ack);
2688 if (swd_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK)
2694 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2697 done =
static_cast<uint16_t
>(i + 1u);
2702 for (uint32_t i = 0; i < count; ++i)
2704 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2706 uint32_t wdata = LoadU32Le(&req[req_off]);
2707 req_off =
static_cast<uint16_t
>(req_off + 4u);
2708 ec =
swd_.DpWriteTxn(
static_cast<LibXR::Debug::SwdProtocol::DpWriteReg
>(ADDR2B),
2710 xresp = MapAckToDapResp(ack);
2711 if (ack != LibXR::Debug::SwdProtocol::Ack::OK)
2717 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2720 done =
static_cast<uint16_t
>(i + 1u);
2723 StoreU16Le(&resp[1], done);
2732 const uint32_t RESP_NEED =
2733 static_cast<uint32_t
>(resp_off) + (
static_cast<uint32_t
>(count) * 4u);
2734 if (RESP_NEED > resp_cap)
2736 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2737 StoreU16Le(&resp[1], done);
2744 for (uint32_t i = 0; i < count; ++i)
2746 LibXR::Debug::SwdProtocol::Ack ack = LibXR::Debug::SwdProtocol::Ack::PROTOCOL;
2748 uint32_t rdata = 0u;
2749 ec =
swd_.DpReadTxn(
static_cast<LibXR::Debug::SwdProtocol::DpReadReg
>(ADDR2B),
2751 xresp = MapAckToDapResp(ack);
2752 if (ack != LibXR::Debug::SwdProtocol::Ack::OK)
2758 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2761 StoreU32Le(&resp[resp_off], rdata);
2762 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
2763 done =
static_cast<uint16_t
>(i + 1u);
2765 StoreU16Le(&resp[1], done);
2773 const uint32_t RESP_NEED =
2774 static_cast<uint32_t
>(resp_off) + (
static_cast<uint32_t
>(count) * 4u);
2775 if (RESP_NEED > resp_cap)
2777 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2778 StoreU16Le(&resp[1], done);
2784 auto ap_read_req = LibXR::Debug::SwdProtocol::make_ap_read_req(ADDR2B);
2785 const auto rdbuff_req = LibXR::Debug::SwdProtocol::make_dp_read_req(
2786 LibXR::Debug::SwdProtocol::DpReadReg::RDBUFF);
2788 ErrorCode ec = TransferTxnFast(ap_read_req, ap_read_resp);
2789 xresp = MapAckToDapResp(ap_read_resp.
ack);
2790 if (ap_read_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK)
2796 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2801 for (uint32_t i = 1; i < count; ++i)
2803 ec = TransferTxnFast(ap_read_req, ap_read_resp);
2804 const uint8_t CUR = MapAckToDapResp(ap_read_resp.
ack);
2806 if (ap_read_resp.
ack != LibXR::Debug::SwdProtocol::Ack::OK ||
2810 if (resp_off + 4u <= resp_cap)
2813 const ErrorCode EC2 = TransferTxnFast(rdbuff_req, rdbuff_resp);
2814 const uint8_t V2 = MapAckToDapResp(rdbuff_resp.
ack);
2818 StoreU32Le(&resp[resp_off], rdbuff_resp.
rdata);
2819 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
2820 done =
static_cast<uint16_t
>(i);
2827 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2836 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2841 StoreU32Le(&resp[resp_off], ap_read_resp.
rdata);
2842 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
2843 done =
static_cast<uint16_t
>(i);
2850 const ErrorCode EC2 = TransferTxnFast(rdbuff_req, rdbuff_resp);
2851 const uint8_t V2 = MapAckToDapResp(rdbuff_resp.
ack);
2860 xresp |= LibXR::USB::DapLinkV2Def::DAP_TRANSFER_ERROR;
2864 StoreU32Le(&resp[resp_off], rdbuff_resp.
rdata);
2865 resp_off =
static_cast<uint16_t
>(resp_off + 4u);
2870 StoreU16Le(&resp[1], done);
2882 void DriveReset(
bool release)
2889 swj_shadow_ |= LibXR::USB::DapLinkV2Def::DAP_SWJ_NRESET;
2903 void DelayUsIfAllowed(
bool , uint32_t us)
2909 static constexpr uint16_t DEFAULT_DAP_PACKET_SIZE = DefaultDapPacketSize;
2910 static constexpr uint8_t PACKET_COUNT_ADVERTISED = AdvertisedPacketCount;
2911 static constexpr uint8_t PACKET_COUNT_EFFECTIVE =
2912 (PACKET_COUNT_ADVERTISED > 4u) ? 4u : PACKET_COUNT_ADVERTISED;
2913 static constexpr uint8_t MAX_OUTSTANDING_RESPONSES = PACKET_COUNT_EFFECTIVE;
2917 static constexpr uint16_t OPENOCD_SAFE_DAP_PACKET_SIZE =
2918 static_cast<uint16_t
>((255u * 5u) + 4u);
2921 static constexpr uint16_t MAX_DAP_PACKET_SIZE = MaxDapPacketSize;
2922 static constexpr uint16_t QUEUED_REQ_BUFFER_SIZE = QueuedRequestBufferSize;
2923 static constexpr uint16_t QUEUED_CMD_COUNT_MAX = QueuedCommandCountMax;
2924 static constexpr uint16_t RESP_SLOT_SIZE = MAX_DAP_PACKET_SIZE;
2925 static constexpr uint8_t RESP_QUEUE_DEPTH = PACKET_COUNT_EFFECTIVE;
2926 static constexpr uint16_t QUEUED_REQ_BUFFER_ALLOC_SIZE = QUEUED_REQ_BUFFER_SIZE;
2927 static_assert(PACKET_COUNT_ADVERTISED > 0u,
"PACKET_COUNT_ADVERTISED must be > 0");
2928 static_assert(PACKET_COUNT_EFFECTIVE > 0u,
"PACKET_COUNT_EFFECTIVE must be > 0");
2929 static_assert(MAX_DAP_PACKET_SIZE >= DEFAULT_DAP_PACKET_SIZE,
2930 "MAX_DAP_PACKET_SIZE must be >= DEFAULT_DAP_PACKET_SIZE");
2931 static_assert(MAX_DAP_PACKET_SIZE <= OPENOCD_SAFE_DAP_PACKET_SIZE,
2932 "MAX_DAP_PACKET_SIZE exceeds OpenOCD-safe limit");
2933 static_assert(((OPENOCD_SAFE_DAP_PACKET_SIZE - 4u) / 5u) <= 255u,
2934 "OPENOCD_SAFE_DAP_PACKET_SIZE too large for CMD_DAP_TFER u8 count");
2935 static_assert(QUEUED_REQ_BUFFER_SIZE > 0u,
"QUEUED_REQ_BUFFER_SIZE must be > 0");
2936 static_assert(QUEUED_CMD_COUNT_MAX > 0u,
"QUEUED_CMD_COUNT_MAX must be > 0");
2937 static_assert(RESP_SLOT_SIZE >= DEFAULT_DAP_PACKET_SIZE,
2938 "RESP_SLOT_SIZE must cover FS bulk packet size");
2939 static_assert((RESP_QUEUE_DEPTH & (RESP_QUEUE_DEPTH - 1u)) == 0u,
2940 "Response queue depth must be power-of-two");
2948 static_cast<uint16_t
>(LibXR::USB::WinUsbMsOs20::GUID_STR_UTF16_BYTES +
2954 uint8_t payload[RESP_SLOT_SIZE] = {};
2958 uint8_t resp_q_head_ = 0u;
2959 uint8_t resp_q_tail_ = 0u;
2960 uint8_t resp_q_count_ = 0u;
2961 bool deferred_in_resp_valid_ =
false;
2962 uint16_t deferred_in_resp_len_ = 0u;
2964 uint8_t queued_request_buffer_[QUEUED_REQ_BUFFER_ALLOC_SIZE] = {};
2965 uint16_t queued_request_length_ = 0u;
2966 uint16_t queued_command_count_ = 0u;
2968 uint8_t out_req_multi_storage_[MAX_DAP_PACKET_SIZE] = {};
2969 LibXR::RawData out_req_multi_buf_{out_req_multi_storage_, DEFAULT_DAP_PACKET_SIZE};
2970 uint8_t in_tx_multi_storage_[MAX_DAP_PACKET_SIZE] = {};
2971 LibXR::RawData in_tx_multi_buf_{in_tx_multi_storage_, DEFAULT_DAP_PACKET_SIZE};
2973#pragma pack(push, 1)
2994 uint8_t
name[LibXR::USB::WinUsbMsOs20::
2995 PROP_NAME_DEVICE_INTERFACE_GUIDS_BYTES];
3010 DapLinkV2Def::DAP_SWJ_SWDIO_TMS |
3011 DapLinkV2Def::DAP_SWJ_NRESET);
3017 "XRDAP",
"XRobot",
"DAP_DEMO",
"0.1.0"};
3032#pragma pack(push, 1)