core_cm3.c 17 KB

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