aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/peripheral/dcb.rs28
-rw-r--r--src/peripheral/nvic.rs30
-rw-r--r--src/peripheral/test.rs2
3 files changed, 54 insertions, 6 deletions
diff --git a/src/peripheral/dcb.rs b/src/peripheral/dcb.rs
index 14dc75b..e12542c 100644
--- a/src/peripheral/dcb.rs
+++ b/src/peripheral/dcb.rs
@@ -2,6 +2,7 @@
use volatile_register::{RW, WO};
+use core::ptr;
use peripheral::DCB;
const DCB_DEMCR_TRCENA: u32 = 1 << 24;
@@ -20,18 +21,37 @@ pub struct RegisterBlock {
}
impl DCB {
- /// Enables TRACE. This is for example required by the
+ /// Enables TRACE. This is for example required by the
/// `peripheral::DWT` cycle counter to work properly.
/// As by STM documentation, this flag is not reset on
/// soft-reset, only on power reset.
pub fn enable_trace(&mut self) {
// set bit 24 / TRCENA
- unsafe { self.demcr.modify(|w| w | DCB_DEMCR_TRCENA); }
+ unsafe {
+ self.demcr.modify(|w| w | DCB_DEMCR_TRCENA);
+ }
}
-
+
/// Disables TRACE. See `DCB::enable_trace()` for more details
pub fn disable_trace(&mut self) {
// unset bit 24 / TRCENA
- unsafe { self.demcr.modify(|w| w & !DCB_DEMCR_TRCENA); }
+ unsafe {
+ self.demcr.modify(|w| w & !DCB_DEMCR_TRCENA);
+ }
+ }
+
+ /// Is there a debugger attached? (see note)
+ ///
+ /// Note: This function is [reported not to
+ /// work](http://web.archive.org/web/20180821191012/https://community.nxp.com/thread/424925#comment-782843)
+ /// on Cortex-M0 devices. Per the ARM v6-M Architecture Reference Manual, "Access to the DHCSR
+ /// from software running on the processor is IMPLEMENTATION DEFINED". Indeed, from the
+ /// [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."
+ pub fn is_debugger_attached() -> bool {
+ unsafe {
+ // do an 8-bit read of the 32-bit DHCSR register, and get the LSB
+ let value = ptr::read_volatile(Self::ptr() as *const u8);
+ value & 0x1 == 1
+ }
}
}
diff --git a/src/peripheral/nvic.rs b/src/peripheral/nvic.rs
index c59c2c8..57ce009 100644
--- a/src/peripheral/nvic.rs
+++ b/src/peripheral/nvic.rs
@@ -1,8 +1,8 @@
//! Nested Vector Interrupt Controller
-#[cfg(not(armv6m))]
-use volatile_register::RO;
use volatile_register::RW;
+#[cfg(not(armv6m))]
+use volatile_register::{RO, WO};
use interrupt::Nr;
use peripheral::NVIC;
@@ -65,9 +65,35 @@ pub struct RegisterBlock {
/// so convenient byte-sized representation wouldn't work on that
/// architecture.
pub ipr: [RW<u32>; 8],
+
+ #[cfg(not(armv6m))]
+ _reserved6: [u32; 580],
+
+ #[cfg(not(armv6m))]
+ /// Software Trigger Interrupt
+ pub stir: WO<u32>,
}
impl NVIC {
+ #[cfg(not(armv6m))]
+ /// Request an IRQ in software
+ ///
+ /// Writing a value to the INTID field is the same as manually pending an interrupt by setting
+ /// the corresponding interrupt bit in an Interrupt Set Pending Register. This is similar to
+ /// `set_pending`.
+ ///
+ /// This method is not available on ARMv6-M chips.
+ pub fn request<I>(&mut self, interrupt: I)
+ where
+ I: Nr,
+ {
+ let nr = interrupt.nr();
+
+ unsafe {
+ self.stir.write(nr as u32);
+ }
+ }
+
/// Clears `interrupt`'s pending state
#[deprecated(since = "0.5.8", note = "Use `NVIC::unpend`")]
pub fn clear_pending<I>(&mut self, interrupt: I)
diff --git a/src/peripheral/test.rs b/src/peripheral/test.rs
index d0d713a..4eb48f5 100644
--- a/src/peripheral/test.rs
+++ b/src/peripheral/test.rs
@@ -117,6 +117,8 @@ fn nvic() {
assert_eq!(address(&nvic.icpr), 0xE000E280);
assert_eq!(address(&nvic.iabr), 0xE000E300);
assert_eq!(address(&nvic.ipr), 0xE000E400);
+ #[cfg(not(armv6m))]
+ assert_eq!(address(&nvic.stir), 0xE000EF00);
}
#[test]