core_cmFunc.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. /**************************************************************************//**
  2. * @file core_cmFunc.h
  3. * @brief CMSIS Cortex-M Core Function Access Header File
  4. * @version V2.03
  5. * @date 07. April 2011
  6. *
  7. * @note
  8. * Copyright (C) 2009-2011 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. #ifndef __CORE_CMFUNC_H__
  24. #define __CORE_CMFUNC_H__
  25. /* ########################### Core Function Access ########################### */
  26. /** \ingroup CMSIS_Core_FunctionInterface
  27. \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
  28. @{
  29. */
  30. #if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
  31. /* ARM armcc specific functions */
  32. /* intrinsic void __enable_irq(); */
  33. /* intrinsic void __disable_irq(); */
  34. /** \brief Get Control Register
  35. This function returns the content of the Control Register.
  36. \return Control Register value
  37. */
  38. #if (__ARMCC_VERSION < 400000)
  39. extern uint32_t __get_CONTROL(void);
  40. #else /* (__ARMCC_VERSION >= 400000) */
  41. static __INLINE uint32_t __get_CONTROL(void)
  42. {
  43. register uint32_t __regControl __ASM("control");
  44. return(__regControl);
  45. }
  46. #endif /* __ARMCC_VERSION */
  47. /** \brief Set Control Register
  48. This function writes the given value to the Control Register.
  49. \param [in] control Control Register value to set
  50. */
  51. #if (__ARMCC_VERSION < 400000)
  52. extern void __set_CONTROL(uint32_t control);
  53. #else /* (__ARMCC_VERSION >= 400000) */
  54. static __INLINE void __set_CONTROL(uint32_t control)
  55. {
  56. register uint32_t __regControl __ASM("control");
  57. __regControl = control;
  58. }
  59. #endif /* __ARMCC_VERSION */
  60. /** \brief Get ISPR Register
  61. This function returns the content of the ISPR Register.
  62. \return ISPR Register value
  63. */
  64. #if (__ARMCC_VERSION < 400000)
  65. extern uint32_t __get_IPSR(void);
  66. #else /* (__ARMCC_VERSION >= 400000) */
  67. static __INLINE uint32_t __get_IPSR(void)
  68. {
  69. register uint32_t __regIPSR __ASM("ipsr");
  70. return(__regIPSR);
  71. }
  72. #endif /* __ARMCC_VERSION */
  73. /** \brief Get APSR Register
  74. This function returns the content of the APSR Register.
  75. \return APSR Register value
  76. */
  77. #if (__ARMCC_VERSION < 400000)
  78. extern uint32_t __get_APSR(void);
  79. #else /* (__ARMCC_VERSION >= 400000) */
  80. static __INLINE uint32_t __get_APSR(void)
  81. {
  82. register uint32_t __regAPSR __ASM("apsr");
  83. return(__regAPSR);
  84. }
  85. #endif /* __ARMCC_VERSION */
  86. /** \brief Get xPSR Register
  87. This function returns the content of the xPSR Register.
  88. \return xPSR Register value
  89. */
  90. #if (__ARMCC_VERSION < 400000)
  91. extern uint32_t __get_xPSR(void);
  92. #else /* (__ARMCC_VERSION >= 400000) */
  93. static __INLINE uint32_t __get_xPSR(void)
  94. {
  95. register uint32_t __regXPSR __ASM("xpsr");
  96. return(__regXPSR);
  97. }
  98. #endif /* __ARMCC_VERSION */
  99. /** \brief Get Process Stack Pointer
  100. This function returns the current value of the Process Stack Pointer (PSP).
  101. \return PSP Register value
  102. */
  103. #if (__ARMCC_VERSION < 400000)
  104. extern uint32_t __get_PSP(void);
  105. #else /* (__ARMCC_VERSION >= 400000) */
  106. static __INLINE uint32_t __get_PSP(void)
  107. {
  108. register uint32_t __regProcessStackPointer __ASM("psp");
  109. return(__regProcessStackPointer);
  110. }
  111. #endif /* __ARMCC_VERSION */
  112. /** \brief Set Process Stack Pointer
  113. This function assigns the given value to the Process Stack Pointer (PSP).
  114. \param [in] topOfProcStack Process Stack Pointer value to set
  115. */
  116. #if (__ARMCC_VERSION < 400000)
  117. extern void __set_PSP(uint32_t topOfProcStack);
  118. #else /* (__ARMCC_VERSION >= 400000) */
  119. static __INLINE void __set_PSP(uint32_t topOfProcStack)
  120. {
  121. register uint32_t __regProcessStackPointer __ASM("psp");
  122. __regProcessStackPointer = topOfProcStack;
  123. }
  124. #endif /* __ARMCC_VERSION */
  125. /** \brief Get Main Stack Pointer
  126. This function returns the current value of the Main Stack Pointer (MSP).
  127. \return MSP Register value
  128. */
  129. #if (__ARMCC_VERSION < 400000)
  130. extern uint32_t __get_MSP(void);
  131. #else /* (__ARMCC_VERSION >= 400000) */
  132. static __INLINE uint32_t __get_MSP(void)
  133. {
  134. register uint32_t __regMainStackPointer __ASM("msp");
  135. return(__regMainStackPointer);
  136. }
  137. #endif /* __ARMCC_VERSION */
  138. /** \brief Set Main Stack Pointer
  139. This function assigns the given value to the Main Stack Pointer (MSP).
  140. \param [in] topOfMainStack Main Stack Pointer value to set
  141. */
  142. #if (__ARMCC_VERSION < 400000)
  143. extern void __set_MSP(uint32_t topOfMainStack);
  144. #else /* (__ARMCC_VERSION >= 400000) */
  145. static __INLINE void __set_MSP(uint32_t topOfMainStack)
  146. {
  147. register uint32_t __regMainStackPointer __ASM("msp");
  148. __regMainStackPointer = topOfMainStack;
  149. }
  150. #endif /* __ARMCC_VERSION */
  151. /** \brief Get Priority Mask
  152. This function returns the current state of the priority mask bit from the Priority Mask Register.
  153. \return Priority Mask value
  154. */
  155. #if (__ARMCC_VERSION < 400000)
  156. extern uint32_t __get_PRIMASK(void);
  157. #else /* (__ARMCC_VERSION >= 400000) */
  158. static __INLINE uint32_t __get_PRIMASK(void)
  159. {
  160. register uint32_t __regPriMask __ASM("primask");
  161. return(__regPriMask);
  162. }
  163. #endif /* __ARMCC_VERSION */
  164. /** \brief Set Priority Mask
  165. This function assigns the given value to the Priority Mask Register.
  166. \param [in] priMask Priority Mask
  167. */
  168. #if (__ARMCC_VERSION < 400000)
  169. extern void __set_PRIMASK(uint32_t priMask);
  170. #else /* (__ARMCC_VERSION >= 400000) */
  171. static __INLINE void __set_PRIMASK(uint32_t priMask)
  172. {
  173. register uint32_t __regPriMask __ASM("primask");
  174. __regPriMask = (priMask);
  175. }
  176. #endif /* __ARMCC_VERSION */
  177. #if (__CORTEX_M >= 0x03)
  178. /** \brief Enable FIQ
  179. This function enables FIQ interrupts by clearing the F-bit in the CPSR.
  180. Can only be executed in Privileged modes.
  181. */
  182. #define __enable_fault_irq __enable_fiq
  183. /** \brief Disable FIQ
  184. This function disables FIQ interrupts by setting the F-bit in the CPSR.
  185. Can only be executed in Privileged modes.
  186. */
  187. #define __disable_fault_irq __disable_fiq
  188. /** \brief Get Base Priority
  189. This function returns the current value of the Base Priority register.
  190. \return Base Priority register value
  191. */
  192. #if (__ARMCC_VERSION < 400000)
  193. extern uint32_t __get_BASEPRI(void);
  194. #else /* (__ARMCC_VERSION >= 400000) */
  195. static __INLINE uint32_t __get_BASEPRI(void)
  196. {
  197. register uint32_t __regBasePri __ASM("basepri");
  198. return(__regBasePri);
  199. }
  200. #endif /* __ARMCC_VERSION */
  201. /** \brief Set Base Priority
  202. This function assigns the given value to the Base Priority register.
  203. \param [in] basePri Base Priority value to set
  204. */
  205. #if (__ARMCC_VERSION < 400000)
  206. extern void __set_BASEPRI(uint32_t basePri);
  207. #else /* (__ARMCC_VERSION >= 400000) */
  208. static __INLINE void __set_BASEPRI(uint32_t basePri)
  209. {
  210. register uint32_t __regBasePri __ASM("basepri");
  211. __regBasePri = (basePri & 0xff);
  212. }
  213. #endif /* __ARMCC_VERSION */
  214. /** \brief Get Fault Mask
  215. This function returns the current value of the Fault Mask register.
  216. \return Fault Mask register value
  217. */
  218. #if (__ARMCC_VERSION < 400000)
  219. extern uint32_t __get_FAULTMASK(void);
  220. #else /* (__ARMCC_VERSION >= 400000) */
  221. static __INLINE uint32_t __get_FAULTMASK(void)
  222. {
  223. register uint32_t __regFaultMask __ASM("faultmask");
  224. return(__regFaultMask);
  225. }
  226. #endif /* __ARMCC_VERSION */
  227. /** \brief Set Fault Mask
  228. This function assigns the given value to the Fault Mask register.
  229. \param [in] faultMask Fault Mask value to set
  230. */
  231. #if (__ARMCC_VERSION < 400000)
  232. extern void __set_FAULTMASK(uint32_t faultMask);
  233. #else /* (__ARMCC_VERSION >= 400000) */
  234. static __INLINE void __set_FAULTMASK(uint32_t faultMask)
  235. {
  236. register uint32_t __regFaultMask __ASM("faultmask");
  237. __regFaultMask = (faultMask & 1);
  238. }
  239. #endif /* __ARMCC_VERSION */
  240. #endif /* (__CORTEX_M >= 0x03) */
  241. #if (__CORTEX_M == 0x04)
  242. /** \brief Get FPSCR
  243. This function returns the current value of the Floating Point Status/Control register.
  244. \return Floating Point Status/Control register value
  245. */
  246. static __INLINE uint32_t __get_FPSCR(void)
  247. {
  248. #if (__FPU_PRESENT == 1)
  249. register uint32_t __regfpscr __ASM("fpscr");
  250. return(__regfpscr);
  251. #else
  252. return(0);
  253. #endif
  254. }
  255. /** \brief Set FPSCR
  256. This function assigns the given value to the Floating Point Status/Control register.
  257. \param [in] fpscr Floating Point Status/Control value to set
  258. */
  259. static __INLINE void __set_FPSCR(uint32_t fpscr)
  260. {
  261. #if (__FPU_PRESENT == 1)
  262. register uint32_t __regfpscr __ASM("fpscr");
  263. __regfpscr = (fpscr);
  264. #endif
  265. }
  266. #endif /* (__CORTEX_M == 0x04) */
  267. #elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
  268. /* IAR iccarm specific functions */
  269. #include <cmsis_iar.h>
  270. #elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
  271. /* GNU gcc specific functions */
  272. /** \brief Enable IRQ Interrupts
  273. This function enables IRQ interrupts by clearing the I-bit in the CPSR.
  274. Can only be executed in Privileged modes.
  275. */
  276. __attribute__( ( always_inline ) ) static __INLINE void __enable_irq(void)
  277. {
  278. __ASM volatile ("cpsie i");
  279. }
  280. /** \brief Disable IRQ Interrupts
  281. This function disables IRQ interrupts by setting the I-bit in the CPSR.
  282. Can only be executed in Privileged modes.
  283. */
  284. __attribute__( ( always_inline ) ) static __INLINE void __disable_irq(void)
  285. {
  286. __ASM volatile ("cpsid i");
  287. }
  288. /** \brief Get Control Register
  289. This function returns the content of the Control Register.
  290. \return Control Register value
  291. */
  292. __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_CONTROL(void)
  293. {
  294. uint32_t result;
  295. __ASM volatile ("MRS %0, control" : "=r" (result) );
  296. return(result);
  297. }
  298. /** \brief Set Control Register
  299. This function writes the given value to the Control Register.
  300. \param [in] control Control Register value to set
  301. */
  302. __attribute__( ( always_inline ) ) static __INLINE void __set_CONTROL(uint32_t control)
  303. {
  304. __ASM volatile ("MSR control, %0" : : "r" (control) );
  305. }
  306. /** \brief Get ISPR Register
  307. This function returns the content of the ISPR Register.
  308. \return ISPR Register value
  309. */
  310. __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_IPSR(void)
  311. {
  312. uint32_t result;
  313. __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
  314. return(result);
  315. }
  316. /** \brief Get APSR Register
  317. This function returns the content of the APSR Register.
  318. \return APSR Register value
  319. */
  320. __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_APSR(void)
  321. {
  322. uint32_t result;
  323. __ASM volatile ("MRS %0, apsr" : "=r" (result) );
  324. return(result);
  325. }
  326. /** \brief Get xPSR Register
  327. This function returns the content of the xPSR Register.
  328. \return xPSR Register value
  329. */
  330. __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_xPSR(void)
  331. {
  332. uint32_t result;
  333. __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
  334. return(result);
  335. }
  336. /** \brief Get Process Stack Pointer
  337. This function returns the current value of the Process Stack Pointer (PSP).
  338. \return PSP Register value
  339. */
  340. __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PSP(void)
  341. {
  342. register uint32_t result;
  343. __ASM volatile ("MRS %0, psp\n" : "=r" (result) );
  344. return(result);
  345. }
  346. /** \brief Set Process Stack Pointer
  347. This function assigns the given value to the Process Stack Pointer (PSP).
  348. \param [in] topOfProcStack Process Stack Pointer value to set
  349. */
  350. __attribute__( ( always_inline ) ) static __INLINE void __set_PSP(uint32_t topOfProcStack)
  351. {
  352. __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
  353. }
  354. /** \brief Get Main Stack Pointer
  355. This function returns the current value of the Main Stack Pointer (MSP).
  356. \return MSP Register value
  357. */
  358. __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_MSP(void)
  359. {
  360. register uint32_t result;
  361. __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
  362. return(result);
  363. }
  364. /** \brief Set Main Stack Pointer
  365. This function assigns the given value to the Main Stack Pointer (MSP).
  366. \param [in] topOfMainStack Main Stack Pointer value to set
  367. */
  368. __attribute__( ( always_inline ) ) static __INLINE void __set_MSP(uint32_t topOfMainStack)
  369. {
  370. __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
  371. }
  372. /** \brief Get Priority Mask
  373. This function returns the current state of the priority mask bit from the Priority Mask Register.
  374. \return Priority Mask value
  375. */
  376. __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PRIMASK(void)
  377. {
  378. uint32_t result;
  379. __ASM volatile ("MRS %0, primask" : "=r" (result) );
  380. return(result);
  381. }
  382. /** \brief Set Priority Mask
  383. This function assigns the given value to the Priority Mask Register.
  384. \param [in] priMask Priority Mask
  385. */
  386. __attribute__( ( always_inline ) ) static __INLINE void __set_PRIMASK(uint32_t priMask)
  387. {
  388. __ASM volatile ("MSR primask, %0" : : "r" (priMask) );
  389. }
  390. #if (__CORTEX_M >= 0x03)
  391. /** \brief Enable FIQ
  392. This function enables FIQ interrupts by clearing the F-bit in the CPSR.
  393. Can only be executed in Privileged modes.
  394. */
  395. __attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void)
  396. {
  397. __ASM volatile ("cpsie f");
  398. }
  399. /** \brief Disable FIQ
  400. This function disables FIQ interrupts by setting the F-bit in the CPSR.
  401. Can only be executed in Privileged modes.
  402. */
  403. __attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void)
  404. {
  405. __ASM volatile ("cpsid f");
  406. }
  407. /** \brief Get Base Priority
  408. This function returns the current value of the Base Priority register.
  409. \return Base Priority register value
  410. */
  411. __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_BASEPRI(void)
  412. {
  413. uint32_t result;
  414. __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
  415. return(result);
  416. }
  417. /** \brief Set Base Priority
  418. This function assigns the given value to the Base Priority register.
  419. \param [in] basePri Base Priority value to set
  420. */
  421. __attribute__( ( always_inline ) ) static __INLINE void __set_BASEPRI(uint32_t value)
  422. {
  423. __ASM volatile ("MSR basepri, %0" : : "r" (value) );
  424. }
  425. /** \brief Get Fault Mask
  426. This function returns the current value of the Fault Mask register.
  427. \return Fault Mask register value
  428. */
  429. __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FAULTMASK(void)
  430. {
  431. uint32_t result;
  432. __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
  433. return(result);
  434. }
  435. /** \brief Set Fault Mask
  436. This function assigns the given value to the Fault Mask register.
  437. \param [in] faultMask Fault Mask value to set
  438. */
  439. __attribute__( ( always_inline ) ) static __INLINE void __set_FAULTMASK(uint32_t faultMask)
  440. {
  441. __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
  442. }
  443. #endif /* (__CORTEX_M >= 0x03) */
  444. #if (__CORTEX_M == 0x04)
  445. /** \brief Get FPSCR
  446. This function returns the current value of the Floating Point Status/Control register.
  447. \return Floating Point Status/Control register value
  448. */
  449. __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FPSCR(void)
  450. {
  451. #if (__FPU_PRESENT == 1)
  452. uint32_t result;
  453. __ASM volatile ("MRS %0, fpscr" : "=r" (result) );
  454. return(result);
  455. #else
  456. return(0);
  457. #endif
  458. }
  459. /** \brief Set FPSCR
  460. This function assigns the given value to the Floating Point Status/Control register.
  461. \param [in] fpscr Floating Point Status/Control value to set
  462. */
  463. __attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fpscr)
  464. {
  465. #if (__FPU_PRESENT == 1)
  466. __ASM volatile ("MSR fpscr, %0" : : "r" (fpscr) );
  467. #endif
  468. }
  469. #endif /* (__CORTEX_M == 0x04) */
  470. #elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
  471. /* TASKING carm specific functions */
  472. /*
  473. * The CMSIS functions have been implemented as intrinsics in the compiler.
  474. * Please use "carm -?i" to get an up to date list of all instrinsics,
  475. * Including the CMSIS ones.
  476. */
  477. #endif
  478. /*@} end of CMSIS_Core_RegAccFunctions */
  479. #endif /* __CORE_CMFUNC_H__ */