Skip to content

Commit b01dcb4

Browse files
authored
Merge pull request #205 from hug-dev/enable-exceptions
Add SCB methods to enable/disable exceptions
2 parents 2ce2384 + 08f2a69 commit b01dcb4

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

src/peripheral/scb.rs

+75
Original file line numberDiff line numberDiff line change
@@ -1019,4 +1019,79 @@ impl SCB {
10191019
});
10201020
}
10211021
}
1022+
1023+
/// Return the bit position of the exception enable bit in the SHCSR register
1024+
#[inline]
1025+
#[cfg(not(any(armv6m, armv8m_base)))]
1026+
fn shcsr_enable_shift(exception: Exception) -> Option<u32> {
1027+
match exception {
1028+
Exception::MemoryManagement => Some(16),
1029+
Exception::BusFault => Some(17),
1030+
Exception::UsageFault => Some(18),
1031+
#[cfg(armv8m_main)]
1032+
Exception::SecureFault => Some(19),
1033+
_ => None,
1034+
}
1035+
}
1036+
1037+
/// Enable the exception
1038+
///
1039+
/// If the exception is enabled, when the exception is triggered, the exception handler will be executed instead of the
1040+
/// HardFault handler.
1041+
/// This function is only allowed on the following exceptions:
1042+
/// * `MemoryManagement`
1043+
/// * `BusFault`
1044+
/// * `UsageFault`
1045+
/// * `SecureFault` (can only be enabled from Secure state)
1046+
///
1047+
/// Calling this function with any other exception will do nothing.
1048+
#[inline]
1049+
#[cfg(not(any(armv6m, armv8m_base)))]
1050+
pub fn enable(&mut self, exception: Exception) {
1051+
if let Some(shift) = SCB::shcsr_enable_shift(exception) {
1052+
// The mutable reference to SCB makes sure that only this code is currently modifying
1053+
// the register.
1054+
unsafe { self.shcsr.modify(|value| value | (1 << shift)) }
1055+
}
1056+
}
1057+
1058+
/// Disable the exception
1059+
///
1060+
/// If the exception is disabled, when the exception is triggered, the HardFault handler will be executed instead of the
1061+
/// exception handler.
1062+
/// This function is only allowed on the following exceptions:
1063+
/// * `MemoryManagement`
1064+
/// * `BusFault`
1065+
/// * `UsageFault`
1066+
/// * `SecureFault` (can not be changed from Non-secure state)
1067+
///
1068+
/// Calling this function with any other exception will do nothing.
1069+
#[inline]
1070+
#[cfg(not(any(armv6m, armv8m_base)))]
1071+
pub fn disable(&mut self, exception: Exception) {
1072+
if let Some(shift) = SCB::shcsr_enable_shift(exception) {
1073+
// The mutable reference to SCB makes sure that only this code is currently modifying
1074+
// the register.
1075+
unsafe { self.shcsr.modify(|value| value & !(1 << shift)) }
1076+
}
1077+
}
1078+
1079+
/// Check if an exception is enabled
1080+
///
1081+
/// This function is only allowed on the following exception:
1082+
/// * `MemoryManagement`
1083+
/// * `BusFault`
1084+
/// * `UsageFault`
1085+
/// * `SecureFault` (can not be read from Non-secure state)
1086+
///
1087+
/// Calling this function with any other exception will read `false`.
1088+
#[inline]
1089+
#[cfg(not(any(armv6m, armv8m_base)))]
1090+
pub fn is_enabled(&self, exception: Exception) -> bool {
1091+
if let Some(shift) = SCB::shcsr_enable_shift(exception) {
1092+
(self.shcsr.read() & (1 << shift)) > 0
1093+
} else {
1094+
false
1095+
}
1096+
}
10221097
}

0 commit comments

Comments
 (0)