1 /**************************************************************************//** 2 * @file core_cmFunc.h 3 * @brief CMSIS Cortex-M Core Function Access Header File 4 * @version V3.20 5 * @date 25. February 2013 6 * 7 * @note 8 * 9 ******************************************************************************/ 10 /* Copyright (c) 2009 - 2013 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) 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) */ 271 272 273 #if (__CORTEX_M == 0x04) 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) */ 307 308 309 #elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ 310 /* IAR iccarm specific functions */ 311 312 #include <cmsis_iar.h> 313 314 315 #elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ 316 /* TI CCS specific functions */ 317 318 #include <cmsis_ccs.h> 319 320 321 #elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ 322 /* GNU gcc specific functions */ 323 324 /** \brief Enable IRQ Interrupts 325 326 This function enables IRQ interrupts by clearing the I-bit in the CPSR. 327 Can only be executed in Privileged modes. 328 */ 329 __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) 330 { 331 __ASM volatile ("cpsie i" : : : "memory"); 332 } 333 334 335 /** \brief Disable IRQ Interrupts 336 337 This function disables IRQ interrupts by setting the I-bit in the CPSR. 338 Can only be executed in Privileged modes. 339 */ 340 __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) 341 { 342 __ASM volatile ("cpsid i" : : : "memory"); 343 } 344 345 346 /** \brief Get Control Register 347 348 This function returns the content of the Control Register. 349 350 \return Control Register value 351 */ 352 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) 353 { 354 uint32_t result; 355 356 __ASM volatile ("MRS %0, control" : "=r" (result) ); 357 return(result); 358 } 359 360 361 /** \brief Set Control Register 362 363 This function writes the given value to the Control Register. 364 365 \param [in] control Control Register value to set 366 */ 367 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) 368 { 369 __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); 370 } 371 372 373 /** \brief Get IPSR Register 374 375 This function returns the content of the IPSR Register. 376 377 \return IPSR Register value 378 */ 379 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) 380 { 381 uint32_t result; 382 383 __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); 384 return(result); 385 } 386 387 388 /** \brief Get APSR Register 389 390 This function returns the content of the APSR Register. 391 392 \return APSR Register value 393 */ 394 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) 395 { 396 uint32_t result; 397 398 __ASM volatile ("MRS %0, apsr" : "=r" (result) ); 399 return(result); 400 } 401 402 403 /** \brief Get xPSR Register 404 405 This function returns the content of the xPSR Register. 406 407 \return xPSR Register value 408 */ 409 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) 410 { 411 uint32_t result; 412 413 __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); 414 return(result); 415 } 416 417 418 /** \brief Get Process Stack Pointer 419 420 This function returns the current value of the Process Stack Pointer (PSP). 421 422 \return PSP Register value 423 */ 424 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) 425 { 426 register uint32_t result; 427 428 __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); 429 return(result); 430 } 431 432 433 /** \brief Set Process Stack Pointer 434 435 This function assigns the given value to the Process Stack Pointer (PSP). 436 437 \param [in] topOfProcStack Process Stack Pointer value to set 438 */ 439 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) 440 { 441 __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp"); 442 } 443 444 445 /** \brief Get Main Stack Pointer 446 447 This function returns the current value of the Main Stack Pointer (MSP). 448 449 \return MSP Register value 450 */ 451 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) 452 { 453 register uint32_t result; 454 455 __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); 456 return(result); 457 } 458 459 460 /** \brief Set Main Stack Pointer 461 462 This function assigns the given value to the Main Stack Pointer (MSP). 463 464 \param [in] topOfMainStack Main Stack Pointer value to set 465 */ 466 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) 467 { 468 __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); 469 } 470 471 472 /** \brief Get Priority Mask 473 474 This function returns the current state of the priority mask bit from the Priority Mask Register. 475 476 \return Priority Mask value 477 */ 478 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) 479 { 480 uint32_t result; 481 482 __ASM volatile ("MRS %0, primask" : "=r" (result) ); 483 return(result); 484 } 485 486 487 /** \brief Set Priority Mask 488 489 This function assigns the given value to the Priority Mask Register. 490 491 \param [in] priMask Priority Mask 492 */ 493 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) 494 { 495 __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); 496 } 497 498 499 #if (__CORTEX_M >= 0x03) 500 501 /** \brief Enable FIQ 502 503 This function enables FIQ interrupts by clearing the F-bit in the CPSR. 504 Can only be executed in Privileged modes. 505 */ 506 __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) 507 { 508 __ASM volatile ("cpsie f" : : : "memory"); 509 } 510 511 512 /** \brief Disable FIQ 513 514 This function disables FIQ interrupts by setting the F-bit in the CPSR. 515 Can only be executed in Privileged modes. 516 */ 517 __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) 518 { 519 __ASM volatile ("cpsid f" : : : "memory"); 520 } 521 522 523 /** \brief Get Base Priority 524 525 This function returns the current value of the Base Priority register. 526 527 \return Base Priority register value 528 */ 529 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) 530 { 531 uint32_t result; 532 533 __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); 534 return(result); 535 } 536 537 538 /** \brief Set Base Priority 539 540 This function assigns the given value to the Base Priority register. 541 542 \param [in] basePri Base Priority value to set 543 */ 544 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) 545 { 546 __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); 547 } 548 549 550 /** \brief Get Fault Mask 551 552 This function returns the current value of the Fault Mask register. 553 554 \return Fault Mask register value 555 */ 556 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) 557 { 558 uint32_t result; 559 560 __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); 561 return(result); 562 } 563 564 565 /** \brief Set Fault Mask 566 567 This function assigns the given value to the Fault Mask register. 568 569 \param [in] faultMask Fault Mask value to set 570 */ 571 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) 572 { 573 __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); 574 } 575 576 #endif /* (__CORTEX_M >= 0x03) */ 577 578 579 #if (__CORTEX_M == 0x04) 580 581 /** \brief Get FPSCR 582 583 This function returns the current value of the Floating Point Status/Control register. 584 585 \return Floating Point Status/Control register value 586 */ 587 __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) 588 { 589 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 590 uint32_t result; 591 592 /* Empty asm statement works as a scheduling barrier */ 593 __ASM volatile (""); 594 __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); 595 __ASM volatile (""); 596 return(result); 597 #else 598 return(0); 599 #endif 600 } 601 602 603 /** \brief Set FPSCR 604 605 This function assigns the given value to the Floating Point Status/Control register. 606 607 \param [in] fpscr Floating Point Status/Control value to set 608 */ 609 __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) 610 { 611 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 612 /* Empty asm statement works as a scheduling barrier */ 613 __ASM volatile (""); 614 __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); 615 __ASM volatile (""); 616 #endif 617 } 618 619 #endif /* (__CORTEX_M == 0x04) */ 620 621 622 #elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ 623 /* TASKING carm specific functions */ 624 625 /* 626 * The CMSIS functions have been implemented as intrinsics in the compiler. 627 * Please use "carm -?i" to get an up to date list of all instrinsics, 628 * Including the CMSIS ones. 629 */ 630 631 #endif 632 633 /*@} end of CMSIS_Core_RegAccFunctions */ 634 635 636 #endif /* __CORE_CMFUNC_H */ 637