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