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