1 /**************************************************************************//**
2  * @file     core_cmFunc.h
3  * @brief    CMSIS Cortex-M Core Function Access Header File
4  * @version  V4.10
5  * @date     18. March 2015
6  *
7  * @note
8  *
9  ******************************************************************************/
10 /* Copyright (c) 2009 - 2015 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) || (__CORTEX_SC >= 300)
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  Set Base Priority with condition
246 
247     This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
248     or the new value increases the BASEPRI priority level.
249 
250     \param [in]    basePri  Base Priority value to set
251  */
__set_BASEPRI_MAX(uint32_t basePri)252 __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
253 {
254   register uint32_t __regBasePriMax      __ASM("basepri_max");
255   __regBasePriMax = (basePri & 0xff);
256 }
257 
258 
259 /** \brief  Get Fault Mask
260 
261     This function returns the current value of the Fault Mask register.
262 
263     \return               Fault Mask register value
264  */
__get_FAULTMASK(void)265 __STATIC_INLINE uint32_t __get_FAULTMASK(void)
266 {
267   register uint32_t __regFaultMask       __ASM("faultmask");
268   return(__regFaultMask);
269 }
270 
271 
272 /** \brief  Set Fault Mask
273 
274     This function assigns the given value to the Fault Mask register.
275 
276     \param [in]    faultMask  Fault Mask value to set
277  */
__set_FAULTMASK(uint32_t faultMask)278 __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
279 {
280   register uint32_t __regFaultMask       __ASM("faultmask");
281   __regFaultMask = (faultMask & (uint32_t)1);
282 }
283 
284 #endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
285 
286 
287 #if       (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
288 
289 /** \brief  Get FPSCR
290 
291     This function returns the current value of the Floating Point Status/Control register.
292 
293     \return               Floating Point Status/Control register value
294  */
__get_FPSCR(void)295 __STATIC_INLINE uint32_t __get_FPSCR(void)
296 {
297 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
298   register uint32_t __regfpscr         __ASM("fpscr");
299   return(__regfpscr);
300 #else
301    return(0);
302 #endif
303 }
304 
305 
306 /** \brief  Set FPSCR
307 
308     This function assigns the given value to the Floating Point Status/Control register.
309 
310     \param [in]    fpscr  Floating Point Status/Control value to set
311  */
__set_FPSCR(uint32_t fpscr)312 __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
313 {
314 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
315   register uint32_t __regfpscr         __ASM("fpscr");
316   __regfpscr = (fpscr);
317 #endif
318 }
319 
320 #endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
321 
322 
323 #elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
324 /* GNU gcc specific functions */
325 
326 /** \brief  Enable IRQ Interrupts
327 
328   This function enables IRQ interrupts by clearing the I-bit in the CPSR.
329   Can only be executed in Privileged modes.
330  */
__enable_irq(void)331 __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
332 {
333   __ASM volatile ("cpsie i" : : : "memory");
334 }
335 
336 
337 /** \brief  Disable IRQ Interrupts
338 
339   This function disables IRQ interrupts by setting the I-bit in the CPSR.
340   Can only be executed in Privileged modes.
341  */
__disable_irq(void)342 __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
343 {
344   __ASM volatile ("cpsid i" : : : "memory");
345 }
346 
347 
348 /** \brief  Get Control Register
349 
350     This function returns the content of the Control Register.
351 
352     \return               Control Register value
353  */
__get_CONTROL(void)354 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
355 {
356   uint32_t result;
357 
358   __ASM volatile ("MRS %0, control" : "=r" (result) );
359   return(result);
360 }
361 
362 
363 /** \brief  Set Control Register
364 
365     This function writes the given value to the Control Register.
366 
367     \param [in]    control  Control Register value to set
368  */
__set_CONTROL(uint32_t control)369 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
370 {
371   __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
372 }
373 
374 
375 /** \brief  Get IPSR Register
376 
377     This function returns the content of the IPSR Register.
378 
379     \return               IPSR Register value
380  */
__get_IPSR(void)381 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
382 {
383   uint32_t result;
384 
385   __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
386   return(result);
387 }
388 
389 
390 /** \brief  Get APSR Register
391 
392     This function returns the content of the APSR Register.
393 
394     \return               APSR Register value
395  */
__get_APSR(void)396 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
397 {
398   uint32_t result;
399 
400   __ASM volatile ("MRS %0, apsr" : "=r" (result) );
401   return(result);
402 }
403 
404 
405 /** \brief  Get xPSR Register
406 
407     This function returns the content of the xPSR Register.
408 
409     \return               xPSR Register value
410  */
__get_xPSR(void)411 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
412 {
413   uint32_t result;
414 
415   __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
416   return(result);
417 }
418 
419 
420 /** \brief  Get Process Stack Pointer
421 
422     This function returns the current value of the Process Stack Pointer (PSP).
423 
424     \return               PSP Register value
425  */
__get_PSP(void)426 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
427 {
428   register uint32_t result;
429 
430   __ASM volatile ("MRS %0, psp\n"  : "=r" (result) );
431   return(result);
432 }
433 
434 
435 /** \brief  Set Process Stack Pointer
436 
437     This function assigns the given value to the Process Stack Pointer (PSP).
438 
439     \param [in]    topOfProcStack  Process Stack Pointer value to set
440  */
__set_PSP(uint32_t topOfProcStack)441 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
442 {
443   __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
444 }
445 
446 
447 /** \brief  Get Main Stack Pointer
448 
449     This function returns the current value of the Main Stack Pointer (MSP).
450 
451     \return               MSP Register value
452  */
__get_MSP(void)453 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
454 {
455   register uint32_t result;
456 
457   __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
458   return(result);
459 }
460 
461 
462 /** \brief  Set Main Stack Pointer
463 
464     This function assigns the given value to the Main Stack Pointer (MSP).
465 
466     \param [in]    topOfMainStack  Main Stack Pointer value to set
467  */
__set_MSP(uint32_t topOfMainStack)468 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
469 {
470   __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
471 }
472 
473 
474 /** \brief  Get Priority Mask
475 
476     This function returns the current state of the priority mask bit from the Priority Mask Register.
477 
478     \return               Priority Mask value
479  */
__get_PRIMASK(void)480 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
481 {
482   uint32_t result;
483 
484   __ASM volatile ("MRS %0, primask" : "=r" (result) );
485   return(result);
486 }
487 
488 
489 /** \brief  Set Priority Mask
490 
491     This function assigns the given value to the Priority Mask Register.
492 
493     \param [in]    priMask  Priority Mask
494  */
__set_PRIMASK(uint32_t priMask)495 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
496 {
497   __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
498 }
499 
500 
501 #if       (__CORTEX_M >= 0x03)
502 
503 /** \brief  Enable FIQ
504 
505     This function enables FIQ interrupts by clearing the F-bit in the CPSR.
506     Can only be executed in Privileged modes.
507  */
__enable_fault_irq(void)508 __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
509 {
510   __ASM volatile ("cpsie f" : : : "memory");
511 }
512 
513 
514 /** \brief  Disable FIQ
515 
516     This function disables FIQ interrupts by setting the F-bit in the CPSR.
517     Can only be executed in Privileged modes.
518  */
__disable_fault_irq(void)519 __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
520 {
521   __ASM volatile ("cpsid f" : : : "memory");
522 }
523 
524 
525 /** \brief  Get Base Priority
526 
527     This function returns the current value of the Base Priority register.
528 
529     \return               Base Priority register value
530  */
__get_BASEPRI(void)531 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
532 {
533   uint32_t result;
534 
535   __ASM volatile ("MRS %0, basepri" : "=r" (result) );
536   return(result);
537 }
538 
539 
540 /** \brief  Set Base Priority
541 
542     This function assigns the given value to the Base Priority register.
543 
544     \param [in]    basePri  Base Priority value to set
545  */
__set_BASEPRI(uint32_t value)546 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
547 {
548   __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
549 }
550 
551 
552 /** \brief  Set Base Priority with condition
553 
554     This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
555 	or the new value increases the BASEPRI priority level.
556 
557     \param [in]    basePri  Base Priority value to set
558  */
__set_BASEPRI_MAX(uint32_t value)559 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
560 {
561   __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
562 }
563 
564 
565 /** \brief  Get Fault Mask
566 
567     This function returns the current value of the Fault Mask register.
568 
569     \return               Fault Mask register value
570  */
__get_FAULTMASK(void)571 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
572 {
573   uint32_t result;
574 
575   __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
576   return(result);
577 }
578 
579 
580 /** \brief  Set Fault Mask
581 
582     This function assigns the given value to the Fault Mask register.
583 
584     \param [in]    faultMask  Fault Mask value to set
585  */
__set_FAULTMASK(uint32_t faultMask)586 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
587 {
588   __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
589 }
590 
591 #endif /* (__CORTEX_M >= 0x03) */
592 
593 
594 #if       (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
595 
596 /** \brief  Get FPSCR
597 
598     This function returns the current value of the Floating Point Status/Control register.
599 
600     \return               Floating Point Status/Control register value
601  */
__get_FPSCR(void)602 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
603 {
604 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
605   uint32_t result;
606 
607   /* Empty asm statement works as a scheduling barrier */
608   __ASM volatile ("");
609   __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
610   __ASM volatile ("");
611   return(result);
612 #else
613    return(0);
614 #endif
615 }
616 
617 
618 /** \brief  Set FPSCR
619 
620     This function assigns the given value to the Floating Point Status/Control register.
621 
622     \param [in]    fpscr  Floating Point Status/Control value to set
623  */
__set_FPSCR(uint32_t fpscr)624 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
625 {
626 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
627   /* Empty asm statement works as a scheduling barrier */
628   __ASM volatile ("");
629   __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
630   __ASM volatile ("");
631 #endif
632 }
633 
634 #endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
635 
636 
637 #elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
638 /* IAR iccarm specific functions */
639 #include <cmsis_iar.h>
640 
641 
642 #elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
643 /* TI CCS specific functions */
644 #include <cmsis_ccs.h>
645 
646 
647 #elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
648 /* TASKING carm specific functions */
649 /*
650  * The CMSIS functions have been implemented as intrinsics in the compiler.
651  * Please use "carm -?i" to get an up to date list of all intrinsics,
652  * Including the CMSIS ones.
653  */
654 
655 
656 #elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
657 /* Cosmic specific functions */
658 #include <cmsis_csm.h>
659 
660 #endif
661 
662 /*@} end of CMSIS_Core_RegAccFunctions */
663 
664 #endif /* __CORE_CMFUNC_H */
665