@@ -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+
177191impl 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