aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Daniel Egger <daniel@eggers-club.de> 2020-07-05 23:03:51 +0200
committerGravatar GitHub <noreply@github.com> 2020-07-05 23:03:51 +0200
commitb01dcb48e1893cb148523c5476a5ab0b0f67c861 (patch)
treedc4a86d5b5c475b875e182103202e151a9ac888f
parent2ce2384d8dd239301b606921abe3b3f35d5fbb05 (diff)
parent08f2a69abeac6d681c2e59b0b0b62e1d803389eb (diff)
downloadcortex-m-b01dcb48e1893cb148523c5476a5ab0b0f67c861.tar.gz
cortex-m-b01dcb48e1893cb148523c5476a5ab0b0f67c861.tar.zst
cortex-m-b01dcb48e1893cb148523c5476a5ab0b0f67c861.zip
Merge pull request #205 from hug-dev/enable-exceptions
Add SCB methods to enable/disable exceptions
-rw-r--r--src/peripheral/scb.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/peripheral/scb.rs b/src/peripheral/scb.rs
index 7343b4d..001bb14 100644
--- a/src/peripheral/scb.rs
+++ b/src/peripheral/scb.rs
@@ -1019,4 +1019,79 @@ impl SCB {
});
}
}
+
+ /// Return the bit position of the exception enable bit in the SHCSR register
+ #[inline]
+ #[cfg(not(any(armv6m, armv8m_base)))]
+ fn shcsr_enable_shift(exception: Exception) -> Option<u32> {
+ match exception {
+ Exception::MemoryManagement => Some(16),
+ Exception::BusFault => Some(17),
+ Exception::UsageFault => Some(18),
+ #[cfg(armv8m_main)]
+ Exception::SecureFault => Some(19),
+ _ => None,
+ }
+ }
+
+ /// Enable the exception
+ ///
+ /// If the exception is enabled, when the exception is triggered, the exception handler will be executed instead of the
+ /// HardFault handler.
+ /// This function is only allowed on the following exceptions:
+ /// * `MemoryManagement`
+ /// * `BusFault`
+ /// * `UsageFault`
+ /// * `SecureFault` (can only be enabled from Secure state)
+ ///
+ /// Calling this function with any other exception will do nothing.
+ #[inline]
+ #[cfg(not(any(armv6m, armv8m_base)))]
+ pub fn enable(&mut self, exception: Exception) {
+ if let Some(shift) = SCB::shcsr_enable_shift(exception) {
+ // The mutable reference to SCB makes sure that only this code is currently modifying
+ // the register.
+ unsafe { self.shcsr.modify(|value| value | (1 << shift)) }
+ }
+ }
+
+ /// Disable the exception
+ ///
+ /// If the exception is disabled, when the exception is triggered, the HardFault handler will be executed instead of the
+ /// exception handler.
+ /// This function is only allowed on the following exceptions:
+ /// * `MemoryManagement`
+ /// * `BusFault`
+ /// * `UsageFault`
+ /// * `SecureFault` (can not be changed from Non-secure state)
+ ///
+ /// Calling this function with any other exception will do nothing.
+ #[inline]
+ #[cfg(not(any(armv6m, armv8m_base)))]
+ pub fn disable(&mut self, exception: Exception) {
+ if let Some(shift) = SCB::shcsr_enable_shift(exception) {
+ // The mutable reference to SCB makes sure that only this code is currently modifying
+ // the register.
+ unsafe { self.shcsr.modify(|value| value & !(1 << shift)) }
+ }
+ }
+
+ /// Check if an exception is enabled
+ ///
+ /// This function is only allowed on the following exception:
+ /// * `MemoryManagement`
+ /// * `BusFault`
+ /// * `UsageFault`
+ /// * `SecureFault` (can not be read from Non-secure state)
+ ///
+ /// Calling this function with any other exception will read `false`.
+ #[inline]
+ #[cfg(not(any(armv6m, armv8m_base)))]
+ pub fn is_enabled(&self, exception: Exception) -> bool {
+ if let Some(shift) = SCB::shcsr_enable_shift(exception) {
+ (self.shcsr.read() & (1 << shift)) > 0
+ } else {
+ false
+ }
+ }
}