@@ -9,6 +9,7 @@ mod request;
9
9
mod response;
10
10
mod state;
11
11
12
+ use bitflags:: bitflags;
12
13
pub use command:: * ;
13
14
pub use request:: * ;
14
15
pub use response:: * ;
@@ -35,13 +36,26 @@ pub struct TransferConfig {
35
36
pub match_mask : u32 ,
36
37
}
37
38
39
+ bitflags ! {
40
+ struct Capabilities : u8 {
41
+ const SWD = 0x01 ;
42
+ const JTAG = 0x02 ;
43
+ const SWO_UART = 0x04 ;
44
+ const SWO_MANCHESTER = 0x08 ;
45
+ const ATOMIC_COMMANDS = 0x10 ;
46
+ const TEST_DOMAIN_TIMER = 0x20 ;
47
+ const SWO_STREAMING = 0x40 ;
48
+ }
49
+ }
50
+
38
51
/// DAP handler.
39
52
pub struct Dap < ' a , DEPS , LEDS , WAIT , JTAG , SWD , SWO > {
40
53
state : State < DEPS , SWD , JTAG > ,
41
54
swo : Option < SWO > ,
42
55
swo_streaming : bool ,
43
56
version_string : & ' a str ,
44
57
transfer_config : TransferConfig ,
58
+ capabilities : Capabilities ,
45
59
// mode: Option<DapMode>,
46
60
leds : LEDS ,
47
61
wait : WAIT ,
64
78
swo : Option < SWO > ,
65
79
version_string : & ' a str ,
66
80
) -> Self {
67
- // TODO: Replace with const assert
68
- assert ! ( SWD :: AVAILABLE || JTAG :: AVAILABLE ) ;
81
+ assert ! ( SWD :: available( & dependencies) || JTAG :: available( & dependencies) ) ;
82
+
83
+ let capabilities = {
84
+ let mut caps = Capabilities :: empty ( ) ;
85
+
86
+ // Bit 0: SWD optional
87
+ if SWD :: available ( & dependencies) {
88
+ caps. insert ( Capabilities :: SWD ) ;
89
+ }
90
+ // Bit 1: JTAG optional
91
+ if JTAG :: available ( & dependencies) {
92
+ caps. insert ( Capabilities :: JTAG ) ;
93
+ }
94
+ // Bit 2: SWO UART optional
95
+ // Bit 3: SWO Manchester optional
96
+ if let Some ( swo) = & swo {
97
+ if swo. support ( ) . uart {
98
+ caps. insert ( Capabilities :: SWO_UART ) ;
99
+ }
100
+ if swo. support ( ) . manchester {
101
+ caps. insert ( Capabilities :: SWO_MANCHESTER ) ;
102
+ }
103
+ }
104
+ // Bit 4: Atomic commands not supported
105
+ // Bit 5: Test Domain Timer not supported
106
+ // Bit 6: SWO Streaming Trace supported
107
+ if swo. is_some ( ) {
108
+ // TODO this depends on the transport layer
109
+ caps. insert ( Capabilities :: SWO_STREAMING ) ;
110
+ }
111
+ caps
112
+ } ;
69
113
70
114
Dap {
71
115
state : State :: new ( dependencies) ,
81
125
// mode: None,
82
126
leds,
83
127
wait,
128
+ capabilities,
84
129
}
85
130
}
86
131
@@ -152,7 +197,7 @@ where
152
197
}
153
198
}
154
199
155
- fn process_info ( & mut self , mut req : Request , resp : & mut ResponseWriter , version : DapVersion ) {
200
+ fn process_info ( & self , mut req : Request , resp : & mut ResponseWriter , version : DapVersion ) {
156
201
match DapInfoID :: try_from ( req. next_u8 ( ) ) {
157
202
// Return 0-length string for VendorID, ProductID, SerialNumber
158
203
// to indicate they should be read from USB descriptor instead
@@ -170,25 +215,7 @@ where
170
215
Ok ( DapInfoID :: TargetName ) => resp. write_u8 ( 0 ) ,
171
216
Ok ( DapInfoID :: Capabilities ) => {
172
217
resp. write_u8 ( 1 ) ;
173
- // Bit 0: SWD supported
174
- // Bit 1: JTAG supported
175
- // Bit 2: SWO UART supported
176
- // Bit 3: SWO Manchester not supported
177
- // Bit 4: Atomic commands not supported
178
- // Bit 5: Test Domain Timer not supported
179
- // Bit 6: SWO Streaming Trace supported
180
- let swd = ( SWD :: AVAILABLE as u8 ) << 0 ;
181
- let jtag = ( JTAG :: AVAILABLE as u8 ) << 1 ;
182
- let swo = match & self . swo {
183
- Some ( swo) => {
184
- let support = swo. support ( ) ;
185
- ( support. uart as u8 ) << 2 | ( support. manchester as u8 ) << 3
186
- }
187
- None => 0 ,
188
- } ;
189
- let atomic = 0 << 4 ;
190
- let swo_streaming = 1 << 6 ;
191
- resp. write_u8 ( swd | jtag | swo | atomic | swo_streaming) ;
218
+ resp. write_u8 ( self . capabilities . bits ) ;
192
219
}
193
220
Ok ( DapInfoID :: SWOTraceBufferSize ) => {
194
221
resp. write_u8 ( 4 ) ;
@@ -249,11 +276,15 @@ where
249
276
info ! (
250
277
"DAP connect: {}, SWD: {}, JTAG: {}" ,
251
278
port,
252
- SWD :: AVAILABLE ,
253
- JTAG :: AVAILABLE
279
+ self . capabilities . contains ( Capabilities :: SWD ) ,
280
+ self . capabilities . contains ( Capabilities :: JTAG ) ,
254
281
) ;
255
282
256
- match ( SWD :: AVAILABLE , JTAG :: AVAILABLE , port) {
283
+ match (
284
+ self . capabilities . contains ( Capabilities :: SWD ) ,
285
+ self . capabilities . contains ( Capabilities :: JTAG ) ,
286
+ port,
287
+ ) {
257
288
// SWD
258
289
( true , true , ConnectPort :: Default )
259
290
| ( true , true , ConnectPort :: SWD )
@@ -298,8 +329,8 @@ where
298
329
299
330
let idx = req. next_u8 ( ) ;
300
331
let word = req. next_u32 ( ) ;
301
- match ( SWD :: AVAILABLE , JTAG :: AVAILABLE , & mut self . state ) {
302
- ( _ , true , State :: Jtag ( jtag) ) => {
332
+ match & mut self . state {
333
+ State :: Jtag ( jtag) => {
303
334
let config = jtag. config ( ) ;
304
335
if !config. select_index ( idx) {
305
336
resp. write_err ( ) ;
@@ -311,16 +342,14 @@ where
311
342
312
343
resp. write_ok ( ) ;
313
344
}
314
- ( true , _ , State :: Swd ( swd) ) => {
345
+ State :: Swd ( swd) => {
315
346
let wait_retries = self . transfer_config . wait_retries ;
316
347
match swd. write_dp ( wait_retries, swd:: DPRegister :: DPIDR , word) {
317
348
Ok ( _) => resp. write_ok ( ) ,
318
349
Err ( _) => resp. write_err ( ) ,
319
350
}
320
351
}
321
- _ => {
322
- resp. write_err ( ) ;
323
- }
352
+ _ => resp. write_err ( ) ,
324
353
}
325
354
}
326
355
0 commit comments