1use crate::{
27 interrupt::InterruptHandler,
28 pac,
29 peripherals::{ASSIST_DEBUG, Interrupt},
30};
31
32pub struct DebugAssist<'d> {
34 debug_assist: ASSIST_DEBUG<'d>,
35}
36
37impl<'d> DebugAssist<'d> {
38 pub fn new(debug_assist: ASSIST_DEBUG<'d>) -> Self {
40 DebugAssist { debug_assist }
44 }
45
46 #[instability::unstable]
51 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
52 for core in crate::system::Cpu::other() {
53 crate::interrupt::disable(core, Interrupt::ASSIST_DEBUG);
54 }
55 unsafe { crate::interrupt::bind_interrupt(Interrupt::ASSIST_DEBUG, handler.handler()) };
56 unwrap!(crate::interrupt::enable(
57 Interrupt::ASSIST_DEBUG,
58 handler.priority()
59 ));
60 }
61
62 fn regs(&self) -> &pac::assist_debug::RegisterBlock {
63 self.debug_assist.register_block()
64 }
65}
66
67impl crate::private::Sealed for DebugAssist<'_> {}
68
69#[instability::unstable]
70impl crate::interrupt::InterruptConfigurable for DebugAssist<'_> {
71 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
72 self.set_interrupt_handler(handler);
73 }
74}
75
76#[cfg(assist_debug_sp_monitor)]
77impl DebugAssist<'_> {
78 pub fn enable_sp_monitor(&mut self, lower_bound: u32, upper_bound: u32) {
82 self.regs()
83 .core_0_sp_min()
84 .write(|w| unsafe { w.core_0_sp_min().bits(lower_bound) });
85
86 self.regs()
87 .core_0_sp_max()
88 .write(|w| unsafe { w.core_0_sp_max().bits(upper_bound) });
89
90 self.regs().core_0_montr_ena().modify(|_, w| {
91 w.core_0_sp_spill_min_ena()
92 .set_bit()
93 .core_0_sp_spill_max_ena()
94 .set_bit()
95 });
96
97 self.clear_sp_monitor_interrupt();
98
99 self.regs().core_0_intr_ena().modify(|_, w| {
100 w.core_0_sp_spill_max_intr_ena()
101 .set_bit()
102 .core_0_sp_spill_min_intr_ena()
103 .set_bit()
104 });
105 }
106
107 pub fn disable_sp_monitor(&mut self) {
109 self.regs().core_0_intr_ena().modify(|_, w| {
110 w.core_0_sp_spill_max_intr_ena()
111 .clear_bit()
112 .core_0_sp_spill_min_intr_ena()
113 .clear_bit()
114 });
115
116 self.regs().core_0_montr_ena().modify(|_, w| {
117 w.core_0_sp_spill_min_ena()
118 .clear_bit()
119 .core_0_sp_spill_max_ena()
120 .clear_bit()
121 });
122 }
123
124 pub fn clear_sp_monitor_interrupt(&mut self) {
126 self.regs().core_0_intr_clr().write(|w| {
127 w.core_0_sp_spill_max_clr()
128 .set_bit()
129 .core_0_sp_spill_min_clr()
130 .set_bit()
131 });
132 }
133
134 pub fn is_sp_monitor_interrupt_set(&self) -> bool {
136 self.regs()
137 .core_0_intr_raw()
138 .read()
139 .core_0_sp_spill_max_raw()
140 .bit_is_set()
141 || self
142 .regs()
143 .core_0_intr_raw()
144 .read()
145 .core_0_sp_spill_min_raw()
146 .bit_is_set()
147 }
148
149 pub fn sp_monitor_pc(&self) -> u32 {
151 self.regs().core_0_sp_pc().read().core_0_sp_pc().bits()
152 }
153}
154
155#[cfg(all(assist_debug_sp_monitor, multi_core))]
156impl<'d> DebugAssist<'d> {
157 pub fn enable_core1_sp_monitor(&mut self, lower_bound: u32, upper_bound: u32) {
161 self.regs()
162 .core_1_sp_min
163 .write(|w| w.core_1_sp_min().bits(lower_bound));
164
165 self.regs()
166 .core_1_sp_max
167 .write(|w| w.core_1_sp_max().bits(upper_bound));
168
169 self.regs().core_1_montr_ena.modify(|_, w| {
170 w.core_1_sp_spill_min_ena()
171 .set_bit()
172 .core_1_sp_spill_max_ena()
173 .set_bit()
174 });
175
176 self.clear_core1_sp_monitor_interrupt();
177
178 self.regs().core_1_intr_ena.modify(|_, w| {
179 w.core_1_sp_spill_max_intr_ena()
180 .set_bit()
181 .core_1_sp_spill_min_intr_ena()
182 .set_bit()
183 });
184 }
185
186 pub fn disable_core1_sp_monitor(&mut self) {
188 self.regs().core_1_intr_ena.modify(|_, w| {
189 w.core_1_sp_spill_max_intr_ena()
190 .clear_bit()
191 .core_1_sp_spill_min_intr_ena()
192 .clear_bit()
193 });
194
195 self.regs().core_1_montr_ena.modify(|_, w| {
196 w.core_1_sp_spill_min_ena()
197 .clear_bit()
198 .core_1_sp_spill_max_ena()
199 .clear_bit()
200 });
201 }
202
203 pub fn clear_core1_sp_monitor_interrupt(&mut self) {
205 self.regs().core_1_intr_clr.write(|w| {
206 w.core_1_sp_spill_max_clr()
207 .set_bit()
208 .core_1_sp_spill_min_clr()
209 .set_bit()
210 });
211 }
212
213 pub fn is_core1_sp_monitor_interrupt_set(&self) -> bool {
215 self.regs()
216 .core_1_intr_raw
217 .read()
218 .core_1_sp_spill_max_raw()
219 .bit_is_set()
220 || self
221 .regs()
222 .core_1_intr_raw
223 .read()
224 .core_1_sp_spill_min_raw()
225 .bit_is_set()
226 }
227
228 pub fn core1_sp_monitor_pc(&self) -> u32 {
230 self.regs().core_1_sp_pc.read().core_1_sp_pc().bits()
231 }
232}
233
234#[cfg(assist_debug_region_monitor)]
235impl DebugAssist<'_> {
236 pub fn enable_region0_monitor(
241 &mut self,
242 lower_bound: u32,
243 upper_bound: u32,
244 reads: bool,
245 writes: bool,
246 ) {
247 self.regs()
248 .core_0_area_dram0_0_min()
249 .write(|w| unsafe { w.core_0_area_dram0_0_min().bits(lower_bound) });
250
251 self.regs()
252 .core_0_area_dram0_0_max()
253 .write(|w| unsafe { w.core_0_area_dram0_0_max().bits(upper_bound) });
254
255 self.regs().core_0_montr_ena().modify(|_, w| {
256 w.core_0_area_dram0_0_rd_ena()
257 .bit(reads)
258 .core_0_area_dram0_0_wr_ena()
259 .bit(writes)
260 });
261
262 self.clear_region0_monitor_interrupt();
263
264 self.regs().core_0_intr_ena().modify(|_, w| {
265 w.core_0_area_dram0_0_rd_intr_ena()
266 .set_bit()
267 .core_0_area_dram0_0_wr_intr_ena()
268 .set_bit()
269 });
270 }
271
272 pub fn disable_region0_monitor(&mut self) {
274 self.regs().core_0_intr_ena().modify(|_, w| {
275 w.core_0_area_dram0_0_rd_intr_ena()
276 .clear_bit()
277 .core_0_area_dram0_0_wr_intr_ena()
278 .clear_bit()
279 });
280
281 self.regs().core_0_montr_ena().modify(|_, w| {
282 w.core_0_area_dram0_0_rd_ena()
283 .clear_bit()
284 .core_0_area_dram0_0_wr_ena()
285 .clear_bit()
286 });
287 }
288
289 pub fn clear_region0_monitor_interrupt(&mut self) {
291 self.regs().core_0_intr_clr().write(|w| {
292 w.core_0_area_dram0_0_rd_clr()
293 .set_bit()
294 .core_0_area_dram0_0_wr_clr()
295 .set_bit()
296 });
297 }
298
299 pub fn is_region0_monitor_interrupt_set(&self) -> bool {
301 self.regs()
302 .core_0_intr_raw()
303 .read()
304 .core_0_area_dram0_0_rd_raw()
305 .bit_is_set()
306 || self
307 .regs()
308 .core_0_intr_raw()
309 .read()
310 .core_0_area_dram0_0_wr_raw()
311 .bit_is_set()
312 }
313
314 pub fn enable_region1_monitor(
318 &mut self,
319 lower_bound: u32,
320 upper_bound: u32,
321 reads: bool,
322 writes: bool,
323 ) {
324 self.regs()
325 .core_0_area_dram0_1_min()
326 .write(|w| unsafe { w.core_0_area_dram0_1_min().bits(lower_bound) });
327
328 self.regs()
329 .core_0_area_dram0_1_max()
330 .write(|w| unsafe { w.core_0_area_dram0_1_max().bits(upper_bound) });
331
332 self.regs().core_0_montr_ena().modify(|_, w| {
333 w.core_0_area_dram0_1_rd_ena()
334 .bit(reads)
335 .core_0_area_dram0_1_wr_ena()
336 .bit(writes)
337 });
338
339 self.clear_region1_monitor_interrupt();
340
341 self.regs().core_0_intr_ena().modify(|_, w| {
342 w.core_0_area_dram0_1_rd_intr_ena()
343 .set_bit()
344 .core_0_area_dram0_1_wr_intr_ena()
345 .set_bit()
346 });
347 }
348
349 pub fn disable_region1_monitor(&mut self) {
351 self.regs().core_0_intr_ena().modify(|_, w| {
352 w.core_0_area_dram0_1_rd_intr_ena()
353 .clear_bit()
354 .core_0_area_dram0_1_wr_intr_ena()
355 .clear_bit()
356 });
357
358 self.regs().core_0_montr_ena().modify(|_, w| {
359 w.core_0_area_dram0_1_rd_ena()
360 .clear_bit()
361 .core_0_area_dram0_1_wr_ena()
362 .clear_bit()
363 });
364 }
365
366 pub fn clear_region1_monitor_interrupt(&mut self) {
368 self.regs().core_0_intr_clr().write(|w| {
369 w.core_0_area_dram0_1_rd_clr()
370 .set_bit()
371 .core_0_area_dram0_1_wr_clr()
372 .set_bit()
373 });
374 }
375
376 pub fn is_region1_monitor_interrupt_set(&self) -> bool {
378 self.regs()
379 .core_0_intr_raw()
380 .read()
381 .core_0_area_dram0_1_rd_raw()
382 .bit_is_set()
383 || self
384 .regs()
385 .core_0_intr_raw()
386 .read()
387 .core_0_area_dram0_1_wr_raw()
388 .bit_is_set()
389 }
390
391 pub fn region_monitor_pc(&self) -> u32 {
393 self.regs().core_0_area_pc().read().core_0_area_pc().bits()
394 }
395}
396
397#[cfg(all(assist_debug_region_monitor, multi_core))]
398impl DebugAssist<'_> {
399 pub fn enable_core1_region0_monitor(
403 &mut self,
404 lower_bound: u32,
405 upper_bound: u32,
406 reads: bool,
407 writes: bool,
408 ) {
409 self.regs()
410 .core_1_area_dram0_0_min()
411 .write(|w| unsafe { w.core_1_area_dram0_0_min().bits(lower_bound) });
412
413 self.regs()
414 .core_1_area_dram0_0_max()
415 .write(|w| unsafe { w.core_1_area_dram0_0_max().bits(upper_bound) });
416
417 self.regs().core_1_montr_ena().modify(|_, w| {
418 w.core_1_area_dram0_0_rd_ena()
419 .bit(reads)
420 .core_1_area_dram0_0_wr_ena()
421 .bit(writes)
422 });
423
424 self.clear_core1_region0_monitor_interrupt();
425
426 self.regs().core_1_intr_ena().modify(|_, w| {
427 w.core_1_area_dram0_0_rd_intr_ena()
428 .set_bit()
429 .core_1_area_dram0_0_wr_intr_ena()
430 .set_bit()
431 });
432 }
433
434 pub fn disable_core1_region0_monitor(&mut self) {
436 self.regs().core_1_intr_ena().modify(|_, w| {
437 w.core_1_area_dram0_0_rd_intr_ena()
438 .clear_bit()
439 .core_1_area_dram0_0_wr_intr_ena()
440 .clear_bit()
441 });
442
443 self.regs().core_1_montr_ena().modify(|_, w| {
444 w.core_1_area_dram0_0_rd_ena()
445 .clear_bit()
446 .core_1_area_dram0_0_wr_ena()
447 .clear_bit()
448 });
449 }
450
451 pub fn clear_core1_region0_monitor_interrupt(&mut self) {
453 self.regs().core_1_intr_clr().write(|w| {
454 w.core_1_area_dram0_0_rd_clr()
455 .set_bit()
456 .core_1_area_dram0_0_wr_clr()
457 .set_bit()
458 });
459 }
460
461 pub fn is_core1_region0_monitor_interrupt_set(&self) -> bool {
463 self.regs()
464 .core_1_intr_raw()
465 .read()
466 .core_1_area_dram0_0_rd_raw()
467 .bit_is_set()
468 || self
469 .regs()
470 .core_1_intr_raw()
471 .read()
472 .core_1_area_dram0_0_wr_raw()
473 .bit_is_set()
474 }
475
476 pub fn enable_core1_region1_monitor(
480 &mut self,
481 lower_bound: u32,
482 upper_bound: u32,
483 reads: bool,
484 writes: bool,
485 ) {
486 self.regs()
487 .core_1_area_dram0_1_min()
488 .write(|w| unsafe { w.core_1_area_dram0_1_min().bits(lower_bound) });
489
490 self.regs()
491 .core_1_area_dram0_1_max()
492 .write(|w| unsafe { w.core_1_area_dram0_1_max().bits(upper_bound) });
493
494 self.regs().core_1_montr_ena().modify(|_, w| {
495 w.core_1_area_dram0_1_rd_ena()
496 .bit(reads)
497 .core_1_area_dram0_1_wr_ena()
498 .bit(writes)
499 });
500
501 self.clear_core1_region1_monitor_interrupt();
502
503 self.regs().core_1_intr_ena().modify(|_, w| {
504 w.core_1_area_dram0_1_rd_intr_ena()
505 .set_bit()
506 .core_1_area_dram0_1_wr_intr_ena()
507 .set_bit()
508 });
509 }
510
511 pub fn disable_core1_region1_monitor(&mut self) {
513 self.regs().core_1_intr_ena().modify(|_, w| {
514 w.core_1_area_dram0_1_rd_intr_ena()
515 .clear_bit()
516 .core_1_area_dram0_1_wr_intr_ena()
517 .clear_bit()
518 });
519
520 self.regs().core_1_montr_ena().modify(|_, w| {
521 w.core_1_area_dram0_1_rd_ena()
522 .clear_bit()
523 .core_1_area_dram0_1_wr_ena()
524 .clear_bit()
525 });
526 }
527
528 pub fn clear_core1_region1_monitor_interrupt(&mut self) {
530 self.regs().core_1_intr_clr().write(|w| {
531 w.core_1_area_dram0_1_rd_clr()
532 .set_bit()
533 .core_1_area_dram0_1_wr_clr()
534 .set_bit()
535 });
536 }
537
538 pub fn is_core1_region1_monitor_interrupt_set(&self) -> bool {
540 self.regs()
541 .core_1_intr_raw()
542 .read()
543 .core_1_area_dram0_1_rd_raw()
544 .bit_is_set()
545 || self
546 .regs()
547 .core_1_intr_raw()
548 .read()
549 .core_1_area_dram0_1_wr_raw()
550 .bit_is_set()
551 }
552
553 pub fn core1_region_monitor_pc(&self) -> u32 {
555 self.regs().core_1_area_pc().read().core_1_area_pc().bits()
556 }
557}