26 static constexpr uint32_t MIN_HZ = 10'000u;
27 static constexpr uint32_t MAX_HZ = 100'000'000u;
29 static constexpr uint32_t NS_PER_SEC = 1'000'000'000u;
30 static constexpr uint32_t LOOPS_SCALE = 1000u;
31 static constexpr uint32_t CEIL_BIAS = LOOPS_SCALE - 1u;
33 static constexpr uint32_t HalfPeriodNsFromHz(uint32_t hz)
36 return (NS_PER_SEC + (2u * hz) - 1u) / (2u * hz);
39 static constexpr uint32_t HALF_PERIOD_NS_MAX = HalfPeriodNsFromHz(MIN_HZ);
40 static constexpr uint32_t MAX_LOOPS_PER_US =
41 (UINT32_MAX - CEIL_BIAS) / HALF_PERIOD_NS_MAX;
43 static_assert(MIN_HZ > 0u);
44 static_assert(MAX_HZ >= MIN_HZ);
45 static_assert(HALF_PERIOD_NS_MAX > 0u);
57 :
swclk_(swclk),
swdio_(swdio), loops_per_us_(loops_per_us)
59 if (loops_per_us_ > MAX_LOOPS_PER_US)
61 loops_per_us_ = MAX_LOOPS_PER_US;
66 {SwclkGpioType::Direction::OUTPUT_PUSH_PULL, SwclkGpioType::Pull::NONE});
70 (void)SetSwdioDriveMode();
87 half_period_loops_ = 0u;
104 const double DEN = 2.0 *
static_cast<double>(hz);
105 const double HALF_PERIOD_NS_F = std::ceil(
static_cast<double>(NS_PER_SEC) / DEN);
106 half_period_ns_ =
static_cast<uint32_t
>(HALF_PERIOD_NS_F);
108 if (loops_per_us_ == 0u)
110 half_period_loops_ = 0u;
111 return ErrorCode::OK;
118 const double HALF_PERIOD_LOOPS_F =
119 (
static_cast<double>(loops_per_us_) *
static_cast<double>(half_period_ns_)) /
120 static_cast<double>(LOOPS_SCALE);
122 if (HALF_PERIOD_LOOPS_F < 1.0)
124 half_period_loops_ = 0u;
128 const double LOOPS_CEIL_F = std::ceil(HALF_PERIOD_LOOPS_F);
129 half_period_loops_ = (LOOPS_CEIL_F >=
static_cast<double>(UINT32_MAX))
131 :
static_cast<uint32_t
>(LOOPS_CEIL_F);
134 return ErrorCode::OK;
145 (void)SetSwdioSampleMode();
153 (void)SetSwdioDriveMode();
159 return ErrorCode::OK;
165 if (ec != ErrorCode::OK)
174 if (ec != ErrorCode::OK)
182 return ErrorCode::OK;
190 if (half_period_loops_ == 0u)
192 return TransferWithoutDelay(req, resp);
196 return TransferWithDelay(req, resp);
205 (void)SetSwdioDriveMode();
208 for (uint32_t i = 0; i < cycles; ++i)
216 ErrorCode SeqWriteBits(uint32_t cycles,
const uint8_t* data_lsb_first)
override
221 return ErrorCode::OK;
223 if (data_lsb_first ==
nullptr)
225 return ErrorCode::ARG_ERR;
228 (void)SetSwdioDriveMode();
233 for (uint32_t i = 0; i < cycles; ++i)
235 const bool BIT = (((data_lsb_first[i / 8u] >> (i & 7u)) & 0x01u) != 0u);
245 return ErrorCode::OK;
248 ErrorCode SeqReadBits(uint32_t cycles, uint8_t* out_lsb_first)
override
253 return ErrorCode::OK;
255 if (out_lsb_first ==
nullptr)
257 return ErrorCode::ARG_ERR;
260 const uint32_t BYTES = (cycles + 7u) / 8u;
263 (void)SetSwdioSampleMode();
268 for (uint32_t i = 0; i < cycles; ++i)
272 if (half_period_loops_ == 0u)
289 out_lsb_first[i / 8u] =
290 static_cast<uint8_t
>(out_lsb_first[i / 8u] | (1u << (i & 7u)));
297 return ErrorCode::OK;
301 static inline uint8_t MakeReq(
bool apndp,
bool rnw, uint8_t addr2b)
303 const uint8_t A2 = addr2b & 0x1u;
304 const uint8_t A3 = (addr2b >> 1) & 0x1u;
305 const uint8_t PAR =
static_cast<uint8_t
>((apndp ^ rnw ^ A2 ^ A3) & 0x1u);
309 return static_cast<uint8_t
>((1u << 0) | (
static_cast<uint8_t
>(apndp) << 1) |
310 (
static_cast<uint8_t
>(rnw) << 2) |
311 (
static_cast<uint8_t
>(A2) << 3) |
312 (
static_cast<uint8_t
>(A3) << 4) |
313 (
static_cast<uint8_t
>(PAR) << 5) | (0u << 6) | (1u << 7));
322 static constexpr uint8_t LUT[16] = {
323 0, 1, 1, 0, 1, 0, 0, 1,
324 1, 0, 0, 1, 0, 1, 1, 0};
329 static inline SwdProtocol::Ack DecodeAck(uint8_t ack_bits)
334 return SwdProtocol::Ack::OK;
336 return SwdProtocol::Ack::WAIT;
338 return SwdProtocol::Ack::FAULT;
340 return SwdProtocol::Ack::NO_ACK;
342 return SwdProtocol::Ack::PROTOCOL;
358 ErrorCode SetSwdioDriveMode()
362 const ErrorCode EC =
swdio_.SetConfig(
363 {SwdioGpioType::Direction::OUTPUT_OPEN_DRAIN, SwdioGpioType::Pull::UP});
364 if (EC != ErrorCode::OK)
371 return ErrorCode::OK;
374 ErrorCode SetSwdioSampleMode()
376 const ErrorCode EC = SetSwdioDriveMode();
377 if (EC != ErrorCode::OK)
390 return ErrorCode::OK;
393 inline void DelayHalf() { BusyLoop(half_period_loops_); }
395 inline void GenOneClk()
403 inline void GenOneClkWithoutDelay()
409 inline void WriteBit(
bool bit)
415 inline void WriteBitWithoutDelay(
bool bit)
418 GenOneClkWithoutDelay();
421 inline void WriteByteLSB(uint8_t b)
425 WriteBit(((b >> i) & 0x1u) != 0u);
429 inline void WriteByteLSBWithoutDelay(uint8_t b)
433 WriteBitWithoutDelay(((b >> i) & 0x1u) != 0u);
437 inline bool ReadBitAndClock()
441 const bool BIT =
swdio_.Read();
447 inline bool ReadBitAndClockWithoutDelay()
450 const bool BIT =
swdio_.Read();
455 inline uint8_t ReadByteLSB()
460 if (ReadBitAndClock())
462 v =
static_cast<uint8_t
>(v | (1u << i));
468 inline uint8_t ReadByteLSBWithoutDelay()
473 if (ReadBitAndClockWithoutDelay())
475 v =
static_cast<uint8_t
>(v | (1u << i));
481 static void BusyLoop(uint32_t loops)
483 volatile uint32_t sink = loops;
490 ErrorCode TransferWithDelay(
const SwdProtocol::Request& req,
491 SwdProtocol::Response& resp)
493 resp.ack = SwdProtocol::Ack::PROTOCOL;
495 resp.parity_ok =
true;
497 const bool APNDP = (req.port == SwdProtocol::Port::AP);
498 const uint8_t REQUEST_BYTE = MakeReq(APNDP, req.rnw, req.addr2b);
500 (void)SetSwdioDriveMode();
501 WriteByteLSB(REQUEST_BYTE);
503 (void)SetSwdioSampleMode();
507 uint8_t ack_raw = 0u;
508 for (uint32_t i = 0; i <
ACK_BITS; ++i)
510 if (ReadBitAndClock())
512 ack_raw |=
static_cast<uint8_t
>(1u << i);
515 resp.ack = DecodeAck(
static_cast<uint8_t
>(ack_raw & 0x7u));
517 if (resp.ack != SwdProtocol::Ack::OK)
520 (void)SetSwdioDriveMode();
523 return ErrorCode::OK;
529 for (uint32_t
byte = 0;
byte < 4u; ++byte)
531 const uint32_t B = ReadByteLSB();
532 data |= (B << (8u * byte));
535 const bool PARITY_BIT = ReadBitAndClock();
537 resp.parity_ok = (
static_cast<uint8_t
>(PARITY_BIT) ==
Parity32(data));
539 (void)SetSwdioDriveMode();
547 (void)SetSwdioDriveMode();
550 const uint32_t DATA = req.wdata;
551 for (uint32_t
byte = 0;
byte < 4u; ++byte)
553 const uint8_t B =
static_cast<uint8_t
>((DATA >> (8u * byte)) & 0xFFu);
557 const bool PARITY_BIT = (
Parity32(DATA) & 0x1u) != 0u;
558 WriteBit(PARITY_BIT);
564 return ErrorCode::OK;
567 ErrorCode TransferWithoutDelay(
const SwdProtocol::Request& req,
568 SwdProtocol::Response& resp)
570 resp.ack = SwdProtocol::Ack::PROTOCOL;
572 resp.parity_ok =
true;
574 const bool APNDP = (req.port == SwdProtocol::Port::AP);
575 const uint8_t REQUEST_BYTE = MakeReq(APNDP, req.rnw, req.addr2b);
577 (void)SetSwdioDriveMode();
578 WriteByteLSBWithoutDelay(REQUEST_BYTE);
580 (void)SetSwdioSampleMode();
581 GenOneClkWithoutDelay();
584 uint8_t ack_raw = 0u;
585 for (uint32_t i = 0; i <
ACK_BITS; ++i)
587 if (ReadBitAndClockWithoutDelay())
589 ack_raw |=
static_cast<uint8_t
>(1u << i);
592 resp.ack = DecodeAck(
static_cast<uint8_t
>(ack_raw & 0x7u));
594 if (resp.ack != SwdProtocol::Ack::OK)
596 GenOneClkWithoutDelay();
597 (void)SetSwdioDriveMode();
600 return ErrorCode::OK;
606 for (uint32_t
byte = 0;
byte < 4u; ++byte)
608 const uint32_t B = ReadByteLSBWithoutDelay();
609 data |= (B << (8u * byte));
612 const bool PARITY_BIT = ReadBitAndClockWithoutDelay();
614 resp.parity_ok = (
static_cast<uint8_t
>(PARITY_BIT) ==
Parity32(data));
616 (void)SetSwdioDriveMode();
618 GenOneClkWithoutDelay();
624 (void)SetSwdioDriveMode();
625 GenOneClkWithoutDelay();
627 const uint32_t DATA = req.wdata;
628 for (uint32_t
byte = 0;
byte < 4u; ++byte)
630 const uint8_t B =
static_cast<uint8_t
>((DATA >> (8u * byte)) & 0xFFu);
631 WriteByteLSBWithoutDelay(B);
634 const bool PARITY_BIT = (
Parity32(DATA) & 0x1u) != 0u;
635 WriteBitWithoutDelay(PARITY_BIT);
641 return ErrorCode::OK;
662 uint32_t loops_per_us_ = 0u;
663 uint32_t half_period_ns_ = 0u;
664 uint32_t half_period_loops_ = 0u;