@@ -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,13 +123,39 @@ 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
81
145
#[ cfg( not( armv6m) ) ]
82
146
#[ inline]
147
+ #[ deprecated(
148
+ since = "0.7.4" ,
149
+ note = "Use `cycle_count` which follows the C-GETTER convention"
150
+ ) ]
83
151
pub fn get_cycle_count ( ) -> u32 {
152
+ Self :: cycle_count ( )
153
+ }
154
+
155
+ /// Returns the current clock cycle count
156
+ #[ cfg( not( armv6m) ) ]
157
+ #[ inline]
158
+ pub fn cycle_count ( ) -> u32 {
84
159
// NOTE(unsafe) atomic read with no side effects
85
160
unsafe { ( * Self :: ptr ( ) ) . cyccnt . read ( ) }
86
161
}
@@ -94,4 +169,93 @@ impl DWT {
94
169
// NOTE(unsafe) atomic write to a stateless, write-only register
95
170
unsafe { ( * Self :: ptr ( ) ) . lar . write ( 0xC5AC_CE55 ) }
96
171
}
172
+
173
+ /// Get the CPI count
174
+ ///
175
+ /// Counts additional cycles required to execute multi-cycle instructions,
176
+ /// except those recorded by [`lsu_count`], and counts any instruction fetch
177
+ /// stalls.
178
+ ///
179
+ /// [`lsu_count`]: DWT::lsu_count
180
+ #[ cfg( not( armv6m) ) ]
181
+ #[ inline]
182
+ pub fn cpi_count ( ) -> u8 {
183
+ // NOTE(unsafe) atomic read with no side effects
184
+ unsafe { ( * Self :: ptr ( ) ) . cpicnt . read ( ) as u8 }
185
+ }
186
+
187
+ /// Set the CPI count
188
+ #[ cfg( not( armv6m) ) ]
189
+ #[ inline]
190
+ pub fn set_cpi_count ( & mut self , count : u8 ) {
191
+ unsafe { self . cpicnt . write ( count as u32 ) }
192
+ }
193
+
194
+ /// Get the total cycles spent in exception processing
195
+ #[ cfg( not( armv6m) ) ]
196
+ #[ inline]
197
+ pub fn exception_count ( ) -> u8 {
198
+ // NOTE(unsafe) atomic read with no side effects
199
+ unsafe { ( * Self :: ptr ( ) ) . exccnt . read ( ) as u8 }
200
+ }
201
+
202
+ /// Set the exception count
203
+ #[ cfg( not( armv6m) ) ]
204
+ #[ inline]
205
+ pub fn set_exception_count ( & mut self , count : u8 ) {
206
+ unsafe { self . exccnt . write ( count as u32 ) }
207
+ }
208
+
209
+ /// Get the total number of cycles that the processor is sleeping
210
+ ///
211
+ /// ARM recommends that this counter counts all cycles when the processor is sleeping,
212
+ /// regardless of whether a WFI or WFE instruction, or the sleep-on-exit functionality,
213
+ /// caused the entry to sleep mode.
214
+ /// However, all sleep features are implementation defined and therefore when
215
+ /// this counter counts is implementation defined.
216
+ #[ cfg( not( armv6m) ) ]
217
+ #[ inline]
218
+ pub fn sleep_count ( ) -> u8 {
219
+ // NOTE(unsafe) atomic read with no side effects
220
+ unsafe { ( * Self :: ptr ( ) ) . sleepcnt . read ( ) as u8 }
221
+ }
222
+
223
+ /// Set the sleep count
224
+ #[ cfg( not( armv6m) ) ]
225
+ #[ inline]
226
+ pub fn set_sleep_count ( & mut self , count : u8 ) {
227
+ unsafe { self . sleepcnt . write ( count as u32 ) }
228
+ }
229
+
230
+ /// Get the additional cycles required to execute all load or store instructions
231
+ #[ cfg( not( armv6m) ) ]
232
+ #[ inline]
233
+ pub fn lsu_count ( ) -> u8 {
234
+ // NOTE(unsafe) atomic read with no side effects
235
+ unsafe { ( * Self :: ptr ( ) ) . lsucnt . read ( ) as u8 }
236
+ }
237
+
238
+ /// Set the lsu count
239
+ #[ cfg( not( armv6m) ) ]
240
+ #[ inline]
241
+ pub fn set_lsu_count ( & mut self , count : u8 ) {
242
+ unsafe { self . lsucnt . write ( count as u32 ) }
243
+ }
244
+
245
+ /// Get the folded instruction count
246
+ ///
247
+ /// Increments on each instruction that takes 0 cycles.
248
+ #[ cfg( not( armv6m) ) ]
249
+ #[ inline]
250
+ pub fn fold_count ( ) -> u8 {
251
+ // NOTE(unsafe) atomic read with no side effects
252
+ unsafe { ( * Self :: ptr ( ) ) . foldcnt . read ( ) as u8 }
253
+ }
254
+
255
+ /// Set the folded instruction count
256
+ #[ cfg( not( armv6m) ) ]
257
+ #[ inline]
258
+ pub fn set_fold_count ( & mut self , count : u8 ) {
259
+ unsafe { self . foldcnt . write ( count as u32 ) }
260
+ }
97
261
}
0 commit comments