Naze32 clone with Frysky receiver
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

core_cmFunc.h 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. /**************************************************************************//**
  2. * @file core_cmFunc.h
  3. * @brief CMSIS Cortex-M Core Function Access Header File
  4. * @version V4.10
  5. * @date 18. March 2015
  6. *
  7. * @note
  8. *
  9. ******************************************************************************/
  10. /* Copyright (c) 2009 - 2015 ARM LIMITED
  11. All rights reserved.
  12. Redistribution and use in source and binary forms, with or without
  13. modification, are permitted provided that the following conditions are met:
  14. - Redistributions of source code must retain the above copyright
  15. notice, this list of conditions and the following disclaimer.
  16. - Redistributions in binary form must reproduce the above copyright
  17. notice, this list of conditions and the following disclaimer in the
  18. documentation and/or other materials provided with the distribution.
  19. - Neither the name of ARM nor the names of its contributors may be used
  20. to endorse or promote products derived from this software without
  21. specific prior written permission.
  22. *
  23. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
  27. LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. POSSIBILITY OF SUCH DAMAGE.
  34. ---------------------------------------------------------------------------*/
  35. #ifndef __CORE_CMFUNC_H
  36. #define __CORE_CMFUNC_H
  37. /* ########################### Core Function Access ########################### */
  38. /** \ingroup CMSIS_Core_FunctionInterface
  39. \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
  40. @{
  41. */
  42. #if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
  43. /* ARM armcc specific functions */
  44. #if (__ARMCC_VERSION < 400677)
  45. #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
  46. #endif
  47. /* intrinsic void __enable_irq(); */
  48. /* intrinsic void __disable_irq(); */
  49. /** \brief Get Control Register
  50. This function returns the content of the Control Register.
  51. \return Control Register value
  52. */
  53. __STATIC_INLINE uint32_t __get_CONTROL(void)
  54. {
  55. register uint32_t __regControl __ASM("control");
  56. return(__regControl);
  57. }
  58. /** \brief Set Control Register
  59. This function writes the given value to the Control Register.
  60. \param [in] control Control Register value to set
  61. */
  62. __STATIC_INLINE void __set_CONTROL(uint32_t control)
  63. {
  64. register uint32_t __regControl __ASM("control");
  65. __regControl = control;
  66. }
  67. /** \brief Get IPSR Register
  68. This function returns the content of the IPSR Register.
  69. \return IPSR Register value
  70. */
  71. __STATIC_INLINE uint32_t __get_IPSR(void)
  72. {
  73. register uint32_t __regIPSR __ASM("ipsr");
  74. return(__regIPSR);
  75. }
  76. /** \brief Get APSR Register
  77. This function returns the content of the APSR Register.
  78. \return APSR Register value
  79. */
  80. __STATIC_INLINE uint32_t __get_APSR(void)
  81. {
  82. register uint32_t __regAPSR __ASM("apsr");
  83. return(__regAPSR);
  84. }
  85. /** \brief Get xPSR Register
  86. This function returns the content of the xPSR Register.
  87. \return xPSR Register value
  88. */
  89. __STATIC_INLINE uint32_t __get_xPSR(void)
  90. {
  91. register uint32_t __regXPSR __ASM("xpsr");
  92. return(__regXPSR);
  93. }
  94. /** \brief Get Process Stack Pointer
  95. This function returns the current value of the Process Stack Pointer (PSP).
  96. \return PSP Register value
  97. */
  98. __STATIC_INLINE uint32_t __get_PSP(void)
  99. {
  100. register uint32_t __regProcessStackPointer __ASM("psp");
  101. return(__regProcessStackPointer);
  102. }
  103. /** \brief Set Process Stack Pointer
  104. This function assigns the given value to the Process Stack Pointer (PSP).
  105. \param [in] topOfProcStack Process Stack Pointer value to set
  106. */
  107. __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
  108. {
  109. register uint32_t __regProcessStackPointer __ASM("psp");
  110. __regProcessStackPointer = topOfProcStack;
  111. }
  112. /** \brief Get Main Stack Pointer
  113. This function returns the current value of the Main Stack Pointer (MSP).
  114. \return MSP Register value
  115. */
  116. __STATIC_INLINE uint32_t __get_MSP(void)
  117. {
  118. register uint32_t __regMainStackPointer __ASM("msp");
  119. return(__regMainStackPointer);
  120. }
  121. /** \brief Set Main Stack Pointer
  122. This function assigns the given value to the Main Stack Pointer (MSP).
  123. \param [in] topOfMainStack Main Stack Pointer value to set
  124. */
  125. __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
  126. {
  127. register uint32_t __regMainStackPointer __ASM("msp");
  128. __regMainStackPointer = topOfMainStack;
  129. }
  130. /** \brief Get Priority Mask
  131. This function returns the current state of the priority mask bit from the Priority Mask Register.
  132. \return Priority Mask value
  133. */
  134. __STATIC_INLINE uint32_t __get_PRIMASK(void)
  135. {
  136. register uint32_t __regPriMask __ASM("primask");
  137. return(__regPriMask);
  138. }
  139. /** \brief Set Priority Mask
  140. This function assigns the given value to the Priority Mask Register.
  141. \param [in] priMask Priority Mask
  142. */
  143. __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
  144. {
  145. register uint32_t __regPriMask __ASM("primask");
  146. __regPriMask = (priMask);
  147. }
  148. #if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
  149. /** \brief Enable FIQ
  150. This function enables FIQ interrupts by clearing the F-bit in the CPSR.
  151. Can only be executed in Privileged modes.
  152. */
  153. #define __enable_fault_irq __enable_fiq
  154. /** \brief Disable FIQ
  155. This function disables FIQ interrupts by setting the F-bit in the CPSR.
  156. Can only be executed in Privileged modes.
  157. */
  158. #define __disable_fault_irq __disable_fiq
  159. /** \brief Get Base Priority
  160. This function returns the current value of the Base Priority register.
  161. \return Base Priority register value
  162. */
  163. __STATIC_INLINE uint32_t __get_BASEPRI(void)
  164. {
  165. register uint32_t __regBasePri __ASM("basepri");
  166. return(__regBasePri);
  167. }
  168. /** \brief Set Base Priority
  169. This function assigns the given value to the Base Priority register.
  170. \param [in] basePri Base Priority value to set
  171. */
  172. __STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
  173. {
  174. register uint32_t __regBasePri __ASM("basepri");
  175. __regBasePri = (basePri & 0xff);
  176. }
  177. /** \brief Set Base Priority with condition
  178. This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
  179. or the new value increases the BASEPRI priority level.
  180. \param [in] basePri Base Priority value to set
  181. */
  182. __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
  183. {
  184. register uint32_t __regBasePriMax __ASM("basepri_max");
  185. __regBasePriMax = (basePri & 0xff);
  186. }
  187. /** \brief Get Fault Mask
  188. This function returns the current value of the Fault Mask register.
  189. \return Fault Mask register value
  190. */
  191. __STATIC_INLINE uint32_t __get_FAULTMASK(void)
  192. {
  193. register uint32_t __regFaultMask __ASM("faultmask");
  194. return(__regFaultMask);
  195. }
  196. /** \brief Set Fault Mask
  197. This function assigns the given value to the Fault Mask register.
  198. \param [in] faultMask Fault Mask value to set
  199. */
  200. __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
  201. {
  202. register uint32_t __regFaultMask __ASM("faultmask");
  203. __regFaultMask = (faultMask & (uint32_t)1);
  204. }
  205. #endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
  206. #if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
  207. /** \brief Get FPSCR
  208. This function returns the current value of the Floating Point Status/Control register.
  209. \return Floating Point Status/Control register value
  210. */
  211. __STATIC_INLINE uint32_t __get_FPSCR(void)
  212. {
  213. #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  214. register uint32_t __regfpscr __ASM("fpscr");
  215. return(__regfpscr);
  216. #else
  217. return(0);
  218. #endif
  219. }
  220. /** \brief Set FPSCR
  221. This function assigns the given value to the Floating Point Status/Control register.
  222. \param [in] fpscr Floating Point Status/Control value to set
  223. */
  224. __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
  225. {
  226. #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  227. register uint32_t __regfpscr __ASM("fpscr");
  228. __regfpscr = (fpscr);
  229. #endif
  230. }
  231. #endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
  232. #elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
  233. /* GNU gcc specific functions */
  234. /** \brief Enable IRQ Interrupts
  235. This function enables IRQ interrupts by clearing the I-bit in the CPSR.
  236. Can only be executed in Privileged modes.
  237. */
  238. __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
  239. {
  240. __ASM volatile ("cpsie i" : : : "memory");
  241. }
  242. /** \brief Disable IRQ Interrupts
  243. This function disables IRQ interrupts by setting the I-bit in the CPSR.
  244. Can only be executed in Privileged modes.
  245. */
  246. __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
  247. {
  248. __ASM volatile ("cpsid i" : : : "memory");
  249. }
  250. /** \brief Get Control Register
  251. This function returns the content of the Control Register.
  252. \return Control Register value
  253. */
  254. __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
  255. {
  256. uint32_t result;
  257. __ASM volatile ("MRS %0, control" : "=r" (result) );
  258. return(result);
  259. }
  260. /** \brief Set Control Register
  261. This function writes the given value to the Control Register.
  262. \param [in] control Control Register value to set
  263. */
  264. __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
  265. {
  266. __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
  267. }
  268. /** \brief Get IPSR Register
  269. This function returns the content of the IPSR Register.
  270. \return IPSR Register value
  271. */
  272. __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
  273. {
  274. uint32_t result;
  275. __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
  276. return(result);
  277. }
  278. /** \brief Get APSR Register
  279. This function returns the content of the APSR Register.
  280. \return APSR Register value
  281. */
  282. __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
  283. {
  284. uint32_t result;
  285. __ASM volatile ("MRS %0, apsr" : "=r" (result) );
  286. return(result);
  287. }
  288. /** \brief Get xPSR Register
  289. This function returns the content of the xPSR Register.
  290. \return xPSR Register value
  291. */
  292. __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
  293. {
  294. uint32_t result;
  295. __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
  296. return(result);
  297. }
  298. /** \brief Get Process Stack Pointer
  299. This function returns the current value of the Process Stack Pointer (PSP).
  300. \return PSP Register value
  301. */
  302. __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
  303. {
  304. register uint32_t result;
  305. __ASM volatile ("MRS %0, psp\n" : "=r" (result) );
  306. return(result);
  307. }
  308. /** \brief Set Process Stack Pointer
  309. This function assigns the given value to the Process Stack Pointer (PSP).
  310. \param [in] topOfProcStack Process Stack Pointer value to set
  311. */
  312. __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
  313. {
  314. __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
  315. }
  316. /** \brief Get Main Stack Pointer
  317. This function returns the current value of the Main Stack Pointer (MSP).
  318. \return MSP Register value
  319. */
  320. __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
  321. {
  322. register uint32_t result;
  323. __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
  324. return(result);
  325. }
  326. /** \brief Set Main Stack Pointer
  327. This function assigns the given value to the Main Stack Pointer (MSP).
  328. \param [in] topOfMainStack Main Stack Pointer value to set
  329. */
  330. __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
  331. {
  332. __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
  333. }
  334. /** \brief Get Priority Mask
  335. This function returns the current state of the priority mask bit from the Priority Mask Register.
  336. \return Priority Mask value
  337. */
  338. __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
  339. {
  340. uint32_t result;
  341. __ASM volatile ("MRS %0, primask" : "=r" (result) );
  342. return(result);
  343. }
  344. /** \brief Set Priority Mask
  345. This function assigns the given value to the Priority Mask Register.
  346. \param [in] priMask Priority Mask
  347. */
  348. __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
  349. {
  350. __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
  351. }
  352. #if (__CORTEX_M >= 0x03)
  353. /** \brief Enable FIQ
  354. This function enables FIQ interrupts by clearing the F-bit in the CPSR.
  355. Can only be executed in Privileged modes.
  356. */
  357. __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
  358. {
  359. __ASM volatile ("cpsie f" : : : "memory");
  360. }
  361. /** \brief Disable FIQ
  362. This function disables FIQ interrupts by setting the F-bit in the CPSR.
  363. Can only be executed in Privileged modes.
  364. */
  365. __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
  366. {
  367. __ASM volatile ("cpsid f" : : : "memory");
  368. }
  369. /** \brief Get Base Priority
  370. This function returns the current value of the Base Priority register.
  371. \return Base Priority register value
  372. */
  373. __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
  374. {
  375. uint32_t result;
  376. __ASM volatile ("MRS %0, basepri" : "=r" (result) );
  377. return(result);
  378. }
  379. /** \brief Set Base Priority
  380. This function assigns the given value to the Base Priority register.
  381. \param [in] basePri Base Priority value to set
  382. */
  383. __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
  384. {
  385. __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
  386. }
  387. /** \brief Set Base Priority with condition
  388. This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
  389. or the new value increases the BASEPRI priority level.
  390. \param [in] basePri Base Priority value to set
  391. */
  392. __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
  393. {
  394. __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
  395. }
  396. /** \brief Get Fault Mask
  397. This function returns the current value of the Fault Mask register.
  398. \return Fault Mask register value
  399. */
  400. __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
  401. {
  402. uint32_t result;
  403. __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
  404. return(result);
  405. }
  406. /** \brief Set Fault Mask
  407. This function assigns the given value to the Fault Mask register.
  408. \param [in] faultMask Fault Mask value to set
  409. */
  410. __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
  411. {
  412. __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
  413. }
  414. #endif /* (__CORTEX_M >= 0x03) */
  415. #if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
  416. /** \brief Get FPSCR
  417. This function returns the current value of the Floating Point Status/Control register.
  418. \return Floating Point Status/Control register value
  419. */
  420. __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
  421. {
  422. #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  423. uint32_t result;
  424. /* Empty asm statement works as a scheduling barrier */
  425. __ASM volatile ("");
  426. __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
  427. __ASM volatile ("");
  428. return(result);
  429. #else
  430. return(0);
  431. #endif
  432. }
  433. /** \brief Set FPSCR
  434. This function assigns the given value to the Floating Point Status/Control register.
  435. \param [in] fpscr Floating Point Status/Control value to set
  436. */
  437. __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
  438. {
  439. #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  440. /* Empty asm statement works as a scheduling barrier */
  441. __ASM volatile ("");
  442. __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
  443. __ASM volatile ("");
  444. #endif
  445. }
  446. #endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
  447. #elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
  448. /* IAR iccarm specific functions */
  449. #include <cmsis_iar.h>
  450. #elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
  451. /* TI CCS specific functions */
  452. #include <cmsis_ccs.h>
  453. #elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
  454. /* TASKING carm specific functions */
  455. /*
  456. * The CMSIS functions have been implemented as intrinsics in the compiler.
  457. * Please use "carm -?i" to get an up to date list of all intrinsics,
  458. * Including the CMSIS ones.
  459. */
  460. #elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
  461. /* Cosmic specific functions */
  462. #include <cmsis_csm.h>
  463. #endif
  464. /*@} end of CMSIS_Core_RegAccFunctions */
  465. #endif /* __CORE_CMFUNC_H */