11//! System Control Block
22
33use core:: ptr;
4- #[ cfg( not( any( armv6m, armv8m_base) ) ) ]
5- use crate :: interrupt;
64
75use volatile_register:: RW ;
86
@@ -1014,6 +1012,20 @@ impl SCB {
10141012 }
10151013 }
10161014
1015+ /// Return the bit position of the exception enable bit in the SHCSR register
1016+ #[ inline]
1017+ #[ cfg( not( any( armv6m, armv8m_base) ) ) ]
1018+ fn shcsr_enable_shift ( exception : Exception ) -> Option < u32 > {
1019+ match exception {
1020+ Exception :: MemoryManagement => Some ( 16 ) ,
1021+ Exception :: BusFault => Some ( 17 ) ,
1022+ Exception :: UsageFault => Some ( 18 ) ,
1023+ #[ cfg( armv8m_main) ]
1024+ Exception :: SecureFault => Some ( 19 ) ,
1025+ _ => None ,
1026+ }
1027+ }
1028+
10171029 /// Enable the exception
10181030 ///
10191031 /// 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 {
10281040 #[ inline]
10291041 #[ cfg( not( any( armv6m, armv8m_base) ) ) ]
10301042 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-
1043+ if let Some ( shift) = SCB :: shcsr_enable_shift ( exception) {
1044+ // The mutable reference to SCB makes sure that only this code is currently modifying
1045+ // the register.
10471046 unsafe { self . shcsr . modify ( |value| value | ( 1 << shift) ) }
1048- } )
1047+ }
10491048 }
10501049
10511050 /// Disable the exception
@@ -1062,24 +1061,11 @@ impl SCB {
10621061 #[ inline]
10631062 #[ cfg( not( any( armv6m, armv8m_base) ) ) ]
10641063 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-
1064+ if let Some ( shift) = SCB :: shcsr_enable_shift ( exception) {
1065+ // The mutable reference to SCB makes sure that only this code is currently modifying
1066+ // the register.
10811067 unsafe { self . shcsr . modify ( |value| value & !( 1 << shift) ) }
1082- } )
1068+ }
10831069 }
10841070
10851071 /// Check if an exception is enabled
@@ -1093,16 +1079,11 @@ impl SCB {
10931079 /// Calling this function with any other exception will read `false`.
10941080 #[ inline]
10951081 #[ 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
1082+ pub fn is_enabled ( & self , exception : Exception ) -> bool {
1083+ if let Some ( shift) = SCB :: shcsr_enable_shift ( exception) {
1084+ ( self . shcsr . read ( ) & ( 1 << shift) ) > 0
1085+ } else {
1086+ false
1087+ }
11071088 }
11081089}
0 commit comments