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