aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Hugues de Valon <hugues.devalon@arm.com> 2020-04-15 09:52:01 +0100
committerGravatar Hugues de Valon <hugues.devalon@arm.com> 2020-06-24 11:13:46 +0100
commit08f2a69abeac6d681c2e59b0b0b62e1d803389eb (patch)
tree8e956def3987f3da9de20ee84ef2531e245925c6
parent27d52597d026fced3e78a45fbedd590a600de270 (diff)
downloadcortex-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.rs75
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
+ }
}
}