@@ -82,11 +82,17 @@ bitfield! {
8282 #[ repr( C ) ]
8383 #[ derive( Copy , Clone ) ]
8484 /// Comparator FUNCTIONn register.
85+ ///
86+ /// See C1.8.17 "Comparator Function registers, DWT_FUNCTIONn"
8587 pub struct Function ( u32 ) ;
8688 u8 , function, set_function: 3 , 0 ;
8789 emitrange, set_emitrange: 5 ;
8890 cycmatch, set_cycmatch: 7 ;
8991 datavmatch, set_datavmatch: 8 ;
92+ lnk1ena, set_lnk1ena: 9 ;
93+ u8 , datavsize, set_datavsize: 11 , 10 ;
94+ u8 , datavaddr0, set_datavaddr0: 15 , 12 ;
95+ u8 , datavaddr1, set_datavaddr1: 19 , 16 ;
9096 matched, _: 24 ;
9197}
9298
@@ -114,10 +120,13 @@ impl DWT {
114120 }
115121
116122 /// Returns `true` if the implementation supports a cycle counter
117- #[ cfg( not( armv6m) ) ]
118123 #[ inline]
119124 pub fn has_cycle_counter ( & self ) -> bool {
120- !self . ctrl . read ( ) . nocyccnt ( )
125+ #[ cfg( not( armv6m) ) ]
126+ return !self . ctrl . read ( ) . nocyccnt ( ) ;
127+
128+ #[ cfg( armv6m) ]
129+ return false ;
121130 }
122131
123132 /// Returns `true` if the implementation the profiling counters
@@ -318,15 +327,15 @@ impl DWT {
318327/// Whether the comparator should match on read, write or read/write operations.
319328#[ derive( Debug , Eq , PartialEq , Copy , Clone ) ]
320329pub enum AccessType {
321- /// Generate packet only when matched adress is read from.
330+ /// Generate packet only when matched address is read from.
322331 ReadOnly ,
323- /// Generate packet only when matched adress is written to.
332+ /// Generate packet only when matched address is written to.
324333 WriteOnly ,
325- /// Generate packet when matched adress is both read from and written to.
334+ /// Generate packet when matched address is both read from and written to.
326335 ReadWrite ,
327336}
328337
329- /// The sequence of packet(s) that should be emitted on comparator match.
338+ /// The sequence of packet(s) or events that should be emitted/generated on comparator match.
330339#[ derive( Debug , Eq , PartialEq , Copy , Clone ) ]
331340pub enum EmitOption {
332341 /// Emit only trace data value packet.
@@ -341,6 +350,14 @@ pub enum EmitOption {
341350 AddressData ,
342351 /// Emit trace PC value and data value packets.
343352 PCData ,
353+ /// Generate a watchpoint debug event. Either halts execution or fires a `DebugMonitor` exception.
354+ ///
355+ /// See more in section "Watchpoint debug event generation" page C1-729.
356+ WatchpointDebugEvent ,
357+ /// Generate a `CMPMATCH[N]` event.
358+ ///
359+ /// See more in section "CMPMATCH[N] event generation" page C1-730.
360+ CompareMatchEvent ,
344361}
345362
346363/// Settings for address matching
@@ -356,12 +373,27 @@ pub struct ComparatorAddressSettings {
356373 pub access_type : AccessType ,
357374}
358375
376+ /// Settings for cycle count matching
377+ #[ derive( Debug , Eq , PartialEq , Copy , Clone ) ]
378+ pub struct CycleCountSettings {
379+ /// The function selection used.
380+ /// See Table C1-15 for DWT cycle count comparison functions.
381+ pub emit : EmitOption ,
382+ /// The cycle count value to compare against.
383+ pub compare : u32 ,
384+ }
385+
359386/// The available functions of a DWT comparator.
360387#[ derive( Debug , Eq , PartialEq , Copy , Clone ) ]
361388#[ non_exhaustive]
362389pub enum ComparatorFunction {
363390 /// Compare accessed memory addresses.
364391 Address ( ComparatorAddressSettings ) ,
392+ /// Compare cycle count & target value.
393+ ///
394+ /// **NOTE**: only supported by comparator 0 and if the HW supports the cycle counter.
395+ /// Check [`DWT::has_cycle_counter`] for support. See C1.8.1 for more details.
396+ CycleCount ( CycleCountSettings ) ,
365397}
366398
367399/// Possible error values returned on [Comparator::configure].
@@ -377,46 +409,85 @@ impl Comparator {
377409 #[ allow( clippy:: missing_inline_in_public_items) ]
378410 pub fn configure ( & self , settings : ComparatorFunction ) -> Result < ( ) , DwtError > {
379411 match settings {
380- ComparatorFunction :: Address ( settings) => unsafe {
412+ ComparatorFunction :: Address ( settings) => {
381413 // FUNCTION, EMITRANGE
382414 // See Table C1-14
383415 let ( function, emit_range) = match ( & settings. access_type , & settings. emit ) {
384416 ( AccessType :: ReadOnly , EmitOption :: Data ) => ( 0b1100 , false ) ,
385417 ( AccessType :: ReadOnly , EmitOption :: Address ) => ( 0b1100 , true ) ,
386418 ( AccessType :: ReadOnly , EmitOption :: AddressData ) => ( 0b1110 , true ) ,
387419 ( AccessType :: ReadOnly , EmitOption :: PCData ) => ( 0b1110 , false ) ,
420+ ( AccessType :: ReadOnly , EmitOption :: WatchpointDebugEvent ) => ( 0b0101 , false ) ,
421+ ( AccessType :: ReadOnly , EmitOption :: CompareMatchEvent ) => ( 0b1001 , false ) ,
388422
389423 ( AccessType :: WriteOnly , EmitOption :: Data ) => ( 0b1101 , false ) ,
390424 ( AccessType :: WriteOnly , EmitOption :: Address ) => ( 0b1101 , true ) ,
391425 ( AccessType :: WriteOnly , EmitOption :: AddressData ) => ( 0b1111 , true ) ,
392426 ( AccessType :: WriteOnly , EmitOption :: PCData ) => ( 0b1111 , false ) ,
427+ ( AccessType :: WriteOnly , EmitOption :: WatchpointDebugEvent ) => ( 0b0110 , false ) ,
428+ ( AccessType :: WriteOnly , EmitOption :: CompareMatchEvent ) => ( 0b1010 , false ) ,
393429
394430 ( AccessType :: ReadWrite , EmitOption :: Data ) => ( 0b0010 , false ) ,
395431 ( AccessType :: ReadWrite , EmitOption :: Address ) => ( 0b0001 , true ) ,
396432 ( AccessType :: ReadWrite , EmitOption :: AddressData ) => ( 0b0010 , true ) ,
397433 ( AccessType :: ReadWrite , EmitOption :: PCData ) => ( 0b0011 , false ) ,
434+ ( AccessType :: ReadWrite , EmitOption :: WatchpointDebugEvent ) => ( 0b0111 , false ) ,
435+ ( AccessType :: ReadWrite , EmitOption :: CompareMatchEvent ) => ( 0b1011 , false ) ,
398436
399437 ( AccessType :: ReadWrite , EmitOption :: PC ) => ( 0b0001 , false ) ,
400438 ( _, EmitOption :: PC ) => return Err ( DwtError :: InvalidFunction ) ,
401439 } ;
402440
403- self . function . modify ( |mut r| {
404- r. set_function ( function) ;
405- r. set_emitrange ( emit_range) ;
406-
407- // don't compare data value
408- r. set_datavmatch ( false ) ;
409-
410- // don't compare cycle counter value
411- // NOTE: only needed for comparator 0, but is SBZP.
412- r. set_cycmatch ( false ) ;
413-
414- r
415- } ) ;
441+ unsafe {
442+ self . function . modify ( |mut r| {
443+ r. set_function ( function) ;
444+ r. set_emitrange ( emit_range) ;
445+ // don't compare data value
446+ r. set_datavmatch ( false ) ;
447+ // don't compare cycle counter value
448+ // NOTE: only needed for comparator 0, but is SBZP.
449+ r. set_cycmatch ( false ) ;
450+ // SBZ as needed, see Page 784/C1-724
451+ r. set_datavsize ( 0 ) ;
452+ r. set_datavaddr0 ( 0 ) ;
453+ r. set_datavaddr1 ( 0 ) ;
454+
455+ r
456+ } ) ;
457+
458+ self . comp . write ( settings. address ) ;
459+ self . mask . write ( settings. mask ) ;
460+ }
461+ }
462+ ComparatorFunction :: CycleCount ( settings) => {
463+ let function = match & settings. emit {
464+ EmitOption :: PCData => 0b0001 ,
465+ EmitOption :: WatchpointDebugEvent => 0b0100 ,
466+ EmitOption :: CompareMatchEvent => 0b1000 ,
467+ _ => return Err ( DwtError :: InvalidFunction ) ,
468+ } ;
416469
417- self . comp . write ( settings. address ) ;
418- self . mask . write ( settings. mask ) ;
419- } ,
470+ unsafe {
471+ self . function . modify ( |mut r| {
472+ r. set_function ( function) ;
473+ // emit_range is N/A for cycle count compare
474+ r. set_emitrange ( false ) ;
475+ // don't compare data
476+ r. set_datavmatch ( false ) ;
477+ // compare cyccnt
478+ r. set_cycmatch ( true ) ;
479+ // SBZ as needed, see Page 784/C1-724
480+ r. set_datavsize ( 0 ) ;
481+ r. set_datavaddr0 ( 0 ) ;
482+ r. set_datavaddr1 ( 0 ) ;
483+
484+ r
485+ } ) ;
486+
487+ self . comp . write ( settings. compare ) ;
488+ self . mask . write ( 0 ) ; // SBZ, see Page 784/C1-724
489+ }
490+ }
420491 }
421492
422493 Ok ( ( ) )
0 commit comments