1 | //! Debug Control Block |
2 | |
3 | use volatile_register::{RW, WO}; |
4 | |
5 | use crate::peripheral::DCB; |
6 | use core::ptr; |
7 | |
8 | const DCB_DEMCR_TRCENA: u32 = 1 << 24; |
9 | |
10 | /// Register block |
11 | #[repr (C)] |
12 | pub struct RegisterBlock { |
13 | /// Debug Halting Control and Status |
14 | pub dhcsr: RW<u32>, |
15 | /// Debug Core Register Selector |
16 | pub dcrsr: WO<u32>, |
17 | /// Debug Core Register Data |
18 | pub dcrdr: RW<u32>, |
19 | /// Debug Exception and Monitor Control |
20 | pub demcr: RW<u32>, |
21 | } |
22 | |
23 | impl DCB { |
24 | /// Enables TRACE. This is for example required by the |
25 | /// `peripheral::DWT` cycle counter to work properly. |
26 | /// As by STM documentation, this flag is not reset on |
27 | /// soft-reset, only on power reset. |
28 | #[inline ] |
29 | pub fn enable_trace(&mut self) { |
30 | // set bit 24 / TRCENA |
31 | unsafe { |
32 | self.demcr.modify(|w| w | DCB_DEMCR_TRCENA); |
33 | } |
34 | } |
35 | |
36 | /// Disables TRACE. See `DCB::enable_trace()` for more details |
37 | #[inline ] |
38 | pub fn disable_trace(&mut self) { |
39 | // unset bit 24 / TRCENA |
40 | unsafe { |
41 | self.demcr.modify(|w| w & !DCB_DEMCR_TRCENA); |
42 | } |
43 | } |
44 | |
45 | /// Is there a debugger attached? (see note) |
46 | /// |
47 | /// Note: This function is [reported not to |
48 | /// work](http://web.archive.org/web/20180821191012/https://community.nxp.com/thread/424925#comment-782843) |
49 | /// on Cortex-M0 devices. Per the ARM v6-M Architecture Reference Manual, "Access to the DHCSR |
50 | /// from software running on the processor is IMPLEMENTATION DEFINED". Indeed, from the |
51 | /// [Cortex-M0+ r0p1 Technical Reference Manual](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0484c/BABJHEIG.html), "Note Software cannot access the debug registers." |
52 | #[inline ] |
53 | pub fn is_debugger_attached() -> bool { |
54 | unsafe { |
55 | // do an 8-bit read of the 32-bit DHCSR register, and get the LSB |
56 | let value = ptr::read_volatile(Self::PTR as *const u8); |
57 | value & 0x1 == 1 |
58 | } |
59 | } |
60 | } |
61 | |