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