Skip to content

Commit 92aa4a6

Browse files
committed
Let impl decide JTAG/SWD in runtime
1 parent 8e29465 commit 92aa4a6

File tree

4 files changed

+70
-37
lines changed

4 files changed

+70
-37
lines changed

src/dap.rs

Lines changed: 60 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod request;
99
mod response;
1010
mod state;
1111

12+
use bitflags::bitflags;
1213
pub use command::*;
1314
pub use request::*;
1415
pub use response::*;
@@ -35,13 +36,26 @@ pub struct TransferConfig {
3536
pub match_mask: u32,
3637
}
3738

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+
3851
/// DAP handler.
3952
pub struct Dap<'a, DEPS, LEDS, WAIT, JTAG, SWD, SWO> {
4053
state: State<DEPS, SWD, JTAG>,
4154
swo: Option<SWO>,
4255
swo_streaming: bool,
4356
version_string: &'a str,
4457
transfer_config: TransferConfig,
58+
capabilities: Capabilities,
4559
// mode: Option<DapMode>,
4660
leds: LEDS,
4761
wait: WAIT,
@@ -64,8 +78,38 @@ where
6478
swo: Option<SWO>,
6579
version_string: &'a str,
6680
) -> 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+
};
69113

70114
Dap {
71115
state: State::new(dependencies),
@@ -81,6 +125,7 @@ where
81125
// mode: None,
82126
leds,
83127
wait,
128+
capabilities,
84129
}
85130
}
86131

@@ -152,7 +197,7 @@ where
152197
}
153198
}
154199

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) {
156201
match DapInfoID::try_from(req.next_u8()) {
157202
// Return 0-length string for VendorID, ProductID, SerialNumber
158203
// to indicate they should be read from USB descriptor instead
@@ -170,25 +215,7 @@ where
170215
Ok(DapInfoID::TargetName) => resp.write_u8(0),
171216
Ok(DapInfoID::Capabilities) => {
172217
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);
192219
}
193220
Ok(DapInfoID::SWOTraceBufferSize) => {
194221
resp.write_u8(4);
@@ -249,11 +276,15 @@ where
249276
info!(
250277
"DAP connect: {}, SWD: {}, JTAG: {}",
251278
port,
252-
SWD::AVAILABLE,
253-
JTAG::AVAILABLE
279+
self.capabilities.contains(Capabilities::SWD),
280+
self.capabilities.contains(Capabilities::JTAG),
254281
);
255282

256-
match (SWD::AVAILABLE, JTAG::AVAILABLE, port) {
283+
match (
284+
self.capabilities.contains(Capabilities::SWD),
285+
self.capabilities.contains(Capabilities::JTAG),
286+
port,
287+
) {
257288
// SWD
258289
(true, true, ConnectPort::Default)
259290
| (true, true, ConnectPort::SWD)
@@ -298,8 +329,8 @@ where
298329

299330
let idx = req.next_u8();
300331
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) => {
303334
let config = jtag.config();
304335
if !config.select_index(idx) {
305336
resp.write_err();
@@ -311,16 +342,14 @@ where
311342

312343
resp.write_ok();
313344
}
314-
(true, _, State::Swd(swd)) => {
345+
State::Swd(swd) => {
315346
let wait_retries = self.transfer_config.wait_retries;
316347
match swd.write_dp(wait_retries, swd::DPRegister::DPIDR, word) {
317348
Ok(_) => resp.write_ok(),
318349
Err(_) => resp.write_err(),
319350
}
320351
}
321-
_ => {
322-
resp.write_err();
323-
}
352+
_ => resp.write_err(),
324353
}
325354
}
326355

src/jtag.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@ const DAP_TRANSFER_OK_FAULT: u32 = 0x02;
183183

184184
/// JTAG interface.
185185
pub trait Jtag<DEPS>: From<DEPS> {
186-
/// If JTAG is available or not.
187-
const AVAILABLE: bool;
186+
/// Returns whether JTAG is available or not.
187+
fn available(deps: &DEPS) -> bool;
188188

189189
/// Returns a mutable reference to the JTAG interface configuration.
190190
fn config(&mut self) -> &mut Config;

src/mock_device.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ impl swj::Dependencies<Self, Self> for MockSwdJtagDevice {
5151
}
5252

5353
impl swd::Swd<Self> for MockSwdJtagDevice {
54-
const AVAILABLE: bool = true;
54+
fn available(_: &Self) -> bool {
55+
true
56+
}
5557

5658
fn set_clock(&mut self, max_frequency: u32) -> bool {
5759
SwdJtagDevice::set_clock(self, max_frequency)
@@ -79,7 +81,9 @@ impl swd::Swd<Self> for MockSwdJtagDevice {
7981
}
8082

8183
impl jtag::Jtag<MockSwdJtagDevice> for MockSwdJtagDevice {
82-
const AVAILABLE: bool = true;
84+
fn available(_: &Self) -> bool {
85+
true
86+
}
8387

8488
fn set_clock(&mut self, max_frequency: u32) -> bool {
8589
SwdJtagDevice::set_clock(self, max_frequency)

src/swd.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ impl Default for Config {
111111

112112
/// Definition of SWD communication.
113113
pub trait Swd<DEPS>: From<DEPS> {
114-
/// If SWD is available or not.
115-
const AVAILABLE: bool;
114+
/// Returns whether SWD is available or not.
115+
fn available(deps: &DEPS) -> bool;
116116

117117
/// Returns a mutable reference to the SWD interface configuration.
118118
fn config(&mut self) -> &mut Config;

0 commit comments

Comments
 (0)