probe_rs/probe/cmsisdap/commands/
swo.rs1use scroll::{LE, Pread};
2
3use super::{CommandId, Request, SendError, Status};
4
5#[repr(u8)]
6#[expect(unused)]
7#[derive(Copy, Clone, Debug)]
8pub enum TransportRequest {
9 NoTransport = 0,
10 DataCommand = 1,
11 WinUsbEndpoint = 2,
12}
13
14impl Request for TransportRequest {
15 const COMMAND_ID: CommandId = CommandId::SwoTransport;
16
17 type Response = TransportResponse;
18
19 fn to_bytes(&self, buffer: &mut [u8]) -> Result<usize, SendError> {
20 buffer[0] = *self as u8;
21 Ok(1)
22 }
23
24 fn parse_response(&self, buffer: &[u8]) -> Result<Self::Response, SendError> {
25 Ok(TransportResponse {
26 status: Status::from_byte(buffer[0])?,
27 })
28 }
29}
30
31#[derive(Debug)]
32pub struct TransportResponse {
33 pub(crate) status: Status,
34}
35
36#[repr(u8)]
37#[expect(unused)]
38#[derive(Copy, Clone, Debug)]
39pub enum ModeRequest {
40 Off = 0,
41 Uart = 1,
42 Manchester = 2,
43}
44
45impl Request for ModeRequest {
46 const COMMAND_ID: CommandId = CommandId::SwoMode;
47
48 type Response = ModeResponse;
49
50 fn to_bytes(&self, buffer: &mut [u8]) -> Result<usize, SendError> {
51 buffer[0] = *self as u8;
52 Ok(1)
53 }
54
55 fn parse_response(&self, buffer: &[u8]) -> Result<Self::Response, SendError> {
56 Ok(ModeResponse {
57 status: Status::from_byte(buffer[0])?,
58 })
59 }
60}
61
62#[derive(Debug)]
63pub struct ModeResponse {
64 pub(crate) status: Status,
65}
66
67#[derive(Copy, Clone, Debug)]
68pub struct BaudrateRequest {
69 pub(crate) baudrate: u32,
70}
71
72impl Request for BaudrateRequest {
73 const COMMAND_ID: CommandId = CommandId::SwoBaudrate;
74
75 type Response = u32;
76
77 fn to_bytes(&self, buffer: &mut [u8]) -> Result<usize, SendError> {
78 assert!(
79 buffer.len() >= 4,
80 "Buffer for CMSIS-DAP command is too small. This is a bug, please report it."
81 );
82 buffer[0..4].copy_from_slice(&self.baudrate.to_le_bytes());
83 Ok(4)
84 }
85
86 fn parse_response(&self, buffer: &[u8]) -> Result<Self::Response, SendError> {
87 if buffer.len() < 4 {
88 return Err(SendError::NotEnoughData);
89 }
90
91 let baud: u32 = buffer
92 .pread_with(0, LE)
93 .map_err(|_| SendError::NotEnoughData)?;
94
95 Ok(baud)
96 }
97}
98
99#[repr(u8)]
100#[derive(Copy, Clone, Debug)]
101pub enum ControlRequest {
102 Stop = 0,
103 Start = 1,
104}
105
106impl Request for ControlRequest {
107 const COMMAND_ID: CommandId = CommandId::SwoControl;
108
109 type Response = ControlResponse;
110
111 fn to_bytes(&self, buffer: &mut [u8]) -> Result<usize, SendError> {
112 buffer[0] = *self as u8;
113 Ok(1)
114 }
115
116 fn parse_response(&self, buffer: &[u8]) -> Result<Self::Response, SendError> {
117 Ok(ControlResponse {
118 status: Status::from_byte(buffer[0])?,
119 })
120 }
121}
122
123#[derive(Debug)]
124pub struct ControlResponse {
125 pub(crate) status: Status,
126}
127
128#[derive(Debug)]
129pub struct StatusRequest;
130
131impl Request for StatusRequest {
132 const COMMAND_ID: CommandId = CommandId::SwoStatus;
133
134 type Response = StatusResponse;
135
136 fn to_bytes(&self, _buffer: &mut [u8]) -> Result<usize, SendError> {
137 Ok(0)
138 }
139
140 fn parse_response(&self, buffer: &[u8]) -> Result<Self::Response, SendError> {
141 let status = TraceStatus::from(buffer[0]);
142 let count = u32::from_le_bytes(
143 buffer[1..5]
144 .try_into()
145 .map_err(|_| SendError::NotEnoughData)?,
146 );
147 Ok(StatusResponse {
148 _status: status,
149 _count: count,
150 })
151 }
152}
153
154#[derive(Copy, Clone, Debug)]
155pub struct TraceStatus {
156 pub(crate) _active: bool,
157 pub(crate) error: bool,
158 pub(crate) _overrun: bool,
159}
160
161impl From<u8> for TraceStatus {
162 fn from(value: u8) -> Self {
163 Self {
164 _active: value & (1 << 0) != 0,
165 error: value & (1 << 6) != 0,
166 _overrun: value & (1 << 7) != 0,
167 }
168 }
169}
170
171#[derive(Debug)]
172pub struct StatusResponse {
173 pub(crate) _status: TraceStatus,
174 pub(crate) _count: u32,
175}
176
177#[derive(Debug)]
178pub struct ExtendedStatusRequest {
179 pub(crate) request_status: bool,
180 pub(crate) request_count: bool,
181 pub(crate) request_index_timestamp: bool,
182}
183
184impl Request for ExtendedStatusRequest {
185 const COMMAND_ID: CommandId = CommandId::SwoExtendedStatus;
186
187 type Response = ExtendedStatusResponse;
188
189 fn to_bytes(&self, buffer: &mut [u8]) -> Result<usize, SendError> {
190 let control = (self.request_status as u8)
191 | ((self.request_count as u8) << 1)
192 | ((self.request_index_timestamp as u8) << 2);
193 buffer[0] = control;
194 Ok(1)
195 }
196
197 fn parse_response(&self, buffer: &[u8]) -> Result<Self::Response, SendError> {
198 if buffer.len() < 13 {
199 return Err(SendError::NotEnoughData);
200 }
201
202 let status = TraceStatus::from(buffer[0]);
203 let count = u32::from_le_bytes(
204 buffer[1..5]
205 .try_into()
206 .map_err(|_| SendError::NotEnoughData)?,
207 );
208 let index = u32::from_le_bytes(
209 buffer[5..9]
210 .try_into()
211 .map_err(|_| SendError::NotEnoughData)?,
212 );
213 let timestamp = u32::from_le_bytes(
214 buffer[9..13]
215 .try_into()
216 .map_err(|_| SendError::NotEnoughData)?,
217 );
218 Ok(ExtendedStatusResponse {
219 _status: status,
220 _count: count,
221 _index: index,
222 _timestamp: timestamp,
223 })
224 }
225}
226
227#[derive(Debug)]
228pub struct ExtendedStatusResponse {
229 pub(crate) _status: TraceStatus,
230 pub(crate) _count: u32,
231 pub(crate) _index: u32,
232 pub(crate) _timestamp: u32,
233}
234
235#[derive(Debug)]
236pub struct DataRequest {
237 pub(crate) max_count: u16,
238}
239
240impl Request for DataRequest {
241 const COMMAND_ID: CommandId = CommandId::SwoData;
242
243 type Response = DataResponse;
244
245 fn to_bytes(&self, buffer: &mut [u8]) -> Result<usize, SendError> {
246 assert!(
247 buffer.len() >= 2,
248 "Buffer for CMSIS-DAP command is too small. This is a bug, please report it."
249 );
250 buffer[0..2].copy_from_slice(&self.max_count.to_le_bytes());
251 Ok(2)
252 }
253
254 fn parse_response(&self, buffer: &[u8]) -> Result<Self::Response, SendError> {
255 let status = TraceStatus::from(buffer[0]);
256 let count = u16::from_le_bytes(
257 buffer[1..3]
258 .try_into()
259 .map_err(|_| SendError::NotEnoughData)?,
260 );
261 let start = 3;
262 let end = start + count as usize;
263 if end > buffer.len() {
264 return Err(SendError::NotEnoughData);
265 }
266
267 Ok(DataResponse {
268 status,
269 data: buffer[start..end].to_vec(),
270 })
271 }
272}
273
274#[derive(Debug)]
275pub struct DataResponse {
276 pub(crate) status: TraceStatus,
277 pub(crate) data: Vec<u8>,
278}