1 /**************************************************************************//**
2  * @file     core_cm3.c
3  * @brief    CMSIS Cortex-M3 Core Peripheral Access Layer Source File
4  * @version  V1.30
5  * @date     30. October 2009
6  *
7  * @note
8  * Copyright (C) 2009 ARM Limited. All rights reserved.
9  *
10  * @par
11  * ARM Limited (ARM) is supplying this software for use with Cortex-M
12  * processor based microcontrollers.  This file can be freely distributed
13  * within development tools that are supporting such ARM based processors.
14  *
15  * @par
16  * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
17  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
19  * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
20  * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
21  *
22  ******************************************************************************/
23 /*******************************************************************************
24  * Microsemi SoC Products Group SVN revision number for the purpose of tracking
25  * changes done to original file supplied by ARM:
26  * SVN $Revision: 6671 $
27  * SVN $Date: 2014-07-04 12:15:22 +0100 (Fri, 04 Jul 2014) $
28  ******************************************************************************/
29 
30 #include <stdint.h>
31 
32 /* define compiler specific symbols */
33 #if defined ( __CC_ARM   )
34   #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */
35   #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */
36 
37 #elif defined ( __ICCARM__ )
38   #define __ASM           __asm                                       /*!< asm keyword for IAR Compiler          */
39   #define __INLINE        inline                                      /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
40 
41 #elif defined   (  __GNUC__  )
42   #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
43   #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
44 
45 #elif defined   (  __TASKING__  )
46   #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */
47   #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */
48 
49 #endif
50 
51 
52 /* ###################  Compiler specific Intrinsics  ########################### */
53 
54 #if defined ( __CC_ARM   ) /*------------------RealView Compiler -----------------*/
55 /* ARM armcc specific functions */
56 
57 /**
58  * @brief  Return the Process Stack Pointer
59  *
60  * @return ProcessStackPointer
61  *
62  * Return the actual process stack pointer
63  */
__get_PSP(void)64 __ASM uint32_t __get_PSP(void)
65 {
66   mrs r0, psp
67   bx lr
68 }
69 
70 /**
71  * @brief  Set the Process Stack Pointer
72  *
73  * @param  topOfProcStack  Process Stack Pointer
74  *
75  * Assign the value ProcessStackPointer to the MSP
76  * (process stack pointer) Cortex processor register
77  */
__set_PSP(uint32_t topOfProcStack)78 __ASM void __set_PSP(uint32_t topOfProcStack)
79 {
80   msr psp, r0
81   bx lr
82 }
83 
84 /**
85  * @brief  Return the Main Stack Pointer
86  *
87  * @return Main Stack Pointer
88  *
89  * Return the current value of the MSP (main stack pointer)
90  * Cortex processor register
91  */
__get_MSP(void)92 __ASM uint32_t __get_MSP(void)
93 {
94   mrs r0, msp
95   bx lr
96 }
97 
98 /**
99  * @brief  Set the Main Stack Pointer
100  *
101  * @param  topOfMainStack  Main Stack Pointer
102  *
103  * Assign the value mainStackPointer to the MSP
104  * (main stack pointer) Cortex processor register
105  */
__set_MSP(uint32_t mainStackPointer)106 __ASM void __set_MSP(uint32_t mainStackPointer)
107 {
108   msr msp, r0
109   bx lr
110 }
111 
112 /**
113  * @brief  Reverse byte order in unsigned short value
114  *
115  * @param   value  value to reverse
116  * @return         reversed value
117  *
118  * Reverse byte order in unsigned short value
119  */
__REV16(uint16_t value)120 __ASM uint32_t __REV16(uint16_t value)
121 {
122   rev16 r0, r0
123   bx lr
124 }
125 
126 /**
127  * @brief  Reverse byte order in signed short value with sign extension to integer
128  *
129  * @param   value  value to reverse
130  * @return         reversed value
131  *
132  * Reverse byte order in signed short value with sign extension to integer
133  */
__REVSH(int16_t value)134 __ASM int32_t __REVSH(int16_t value)
135 {
136   revsh r0, r0
137   bx lr
138 }
139 
140 
141 #if (__ARMCC_VERSION < 400000)
142 
143 /**
144  * @brief  Remove the exclusive lock created by ldrex
145  *
146  * Removes the exclusive lock which is created by ldrex.
147  */
__CLREX(void)148 __ASM void __CLREX(void)
149 {
150   clrex
151 }
152 
153 /**
154  * @brief  Return the Base Priority value
155  *
156  * @return BasePriority
157  *
158  * Return the content of the base priority register
159  */
__get_BASEPRI(void)160 __ASM uint32_t  __get_BASEPRI(void)
161 {
162   mrs r0, basepri
163   bx lr
164 }
165 
166 /**
167  * @brief  Set the Base Priority value
168  *
169  * @param  basePri  BasePriority
170  *
171  * Set the base priority register
172  */
__set_BASEPRI(uint32_t basePri)173 __ASM void __set_BASEPRI(uint32_t basePri)
174 {
175   msr basepri, r0
176   bx lr
177 }
178 
179 /**
180  * @brief  Return the Priority Mask value
181  *
182  * @return PriMask
183  *
184  * Return state of the priority mask bit from the priority mask register
185  */
__get_PRIMASK(void)186 __ASM uint32_t __get_PRIMASK(void)
187 {
188   mrs r0, primask
189   bx lr
190 }
191 
192 /**
193  * @brief  Set the Priority Mask value
194  *
195  * @param  priMask  PriMask
196  *
197  * Set the priority mask bit in the priority mask register
198  */
__set_PRIMASK(uint32_t priMask)199 __ASM void __set_PRIMASK(uint32_t priMask)
200 {
201   msr primask, r0
202   bx lr
203 }
204 
205 /**
206  * @brief  Return the Fault Mask value
207  *
208  * @return FaultMask
209  *
210  * Return the content of the fault mask register
211  */
__get_FAULTMASK(void)212 __ASM uint32_t  __get_FAULTMASK(void)
213 {
214   mrs r0, faultmask
215   bx lr
216 }
217 
218 /**
219  * @brief  Set the Fault Mask value
220  *
221  * @param  faultMask  faultMask value
222  *
223  * Set the fault mask register
224  */
__set_FAULTMASK(uint32_t faultMask)225 __ASM void __set_FAULTMASK(uint32_t faultMask)
226 {
227   msr faultmask, r0
228   bx lr
229 }
230 
231 /**
232  * @brief  Return the Control Register value
233  *
234  * @return Control value
235  *
236  * Return the content of the control register
237  */
__get_CONTROL(void)238 __ASM uint32_t __get_CONTROL(void)
239 {
240   mrs r0, control
241   bx lr
242 }
243 
244 /**
245  * @brief  Set the Control Register value
246  *
247  * @param  control  Control value
248  *
249  * Set the control register
250  */
__set_CONTROL(uint32_t control)251 __ASM void __set_CONTROL(uint32_t control)
252 {
253   msr control, r0
254   bx lr
255 }
256 
257 #endif /* __ARMCC_VERSION  */
258 
259 
260 
261 #elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
262 /* IAR iccarm specific functions */
263 #pragma diag_suppress=Pe940
264 
265 /**
266  * @brief  Return the Process Stack Pointer
267  *
268  * @return ProcessStackPointer
269  *
270  * Return the actual process stack pointer
271  */
272 #if (__VER__ < 6020000)
__get_PSP(void)273 uint32_t __get_PSP(void)
274 {
275   __ASM("mrs r0, psp");
276   __ASM("bx lr");
277 }
278 #endif
279 
280 /**
281  * @brief  Set the Process Stack Pointer
282  *
283  * @param  topOfProcStack  Process Stack Pointer
284  *
285  * Assign the value ProcessStackPointer to the MSP
286  * (process stack pointer) Cortex processor register
287  */
288 #if (__VER__ < 6020000)
__set_PSP(uint32_t topOfProcStack)289 void __set_PSP(uint32_t topOfProcStack)
290 {
291   __ASM("msr psp, r0");
292   __ASM("bx lr");
293 }
294 #endif
295 
296 /**
297  * @brief  Return the Main Stack Pointer
298  *
299  * @return Main Stack Pointer
300  *
301  * Return the current value of the MSP (main stack pointer)
302  * Cortex processor register
303  */
304 #if (__VER__ < 6020000)
__get_MSP(void)305 uint32_t __get_MSP(void)
306 {
307   __ASM("mrs r0, msp");
308   __ASM("bx lr");
309 }
310 #endif
311 
312 /**
313  * @brief  Set the Main Stack Pointer
314  *
315  * @param  topOfMainStack  Main Stack Pointer
316  *
317  * Assign the value mainStackPointer to the MSP
318  * (main stack pointer) Cortex processor register
319  */
320 #if (__VER__ < 6020000)
__set_MSP(uint32_t topOfMainStack)321 void __set_MSP(uint32_t topOfMainStack)
322 {
323   __ASM("msr msp, r0");
324   __ASM("bx lr");
325 }
326 #endif
327 
328 /**
329  * @brief  Reverse byte order in unsigned short value
330  *
331  * @param  value  value to reverse
332  * @return        reversed value
333  *
334  * Reverse byte order in unsigned short value
335  */
336 #if (__VER__ < 6020000)
__REV16(uint16_t value)337 uint32_t __REV16(uint16_t value)
338 {
339   __ASM("rev16 r0, r0");
340   __ASM("bx lr");
341 }
342 #endif
343 
344 /**
345  * @brief  Reverse bit order of value
346  *
347  * @param  value  value to reverse
348  * @return        reversed value
349  *
350  * Reverse bit order of value
351  */
352 #if (__VER__ < 6020000)
__RBIT(uint32_t value)353 uint32_t __RBIT(uint32_t value)
354 {
355   __ASM("rbit r0, r0");
356   __ASM("bx lr");
357 }
358 #endif
359 
360 /**
361  * @brief  LDR Exclusive (8 bit)
362  *
363  * @param  *addr  address pointer
364  * @return        value of (*address)
365  *
366  * Exclusive LDR command for 8 bit values)
367  */
368 #if (__VER__ < 6020000)
__LDREXB(uint8_t * addr)369 uint8_t __LDREXB(uint8_t *addr)
370 {
371   __ASM("ldrexb r0, [r0]");
372   __ASM("bx lr");
373 }
374 #endif
375 
376 /**
377  * @brief  LDR Exclusive (16 bit)
378  *
379  * @param  *addr  address pointer
380  * @return        value of (*address)
381  *
382  * Exclusive LDR command for 16 bit values
383  */
384 #if (__VER__ < 6020000)
__LDREXH(uint16_t * addr)385 uint16_t __LDREXH(uint16_t *addr)
386 {
387   __ASM("ldrexh r0, [r0]");
388   __ASM("bx lr");
389 }
390 #endif
391 
392 /**
393  * @brief  LDR Exclusive (32 bit)
394  *
395  * @param  *addr  address pointer
396  * @return        value of (*address)
397  *
398  * Exclusive LDR command for 32 bit values
399  */
__LDREXW(uint32_t * addr)400 uint32_t __LDREXW(uint32_t *addr)
401 {
402   __ASM("ldrex r0, [r0]");
403   __ASM("bx lr");
404 }
405 
406 /**
407  * @brief  STR Exclusive (8 bit)
408  *
409  * @param  value  value to store
410  * @param  *addr  address pointer
411  * @return        successful / failed
412  *
413  * Exclusive STR command for 8 bit values
414  */
415 #if (__VER__ < 6020000)
__STREXB(uint8_t value,uint8_t * addr)416 uint32_t __STREXB(uint8_t value, uint8_t *addr)
417 {
418   __ASM("strexb r0, r0, [r1]");
419   __ASM("bx lr");
420 }
421 #endif
422 
423 /**
424  * @brief  STR Exclusive (16 bit)
425  *
426  * @param  value  value to store
427  * @param  *addr  address pointer
428  * @return        successful / failed
429  *
430  * Exclusive STR command for 16 bit values
431  */
432 #if (__VER__ < 6020000)
__STREXH(uint16_t value,uint16_t * addr)433 uint32_t __STREXH(uint16_t value, uint16_t *addr)
434 {
435   __ASM("strexh r0, r0, [r1]");
436   __ASM("bx lr");
437 }
438 #endif
439 
440 /**
441  * @brief  STR Exclusive (32 bit)
442  *
443  * @param  value  value to store
444  * @param  *addr  address pointer
445  * @return        successful / failed
446  *
447  * Exclusive STR command for 32 bit values
448  */
__STREXW(uint32_t value,uint32_t * addr)449 uint32_t __STREXW(uint32_t value, uint32_t *addr)
450 {
451   __ASM("strex r0, r0, [r1]");
452   __ASM("bx lr");
453 }
454 
455 #pragma diag_default=Pe940
456 
457 
458 #elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
459 /* GNU gcc specific functions */
460 
461 /**
462  * @brief  Return the Process Stack Pointer
463  *
464  * @return ProcessStackPointer
465  *
466  * Return the actual process stack pointer
467  */
468 uint32_t __get_PSP(void) __attribute__( ( naked ) );
__get_PSP(void)469 uint32_t __get_PSP(void)
470 {
471   uint32_t result=0;
472 
473   __ASM volatile ("MRS %0, psp\n\t"
474                   "MOV r0, %0 \n\t"
475                   "BX  lr     \n\t"  : "=r" (result) );
476   return(result);
477 }
478 
479 /**
480  * @brief  Set the Process Stack Pointer
481  *
482  * @param  topOfProcStack  Process Stack Pointer
483  *
484  * Assign the value ProcessStackPointer to the MSP
485  * (process stack pointer) Cortex processor register
486  */
487 void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) );
__set_PSP(uint32_t topOfProcStack)488 void __set_PSP(uint32_t topOfProcStack)
489 {
490   __ASM volatile ("MSR psp, %0\n\t"
491                   "BX  lr     \n\t" : : "r" (topOfProcStack) );
492 }
493 
494 /**
495  * @brief  Return the Main Stack Pointer
496  *
497  * @return Main Stack Pointer
498  *
499  * Return the current value of the MSP (main stack pointer)
500  * Cortex processor register
501  */
502 uint32_t __get_MSP(void) __attribute__( ( naked ) );
__get_MSP(void)503 uint32_t __get_MSP(void)
504 {
505   uint32_t result=0;
506 
507   __ASM volatile ("MRS %0, msp\n\t"
508                   "MOV r0, %0 \n\t"
509                   "BX  lr     \n\t"  : "=r" (result) );
510   return(result);
511 }
512 
513 /**
514  * @brief  Set the Main Stack Pointer
515  *
516  * @param  topOfMainStack  Main Stack Pointer
517  *
518  * Assign the value mainStackPointer to the MSP
519  * (main stack pointer) Cortex processor register
520  */
521 void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) );
__set_MSP(uint32_t topOfMainStack)522 void __set_MSP(uint32_t topOfMainStack)
523 {
524   __ASM volatile ("MSR msp, %0\n\t"
525                   "BX  lr     \n\t" : : "r" (topOfMainStack) );
526 }
527 
528 /**
529  * @brief  Return the Base Priority value
530  *
531  * @return BasePriority
532  *
533  * Return the content of the base priority register
534  */
__get_BASEPRI(void)535 uint32_t __get_BASEPRI(void)
536 {
537   uint32_t result=0;
538 
539   __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
540   return(result);
541 }
542 
543 /**
544  * @brief  Set the Base Priority value
545  *
546  * @param  basePri  BasePriority
547  *
548  * Set the base priority register
549  */
__set_BASEPRI(uint32_t value)550 void __set_BASEPRI(uint32_t value)
551 {
552   __ASM volatile ("MSR basepri, %0" : : "r" (value) );
553 }
554 
555 /**
556  * @brief  Return the Priority Mask value
557  *
558  * @return PriMask
559  *
560  * Return state of the priority mask bit from the priority mask register
561  */
__get_PRIMASK(void)562 uint32_t __get_PRIMASK(void)
563 {
564   uint32_t result=0;
565 
566   __ASM volatile ("MRS %0, primask" : "=r" (result) );
567   return(result);
568 }
569 
570 /**
571  * @brief  Set the Priority Mask value
572  *
573  * @param  priMask  PriMask
574  *
575  * Set the priority mask bit in the priority mask register
576  */
__set_PRIMASK(uint32_t priMask)577 void __set_PRIMASK(uint32_t priMask)
578 {
579   __ASM volatile ("MSR primask, %0" : : "r" (priMask) );
580 }
581 
582 /**
583  * @brief  Return the Fault Mask value
584  *
585  * @return FaultMask
586  *
587  * Return the content of the fault mask register
588  */
__get_FAULTMASK(void)589 uint32_t __get_FAULTMASK(void)
590 {
591   uint32_t result=0;
592 
593   __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
594   return(result);
595 }
596 
597 /**
598  * @brief  Set the Fault Mask value
599  *
600  * @param  faultMask  faultMask value
601  *
602  * Set the fault mask register
603  */
__set_FAULTMASK(uint32_t faultMask)604 void __set_FAULTMASK(uint32_t faultMask)
605 {
606   __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
607 }
608 
609 /**
610  * @brief  Return the Control Register value
611 *
612 *  @return Control value
613  *
614  * Return the content of the control register
615  */
__get_CONTROL(void)616 uint32_t __get_CONTROL(void)
617 {
618   uint32_t result=0;
619 
620   __ASM volatile ("MRS %0, control" : "=r" (result) );
621   return(result);
622 }
623 
624 /**
625  * @brief  Set the Control Register value
626  *
627  * @param  control  Control value
628  *
629  * Set the control register
630  */
__set_CONTROL(uint32_t control)631 void __set_CONTROL(uint32_t control)
632 {
633   __ASM volatile ("MSR control, %0" : : "r" (control) );
634 }
635 
636 
637 /**
638  * @brief  Reverse byte order in integer value
639  *
640  * @param  value  value to reverse
641  * @return        reversed value
642  *
643  * Reverse byte order in integer value
644  */
__REV(uint32_t value)645 uint32_t __REV(uint32_t value)
646 {
647   uint32_t result=0;
648 
649   __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
650   return(result);
651 }
652 
653 /**
654  * @brief  Reverse byte order in unsigned short value
655  *
656  * @param  value  value to reverse
657  * @return        reversed value
658  *
659  * Reverse byte order in unsigned short value
660  */
__REV16(uint16_t value)661 uint32_t __REV16(uint16_t value)
662 {
663   uint32_t result=0;
664 
665   __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
666   return(result);
667 }
668 
669 /**
670  * @brief  Reverse byte order in signed short value with sign extension to integer
671  *
672  * @param  value  value to reverse
673  * @return        reversed value
674  *
675  * Reverse byte order in signed short value with sign extension to integer
676  */
__REVSH(int16_t value)677 int32_t __REVSH(int16_t value)
678 {
679   uint32_t result=0;
680 
681   __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
682   return(result);
683 }
684 
685 /**
686  * @brief  Reverse bit order of value
687  *
688  * @param  value  value to reverse
689  * @return        reversed value
690  *
691  * Reverse bit order of value
692  */
__RBIT(uint32_t value)693 uint32_t __RBIT(uint32_t value)
694 {
695   uint32_t result=0;
696 
697    __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
698    return(result);
699 }
700 
701 /**
702  * @brief  LDR Exclusive (8 bit)
703  *
704  * @param  *addr  address pointer
705  * @return        value of (*address)
706  *
707  * Exclusive LDR command for 8 bit value
708  */
__LDREXB(uint8_t * addr)709 uint8_t __LDREXB(uint8_t *addr)
710 {
711     uint8_t result=0;
712 
713    __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
714    return(result);
715 }
716 
717 /**
718  * @brief  LDR Exclusive (16 bit)
719  *
720  * @param  *addr  address pointer
721  * @return        value of (*address)
722  *
723  * Exclusive LDR command for 16 bit values
724  */
__LDREXH(uint16_t * addr)725 uint16_t __LDREXH(uint16_t *addr)
726 {
727     uint16_t result=0;
728 
729    __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
730    return(result);
731 }
732 
733 /**
734  * @brief  LDR Exclusive (32 bit)
735  *
736  * @param  *addr  address pointer
737  * @return        value of (*address)
738  *
739  * Exclusive LDR command for 32 bit values
740  */
__LDREXW(uint32_t * addr)741 uint32_t __LDREXW(uint32_t *addr)
742 {
743     uint32_t result=0;
744 
745    __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
746    return(result);
747 }
748 
749 /**
750  * @brief  STR Exclusive (8 bit)
751  *
752  * @param  value  value to store
753  * @param  *addr  address pointer
754  * @return        successful / failed
755  *
756  * Exclusive STR command for 8 bit values
757  */
__STREXB(uint8_t value,uint8_t * addr)758 uint32_t __STREXB(uint8_t value, uint8_t *addr)
759 {
760    uint32_t result=0;
761 
762    __ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
763    return(result);
764 }
765 
766 /**
767  * @brief  STR Exclusive (16 bit)
768  *
769  * @param  value  value to store
770  * @param  *addr  address pointer
771  * @return        successful / failed
772  *
773  * Exclusive STR command for 16 bit values
774  */
__STREXH(uint16_t value,uint16_t * addr)775 uint32_t __STREXH(uint16_t value, uint16_t *addr)
776 {
777    uint32_t result=0;
778 
779    __ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
780    return(result);
781 }
782 
783 /**
784  * @brief  STR Exclusive (32 bit)
785  *
786  * @param  value  value to store
787  * @param  *addr  address pointer
788  * @return        successful / failed
789  *
790  * Exclusive STR command for 32 bit values
791  */
__STREXW(uint32_t value,uint32_t * addr)792 uint32_t __STREXW(uint32_t value, uint32_t *addr)
793 {
794    uint32_t result=0;
795 
796    __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
797    return(result);
798 }
799 
800 
801 #elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
802 /* TASKING carm specific functions */
803 
804 /*
805  * The CMSIS functions have been implemented as intrinsics in the compiler.
806  * Please use "carm -?i" to get an up to date list of all instrinsics,
807  * Including the CMSIS ones.
808  */
809 
810 #endif
811