34 static constexpr uint32_t MIN_HZ = 10'000u;
35 static constexpr uint32_t MAX_HZ = 100'000'000u;
37 static constexpr uint32_t NS_PER_SEC = 1'000'000'000u;
38 static constexpr uint32_t LOOPS_SCALE = 1000u;
39 static constexpr uint32_t CEIL_BIAS = LOOPS_SCALE - 1u;
41 static constexpr uint32_t HalfPeriodNsFromHz(uint32_t hz)
44 return (NS_PER_SEC + (2u * hz) - 1u) / (2u * hz);
47 static constexpr uint32_t HALF_PERIOD_NS_MAX = HalfPeriodNsFromHz(MIN_HZ);
48 static constexpr uint32_t MAX_LOOPS_PER_US =
49 (UINT32_MAX - CEIL_BIAS) / HALF_PERIOD_NS_MAX;
51 static_assert(MIN_HZ > 0u);
52 static_assert(MAX_HZ >= MIN_HZ);
53 static_assert(HALF_PERIOD_NS_MAX > 0u);
65 :
swclk_(swclk),
swdio_(swdio), loops_per_us_(loops_per_us)
67 if (loops_per_us_ > MAX_LOOPS_PER_US)
69 loops_per_us_ = MAX_LOOPS_PER_US;
74 {SwclkGpioType::Direction::OUTPUT_PUSH_PULL, SwclkGpioType::Pull::NONE});
78 (void)SetSwdioDriveMode();
95 half_period_loops_ = 0u;
112 const double DEN = 2.0 *
static_cast<double>(hz);
113 const double HALF_PERIOD_NS_F = std::ceil(
static_cast<double>(NS_PER_SEC) / DEN);
114 half_period_ns_ =
static_cast<uint32_t
>(HALF_PERIOD_NS_F);
116 if (loops_per_us_ == 0u)
118 half_period_loops_ = 0u;
126 const double HALF_PERIOD_LOOPS_F =
127 (
static_cast<double>(loops_per_us_) *
static_cast<double>(half_period_ns_)) /
128 static_cast<double>(LOOPS_SCALE);
130 if (HALF_PERIOD_LOOPS_F < 1.0)
132 half_period_loops_ = 0u;
136 const double LOOPS_CEIL_F = std::ceil(HALF_PERIOD_LOOPS_F);
137 half_period_loops_ = (LOOPS_CEIL_F >=
static_cast<double>(UINT32_MAX))
139 :
static_cast<uint32_t
>(LOOPS_CEIL_F);
153 (void)SetSwdioSampleMode();
161 (void)SetSwdioDriveMode();
198 if (half_period_loops_ == 0u)
200 return TransferWithoutDelay(req, resp);
204 return TransferWithDelay(req, resp);
213 (void)SetSwdioDriveMode();
216 for (uint32_t i = 0; i < cycles; ++i)
224 ErrorCode SeqWriteBits(uint32_t cycles,
const uint8_t* data_lsb_first)
override
231 if (data_lsb_first ==
nullptr)
236 (void)SetSwdioDriveMode();
241 for (uint32_t i = 0; i < cycles; ++i)
243 const bool BIT = (((data_lsb_first[i / 8u] >> (i & 7u)) & 0x01u) != 0u);
256 ErrorCode SeqReadBits(uint32_t cycles, uint8_t* out_lsb_first)
override
263 if (out_lsb_first ==
nullptr)
268 const uint32_t BYTES = (cycles + 7u) / 8u;
271 (void)SetSwdioSampleMode();
276 for (uint32_t i = 0; i < cycles; ++i)
280 if (half_period_loops_ == 0u)
297 out_lsb_first[i / 8u] =
298 static_cast<uint8_t
>(out_lsb_first[i / 8u] | (1u << (i & 7u)));
309 static inline uint8_t MakeReq(
bool apndp,
bool rnw, uint8_t addr2b)
311 const uint8_t A2 = addr2b & 0x1u;
312 const uint8_t A3 = (addr2b >> 1) & 0x1u;
313 const uint8_t PAR =
static_cast<uint8_t
>((apndp ^ rnw ^ A2 ^ A3) & 0x1u);
317 return static_cast<uint8_t
>((1u << 0) | (
static_cast<uint8_t
>(apndp) << 1) |
318 (
static_cast<uint8_t
>(rnw) << 2) |
319 (
static_cast<uint8_t
>(A2) << 3) |
320 (
static_cast<uint8_t
>(A3) << 4) |
321 (
static_cast<uint8_t
>(PAR) << 5) | (0u << 6) | (1u << 7));
330 static constexpr uint8_t LUT[16] = {
331 0, 1, 1, 0, 1, 0, 0, 1,
332 1, 0, 0, 1, 0, 1, 1, 0};
337 static inline SwdProtocol::Ack DecodeAck(uint8_t ack_bits)
342 return SwdProtocol::Ack::OK;
344 return SwdProtocol::Ack::WAIT;
346 return SwdProtocol::Ack::FAULT;
348 return SwdProtocol::Ack::NO_ACK;
350 return SwdProtocol::Ack::PROTOCOL;
371 swdio_.SetConfig({(kIoDriveMode == SwdIoDriveMode::OPEN_DRAIN)
372 ? SwdioGpioType::Direction::OUTPUT_OPEN_DRAIN
373 : SwdioGpioType::Direction::OUTPUT_PUSH_PULL,
374 SwdioGpioType::Pull::NONE});
394 swdio_.SetConfig({SwdioGpioType::Direction::INPUT, SwdioGpioType::Pull::UP});
405 inline void DelayHalf() { BusyLoop(half_period_loops_); }
407 inline void GenOneClk()
415 inline void GenOneClkWithoutDelay()
421 inline void WriteBit(
bool bit)
427 inline void WriteBitWithoutDelay(
bool bit)
430 GenOneClkWithoutDelay();
433 inline void WriteByteLSB(uint8_t b)
437 WriteBit(((b >> i) & 0x1u) != 0u);
441 inline void WriteByteLSBWithoutDelay(uint8_t b)
445 WriteBitWithoutDelay(((b >> i) & 0x1u) != 0u);
449 inline bool ReadBitAndClock()
453 const bool BIT =
swdio_.Read();
459 inline bool ReadBitAndClockWithoutDelay()
462 const bool BIT =
swdio_.Read();
467 inline uint8_t ReadByteLSB()
472 if (ReadBitAndClock())
474 v =
static_cast<uint8_t
>(v | (1u << i));
480 inline uint8_t ReadByteLSBWithoutDelay()
483 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x01u : 0u);
484 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x02u : 0u);
485 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x04u : 0u);
486 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x08u : 0u);
487 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x10u : 0u);
488 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x20u : 0u);
489 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x40u : 0u);
490 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x80u : 0u);
494 static void BusyLoop(uint32_t loops)
496 volatile uint32_t sink = loops;
503 ErrorCode TransferWithDelay(
const SwdProtocol::Request& req,
504 SwdProtocol::Response& resp)
506 resp.ack = SwdProtocol::Ack::PROTOCOL;
508 resp.parity_ok =
true;
510 const bool APNDP = (req.port == SwdProtocol::Port::AP);
511 const uint8_t REQUEST_BYTE = MakeReq(APNDP, req.rnw, req.addr2b);
513 (void)SetSwdioDriveMode();
514 WriteByteLSB(REQUEST_BYTE);
516 (void)SetSwdioSampleMode();
520 uint8_t ack_raw = 0u;
521 for (uint32_t i = 0; i <
ACK_BITS; ++i)
523 if (ReadBitAndClock())
525 ack_raw |=
static_cast<uint8_t
>(1u << i);
528 resp.ack = DecodeAck(
static_cast<uint8_t
>(ack_raw & 0x7u));
530 if (resp.ack != SwdProtocol::Ack::OK)
533 (void)SetSwdioDriveMode();
542 for (uint32_t
byte = 0;
byte < 4u; ++byte)
544 const uint32_t B = ReadByteLSB();
545 data |= (B << (8u * byte));
548 const bool PARITY_BIT = ReadBitAndClock();
550 resp.parity_ok = (
static_cast<uint8_t
>(PARITY_BIT) ==
Parity32(data));
552 (void)SetSwdioDriveMode();
560 (void)SetSwdioDriveMode();
563 const uint32_t DATA = req.wdata;
564 for (uint32_t
byte = 0;
byte < 4u; ++byte)
566 const uint8_t B =
static_cast<uint8_t
>((DATA >> (8u * byte)) & 0xFFu);
570 const bool PARITY_BIT = (
Parity32(DATA) & 0x1u) != 0u;
571 WriteBit(PARITY_BIT);
580 ErrorCode TransferWithoutDelay(
const SwdProtocol::Request& req,
581 SwdProtocol::Response& resp)
583 resp.ack = SwdProtocol::Ack::PROTOCOL;
585 resp.parity_ok =
true;
587 const bool APNDP = (req.port == SwdProtocol::Port::AP);
588 const uint8_t REQUEST_BYTE = MakeReq(APNDP, req.rnw, req.addr2b);
590 (void)SetSwdioDriveMode();
591 WriteByteLSBWithoutDelay(REQUEST_BYTE);
593 (void)SetSwdioSampleMode();
594 GenOneClkWithoutDelay();
597 uint8_t ack_raw = 0u;
598 for (uint32_t i = 0; i <
ACK_BITS; ++i)
600 if (ReadBitAndClockWithoutDelay())
602 ack_raw |=
static_cast<uint8_t
>(1u << i);
605 resp.ack = DecodeAck(
static_cast<uint8_t
>(ack_raw & 0x7u));
607 if (resp.ack != SwdProtocol::Ack::OK)
609 GenOneClkWithoutDelay();
610 (void)SetSwdioDriveMode();
619 for (uint32_t
byte = 0;
byte < 4u; ++byte)
621 const uint32_t B = ReadByteLSBWithoutDelay();
622 data |= (B << (8u * byte));
625 const bool PARITY_BIT = ReadBitAndClockWithoutDelay();
627 resp.parity_ok = (
static_cast<uint8_t
>(PARITY_BIT) ==
Parity32(data));
629 (void)SetSwdioDriveMode();
631 GenOneClkWithoutDelay();
637 (void)SetSwdioDriveMode();
638 GenOneClkWithoutDelay();
640 const uint32_t DATA = req.wdata;
641 for (uint32_t
byte = 0;
byte < 4u; ++byte)
643 const uint8_t B =
static_cast<uint8_t
>((DATA >> (8u * byte)) & 0xFFu);
644 WriteByteLSBWithoutDelay(B);
647 const bool PARITY_BIT = (
Parity32(DATA) & 0x1u) != 0u;
648 WriteBitWithoutDelay(PARITY_BIT);
675 uint32_t loops_per_us_ = 0u;
676 uint32_t half_period_ns_ = 0u;
677 uint32_t half_period_loops_ = 0u;