@@ -82,11 +82,17 @@ bitfield! {
82
82
#[ repr( C ) ]
83
83
#[ derive( Copy , Clone ) ]
84
84
/// Comparator FUNCTIONn register.
85
+ ///
86
+ /// See C1.8.17 "Comparator Function registers, DWT_FUNCTIONn"
85
87
pub struct Function ( u32 ) ;
86
88
u8 , function, set_function: 3 , 0 ;
87
89
emitrange, set_emitrange: 5 ;
88
90
cycmatch, set_cycmatch: 7 ;
89
91
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 ;
90
96
matched, _: 24 ;
91
97
}
92
98
@@ -114,10 +120,13 @@ impl DWT {
114
120
}
115
121
116
122
/// Returns `true` if the implementation supports a cycle counter
117
- #[ cfg( not( armv6m) ) ]
118
123
#[ inline]
119
124
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 ;
121
130
}
122
131
123
132
/// Returns `true` if the implementation the profiling counters
@@ -318,15 +327,15 @@ impl DWT {
318
327
/// Whether the comparator should match on read, write or read/write operations.
319
328
#[ derive( Debug , Eq , PartialEq , Copy , Clone ) ]
320
329
pub enum AccessType {
321
- /// Generate packet only when matched adress is read from.
330
+ /// Generate packet only when matched address is read from.
322
331
ReadOnly ,
323
- /// Generate packet only when matched adress is written to.
332
+ /// Generate packet only when matched address is written to.
324
333
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.
326
335
ReadWrite ,
327
336
}
328
337
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.
330
339
#[ derive( Debug , Eq , PartialEq , Copy , Clone ) ]
331
340
pub enum EmitOption {
332
341
/// Emit only trace data value packet.
@@ -341,6 +350,14 @@ pub enum EmitOption {
341
350
AddressData ,
342
351
/// Emit trace PC value and data value packets.
343
352
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 ,
344
361
}
345
362
346
363
/// Settings for address matching
@@ -356,12 +373,27 @@ pub struct ComparatorAddressSettings {
356
373
pub access_type : AccessType ,
357
374
}
358
375
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
+
359
386
/// The available functions of a DWT comparator.
360
387
#[ derive( Debug , Eq , PartialEq , Copy , Clone ) ]
361
388
#[ non_exhaustive]
362
389
pub enum ComparatorFunction {
363
390
/// Compare accessed memory addresses.
364
391
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 ) ,
365
397
}
366
398
367
399
/// Possible error values returned on [Comparator::configure].
@@ -377,46 +409,85 @@ impl Comparator {
377
409
#[ allow( clippy:: missing_inline_in_public_items) ]
378
410
pub fn configure ( & self , settings : ComparatorFunction ) -> Result < ( ) , DwtError > {
379
411
match settings {
380
- ComparatorFunction :: Address ( settings) => unsafe {
412
+ ComparatorFunction :: Address ( settings) => {
381
413
// FUNCTION, EMITRANGE
382
414
// See Table C1-14
383
415
let ( function, emit_range) = match ( & settings. access_type , & settings. emit ) {
384
416
( AccessType :: ReadOnly , EmitOption :: Data ) => ( 0b1100 , false ) ,
385
417
( AccessType :: ReadOnly , EmitOption :: Address ) => ( 0b1100 , true ) ,
386
418
( AccessType :: ReadOnly , EmitOption :: AddressData ) => ( 0b1110 , true ) ,
387
419
( AccessType :: ReadOnly , EmitOption :: PCData ) => ( 0b1110 , false ) ,
420
+ ( AccessType :: ReadOnly , EmitOption :: WatchpointDebugEvent ) => ( 0b0101 , false ) ,
421
+ ( AccessType :: ReadOnly , EmitOption :: CompareMatchEvent ) => ( 0b1001 , false ) ,
388
422
389
423
( AccessType :: WriteOnly , EmitOption :: Data ) => ( 0b1101 , false ) ,
390
424
( AccessType :: WriteOnly , EmitOption :: Address ) => ( 0b1101 , true ) ,
391
425
( AccessType :: WriteOnly , EmitOption :: AddressData ) => ( 0b1111 , true ) ,
392
426
( AccessType :: WriteOnly , EmitOption :: PCData ) => ( 0b1111 , false ) ,
427
+ ( AccessType :: WriteOnly , EmitOption :: WatchpointDebugEvent ) => ( 0b0110 , false ) ,
428
+ ( AccessType :: WriteOnly , EmitOption :: CompareMatchEvent ) => ( 0b1010 , false ) ,
393
429
394
430
( AccessType :: ReadWrite , EmitOption :: Data ) => ( 0b0010 , false ) ,
395
431
( AccessType :: ReadWrite , EmitOption :: Address ) => ( 0b0001 , true ) ,
396
432
( AccessType :: ReadWrite , EmitOption :: AddressData ) => ( 0b0010 , true ) ,
397
433
( AccessType :: ReadWrite , EmitOption :: PCData ) => ( 0b0011 , false ) ,
434
+ ( AccessType :: ReadWrite , EmitOption :: WatchpointDebugEvent ) => ( 0b0111 , false ) ,
435
+ ( AccessType :: ReadWrite , EmitOption :: CompareMatchEvent ) => ( 0b1011 , false ) ,
398
436
399
437
( AccessType :: ReadWrite , EmitOption :: PC ) => ( 0b0001 , false ) ,
400
438
( _, EmitOption :: PC ) => return Err ( DwtError :: InvalidFunction ) ,
401
439
} ;
402
440
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
+ } ;
416
469
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
+ }
420
491
}
421
492
422
493
Ok ( ( ) )
0 commit comments