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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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