@@ -7,12 +7,20 @@ pub struct Control {
77}
88
99impl Control {
10+ /// Creates a `Control` value from raw bits.
11+ #[ inline]
12+ pub fn from_bits ( bits : u32 ) -> Self {
13+ Self { bits }
14+ }
15+
1016 /// Returns the contents of the register as raw bits
17+ #[ inline]
1118 pub fn bits ( & self ) -> u32 {
1219 self . bits
1320 }
1421
1522 /// Thread mode privilege level
23+ #[ inline]
1624 pub fn npriv ( & self ) -> Npriv {
1725 if self . bits & ( 1 << 0 ) == ( 1 << 0 ) {
1826 Npriv :: Unprivileged
@@ -21,7 +29,18 @@ impl Control {
2129 }
2230 }
2331
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+
2442 /// Currently active stack pointer
43+ #[ inline]
2544 pub fn spsel ( & self ) -> Spsel {
2645 if self . bits & ( 1 << 1 ) == ( 1 << 1 ) {
2746 Spsel :: Psp
@@ -30,14 +49,35 @@ impl Control {
3049 }
3150 }
3251
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+
3362 /// Whether context floating-point is currently active
63+ #[ inline]
3464 pub fn fpca ( & self ) -> Fpca {
3565 if self . bits & ( 1 << 2 ) == ( 1 << 2 ) {
3666 Fpca :: Active
3767 } else {
3868 Fpca :: NotActive
3969 }
4070 }
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+ }
4181}
4282
4383/// Thread mode privilege level
@@ -51,11 +91,13 @@ pub enum Npriv {
5191
5292impl Npriv {
5393 /// Is in privileged thread mode?
94+ #[ inline]
5495 pub fn is_privileged ( & self ) -> bool {
5596 * self == Npriv :: Privileged
5697 }
5798
5899 /// Is in unprivileged thread mode?
100+ #[ inline]
59101 pub fn is_unprivileged ( & self ) -> bool {
60102 * self == Npriv :: Unprivileged
61103 }
@@ -72,11 +114,13 @@ pub enum Spsel {
72114
73115impl Spsel {
74116 /// Is MSP the current stack pointer?
117+ #[ inline]
75118 pub fn is_msp ( & self ) -> bool {
76119 * self == Spsel :: Msp
77120 }
78121
79122 /// Is PSP the current stack pointer?
123+ #[ inline]
80124 pub fn is_psp ( & self ) -> bool {
81125 * self == Spsel :: Psp
82126 }
@@ -93,11 +137,13 @@ pub enum Fpca {
93137
94138impl Fpca {
95139 /// Is a floating-point context active?
140+ #[ inline]
96141 pub fn is_active ( & self ) -> bool {
97142 * self == Fpca :: Active
98143 }
99144
100145 /// Is a floating-point context not active?
146+ #[ inline]
101147 pub fn is_not_active ( & self ) -> bool {
102148 * self == Fpca :: NotActive
103149 }
@@ -120,10 +166,10 @@ pub fn read() -> Control {
120166 #[ cfg( not( feature = "inline-asm" ) ) ]
121167 ( ) => unsafe {
122168 extern "C" {
123- fn __control ( ) -> u32 ;
169+ fn __control_r ( ) -> u32 ;
124170 }
125171
126- __control ( )
172+ __control_r ( )
127173 } ,
128174 } ;
129175
@@ -134,3 +180,30 @@ pub fn read() -> Control {
134180 ( ) => unimplemented ! ( ) ,
135181 }
136182}
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