Skip to content

Commit b812e51

Browse files
committed
itm: configure: check feature support during configuration
Related to rust-embedded#382.
1 parent 1c4453a commit b812e51

File tree

1 file changed

+74
-12
lines changed

1 file changed

+74
-12
lines changed

src/peripheral/itm.rs

+74-12
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,20 @@ pub struct ITMSettings {
174174
pub timestamp_clk_src: TimestampClkSrc,
175175
}
176176

177+
/// Possible errors on [ITM::configure].
178+
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
179+
pub enum ITMConfigurationError {
180+
/// Global timestamp generation is not supported on this target.
181+
/// Request [GlobalTimestampOptions::Disabled] instead.
182+
GTS,
183+
/// The requested timestamp clock source is not supported on this target.
184+
TimestampClkSrc,
185+
/// The target does not implement the local timestamp prescaler.
186+
/// Request [LocalTimestampOptions::Disabled] or
187+
/// [LocalTimestampOptions::Disabled] instead.
188+
TSPrescale,
189+
}
190+
177191
impl ITM {
178192
/// Removes the software lock on the ITM. Must be called before any other [ITM] functions.
179193
#[inline]
@@ -182,34 +196,82 @@ impl ITM {
182196
unsafe { self.lar.write(0xC5AC_CE55) }
183197
}
184198

185-
/// Configures the ITM with the passed [ITMSettings].
186-
#[inline]
187-
pub fn configure(&mut self, settings: ITMSettings) {
199+
/// Configures the ITM with the passed [ITMSettings]. Returns `true`
200+
/// if the configuration was successfully applied.
201+
#[allow(clippy::missing_inline_in_public_items)]
202+
pub fn configure(&mut self, settings: ITMSettings) -> Result<(), ITMConfigurationError> {
203+
use ITMConfigurationError as Error;
204+
188205
unsafe {
189206
self.tcr.modify(|mut r| {
190-
r.set_itmena(settings.enable);
191-
r.set_tsena(settings.local_timestamps != LocalTimestampOptions::Disabled);
192-
r.set_txena(settings.forward_dwt);
193-
r.set_tsprescale(match settings.local_timestamps {
194-
LocalTimestampOptions::Disabled | LocalTimestampOptions::Enabled => 0b00,
195-
LocalTimestampOptions::EnabledDiv4 => 0b10,
196-
LocalTimestampOptions::EnabledDiv16 => 0b10,
197-
LocalTimestampOptions::EnabledDiv64 => 0b11,
198-
});
199207
r.set_gtsfreq(match settings.global_timestamps {
200208
GlobalTimestampOptions::Disabled => 0b00,
201209
GlobalTimestampOptions::Every128Cycles => 0b01,
202210
GlobalTimestampOptions::Every8192Cycles => 0b10,
203211
GlobalTimestampOptions::EveryPacket => 0b11,
204212
});
213+
214+
r
215+
});
216+
}
217+
// GTSFREQ is potentially RAZ/WI
218+
if settings.global_timestamps != GlobalTimestampOptions::Disabled
219+
&& self.tcr.read().gtsfreq() == 0
220+
{
221+
return Err(Error::GTS);
222+
}
223+
224+
unsafe {
225+
self.tcr.modify(|mut r| {
205226
r.set_swoena(match settings.timestamp_clk_src {
206227
TimestampClkSrc::SystemClock => false,
207228
TimestampClkSrc::AsyncTPIU => true,
208229
});
230+
231+
r
232+
});
233+
}
234+
// SWOENA is potentially either RAZ or RAO
235+
if !{
236+
match settings.timestamp_clk_src {
237+
TimestampClkSrc::SystemClock => !self.tcr.read().swoena(),
238+
TimestampClkSrc::AsyncTPIU => self.tcr.read().swoena(),
239+
}
240+
} {
241+
return Err(Error::TimestampClkSrc);
242+
}
243+
244+
unsafe {
245+
self.tcr.modify(|mut r| {
246+
r.set_tsprescale(match settings.local_timestamps {
247+
LocalTimestampOptions::Disabled | LocalTimestampOptions::Enabled => 0b00,
248+
LocalTimestampOptions::EnabledDiv4 => 0b10,
249+
LocalTimestampOptions::EnabledDiv16 => 0b10,
250+
LocalTimestampOptions::EnabledDiv64 => 0b11,
251+
});
252+
253+
r
254+
})
255+
}
256+
// TSPrescale is potentially RAZ/WI
257+
if settings.local_timestamps != LocalTimestampOptions::Disabled
258+
&& settings.local_timestamps != LocalTimestampOptions::Enabled
259+
&& self.tcr.read().tsprescale() == 0
260+
{
261+
return Err(Error::TSPrescale);
262+
}
263+
264+
unsafe {
265+
self.tcr.modify(|mut r| {
266+
r.set_itmena(settings.enable);
267+
r.set_tsena(settings.local_timestamps != LocalTimestampOptions::Disabled);
268+
r.set_txena(settings.forward_dwt); // forward hardware event packets from the DWT to the ITM
209269
r.set_tracebusid(settings.bus_id.unwrap_or(0));
210270

211271
r
212272
});
213273
}
274+
275+
Ok(())
214276
}
215277
}

0 commit comments

Comments
 (0)