@@ -62,7 +62,56 @@ pub struct Comparator {
62
62
reserved : u32 ,
63
63
}
64
64
65
+ // DWT CTRL register fields
66
+ const NUMCOMP_OFFSET : u32 = 28 ;
67
+ const NOTRCPKT : u32 = 1 << 27 ;
68
+ const NOEXTTRIG : u32 = 1 << 26 ;
69
+ const NOCYCCNT : u32 = 1 << 25 ;
70
+ const NOPRFCNT : u32 = 1 << 24 ;
71
+ const CYCCNTENA : u32 = 1 << 0 ;
72
+
65
73
impl DWT {
74
+ /// Number of comparators implemented
75
+ ///
76
+ /// A value of zero indicates no comparator support.
77
+ #[ inline]
78
+ pub fn num_comp ( ) -> u8 {
79
+ // NOTE(unsafe) atomic read with no side effects
80
+ unsafe { ( ( * Self :: ptr ( ) ) . ctrl . read ( ) >> NUMCOMP_OFFSET ) as u8 }
81
+ }
82
+
83
+ /// Returns `true` if the the implementation supports sampling and exception tracing
84
+ #[ cfg( not( armv6m) ) ]
85
+ #[ inline]
86
+ pub fn has_exception_trace ( ) -> bool {
87
+ // NOTE(unsafe) atomic read with no side effects
88
+ unsafe { ( * Self :: ptr ( ) ) . ctrl . read ( ) & NOTRCPKT == 0 }
89
+ }
90
+
91
+ /// Returns `true` if the implementation includes external match signals
92
+ #[ cfg( not( armv6m) ) ]
93
+ #[ inline]
94
+ pub fn has_external_match ( ) -> bool {
95
+ // NOTE(unsafe) atomic read with no side effects
96
+ unsafe { ( * Self :: ptr ( ) ) . ctrl . read ( ) & NOEXTTRIG == 0 }
97
+ }
98
+
99
+ /// Returns `true` if the implementation supports a cycle counter
100
+ #[ cfg( not( armv6m) ) ]
101
+ #[ inline]
102
+ pub fn has_cycle_counter ( ) -> bool {
103
+ // NOTE(unsafe) atomic read with no side effects
104
+ unsafe { ( * Self :: ptr ( ) ) . ctrl . read ( ) & NOCYCCNT == 0 }
105
+ }
106
+
107
+ /// Returns `true` if the implementation the profiling counters
108
+ #[ cfg( not( armv6m) ) ]
109
+ #[ inline]
110
+ pub fn has_profiling_counter ( ) -> bool {
111
+ // NOTE(unsafe) atomic read with no side effects
112
+ unsafe { ( * Self :: ptr ( ) ) . ctrl . read ( ) & NOPRFCNT == 0 }
113
+ }
114
+
66
115
/// Enables the cycle counter
67
116
///
68
117
/// The global trace enable ([`DCB::enable_trace`]) should be set before
@@ -74,7 +123,22 @@ impl DWT {
74
123
#[ cfg( not( armv6m) ) ]
75
124
#[ inline]
76
125
pub fn enable_cycle_counter ( & mut self ) {
77
- unsafe { self . ctrl . modify ( |r| r | 1 ) }
126
+ unsafe { self . ctrl . modify ( |r| r | CYCCNTENA ) }
127
+ }
128
+
129
+ /// Disables the cycle counter
130
+ #[ cfg( not( armv6m) ) ]
131
+ #[ inline]
132
+ pub fn disable_cycle_counter ( & mut self ) {
133
+ unsafe { self . ctrl . modify ( |r| r & !CYCCNTENA ) }
134
+ }
135
+
136
+ /// Returns `true` if the cycle counter is enabled
137
+ #[ cfg( not( armv6m) ) ]
138
+ #[ inline]
139
+ pub fn cycle_counter_enabled ( ) -> bool {
140
+ // NOTE(unsafe) atomic read with no side effects
141
+ unsafe { ( * Self :: ptr ( ) ) . ctrl . read ( ) & CYCCNTENA != 0 }
78
142
}
79
143
80
144
/// Returns the current clock cycle count
@@ -94,4 +158,93 @@ impl DWT {
94
158
// NOTE(unsafe) atomic write to a stateless, write-only register
95
159
unsafe { ( * Self :: ptr ( ) ) . lar . write ( 0xC5AC_CE55 ) }
96
160
}
161
+
162
+ /// Get the CPI count
163
+ ///
164
+ /// Counts additional cycles required to execute multi-cycle instructions,
165
+ /// except those recorded by [`lsu_count`], and counts any instruction fetch
166
+ /// stalls.
167
+ ///
168
+ /// [`lsu_count`]: DWT::lsu_count
169
+ #[ cfg( not( armv6m) ) ]
170
+ #[ inline]
171
+ pub fn cpi_count ( ) -> u8 {
172
+ // NOTE(unsafe) atomic read with no side effects
173
+ unsafe { ( * Self :: ptr ( ) ) . cpicnt . read ( ) as u8 }
174
+ }
175
+
176
+ /// Set the CPI count
177
+ #[ cfg( not( armv6m) ) ]
178
+ #[ inline]
179
+ pub fn set_cpi_count ( & mut self , count : u8 ) {
180
+ unsafe { self . cpicnt . write ( count as u32 ) }
181
+ }
182
+
183
+ /// Get the total cycles spent in exception processing
184
+ #[ cfg( not( armv6m) ) ]
185
+ #[ inline]
186
+ pub fn exception_count ( ) -> u8 {
187
+ // NOTE(unsafe) atomic read with no side effects
188
+ unsafe { ( * Self :: ptr ( ) ) . exccnt . read ( ) as u8 }
189
+ }
190
+
191
+ /// Set the exception count
192
+ #[ cfg( not( armv6m) ) ]
193
+ #[ inline]
194
+ pub fn set_exception_count ( & mut self , count : u8 ) {
195
+ unsafe { self . exccnt . write ( count as u32 ) }
196
+ }
197
+
198
+ /// Get the total number of cycles that the processor is sleeping
199
+ ///
200
+ /// ARM recommends that this counter counts all cycles when the processor is sleeping,
201
+ /// regardless of whether a WFI or WFE instruction, or the sleep-on-exit functionality,
202
+ /// caused the entry to sleep mode.
203
+ /// However, all sleep features are implementation defined and therefore when
204
+ /// this counter counts is implementation defined.
205
+ #[ cfg( not( armv6m) ) ]
206
+ #[ inline]
207
+ pub fn sleep_count ( ) -> u8 {
208
+ // NOTE(unsafe) atomic read with no side effects
209
+ unsafe { ( * Self :: ptr ( ) ) . sleepcnt . read ( ) as u8 }
210
+ }
211
+
212
+ /// Set the sleep count
213
+ #[ cfg( not( armv6m) ) ]
214
+ #[ inline]
215
+ pub fn set_sleep_count ( & mut self , count : u8 ) {
216
+ unsafe { self . sleepcnt . write ( count as u32 ) }
217
+ }
218
+
219
+ /// Get the additional cycles required to execute all load or store instructions
220
+ #[ cfg( not( armv6m) ) ]
221
+ #[ inline]
222
+ pub fn lsu_count ( ) -> u8 {
223
+ // NOTE(unsafe) atomic read with no side effects
224
+ unsafe { ( * Self :: ptr ( ) ) . lsucnt . read ( ) as u8 }
225
+ }
226
+
227
+ /// Set the lsu count
228
+ #[ cfg( not( armv6m) ) ]
229
+ #[ inline]
230
+ pub fn set_lsu_count ( & mut self , count : u8 ) {
231
+ unsafe { self . lsucnt . write ( count as u32 ) }
232
+ }
233
+
234
+ /// Get the folded instruction count
235
+ ///
236
+ /// Increments on each instruction that takes 0 cycles.
237
+ #[ cfg( not( armv6m) ) ]
238
+ #[ inline]
239
+ pub fn fold_count ( ) -> u8 {
240
+ // NOTE(unsafe) atomic read with no side effects
241
+ unsafe { ( * Self :: ptr ( ) ) . foldcnt . read ( ) as u8 }
242
+ }
243
+
244
+ /// Set the folded instruction count
245
+ #[ cfg( not( armv6m) ) ]
246
+ #[ inline]
247
+ pub fn set_fold_count ( & mut self , count : u8 ) {
248
+ unsafe { self . foldcnt . write ( count as u32 ) }
249
+ }
97
250
}
0 commit comments