Skip to content

Commit 563c27a

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 3b574e8 + 771fc84 commit 563c27a

File tree

3 files changed

+54
-6
lines changed

3 files changed

+54
-6
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: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Nested Vector Interrupt Controller
22
3-
#[cfg(not(armv6m))]
4-
use volatile_register::RO;
53
use volatile_register::RW;
4+
#[cfg(not(armv6m))]
5+
use volatile_register::{RO, WO};
66

77
use interrupt::Nr;
88
use peripheral::NVIC;
@@ -65,9 +65,35 @@ 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+
_reserved6: [u32; 580],
71+
72+
#[cfg(not(armv6m))]
73+
/// Software Trigger Interrupt
74+
pub stir: WO<u32>,
6875
}
6976

7077
impl NVIC {
78+
#[cfg(not(armv6m))]
79+
/// Request an IRQ in software
80+
///
81+
/// Writing a value to the INTID field is the same as manually pending an interrupt by setting
82+
/// the corresponding interrupt bit in an Interrupt Set Pending Register. This is similar to
83+
/// `set_pending`.
84+
///
85+
/// This method is not available on ARMv6-M chips.
86+
pub fn request<I>(&mut self, interrupt: I)
87+
where
88+
I: Nr,
89+
{
90+
let nr = interrupt.nr();
91+
92+
unsafe {
93+
self.stir.write(nr as u32);
94+
}
95+
}
96+
7197
/// Clears `interrupt`'s pending state
7298
#[deprecated(since = "0.5.8", note = "Use `NVIC::unpend`")]
7399
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
@@ -117,6 +117,8 @@ fn nvic() {
117117
assert_eq!(address(&nvic.icpr), 0xE000E280);
118118
assert_eq!(address(&nvic.iabr), 0xE000E300);
119119
assert_eq!(address(&nvic.ipr), 0xE000E400);
120+
#[cfg(not(armv6m))]
121+
assert_eq!(address(&nvic.stir), 0xE000EF00);
120122
}
121123

122124
#[test]

0 commit comments

Comments
 (0)