1
1
//! System Control Block
2
2
3
3
use core:: ptr;
4
- #[ cfg( not( any( armv6m, armv8m_base) ) ) ]
5
- use crate :: interrupt;
6
4
7
5
use volatile_register:: RW ;
8
6
@@ -1014,6 +1012,20 @@ impl SCB {
1014
1012
}
1015
1013
}
1016
1014
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
+
1017
1029
/// Enable the exception
1018
1030
///
1019
1031
/// 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 {
1028
1040
#[ inline]
1029
1041
#[ cfg( not( any( armv6m, armv8m_base) ) ) ]
1030
1042
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.
1047
1046
unsafe { self . shcsr . modify ( |value| value | ( 1 << shift) ) }
1048
- } )
1047
+ }
1049
1048
}
1050
1049
1051
1050
/// Disable the exception
@@ -1062,24 +1061,11 @@ impl SCB {
1062
1061
#[ inline]
1063
1062
#[ cfg( not( any( armv6m, armv8m_base) ) ) ]
1064
1063
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.
1081
1067
unsafe { self . shcsr . modify ( |value| value & !( 1 << shift) ) }
1082
- } )
1068
+ }
1083
1069
}
1084
1070
1085
1071
/// Check if an exception is enabled
@@ -1093,16 +1079,11 @@ impl SCB {
1093
1079
/// Calling this function with any other exception will read `false`.
1094
1080
#[ inline]
1095
1081
#[ 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
+ }
1107
1088
}
1108
1089
}
0 commit comments