|
1 | 1 | //! System Control Block
|
2 | 2 |
|
3 | 3 | use core::ptr;
|
| 4 | +#[cfg(not(any(armv6m, armv8m_base)))] |
| 5 | +use crate::interrupt; |
4 | 6 |
|
5 | 7 | use volatile_register::RW;
|
6 | 8 |
|
@@ -1011,4 +1013,96 @@ impl SCB {
|
1011 | 1013 | });
|
1012 | 1014 | }
|
1013 | 1015 | }
|
| 1016 | + |
| 1017 | + /// Enable the exception |
| 1018 | + /// |
| 1019 | + /// If the exception is enabled, when the exception is triggered, the exception handler will be executed instead of the |
| 1020 | + /// HardFault handler. |
| 1021 | + /// This function is only allowed on the following exceptions: |
| 1022 | + /// * `MemoryManagement` |
| 1023 | + /// * `BusFault` |
| 1024 | + /// * `UsageFault` |
| 1025 | + /// * `SecureFault` (can only be enabled from Secure state) |
| 1026 | + /// |
| 1027 | + /// Calling this function with any other exception will do nothing. |
| 1028 | + #[inline] |
| 1029 | + #[cfg(not(any(armv6m, armv8m_base)))] |
| 1030 | + pub fn enable(&mut self, exception: Exception) { |
| 1031 | + if self.is_enabled(exception) { |
| 1032 | + return; |
| 1033 | + } |
| 1034 | + |
| 1035 | + // Make sure that the read-modify-write sequence happens during a critical section to avoid |
| 1036 | + // modifying pending and active interrupts. |
| 1037 | + interrupt::free(|_| { |
| 1038 | + let shift = match exception { |
| 1039 | + Exception::MemoryManagement => 16, |
| 1040 | + Exception::BusFault => 17, |
| 1041 | + Exception::UsageFault => 18, |
| 1042 | + #[cfg(armv8m_main)] |
| 1043 | + Exception::SecureFault => 19, |
| 1044 | + _ => return, |
| 1045 | + }; |
| 1046 | + |
| 1047 | + unsafe { self.shcsr.modify(|value| value | (1 << shift)) } |
| 1048 | + }) |
| 1049 | + } |
| 1050 | + |
| 1051 | + /// Disable the exception |
| 1052 | + /// |
| 1053 | + /// If the exception is disabled, when the exception is triggered, the HardFault handler will be executed instead of the |
| 1054 | + /// exception handler. |
| 1055 | + /// This function is only allowed on the following exceptions: |
| 1056 | + /// * `MemoryManagement` |
| 1057 | + /// * `BusFault` |
| 1058 | + /// * `UsageFault` |
| 1059 | + /// * `SecureFault` (can not be changed from Non-secure state) |
| 1060 | + /// |
| 1061 | + /// Calling this function with any other exception will do nothing. |
| 1062 | + #[inline] |
| 1063 | + #[cfg(not(any(armv6m, armv8m_base)))] |
| 1064 | + pub fn disable(&mut self, exception: Exception) { |
| 1065 | + if !self.is_enabled(exception) { |
| 1066 | + return; |
| 1067 | + } |
| 1068 | + |
| 1069 | + // Make sure that the read-modify-write sequence happens during a critical section to avoid |
| 1070 | + // modifying pending and active interrupts. |
| 1071 | + interrupt::free(|_| { |
| 1072 | + let shift = match exception { |
| 1073 | + Exception::MemoryManagement => 16, |
| 1074 | + Exception::BusFault => 17, |
| 1075 | + Exception::UsageFault => 18, |
| 1076 | + #[cfg(armv8m_main)] |
| 1077 | + Exception::SecureFault => 19, |
| 1078 | + _ => return, |
| 1079 | + }; |
| 1080 | + |
| 1081 | + unsafe { self.shcsr.modify(|value| value & !(1 << shift)) } |
| 1082 | + }) |
| 1083 | + } |
| 1084 | + |
| 1085 | + /// Check if an exception is enabled |
| 1086 | + /// |
| 1087 | + /// This function is only allowed on the following exception: |
| 1088 | + /// * `MemoryManagement` |
| 1089 | + /// * `BusFault` |
| 1090 | + /// * `UsageFault` |
| 1091 | + /// * `SecureFault` (can not be read from Non-secure state) |
| 1092 | + /// |
| 1093 | + /// Calling this function with any other exception will read `false`. |
| 1094 | + #[inline] |
| 1095 | + #[cfg(not(any(armv6m, armv8m_base)))] |
| 1096 | + pub fn is_enabled(&mut self, exception: Exception) -> bool { |
| 1097 | + let shift = match exception { |
| 1098 | + Exception::MemoryManagement => 16, |
| 1099 | + Exception::BusFault => 17, |
| 1100 | + Exception::UsageFault => 18, |
| 1101 | + #[cfg(armv8m_main)] |
| 1102 | + Exception::SecureFault => 19, |
| 1103 | + _ => return false, |
| 1104 | + }; |
| 1105 | + |
| 1106 | + (self.shcsr.read() & (1 << shift)) > 0 |
| 1107 | + } |
1014 | 1108 | }
|
0 commit comments