diff options
author | 2020-07-05 23:03:51 +0200 | |
---|---|---|
committer | 2020-07-05 23:03:51 +0200 | |
commit | b01dcb48e1893cb148523c5476a5ab0b0f67c861 (patch) | |
tree | dc4a86d5b5c475b875e182103202e151a9ac888f | |
parent | 2ce2384d8dd239301b606921abe3b3f35d5fbb05 (diff) | |
parent | 08f2a69abeac6d681c2e59b0b0b62e1d803389eb (diff) | |
download | cortex-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.rs | 75 |
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 + } + } } |