1use num_enum::{IntoPrimitive, TryFromPrimitive};
2
3#[derive(Copy, Clone, Debug, PartialEq, Eq)]
5#[cfg_attr(feature = "defmt", derive(defmt::Format))]
6pub enum Error {
7 BadParity,
9 AckWait,
11 AckFault,
13 AckProtocol,
15 AckUnknown(u8),
17}
18
19pub type Result<T> = core::result::Result<T, Error>;
21
22#[repr(u8)]
24#[derive(PartialEq, Eq, Copy, Clone, Debug, IntoPrimitive, TryFromPrimitive)]
25#[cfg_attr(feature = "defmt", derive(defmt::Format))]
26#[allow(missing_docs)]
27pub enum DPRegister {
28 DPIDR = 0,
29 CTRLSTAT = 1,
30 SELECT = 2,
31 RDBUFF = 3,
32}
33
34#[repr(u8)]
36#[derive(PartialEq, Eq, Copy, Clone, Debug, TryFromPrimitive)]
37#[cfg_attr(feature = "defmt", derive(defmt::Format))]
38pub enum APnDP {
39 DP = 0,
41 AP = 1,
43}
44
45#[repr(u8)]
47#[derive(PartialEq, Eq, Copy, Clone, Debug, TryFromPrimitive)]
48#[cfg_attr(feature = "defmt", derive(defmt::Format))]
49pub enum RnW {
50 W = 0,
52 R = 1,
54}
55
56#[repr(u8)]
58#[derive(PartialEq, Eq, Copy, Clone, Debug)]
59#[cfg_attr(feature = "defmt", derive(defmt::Format))]
60#[allow(missing_docs)]
61pub enum Ack {
62 Ok = 0b001,
63 Wait = 0b010,
64 Fault = 0b100,
65 Protocol = 0b111,
66}
67
68impl Ack {
69 pub fn try_ok(ack: u8) -> Result<()> {
71 match ack {
72 v if v == (Ack::Ok as u8) => Ok(()),
73 v if v == (Ack::Wait as u8) => Err(Error::AckWait),
74 v if v == (Ack::Fault as u8) => Err(Error::AckFault),
75 v if v == (Ack::Protocol as u8) => Err(Error::AckProtocol),
76 _ => Err(Error::AckUnknown(ack)),
77 }
78 }
79}
80
81#[derive(Copy, Clone, Debug, TryFromPrimitive, PartialEq, Eq)]
83#[cfg_attr(feature = "defmt", derive(defmt::Format))]
84#[allow(missing_docs)]
85#[repr(u8)]
86pub enum TurnaroundPeriod {
87 Cycles1 = 0b00,
88 Cycles2 = 0b01,
89 Cycles3 = 0b10,
90 Cycles4 = 0b11,
91}
92
93#[derive(Copy, Clone, Debug, TryFromPrimitive, PartialEq, Eq)]
95#[cfg_attr(feature = "defmt", derive(defmt::Format))]
96#[allow(missing_docs)]
97#[repr(u8)]
98pub enum DataPhase {
99 NoDataPhase = 0,
100 AlwaysDataPhase = 1,
101}
102
103pub trait Swd<DEPS>: From<DEPS> {
105 const AVAILABLE: bool;
107
108 fn read(&mut self, wait_retries: usize, apndp: APnDP, a: DPRegister) -> Result<u32> {
110 for _ in 0..wait_retries {
111 match self.read_inner(apndp, a) {
112 Err(Error::AckWait) => continue,
113 x => return x,
114 }
115 }
116
117 Err(Error::AckWait)
118 }
119
120 fn read_inner(&mut self, apndp: APnDP, a: DPRegister) -> Result<u32>;
122
123 fn write(&mut self, wait_retries: usize, apndp: APnDP, a: DPRegister, data: u32) -> Result<()> {
125 for _ in 0..wait_retries {
126 match self.write_inner(apndp, a, data) {
127 Err(Error::AckWait) => continue,
128 x => return x,
129 }
130 }
131
132 Err(Error::AckWait)
133 }
134
135 fn write_inner(&mut self, apndp: APnDP, a: DPRegister, data: u32) -> Result<()>;
137
138 fn read_dp(&mut self, wait_retries: usize, a: DPRegister) -> Result<u32> {
140 self.read(wait_retries, APnDP::DP, a)
141 }
142
143 fn write_dp(&mut self, wait_retries: usize, a: DPRegister, data: u32) -> Result<()> {
145 self.write(wait_retries, APnDP::DP, a, data)
146 }
147
148 fn read_ap(&mut self, wait_retries: usize, a: DPRegister) -> Result<u32> {
150 self.read(wait_retries, APnDP::AP, a)
151 }
152
153 fn set_clock(&mut self, max_frequency: u32) -> bool;
155
156 fn write_sequence(&mut self, num_bits: usize, data: &[u8]) -> Result<()>;
158
159 fn read_sequence(&mut self, num_bits: usize, data: &mut [u8]) -> Result<()>;
161}
162
163pub fn make_request(apndp: APnDP, rnw: RnW, a: DPRegister) -> u8 {
165 let req = 1 | ((apndp as u8) << 1) | ((rnw as u8) << 2) | ((a as u8) << 3) | (1 << 7);
166 let parity = (req.count_ones() & 1) as u8;
167 req | (parity << 5)
168}