xref: /nrf52832-nimble/rt-thread/components/CMSIS/Include/core_cmFunc.h (revision 104654410c56c573564690304ae786df310c91fc)
1 /**************************************************************************//**
2  * @file     core_cmFunc.h
3  * @brief    CMSIS Cortex-M Core Function Access Header File
4  * @version  V3.20
5  * @date     25. February 2013
6  *
7  * @note
8  *
9  ******************************************************************************/
10 /* Copyright (c) 2009 - 2013 ARM LIMITED
11 
12    All rights reserved.
13    Redistribution and use in source and binary forms, with or without
14    modification, are permitted provided that the following conditions are met:
15    - Redistributions of source code must retain the above copyright
16      notice, this list of conditions and the following disclaimer.
17    - Redistributions in binary form must reproduce the above copyright
18      notice, this list of conditions and the following disclaimer in the
19      documentation and/or other materials provided with the distribution.
20    - Neither the name of ARM nor the names of its contributors may be used
21      to endorse or promote products derived from this software without
22      specific prior written permission.
23    *
24    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27    ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34    POSSIBILITY OF SUCH DAMAGE.
35    ---------------------------------------------------------------------------*/
36 
37 
38 #ifndef __CORE_CMFUNC_H
39 #define __CORE_CMFUNC_H
40 
41 
42 /* ###########################  Core Function Access  ########################### */
43 /** \ingroup  CMSIS_Core_FunctionInterface
44     \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
45   @{
46  */
47 
48 #if   defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
49 /* ARM armcc specific functions */
50 
51 #if (__ARMCC_VERSION < 400677)
52   #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
53 #endif
54 
55 /* intrinsic void __enable_irq();     */
56 /* intrinsic void __disable_irq();    */
57 
58 /** \brief  Get Control Register
59 
60     This function returns the content of the Control Register.
61 
62     \return               Control Register value
63  */
__get_CONTROL(void)64 __STATIC_INLINE uint32_t __get_CONTROL(void)
65 {
66   register uint32_t __regControl         __ASM("control");
67   return(__regControl);
68 }
69 
70 
71 /** \brief  Set Control Register
72 
73     This function writes the given value to the Control Register.
74 
75     \param [in]    control  Control Register value to set
76  */
__set_CONTROL(uint32_t control)77 __STATIC_INLINE void __set_CONTROL(uint32_t control)
78 {
79   register uint32_t __regControl         __ASM("control");
80   __regControl = control;
81 }
82 
83 
84 /** \brief  Get IPSR Register
85 
86     This function returns the content of the IPSR Register.
87 
88     \return               IPSR Register value
89  */
__get_IPSR(void)90 __STATIC_INLINE uint32_t __get_IPSR(void)
91 {
92   register uint32_t __regIPSR          __ASM("ipsr");
93   return(__regIPSR);
94 }
95 
96 
97 /** \brief  Get APSR Register
98 
99     This function returns the content of the APSR Register.
100 
101     \return               APSR Register value
102  */
__get_APSR(void)103 __STATIC_INLINE uint32_t __get_APSR(void)
104 {
105   register uint32_t __regAPSR          __ASM("apsr");
106   return(__regAPSR);
107 }
108 
109 
110 /** \brief  Get xPSR Register
111 
112     This function returns the content of the xPSR Register.
113 
114     \return               xPSR Register value
115  */
__get_xPSR(void)116 __STATIC_INLINE uint32_t __get_xPSR(void)
117 {
118   register uint32_t __regXPSR          __ASM("xpsr");
119   return(__regXPSR);
120 }
121 
122 
123 /** \brief  Get Process Stack Pointer
124 
125     This function returns the current value of the Process Stack Pointer (PSP).
126 
127     \return               PSP Register value
128  */
__get_PSP(void)129 __STATIC_INLINE uint32_t __get_PSP(void)
130 {
131   register uint32_t __regProcessStackPointer  __ASM("psp");
132   return(__regProcessStackPointer);
133 }
134 
135 
136 /** \brief  Set Process Stack Pointer
137 
138     This function assigns the given value to the Process Stack Pointer (PSP).
139 
140     \param [in]    topOfProcStack  Process Stack Pointer value to set
141  */
__set_PSP(uint32_t topOfProcStack)142 __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
143 {
144   register uint32_t __regProcessStackPointer  __ASM("psp");
145   __regProcessStackPointer = topOfProcStack;
146 }
147 
148 
149 /** \brief  Get Main Stack Pointer
150 
151     This function returns the current value of the Main Stack Pointer (MSP).
152 
153     \return               MSP Register value
154  */
__get_MSP(void)155 __STATIC_INLINE uint32_t __get_MSP(void)
156 {
157   register uint32_t __regMainStackPointer     __ASM("msp");
158   return(__regMainStackPointer);
159 }
160 
161 
162 /** \brief  Set Main Stack Pointer
163 
164     This function assigns the given value to the Main Stack Pointer (MSP).
165 
166     \param [in]    topOfMainStack  Main Stack Pointer value to set
167  */
__set_MSP(uint32_t topOfMainStack)168 __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
169 {
170   register uint32_t __regMainStackPointer     __ASM("msp");
171   __regMainStackPointer = topOfMainStack;
172 }
173 
174 
175 /** \brief  Get Priority Mask
176 
177     This function returns the current state of the priority mask bit from the Priority Mask Register.
178 
179     \return               Priority Mask value
180  */
__get_PRIMASK(void)181 __STATIC_INLINE uint32_t __get_PRIMASK(void)
182 {
183   register uint32_t __regPriMask         __ASM("primask");
184   return(__regPriMask);
185 }
186 
187 
188 /** \brief  Set Priority Mask
189 
190     This function assigns the given value to the Priority Mask Register.
191 
192     \param [in]    priMask  Priority Mask
193  */
__set_PRIMASK(uint32_t priMask)194 __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
195 {
196   register uint32_t __regPriMask         __ASM("primask");
197   __regPriMask = (priMask);
198 }
199 
200 
201 #if       (__CORTEX_M >= 0x03)
202 
203 /** \brief  Enable FIQ
204 
205     This function enables FIQ interrupts by clearing the F-bit in the CPSR.
206     Can only be executed in Privileged modes.
207  */
208 #define __enable_fault_irq                __enable_fiq
209 
210 
211 /** \brief  Disable FIQ
212 
213     This function disables FIQ interrupts by setting the F-bit in the CPSR.
214     Can only be executed in Privileged modes.
215  */
216 #define __disable_fault_irq               __disable_fiq
217 
218 
219 /** \brief  Get Base Priority
220 
221     This function returns the current value of the Base Priority register.
222 
223     \return               Base Priority register value
224  */
__get_BASEPRI(void)225 __STATIC_INLINE uint32_t  __get_BASEPRI(void)
226 {
227   register uint32_t __regBasePri         __ASM("basepri");
228   return(__regBasePri);
229 }
230 
231 
232 /** \brief  Set Base Priority
233 
234     This function assigns the given value to the Base Priority register.
235 
236     \param [in]    basePri  Base Priority value to set
237  */
__set_BASEPRI(uint32_t basePri)238 __STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
239 {
240   register uint32_t __regBasePri         __ASM("basepri");
241   __regBasePri = (basePri & 0xff);
242 }
243 
244 
245 /** \brief  Get Fault Mask
246 
247     This function returns the current value of the Fault Mask register.
248 
249     \return               Fault Mask register value
250  */
__get_FAULTMASK(void)251 __STATIC_INLINE uint32_t __get_FAULTMASK(void)
252 {
253   register uint32_t __regFaultMask       __ASM("faultmask");
254   return(__regFaultMask);
255 }
256 
257 
258 /** \brief  Set Fault Mask
259 
260     This function assigns the given value to the Fault Mask register.
261 
262     \param [in]    faultMask  Fault Mask value to set
263  */
__set_FAULTMASK(uint32_t faultMask)264 __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
265 {
266   register uint32_t __regFaultMask       __ASM("faultmask");
267   __regFaultMask = (faultMask & (uint32_t)1);
268 }
269 
270 #endif /* (__CORTEX_M >= 0x03) */
271 
272 
273 #if       (__CORTEX_M == 0x04)
274 
275 /** \brief  Get FPSCR
276 
277     This function returns the current value of the Floating Point Status/Control register.
278 
279     \return               Floating Point Status/Control register value
280  */
__get_FPSCR(void)281 __STATIC_INLINE uint32_t __get_FPSCR(void)
282 {
283 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
284   register uint32_t __regfpscr         __ASM("fpscr");
285   return(__regfpscr);
286 #else
287    return(0);
288 #endif
289 }
290 
291 
292 /** \brief  Set FPSCR
293 
294     This function assigns the given value to the Floating Point Status/Control register.
295 
296     \param [in]    fpscr  Floating Point Status/Control value to set
297  */
__set_FPSCR(uint32_t fpscr)298 __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
299 {
300 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
301   register uint32_t __regfpscr         __ASM("fpscr");
302   __regfpscr = (fpscr);
303 #endif
304 }
305 
306 #endif /* (__CORTEX_M == 0x04) */
307 
308 
309 #elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
310 /* IAR iccarm specific functions */
311 
312 #include <cmsis_iar.h>
313 
314 
315 #elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
316 /* TI CCS specific functions */
317 
318 #include <cmsis_ccs.h>
319 
320 
321 #elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
322 /* GNU gcc specific functions */
323 
324 /** \brief  Enable IRQ Interrupts
325 
326   This function enables IRQ interrupts by clearing the I-bit in the CPSR.
327   Can only be executed in Privileged modes.
328  */
__enable_irq(void)329 __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
330 {
331   __ASM volatile ("cpsie i" : : : "memory");
332 }
333 
334 
335 /** \brief  Disable IRQ Interrupts
336 
337   This function disables IRQ interrupts by setting the I-bit in the CPSR.
338   Can only be executed in Privileged modes.
339  */
__disable_irq(void)340 __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
341 {
342   __ASM volatile ("cpsid i" : : : "memory");
343 }
344 
345 
346 /** \brief  Get Control Register
347 
348     This function returns the content of the Control Register.
349 
350     \return               Control Register value
351  */
__get_CONTROL(void)352 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
353 {
354   uint32_t result;
355 
356   __ASM volatile ("MRS %0, control" : "=r" (result) );
357   return(result);
358 }
359 
360 
361 /** \brief  Set Control Register
362 
363     This function writes the given value to the Control Register.
364 
365     \param [in]    control  Control Register value to set
366  */
__set_CONTROL(uint32_t control)367 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
368 {
369   __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
370 }
371 
372 
373 /** \brief  Get IPSR Register
374 
375     This function returns the content of the IPSR Register.
376 
377     \return               IPSR Register value
378  */
__get_IPSR(void)379 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
380 {
381   uint32_t result;
382 
383   __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
384   return(result);
385 }
386 
387 
388 /** \brief  Get APSR Register
389 
390     This function returns the content of the APSR Register.
391 
392     \return               APSR Register value
393  */
__get_APSR(void)394 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
395 {
396   uint32_t result;
397 
398   __ASM volatile ("MRS %0, apsr" : "=r" (result) );
399   return(result);
400 }
401 
402 
403 /** \brief  Get xPSR Register
404 
405     This function returns the content of the xPSR Register.
406 
407     \return               xPSR Register value
408  */
__get_xPSR(void)409 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
410 {
411   uint32_t result;
412 
413   __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
414   return(result);
415 }
416 
417 
418 /** \brief  Get Process Stack Pointer
419 
420     This function returns the current value of the Process Stack Pointer (PSP).
421 
422     \return               PSP Register value
423  */
__get_PSP(void)424 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
425 {
426   register uint32_t result;
427 
428   __ASM volatile ("MRS %0, psp\n"  : "=r" (result) );
429   return(result);
430 }
431 
432 
433 /** \brief  Set Process Stack Pointer
434 
435     This function assigns the given value to the Process Stack Pointer (PSP).
436 
437     \param [in]    topOfProcStack  Process Stack Pointer value to set
438  */
__set_PSP(uint32_t topOfProcStack)439 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
440 {
441   __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
442 }
443 
444 
445 /** \brief  Get Main Stack Pointer
446 
447     This function returns the current value of the Main Stack Pointer (MSP).
448 
449     \return               MSP Register value
450  */
__get_MSP(void)451 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
452 {
453   register uint32_t result;
454 
455   __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
456   return(result);
457 }
458 
459 
460 /** \brief  Set Main Stack Pointer
461 
462     This function assigns the given value to the Main Stack Pointer (MSP).
463 
464     \param [in]    topOfMainStack  Main Stack Pointer value to set
465  */
__set_MSP(uint32_t topOfMainStack)466 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
467 {
468   __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
469 }
470 
471 
472 /** \brief  Get Priority Mask
473 
474     This function returns the current state of the priority mask bit from the Priority Mask Register.
475 
476     \return               Priority Mask value
477  */
__get_PRIMASK(void)478 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
479 {
480   uint32_t result;
481 
482   __ASM volatile ("MRS %0, primask" : "=r" (result) );
483   return(result);
484 }
485 
486 
487 /** \brief  Set Priority Mask
488 
489     This function assigns the given value to the Priority Mask Register.
490 
491     \param [in]    priMask  Priority Mask
492  */
__set_PRIMASK(uint32_t priMask)493 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
494 {
495   __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
496 }
497 
498 
499 #if       (__CORTEX_M >= 0x03)
500 
501 /** \brief  Enable FIQ
502 
503     This function enables FIQ interrupts by clearing the F-bit in the CPSR.
504     Can only be executed in Privileged modes.
505  */
__enable_fault_irq(void)506 __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
507 {
508   __ASM volatile ("cpsie f" : : : "memory");
509 }
510 
511 
512 /** \brief  Disable FIQ
513 
514     This function disables FIQ interrupts by setting the F-bit in the CPSR.
515     Can only be executed in Privileged modes.
516  */
__disable_fault_irq(void)517 __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
518 {
519   __ASM volatile ("cpsid f" : : : "memory");
520 }
521 
522 
523 /** \brief  Get Base Priority
524 
525     This function returns the current value of the Base Priority register.
526 
527     \return               Base Priority register value
528  */
__get_BASEPRI(void)529 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
530 {
531   uint32_t result;
532 
533   __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
534   return(result);
535 }
536 
537 
538 /** \brief  Set Base Priority
539 
540     This function assigns the given value to the Base Priority register.
541 
542     \param [in]    basePri  Base Priority value to set
543  */
__set_BASEPRI(uint32_t value)544 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
545 {
546   __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
547 }
548 
549 
550 /** \brief  Get Fault Mask
551 
552     This function returns the current value of the Fault Mask register.
553 
554     \return               Fault Mask register value
555  */
__get_FAULTMASK(void)556 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
557 {
558   uint32_t result;
559 
560   __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
561   return(result);
562 }
563 
564 
565 /** \brief  Set Fault Mask
566 
567     This function assigns the given value to the Fault Mask register.
568 
569     \param [in]    faultMask  Fault Mask value to set
570  */
__set_FAULTMASK(uint32_t faultMask)571 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
572 {
573   __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
574 }
575 
576 #endif /* (__CORTEX_M >= 0x03) */
577 
578 
579 #if       (__CORTEX_M == 0x04)
580 
581 /** \brief  Get FPSCR
582 
583     This function returns the current value of the Floating Point Status/Control register.
584 
585     \return               Floating Point Status/Control register value
586  */
__get_FPSCR(void)587 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
588 {
589 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
590   uint32_t result;
591 
592   /* Empty asm statement works as a scheduling barrier */
593   __ASM volatile ("");
594   __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
595   __ASM volatile ("");
596   return(result);
597 #else
598    return(0);
599 #endif
600 }
601 
602 
603 /** \brief  Set FPSCR
604 
605     This function assigns the given value to the Floating Point Status/Control register.
606 
607     \param [in]    fpscr  Floating Point Status/Control value to set
608  */
__set_FPSCR(uint32_t fpscr)609 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
610 {
611 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
612   /* Empty asm statement works as a scheduling barrier */
613   __ASM volatile ("");
614   __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
615   __ASM volatile ("");
616 #endif
617 }
618 
619 #endif /* (__CORTEX_M == 0x04) */
620 
621 
622 #elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
623 /* TASKING carm specific functions */
624 
625 /*
626  * The CMSIS functions have been implemented as intrinsics in the compiler.
627  * Please use "carm -?i" to get an up to date list of all instrinsics,
628  * Including the CMSIS ones.
629  */
630 
631 #endif
632 
633 /*@} end of CMSIS_Core_RegAccFunctions */
634 
635 
636 #endif /* __CORE_CMFUNC_H */
637