diff options
author | 2020-04-15 09:52:01 +0100 | |
---|---|---|
committer | 2020-06-24 11:13:46 +0100 | |
commit | 08f2a69abeac6d681c2e59b0b0b62e1d803389eb (patch) | |
tree | 8e956def3987f3da9de20ee84ef2531e245925c6 | |
parent | 27d52597d026fced3e78a45fbedd590a600de270 (diff) | |
download | cortex-m-08f2a69abeac6d681c2e59b0b0b62e1d803389eb.tar.gz cortex-m-08f2a69abeac6d681c2e59b0b0b62e1d803389eb.tar.zst cortex-m-08f2a69abeac6d681c2e59b0b0b62e1d803389eb.zip |
Add a function to get SHCSR enable bit positions
This removes the duplication of the look-up table and enforces some
safety checks with the match statement.
Signed-off-by: Hugues de Valon <hugues.devalon@arm.com>
-rw-r--r-- | src/peripheral/scb.rs | 75 |
1 files changed, 28 insertions, 47 deletions
diff --git a/src/peripheral/scb.rs b/src/peripheral/scb.rs index d33a110..7fb4505 100644 --- a/src/peripheral/scb.rs +++ b/src/peripheral/scb.rs @@ -1,8 +1,6 @@ //! System Control Block use core::ptr; -#[cfg(not(any(armv6m, armv8m_base)))] -use crate::interrupt; use volatile_register::RW; @@ -1014,6 +1012,20 @@ 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 @@ -1028,24 +1040,11 @@ impl SCB { #[inline] #[cfg(not(any(armv6m, armv8m_base)))] pub fn enable(&mut self, exception: Exception) { - if self.is_enabled(exception) { - return; - } - - // Make sure that the read-modify-write sequence happens during a critical section to avoid - // modifying pending and active interrupts. - interrupt::free(|_| { - let shift = match exception { - Exception::MemoryManagement => 16, - Exception::BusFault => 17, - Exception::UsageFault => 18, - #[cfg(armv8m_main)] - Exception::SecureFault => 19, - _ => return, - }; - + 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 @@ -1062,24 +1061,11 @@ impl SCB { #[inline] #[cfg(not(any(armv6m, armv8m_base)))] pub fn disable(&mut self, exception: Exception) { - if !self.is_enabled(exception) { - return; - } - - // Make sure that the read-modify-write sequence happens during a critical section to avoid - // modifying pending and active interrupts. - interrupt::free(|_| { - let shift = match exception { - Exception::MemoryManagement => 16, - Exception::BusFault => 17, - Exception::UsageFault => 18, - #[cfg(armv8m_main)] - Exception::SecureFault => 19, - _ => return, - }; - + 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 @@ -1093,16 +1079,11 @@ impl SCB { /// Calling this function with any other exception will read `false`. #[inline] #[cfg(not(any(armv6m, armv8m_base)))] - pub fn is_enabled(&mut self, exception: Exception) -> bool { - let shift = match exception { - Exception::MemoryManagement => 16, - Exception::BusFault => 17, - Exception::UsageFault => 18, - #[cfg(armv8m_main)] - Exception::SecureFault => 19, - _ => return false, - }; - - (self.shcsr.read() & (1 << shift)) > 0 + 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 + } } } |