@@ -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,81 @@ 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+ pub fn configure ( & mut self , settings : ITMSettings ) -> Result < ( ) , ITMConfigurationError > {
202+ use ITMConfigurationError as Error ;
203+
188204 unsafe {
189205 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- } ) ;
199206 r. set_gtsfreq ( match settings. global_timestamps {
200207 GlobalTimestampOptions :: Disabled => 0b00 ,
201208 GlobalTimestampOptions :: Every128Cycles => 0b01 ,
202209 GlobalTimestampOptions :: Every8192Cycles => 0b10 ,
203210 GlobalTimestampOptions :: EveryPacket => 0b11 ,
204211 } ) ;
212+
213+ r
214+ } ) ;
215+ }
216+ // GTSFREQ is potentially RAZ/WI
217+ if settings. global_timestamps != GlobalTimestampOptions :: Disabled
218+ && self . tcr . read ( ) . gtsfreq ( ) == 0
219+ {
220+ return Err ( Error :: GTS ) ;
221+ }
222+
223+ unsafe {
224+ self . tcr . modify ( |mut r| {
205225 r. set_swoena ( match settings. timestamp_clk_src {
206226 TimestampClkSrc :: SystemClock => false ,
207227 TimestampClkSrc :: AsyncTPIU => true ,
208228 } ) ;
229+
230+ r
231+ } ) ;
232+ }
233+ // SWOENA is potentially either RAZ or RAO
234+ if !{
235+ match settings. timestamp_clk_src {
236+ TimestampClkSrc :: SystemClock => self . tcr . read ( ) . swoena ( ) == false ,
237+ TimestampClkSrc :: AsyncTPIU => self . tcr . read ( ) . swoena ( ) == true ,
238+ }
239+ } {
240+ return Err ( Error :: TimestampClkSrc ) ;
241+ }
242+
243+ unsafe {
244+ self . tcr . modify ( |mut r| {
245+ r. set_tsprescale ( match settings. local_timestamps {
246+ LocalTimestampOptions :: Disabled | LocalTimestampOptions :: Enabled => 0b00 ,
247+ LocalTimestampOptions :: EnabledDiv4 => 0b10 ,
248+ LocalTimestampOptions :: EnabledDiv16 => 0b10 ,
249+ LocalTimestampOptions :: EnabledDiv64 => 0b11 ,
250+ } ) ;
251+
252+ r
253+ } )
254+ }
255+ // TSPrescale is potentially RAZ/WI
256+ if settings. local_timestamps != LocalTimestampOptions :: Disabled
257+ && settings. local_timestamps != LocalTimestampOptions :: Enabled
258+ && self . tcr . read ( ) . tsprescale ( ) == 0
259+ {
260+ return Err ( Error :: TSPrescale ) ;
261+ }
262+
263+ unsafe {
264+ self . tcr . modify ( |mut r| {
265+ r. set_itmena ( settings. enable ) ;
266+ r. set_tsena ( settings. local_timestamps != LocalTimestampOptions :: Disabled ) ;
267+ r. set_txena ( settings. forward_dwt ) ; // forward hardware event packets from the DWT to the ITM
209268 r. set_tracebusid ( settings. bus_id . unwrap_or ( 0 ) ) ;
210269
211270 r
212271 } ) ;
213272 }
273+
274+ Ok ( ( ) )
214275 }
215276}
0 commit comments