@@ -7,12 +7,20 @@ pub struct Control {
7
7
}
8
8
9
9
impl Control {
10
+ /// Creates a `Control` value from raw bits.
11
+ #[ inline]
12
+ pub fn from_bits ( bits : u32 ) -> Self {
13
+ Self { bits }
14
+ }
15
+
10
16
/// Returns the contents of the register as raw bits
17
+ #[ inline]
11
18
pub fn bits ( & self ) -> u32 {
12
19
self . bits
13
20
}
14
21
15
22
/// Thread mode privilege level
23
+ #[ inline]
16
24
pub fn npriv ( & self ) -> Npriv {
17
25
if self . bits & ( 1 << 0 ) == ( 1 << 0 ) {
18
26
Npriv :: Unprivileged
@@ -21,7 +29,18 @@ impl Control {
21
29
}
22
30
}
23
31
32
+ /// Sets the thread mode privilege level value (nPRIV).
33
+ #[ inline]
34
+ pub fn set_npriv ( & mut self , npriv : Npriv ) {
35
+ let mask = 1 << 0 ;
36
+ match npriv {
37
+ Npriv :: Unprivileged => self . bits |= mask,
38
+ Npriv :: Privileged => self . bits &= !mask,
39
+ }
40
+ }
41
+
24
42
/// Currently active stack pointer
43
+ #[ inline]
25
44
pub fn spsel ( & self ) -> Spsel {
26
45
if self . bits & ( 1 << 1 ) == ( 1 << 1 ) {
27
46
Spsel :: Psp
@@ -30,14 +49,35 @@ impl Control {
30
49
}
31
50
}
32
51
52
+ /// Sets the SPSEL value.
53
+ #[ inline]
54
+ pub fn set_spsel ( & mut self , spsel : Spsel ) {
55
+ let mask = 1 << 1 ;
56
+ match spsel {
57
+ Spsel :: Psp => self . bits |= mask,
58
+ Spsel :: Msp => self . bits &= !mask,
59
+ }
60
+ }
61
+
33
62
/// Whether context floating-point is currently active
63
+ #[ inline]
34
64
pub fn fpca ( & self ) -> Fpca {
35
65
if self . bits & ( 1 << 2 ) == ( 1 << 2 ) {
36
66
Fpca :: Active
37
67
} else {
38
68
Fpca :: NotActive
39
69
}
40
70
}
71
+
72
+ /// Sets the FPCA value.
73
+ #[ inline]
74
+ pub fn set_fpca ( & mut self , fpca : Fpca ) {
75
+ let mask = 1 << 2 ;
76
+ match fpca {
77
+ Fpca :: Active => self . bits |= mask,
78
+ Fpca :: NotActive => self . bits &= !mask,
79
+ }
80
+ }
41
81
}
42
82
43
83
/// Thread mode privilege level
@@ -51,11 +91,13 @@ pub enum Npriv {
51
91
52
92
impl Npriv {
53
93
/// Is in privileged thread mode?
94
+ #[ inline]
54
95
pub fn is_privileged ( & self ) -> bool {
55
96
* self == Npriv :: Privileged
56
97
}
57
98
58
99
/// Is in unprivileged thread mode?
100
+ #[ inline]
59
101
pub fn is_unprivileged ( & self ) -> bool {
60
102
* self == Npriv :: Unprivileged
61
103
}
@@ -72,11 +114,13 @@ pub enum Spsel {
72
114
73
115
impl Spsel {
74
116
/// Is MSP the current stack pointer?
117
+ #[ inline]
75
118
pub fn is_msp ( & self ) -> bool {
76
119
* self == Spsel :: Msp
77
120
}
78
121
79
122
/// Is PSP the current stack pointer?
123
+ #[ inline]
80
124
pub fn is_psp ( & self ) -> bool {
81
125
* self == Spsel :: Psp
82
126
}
@@ -93,11 +137,13 @@ pub enum Fpca {
93
137
94
138
impl Fpca {
95
139
/// Is a floating-point context active?
140
+ #[ inline]
96
141
pub fn is_active ( & self ) -> bool {
97
142
* self == Fpca :: Active
98
143
}
99
144
100
145
/// Is a floating-point context not active?
146
+ #[ inline]
101
147
pub fn is_not_active ( & self ) -> bool {
102
148
* self == Fpca :: NotActive
103
149
}
@@ -120,10 +166,10 @@ pub fn read() -> Control {
120
166
#[ cfg( not( feature = "inline-asm" ) ) ]
121
167
( ) => unsafe {
122
168
extern "C" {
123
- fn __control ( ) -> u32 ;
169
+ fn __control_r ( ) -> u32 ;
124
170
}
125
171
126
- __control ( )
172
+ __control_r ( )
127
173
} ,
128
174
} ;
129
175
@@ -134,3 +180,30 @@ pub fn read() -> Control {
134
180
( ) => unimplemented ! ( ) ,
135
181
}
136
182
}
183
+
184
+ /// Writes to the CPU register.
185
+ #[ inline]
186
+ pub unsafe fn write ( _control : Control ) {
187
+ match ( ) {
188
+ #[ cfg( cortex_m) ]
189
+ ( ) => match ( ) {
190
+ #[ cfg( feature = "inline-asm" ) ]
191
+ ( ) => {
192
+ let control = _control. bits ( ) ;
193
+ asm ! ( "msr CONTROL, $0" :: "r" ( control) : "memory" : "volatile" ) ;
194
+ }
195
+
196
+ #[ cfg( not( feature = "inline-asm" ) ) ]
197
+ ( ) => {
198
+ extern "C" {
199
+ fn __control_w ( bits : u32 ) ;
200
+ }
201
+
202
+ __control_w ( _control. bits ( ) ) ;
203
+ }
204
+ } ,
205
+
206
+ #[ cfg( not( cortex_m) ) ]
207
+ ( ) => unimplemented ! ( ) ,
208
+ }
209
+ }
0 commit comments