@@ -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