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