34 static constexpr uint32_t MIN_HZ = 50'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 uint64_t DEN =
static_cast<uint64_t
>(2u) *
static_cast<uint64_t
>(hz);
114 static_cast<uint32_t
>((
static_cast<uint64_t
>(NS_PER_SEC) + DEN - 1u) / DEN);
116 if (loops_per_us_ == 0u)
118 half_period_loops_ = 0u;
122 const uint64_t loops_num =
123 static_cast<uint64_t
>(loops_per_us_) *
static_cast<uint64_t
>(half_period_ns_);
125 if (loops_num <
static_cast<uint64_t
>(LOOPS_SCALE))
127 half_period_loops_ = 0u;
131 const uint64_t loops_ceil = (loops_num +
static_cast<uint64_t
>(LOOPS_SCALE) - 1u) /
132 static_cast<uint64_t
>(LOOPS_SCALE);
133 half_period_loops_ = (loops_ceil >=
static_cast<uint64_t
>(UINT32_MAX))
135 :
static_cast<uint32_t
>(loops_ceil);
149 (void)SetSwdioSampleMode();
157 (void)SetSwdioDriveMode();
194 if (half_period_loops_ == 0u)
196 return TransferWithoutDelay(req, resp);
200 return TransferWithDelay(req, resp);
209 (void)SetSwdioDriveMode();
212 for (uint32_t i = 0; i < cycles; ++i)
220 ErrorCode SeqWriteBits(uint32_t cycles,
const uint8_t* data_lsb_first)
override
227 if (data_lsb_first ==
nullptr)
232 (void)SetSwdioDriveMode();
237 for (uint32_t i = 0; i < cycles; ++i)
239 const bool BIT = (((data_lsb_first[i / 8u] >> (i & 7u)) & 0x01u) != 0u);
253 ErrorCode SeqReadBits(uint32_t cycles, uint8_t* out_lsb_first)
override
260 if (out_lsb_first ==
nullptr)
265 const uint32_t BYTES = (cycles + 7u) / 8u;
268 (void)SetSwdioSampleMode();
273 for (uint32_t i = 0; i < cycles; ++i)
277 if (half_period_loops_ == 0u)
294 out_lsb_first[i / 8u] =
295 static_cast<uint8_t
>(out_lsb_first[i / 8u] | (1u << (i & 7u)));
306 static inline uint8_t MakeReq(
bool apndp,
bool rnw, uint8_t addr2b)
308 const uint8_t A2 = addr2b & 0x1u;
309 const uint8_t A3 = (addr2b >> 1) & 0x1u;
310 const uint8_t PAR =
static_cast<uint8_t
>((apndp ^ rnw ^ A2 ^ A3) & 0x1u);
314 return static_cast<uint8_t
>((1u << 0) | (
static_cast<uint8_t
>(apndp) << 1) |
315 (
static_cast<uint8_t
>(rnw) << 2) |
316 (
static_cast<uint8_t
>(A2) << 3) |
317 (
static_cast<uint8_t
>(A3) << 4) |
318 (
static_cast<uint8_t
>(PAR) << 5) | (0u << 6) | (1u << 7));
327 static constexpr uint8_t LUT[16] = {
328 0, 1, 1, 0, 1, 0, 0, 1,
329 1, 0, 0, 1, 0, 1, 1, 0};
334 static inline SwdProtocol::Ack DecodeAck(uint8_t ack_bits)
339 return SwdProtocol::Ack::OK;
341 return SwdProtocol::Ack::WAIT;
343 return SwdProtocol::Ack::FAULT;
345 return SwdProtocol::Ack::NO_ACK;
347 return SwdProtocol::Ack::PROTOCOL;
368 swdio_.SetConfig({(IO_DRIVE_MODE == SwdIoDriveMode::OPEN_DRAIN)
369 ? SwdioGpioType::Direction::OUTPUT_OPEN_DRAIN
370 : SwdioGpioType::Direction::OUTPUT_PUSH_PULL,
371 SwdioGpioType::Pull::NONE});
391 swdio_.SetConfig({SwdioGpioType::Direction::INPUT, SwdioGpioType::Pull::UP});
402 inline void DelayHalf() { BusyLoop(half_period_loops_); }
404 inline void GenOneClk()
412 inline void GenOneClkWithoutDelay()
418 inline void WriteBit(
bool bit)
424 inline void WriteBitWithoutDelay(
bool bit)
427 GenOneClkWithoutDelay();
430 inline void WriteByteLSB(uint8_t b)
434 WriteBit(((b >> i) & 0x1u) != 0u);
438 inline void WriteByteLSBWithoutDelay(uint8_t b)
442 WriteBitWithoutDelay(((b >> i) & 0x1u) != 0u);
446 inline bool ReadBitAndClock()
450 const bool BIT =
swdio_.Read();
456 inline bool ReadBitAndClockWithoutDelay()
459 const bool BIT =
swdio_.Read();
464 inline uint8_t ReadByteLSB()
469 if (ReadBitAndClock())
471 v =
static_cast<uint8_t
>(v | (1u << i));
477 inline uint8_t ReadByteLSBWithoutDelay()
480 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x01u : 0u);
481 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x02u : 0u);
482 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x04u : 0u);
483 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x08u : 0u);
484 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x10u : 0u);
485 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x20u : 0u);
486 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x40u : 0u);
487 v |=
static_cast<uint8_t
>(ReadBitAndClockWithoutDelay() ? 0x80u : 0u);
491 static void BusyLoop(uint32_t loops)
493 volatile uint32_t sink = loops;
500 ErrorCode TransferWithDelay(
const SwdProtocol::Request& req,
501 SwdProtocol::Response& resp)
503 resp.ack = SwdProtocol::Ack::PROTOCOL;
505 resp.parity_ok =
true;
507 const bool APNDP = (req.port == SwdProtocol::Port::AP);
508 const uint8_t REQUEST_BYTE = MakeReq(APNDP, req.rnw, req.addr2b);
510 (void)SetSwdioDriveMode();
511 WriteByteLSB(REQUEST_BYTE);
513 (void)SetSwdioSampleMode();
517 uint8_t ack_raw = 0u;
518 for (uint32_t i = 0; i <
ACK_BITS; ++i)
520 if (ReadBitAndClock())
522 ack_raw |=
static_cast<uint8_t
>(1u << i);
525 resp.ack = DecodeAck(
static_cast<uint8_t
>(ack_raw & 0x7u));
527 if (resp.ack != SwdProtocol::Ack::OK)
530 (void)SetSwdioDriveMode();
539 for (uint32_t
byte = 0;
byte < 4u; ++byte)
541 const uint32_t B = ReadByteLSB();
542 data |= (B << (8u * byte));
545 const bool PARITY_BIT = ReadBitAndClock();
547 resp.parity_ok = (
static_cast<uint8_t
>(PARITY_BIT) ==
Parity32(data));
549 (void)SetSwdioDriveMode();
557 (void)SetSwdioDriveMode();
560 const uint32_t DATA = req.wdata;
561 for (uint32_t
byte = 0;
byte < 4u; ++byte)
563 const uint8_t B =
static_cast<uint8_t
>((DATA >> (8u * byte)) & 0xFFu);
567 const bool PARITY_BIT = (
Parity32(DATA) & 0x1u) != 0u;
568 WriteBit(PARITY_BIT);
577 ErrorCode TransferWithoutDelay(
const SwdProtocol::Request& req,
578 SwdProtocol::Response& resp)
580 resp.ack = SwdProtocol::Ack::PROTOCOL;
582 resp.parity_ok =
true;
584 const bool APNDP = (req.port == SwdProtocol::Port::AP);
585 const uint8_t REQUEST_BYTE = MakeReq(APNDP, req.rnw, req.addr2b);
587 (void)SetSwdioDriveMode();
588 WriteByteLSBWithoutDelay(REQUEST_BYTE);
590 (void)SetSwdioSampleMode();
591 GenOneClkWithoutDelay();
594 uint8_t ack_raw = 0u;
595 for (uint32_t i = 0; i <
ACK_BITS; ++i)
597 if (ReadBitAndClockWithoutDelay())
599 ack_raw |=
static_cast<uint8_t
>(1u << i);
602 resp.ack = DecodeAck(
static_cast<uint8_t
>(ack_raw & 0x7u));
604 if (resp.ack != SwdProtocol::Ack::OK)
606 GenOneClkWithoutDelay();
607 (void)SetSwdioDriveMode();
616 for (uint32_t
byte = 0;
byte < 4u; ++byte)
618 const uint32_t B = ReadByteLSBWithoutDelay();
619 data |= (B << (8u * byte));
622 const bool PARITY_BIT = ReadBitAndClockWithoutDelay();
624 resp.parity_ok = (
static_cast<uint8_t
>(PARITY_BIT) ==
Parity32(data));
626 (void)SetSwdioDriveMode();
628 GenOneClkWithoutDelay();
634 (void)SetSwdioDriveMode();
635 GenOneClkWithoutDelay();
637 const uint32_t DATA = req.wdata;
638 for (uint32_t
byte = 0;
byte < 4u; ++byte)
640 const uint8_t B =
static_cast<uint8_t
>((DATA >> (8u * byte)) & 0xFFu);
641 WriteByteLSBWithoutDelay(B);
644 const bool PARITY_BIT = (
Parity32(DATA) & 0x1u) != 0u;
645 WriteBitWithoutDelay(PARITY_BIT);
672 uint32_t loops_per_us_ = 0u;
673 uint32_t half_period_ns_ = 0u;
674 uint32_t half_period_loops_ = 0u;