Skip to content

Commit 17d3561

Browse files
bors[bot]Brandon Matthewsthenewwazoo
committed
Merge #106
106: Stir register and debugger check r=adamgreig a=thenewwazoo Adds support for requesting an interrupt via the STIR register and checking whether a debugger is attached. Co-authored-by: Brandon Matthews <[email protected]> Co-authored-by: Brandon Matthews <[email protected]>
2 parents ac5f677 + 2ff4735 commit 17d3561

File tree

3 files changed

+56
-5
lines changed

3 files changed

+56
-5
lines changed

src/peripheral/dcb.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use volatile_register::{RW, WO};
44

5+
use core::ptr;
56
use peripheral::DCB;
67

78
const DCB_DEMCR_TRCENA: u32 = 1 << 24;
@@ -20,18 +21,37 @@ pub struct RegisterBlock {
2021
}
2122

2223
impl DCB {
23-
/// Enables TRACE. This is for example required by the
24+
/// Enables TRACE. This is for example required by the
2425
/// `peripheral::DWT` cycle counter to work properly.
2526
/// As by STM documentation, this flag is not reset on
2627
/// soft-reset, only on power reset.
2728
pub fn enable_trace(&mut self) {
2829
// set bit 24 / TRCENA
29-
unsafe { self.demcr.modify(|w| w | DCB_DEMCR_TRCENA); }
30+
unsafe {
31+
self.demcr.modify(|w| w | DCB_DEMCR_TRCENA);
32+
}
3033
}
31-
34+
3235
/// Disables TRACE. See `DCB::enable_trace()` for more details
3336
pub fn disable_trace(&mut self) {
3437
// unset bit 24 / TRCENA
35-
unsafe { self.demcr.modify(|w| w & !DCB_DEMCR_TRCENA); }
38+
unsafe {
39+
self.demcr.modify(|w| w & !DCB_DEMCR_TRCENA);
40+
}
41+
}
42+
43+
/// Is there a debugger attached? (see note)
44+
///
45+
/// Note: This function is [reported not to
46+
/// work](http://web.archive.org/web/20180821191012/https://community.nxp.com/thread/424925#comment-782843)
47+
/// on Cortex-M0 devices. Per the ARM v6-M Architecture Reference Manual, "Access to the DHCSR
48+
/// from software running on the processor is IMPLEMENTATION DEFINED". Indeed, from the
49+
/// [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."
50+
pub fn is_debugger_attached() -> bool {
51+
unsafe {
52+
// do an 8-bit read of the 32-bit DHCSR register, and get the LSB
53+
let value = ptr::read_volatile(Self::ptr() as *const u8);
54+
value & 0x1 == 1
55+
}
3656
}
3757
}

src/peripheral/nvic.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Nested Vector Interrupt Controller
22
33
#[cfg(not(armv6m))]
4-
use volatile_register::RO;
4+
use volatile_register::{RO, WO};
55
use volatile_register::RW;
66

77
use interrupt::Nr;
@@ -65,9 +65,38 @@ pub struct RegisterBlock {
6565
/// so convenient byte-sized representation wouldn't work on that
6666
/// architecture.
6767
pub ipr: [RW<u32>; 8],
68+
69+
#[cfg(not(armv6m))]
70+
reserved5: [u32; 208],
71+
72+
#[cfg(armv6m)]
73+
reserved5: [u32; 696],
74+
75+
#[cfg(not(armv6m))]
76+
/// Software Trigger Interrupt
77+
pub stir: WO<u32>,
6878
}
6979

7080
impl NVIC {
81+
#[cfg(not(armv6m))]
82+
/// Request an IRQ in software
83+
///
84+
/// Writing a value to the INTID field is the same as manually pending an interrupt by setting
85+
/// the corresponding interrupt bit in an Interrupt Set Pending Register. This is similar to
86+
/// `set_pending`.
87+
///
88+
/// This method is not available on ARMv6-M chips.
89+
pub fn request<I>(&mut self, interrupt: I)
90+
where
91+
I: Nr,
92+
{
93+
let nr = interrupt.nr();
94+
95+
unsafe {
96+
self.stir.write(nr as u32);
97+
}
98+
}
99+
71100
/// Clears `interrupt`'s pending state
72101
#[deprecated(since = "0.5.8", note = "Use `NVIC::unpend`")]
73102
pub fn clear_pending<I>(&mut self, interrupt: I)

src/peripheral/test.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ fn nvic() {
109109
assert_eq!(address(&nvic.icpr), 0xE000E280);
110110
assert_eq!(address(&nvic.iabr), 0xE000E300);
111111
assert_eq!(address(&nvic.ipr), 0xE000E400);
112+
#[cfg(not(armv6m))]
113+
assert_eq!(address(&nvic.stir), 0xE000EF00);
112114
}
113115

114116
#[test]

0 commit comments

Comments
 (0)