]>
Commit | Line | Data |
---|---|---|
8faf50e0 XL |
1 | //! CMSIS: Cortex Microcontroller Software Interface Standard |
2 | //! | |
3 | //! The version 5 of the standard can be found at: | |
4 | //! | |
5 | //! http://arm-software.github.io/CMSIS_5/Core/html/index.html | |
6 | //! | |
7 | //! The API reference of the standard can be found at: | |
8 | //! | |
9 | //! - Core function access -- http://arm-software.github.io/CMSIS_5/Core/html/group__Core__Register__gr.html | |
10 | //! - Intrinsic functions for CPU instructions -- http://arm-software.github.io/CMSIS_5/Core/html/group__intrinsic__CPU__gr.html | |
11 | //! | |
0bf4aa26 XL |
12 | //! The reference C implementation used as the base of this Rust port can be |
13 | //! found at | |
8faf50e0 XL |
14 | //! |
15 | //! https://github.com/ARM-software/CMSIS_5/blob/5.3.0/CMSIS/Core/Include/cmsis_gcc.h | |
16 | ||
17 | #![allow(non_snake_case)] | |
18 | ||
19 | /* Core function access */ | |
20 | ||
21 | /// Enable IRQ Interrupts | |
22 | /// | |
23 | /// Enables IRQ interrupts by clearing the I-bit in the CPSR. Can only be | |
24 | /// executed in Privileged modes. | |
25 | #[inline] | |
26 | #[target_feature(enable = "mclass")] | |
27 | #[cfg_attr(test, assert_instr(cpsie))] | |
28 | pub unsafe fn __enable_irq() { | |
29 | asm!("cpsie i" : : : "memory" : "volatile"); | |
30 | } | |
31 | ||
32 | /// Disable IRQ Interrupts | |
33 | /// | |
34 | /// Disables IRQ interrupts by setting the I-bit in the CPSR. Can only be | |
35 | /// executed in Privileged modes. | |
36 | #[inline] | |
37 | #[target_feature(enable = "mclass")] | |
38 | #[cfg_attr(test, assert_instr(cpsid))] | |
39 | pub unsafe fn __disable_irq() { | |
40 | asm!("cpsid i" : : : "memory" : "volatile"); | |
41 | } | |
42 | ||
43 | /// Get Control Register | |
44 | /// | |
45 | /// Returns the content of the Control Register. | |
46 | #[inline] | |
47 | #[target_feature(enable = "mclass")] | |
48 | #[cfg_attr(test, assert_instr(mrs))] | |
49 | pub unsafe fn __get_CONTROL() -> u32 { | |
50 | let result: u32; | |
51 | asm!("mrs $0, CONTROL" : "=r"(result) : : : "volatile"); | |
52 | result | |
53 | } | |
54 | ||
55 | /// Set Control Register | |
56 | /// | |
57 | /// Writes the given value to the Control Register. | |
58 | #[inline] | |
59 | #[target_feature(enable = "mclass")] | |
60 | #[cfg_attr(test, assert_instr(msr))] | |
61 | pub unsafe fn __set_CONTROL(control: u32) { | |
62 | asm!("msr CONTROL, $0" : : "r"(control) : "memory" : "volatile"); | |
63 | } | |
64 | ||
65 | /// Get IPSR Register | |
66 | /// | |
67 | /// Returns the content of the IPSR Register. | |
68 | #[inline] | |
69 | #[target_feature(enable = "mclass")] | |
70 | #[cfg_attr(test, assert_instr(mrs))] | |
71 | pub unsafe fn __get_IPSR() -> u32 { | |
72 | let result: u32; | |
73 | asm!("mrs $0, IPSR" : "=r"(result) : : : "volatile"); | |
74 | result | |
75 | } | |
76 | ||
77 | /// Get APSR Register | |
78 | /// | |
79 | /// Returns the content of the APSR Register. | |
80 | #[inline] | |
81 | #[target_feature(enable = "mclass")] | |
82 | #[cfg_attr(test, assert_instr(mrs))] | |
83 | pub unsafe fn __get_APSR() -> u32 { | |
84 | let result: u32; | |
85 | asm!("mrs $0, APSR" : "=r"(result) : : : "volatile"); | |
86 | result | |
87 | } | |
88 | ||
89 | /// Get xPSR Register | |
90 | /// | |
91 | /// Returns the content of the xPSR Register. | |
92 | #[inline] | |
93 | #[target_feature(enable = "mclass")] | |
94 | #[cfg_attr(test, assert_instr(mrs))] | |
95 | pub unsafe fn __get_xPSR() -> u32 { | |
96 | let result: u32; | |
97 | asm!("mrs $0, XPSR" : "=r"(result) : : : "volatile"); | |
98 | result | |
99 | } | |
100 | ||
101 | /// Get Process Stack Pointer | |
102 | /// | |
103 | /// Returns the current value of the Process Stack Pointer (PSP). | |
104 | #[inline] | |
105 | #[target_feature(enable = "mclass")] | |
106 | #[cfg_attr(test, assert_instr(mrs))] | |
107 | pub unsafe fn __get_PSP() -> u32 { | |
108 | let result: u32; | |
109 | asm!("mrs $0, PSP" : "=r"(result) : : : "volatile"); | |
110 | result | |
111 | } | |
112 | ||
113 | /// Set Process Stack Pointer | |
114 | /// | |
115 | /// Assigns the given value to the Process Stack Pointer (PSP). | |
116 | #[inline] | |
117 | #[target_feature(enable = "mclass")] | |
118 | #[cfg_attr(test, assert_instr(msr))] | |
119 | pub unsafe fn __set_PSP(top_of_proc_stack: u32) { | |
120 | asm!("msr PSP, $0" : : "r"(top_of_proc_stack) : : "volatile"); | |
121 | } | |
122 | ||
123 | /// Get Main Stack Pointer | |
124 | /// | |
125 | /// Returns the current value of the Main Stack Pointer (MSP). | |
126 | #[inline] | |
127 | #[target_feature(enable = "mclass")] | |
128 | #[cfg_attr(test, assert_instr(mrs))] | |
129 | pub unsafe fn __get_MSP() -> u32 { | |
130 | let result: u32; | |
131 | asm!("mrs $0, MSP" : "=r"(result) : : : "volatile"); | |
132 | result | |
133 | } | |
134 | ||
135 | /// Set Main Stack Pointer | |
136 | /// | |
137 | /// Assigns the given value to the Main Stack Pointer (MSP). | |
138 | #[inline] | |
139 | #[target_feature(enable = "mclass")] | |
140 | #[cfg_attr(test, assert_instr(msr))] | |
141 | pub unsafe fn __set_MSP(top_of_main_stack: u32) { | |
142 | asm!("msr MSP, $0" : : "r"(top_of_main_stack) : : "volatile"); | |
143 | } | |
144 | ||
145 | /// Get Priority Mask | |
146 | /// | |
147 | /// Returns the current state of the priority mask bit from the Priority Mask | |
148 | /// Register. | |
149 | #[inline] | |
150 | #[target_feature(enable = "mclass")] | |
151 | #[cfg_attr(test, assert_instr(mrs))] | |
152 | pub unsafe fn __get_PRIMASK() -> u32 { | |
153 | let result: u32; | |
154 | asm!("mrs $0, PRIMASK" : "=r"(result) : : "memory" : "volatile"); | |
155 | result | |
156 | } | |
157 | ||
158 | /// Set Priority Mask | |
159 | /// | |
160 | /// Assigns the given value to the Priority Mask Register. | |
161 | #[inline] | |
162 | #[target_feature(enable = "mclass")] | |
163 | #[cfg_attr(test, assert_instr(msr))] | |
164 | pub unsafe fn __set_PRIMASK(pri_mask: u32) { | |
165 | asm!("msr PRIMASK, $0" : : "r"(pri_mask) : : "volatile"); | |
166 | } | |
167 | ||
168 | #[cfg(any(target_feature = "v7", dox))] | |
169 | mod v7 { | |
170 | /// Enable FIQ | |
171 | /// | |
172 | /// Enables FIQ interrupts by clearing the F-bit in the CPSR. Can only be | |
173 | /// executed in Privileged modes. | |
174 | #[inline] | |
175 | #[target_feature(enable = "mclass")] | |
176 | #[cfg_attr(test, assert_instr(cpsie))] | |
177 | pub unsafe fn __enable_fault_irq() { | |
178 | asm!("cpsie f" : : : "memory" : "volatile"); | |
179 | } | |
180 | ||
181 | /// Disable FIQ | |
182 | /// | |
183 | /// Disables FIQ interrupts by setting the F-bit in the CPSR. Can only be | |
184 | /// executed in Privileged modes. | |
185 | #[inline] | |
186 | #[target_feature(enable = "mclass")] | |
187 | #[cfg_attr(test, assert_instr(cpsid))] | |
188 | pub unsafe fn __disable_fault_irq() { | |
189 | asm!("cpsid f" : : : "memory" : "volatile"); | |
190 | } | |
191 | ||
192 | /// Get Base Priority | |
193 | /// | |
194 | /// Returns the current value of the Base Priority register. | |
195 | #[inline] | |
196 | #[target_feature(enable = "mclass")] | |
197 | #[cfg_attr(test, assert_instr(mrs))] | |
198 | pub unsafe fn __get_BASEPRI() -> u32 { | |
199 | let result: u32; | |
200 | asm!("mrs $0, BASEPRI" : "=r"(result) : : : "volatile"); | |
201 | result | |
202 | } | |
203 | ||
204 | /// Set Base Priority | |
205 | /// | |
206 | /// Assigns the given value to the Base Priority register. | |
207 | #[inline] | |
208 | #[target_feature(enable = "mclass")] | |
209 | #[cfg_attr(test, assert_instr(msr))] | |
210 | pub unsafe fn __set_BASEPRI(base_pri: u32) { | |
211 | asm!("msr BASEPRI, $0" : : "r"(base_pri) : "memory" : "volatile"); | |
212 | } | |
213 | ||
214 | /// Set Base Priority with condition | |
215 | /// | |
216 | /// Assigns the given value to the Base Priority register only if BASEPRI | |
217 | /// masking is disabled, or the new value increases the BASEPRI | |
218 | /// priority level. | |
219 | #[inline] | |
220 | #[target_feature(enable = "mclass")] | |
221 | #[cfg_attr(test, assert_instr(mrs))] | |
222 | pub unsafe fn __set_BASEPRI_MAX(base_pri: u32) { | |
223 | asm!("msr BASEPRI_MAX, $0" : : "r"(base_pri) : "memory" : "volatile"); | |
224 | } | |
225 | ||
226 | /// Get Fault Mask | |
227 | /// | |
228 | /// Returns the current value of the Fault Mask register. | |
229 | #[inline] | |
230 | #[target_feature(enable = "mclass")] | |
231 | #[cfg_attr(test, assert_instr(mrs))] | |
232 | pub unsafe fn __get_FAULTMASK() -> u32 { | |
233 | let result: u32; | |
234 | asm!("mrs $0, FAULTMASK" : "=r"(result) : : : "volatile"); | |
235 | result | |
236 | } | |
237 | ||
238 | /// Set Fault Mask | |
239 | /// | |
240 | /// Assigns the given value to the Fault Mask register. | |
241 | #[inline] | |
242 | #[target_feature(enable = "mclass")] | |
243 | #[cfg_attr(test, assert_instr(msr))] | |
244 | pub unsafe fn __set_FAULTMASK(fault_mask: u32) { | |
245 | asm!("msr FAULTMASK, $0" : : "r"(fault_mask) : "memory" : "volatile"); | |
246 | } | |
247 | } | |
248 | ||
249 | #[cfg(any(target_feature = "v7", dox))] | |
250 | pub use self::v7::*; | |
251 | ||
252 | /* Core instruction access */ | |
253 | ||
254 | /// No Operation | |
255 | /// | |
256 | /// No Operation does nothing. This instruction can be used for code alignment | |
257 | /// purposes. | |
258 | #[inline] | |
259 | #[target_feature(enable = "mclass")] | |
260 | #[cfg_attr(test, assert_instr(nop))] | |
261 | pub unsafe fn __NOP() { | |
262 | asm!("nop" : : : : "volatile"); | |
263 | } | |
264 | ||
265 | /// Wait For Interrupt | |
266 | /// | |
267 | /// Wait For Interrupt is a hint instruction that suspends execution until one | |
268 | /// of a number of events occurs. | |
269 | #[inline] | |
270 | #[target_feature(enable = "mclass")] | |
271 | #[cfg_attr(test, assert_instr(wfi))] | |
272 | pub unsafe fn __WFI() { | |
273 | asm!("wfi" : : : : "volatile"); | |
274 | } | |
275 | ||
276 | /// Wait For Event | |
277 | /// | |
278 | /// Wait For Event is a hint instruction that permits the processor to enter a | |
279 | /// low-power state until one of a number of events occurs. | |
280 | #[inline] | |
281 | #[target_feature(enable = "mclass")] | |
282 | #[cfg_attr(test, assert_instr(wfe))] | |
283 | pub unsafe fn __WFE() { | |
284 | asm!("wfe" : : : : "volatile"); | |
285 | } | |
286 | ||
287 | /// Send Event | |
288 | /// | |
289 | /// Send Event is a hint instruction. It causes an event to be signaled to the | |
290 | /// CPU. | |
291 | #[inline] | |
292 | #[target_feature(enable = "mclass")] | |
293 | #[cfg_attr(test, assert_instr(sev))] | |
294 | pub unsafe fn __SEV() { | |
295 | asm!("sev" : : : : "volatile"); | |
296 | } | |
297 | ||
298 | /// Instruction Synchronization Barrier | |
299 | /// | |
300 | /// Instruction Synchronization Barrier flushes the pipeline in the processor, | |
301 | /// so that all instructions following the ISB are fetched from cache or | |
302 | /// memory, after the instruction has been completed. | |
303 | #[inline] | |
304 | #[target_feature(enable = "mclass")] | |
305 | #[cfg_attr(test, assert_instr(isb))] | |
306 | pub unsafe fn __ISB() { | |
307 | asm!("isb 0xF" : : : "memory" : "volatile"); | |
308 | } | |
309 | ||
310 | /// Data Synchronization Barrier | |
311 | /// | |
312 | /// Acts as a special kind of Data Memory Barrier. It completes when all | |
313 | /// explicit memory accesses before this instruction complete. | |
314 | #[inline] | |
315 | #[target_feature(enable = "mclass")] | |
316 | #[cfg_attr(test, assert_instr(dsb))] | |
317 | pub unsafe fn __DSB() { | |
318 | asm!("dsb 0xF" : : : "memory" : "volatile"); | |
319 | } | |
320 | ||
321 | /// Data Memory Barrier | |
322 | /// | |
323 | /// Ensures the apparent order of the explicit memory operations before and | |
324 | /// after the instruction, without ensuring their completion. | |
325 | #[inline] | |
326 | #[target_feature(enable = "mclass")] | |
327 | #[cfg_attr(test, assert_instr(dmb))] | |
328 | pub unsafe fn __DMB() { | |
329 | asm!("dmb 0xF" : : : "memory" : "volatile"); | |
330 | } |