system_gd32vf103.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. /*!
  2. \file system_gd32vf103.c
  3. \brief RISC-V Device Peripheral Access Layer Source File for
  4. GD32VF103 Device Series
  5. \version 2019-6-5, V1.0.0, firmware for GD32VF103
  6. */
  7. /*
  8. Copyright (c) 2019, GigaDevice Semiconductor Inc.
  9. Redistribution and use in source and binary forms, with or without modification,
  10. are permitted provided that the following conditions are met:
  11. 1. Redistributions of source code must retain the above copyright notice, this
  12. list of conditions and the following disclaimer.
  13. 2. Redistributions in binary form must reproduce the above copyright notice,
  14. this list of conditions and the following disclaimer in the documentation
  15. and/or other materials provided with the distribution.
  16. 3. Neither the name of the copyright holder nor the names of its contributors
  17. may be used to endorse or promote products derived from this software without
  18. specific prior written permission.
  19. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  23. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  25. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  28. OF SUCH DAMAGE.
  29. */
  30. /* This file refers the RISC-V standard, some adjustments are made according to GigaDevice chips */
  31. #include "gd32vf103.h"
  32. /* system frequency define */
  33. #define __IRC8M (IRC8M_VALUE) /* internal 8 MHz RC oscillator frequency */
  34. #define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */
  35. #define __SYS_OSC_CLK (__IRC8M) /* main oscillator frequency */
  36. /* select a system clock by uncommenting the following line */
  37. /* use IRC8M */
  38. //#define __SYSTEM_CLOCK_48M_PLL_IRC8M (uint32_t)(48000000)
  39. //#define __SYSTEM_CLOCK_72M_PLL_IRC8M (uint32_t)(72000000)
  40. //#define __SYSTEM_CLOCK_108M_PLL_IRC8M (uint32_t)(108000000)
  41. /********************************************************************/
  42. //#define __SYSTEM_CLOCK_HXTAL (HXTAL_VALUE)
  43. //#define __SYSTEM_CLOCK_24M_PLL_HXTAL (uint32_t)(24000000)
  44. /********************************************************************/
  45. //#define __SYSTEM_CLOCK_36M_PLL_HXTAL (uint32_t)(36000000)
  46. //#define __SYSTEM_CLOCK_48M_PLL_HXTAL (uint32_t)(48000000)
  47. //#define __SYSTEM_CLOCK_56M_PLL_HXTAL (uint32_t)(56000000)
  48. //#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000)
  49. //#define __SYSTEM_CLOCK_96M_PLL_HXTAL (uint32_t)(96000000)
  50. #define __SYSTEM_CLOCK_108M_PLL_HXTAL (uint32_t)(108000000)
  51. #define SEL_IRC8M 0x00U
  52. #define SEL_HXTAL 0x01U
  53. #define SEL_PLL 0x02U
  54. /* set the system clock frequency and declare the system clock configuration function */
  55. #ifdef __SYSTEM_CLOCK_48M_PLL_IRC8M
  56. uint32_t SystemCoreClock = __SYSTEM_CLOCK_48M_PLL_IRC8M;
  57. static void system_clock_48m_irc8m(void);
  58. #elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M)
  59. uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_IRC8M;
  60. static void system_clock_72m_irc8m(void);
  61. #elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M)
  62. uint32_t SystemCoreClock = __SYSTEM_CLOCK_108M_PLL_IRC8M;
  63. static void system_clock_108m_irc8m(void);
  64. #elif defined (__SYSTEM_CLOCK_HXTAL)
  65. uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL;
  66. static void system_clock_hxtal(void);
  67. #elif defined (__SYSTEM_CLOCK_24M_PLL_HXTAL)
  68. uint32_t SystemCoreClock = __SYSTEM_CLOCK_24M_PLL_HXTAL;
  69. static void system_clock_24m_hxtal(void);
  70. #elif defined (__SYSTEM_CLOCK_36M_PLL_HXTAL)
  71. uint32_t SystemCoreClock = __SYSTEM_CLOCK_36M_PLL_HXTAL;
  72. static void system_clock_36m_hxtal(void);
  73. #elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL)
  74. uint32_t SystemCoreClock = __SYSTEM_CLOCK_48M_PLL_HXTAL;
  75. static void system_clock_48m_hxtal(void);
  76. #elif defined (__SYSTEM_CLOCK_56M_PLL_HXTAL)
  77. uint32_t SystemCoreClock = __SYSTEM_CLOCK_56M_PLL_HXTAL;
  78. static void system_clock_56m_hxtal(void);
  79. #elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
  80. uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_HXTAL;
  81. static void system_clock_72m_hxtal(void);
  82. #elif defined (__SYSTEM_CLOCK_96M_PLL_HXTAL)
  83. uint32_t SystemCoreClock = __SYSTEM_CLOCK_96M_PLL_HXTAL;
  84. static void system_clock_96m_hxtal(void);
  85. #elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
  86. uint32_t SystemCoreClock = __SYSTEM_CLOCK_108M_PLL_HXTAL;
  87. static void system_clock_108m_hxtal(void);
  88. #else
  89. uint32_t SystemCoreClock = IRC8M_VALUE;
  90. #endif /* __SYSTEM_CLOCK_48M_PLL_IRC8M */
  91. /* configure the system clock */
  92. static void system_clock_config(void);
  93. /*!
  94. \brief configure the system clock
  95. \param[in] none
  96. \param[out] none
  97. \retval none
  98. */
  99. static void system_clock_config(void) {
  100. #ifdef __SYSTEM_CLOCK_HXTAL
  101. system_clock_hxtal();
  102. #elif defined (__SYSTEM_CLOCK_24M_PLL_HXTAL)
  103. system_clock_24m_hxtal();
  104. #elif defined (__SYSTEM_CLOCK_36M_PLL_HXTAL)
  105. system_clock_36m_hxtal();
  106. #elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL)
  107. system_clock_48m_hxtal();
  108. #elif defined (__SYSTEM_CLOCK_56M_PLL_HXTAL)
  109. system_clock_56m_hxtal();
  110. #elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
  111. system_clock_72m_hxtal();
  112. #elif defined (__SYSTEM_CLOCK_96M_PLL_HXTAL)
  113. system_clock_96m_hxtal();
  114. #elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
  115. system_clock_108m_hxtal();
  116. #elif defined (__SYSTEM_CLOCK_48M_PLL_IRC8M)
  117. system_clock_48m_irc8m();
  118. #elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M)
  119. system_clock_72m_irc8m();
  120. #elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M)
  121. system_clock_108m_irc8m();
  122. #endif /* __SYSTEM_CLOCK_HXTAL */
  123. }
  124. /*!
  125. \brief setup the microcontroller system, initialize the system
  126. \param[in] none
  127. \param[out] none
  128. \retval none
  129. */
  130. void SystemInit(void) {
  131. /* reset the RCC clock configuration to the default reset state */
  132. /* enable IRC8M */
  133. RCU_CTL |= RCU_CTL_IRC8MEN;
  134. /* reset SCS, AHBPSC, APB1PSC, APB2PSC, ADCPSC, CKOUT0SEL bits */
  135. RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC
  136. | RCU_CFG0_APB2PSC |
  137. RCU_CFG0_ADCPSC | RCU_CFG0_ADCPSC_2 | RCU_CFG0_CKOUT0SEL);
  138. /* reset HXTALEN, CKMEN, PLLEN bits */
  139. RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN);
  140. /* Reset HXTALBPS bit */
  141. RCU_CTL &= ~(RCU_CTL_HXTALBPS);
  142. /* reset PLLSEL, PREDV0_LSB, PLLMF, USBFSPSC bits */
  143. RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0_LSB | RCU_CFG0_PLLMF |
  144. RCU_CFG0_USBFSPSC | RCU_CFG0_PLLMF_4);
  145. RCU_CFG1 = 0x00000000U;
  146. /* Reset HXTALEN, CKMEN, PLLEN, PLL1EN and PLL2EN bits */
  147. RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_CKMEN
  148. | RCU_CTL_HXTALEN);
  149. /* disable all interrupts */
  150. RCU_INT = 0x00FF0000U;
  151. /* Configure the System clock source, PLL Multiplier, AHB/APBx prescalers and Flash settings */
  152. system_clock_config();
  153. }
  154. /*!
  155. \brief update the SystemCoreClock with current core clock retrieved from cpu registers
  156. \param[in] none
  157. \param[out] none
  158. \retval none
  159. */
  160. void SystemCoreClockUpdate(void) {
  161. uint32_t scss;
  162. uint32_t pllsel, predv0sel, pllmf, ck_src;
  163. uint32_t predv0, predv1, pll1mf;
  164. scss = GET_BITS(RCU_CFG0, 2, 3);
  165. switch (scss) {
  166. /* IRC8M is selected as CK_SYS */
  167. case SEL_IRC8M:
  168. SystemCoreClock = IRC8M_VALUE;
  169. break;
  170. /* HXTAL is selected as CK_SYS */
  171. case SEL_HXTAL:
  172. SystemCoreClock = HXTAL_VALUE;
  173. break;
  174. /* PLL is selected as CK_SYS */
  175. case SEL_PLL:
  176. /* PLL clock source selection, HXTAL or IRC8M/2 */
  177. pllsel = (RCU_CFG0 & RCU_CFG0_PLLSEL);
  178. if (RCU_PLLSRC_IRC8M_DIV2 == pllsel) {
  179. /* PLL clock source is IRC8M/2 */
  180. ck_src = IRC8M_VALUE / 2U;
  181. } else {
  182. /* PLL clock source is HXTAL */
  183. ck_src = HXTAL_VALUE;
  184. predv0sel = (RCU_CFG1 & RCU_CFG1_PREDV0SEL);
  185. /* source clock use PLL1 */
  186. if (RCU_PREDV0SRC_CKPLL1 == predv0sel) {
  187. predv1 = ((RCU_CFG1 & RCU_CFG1_PREDV1) >> 4) + 1U;
  188. pll1mf = ((RCU_CFG1 & RCU_CFG1_PLL1MF) >> 8) + 2U;
  189. if (17U == pll1mf) {
  190. pll1mf = 20U;
  191. }
  192. ck_src = (ck_src / predv1) * pll1mf;
  193. }
  194. predv0 = (RCU_CFG1 & RCU_CFG1_PREDV0) + 1U;
  195. ck_src /= predv0;
  196. }
  197. /* PLL multiplication factor */
  198. pllmf = GET_BITS(RCU_CFG0, 18, 21);
  199. if ((RCU_CFG0 & RCU_CFG0_PLLMF_4)) {
  200. pllmf |= 0x10U;
  201. }
  202. if (pllmf >= 15U) {
  203. pllmf += 1U;
  204. } else {
  205. pllmf += 2U;
  206. }
  207. SystemCoreClock = ck_src * pllmf;
  208. if (15U == pllmf) {
  209. /* PLL source clock multiply by 6.5 */
  210. SystemCoreClock = ck_src * 6U + ck_src / 2U;
  211. }
  212. break;
  213. /* IRC8M is selected as CK_SYS */
  214. default:
  215. SystemCoreClock = IRC8M_VALUE;
  216. break;
  217. }
  218. }
  219. #ifdef __SYSTEM_CLOCK_HXTAL
  220. /*!
  221. \brief configure the system clock to HXTAL
  222. \param[in] none
  223. \param[out] none
  224. \retval none
  225. */
  226. static void system_clock_hxtal(void)
  227. {
  228. uint32_t timeout = 0U;
  229. uint32_t stab_flag = 0U;
  230. /* enable HXTAL */
  231. RCU_CTL |= RCU_CTL_HXTALEN;
  232. /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
  233. do{
  234. timeout++;
  235. stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
  236. }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
  237. /* if fail */
  238. if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
  239. while(1){
  240. }
  241. }
  242. /* AHB = SYSCLK */
  243. RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
  244. /* APB2 = AHB/1 */
  245. RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
  246. /* APB1 = AHB/2 */
  247. RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
  248. /* select HXTAL as system clock */
  249. RCU_CFG0 &= ~RCU_CFG0_SCS;
  250. RCU_CFG0 |= RCU_CKSYSSRC_HXTAL;
  251. /* wait until HXTAL is selected as system clock */
  252. while(0 == (RCU_CFG0 & RCU_SCSS_HXTAL)){
  253. }
  254. }
  255. #elif defined (__SYSTEM_CLOCK_24M_PLL_HXTAL)
  256. /*!
  257. \brief configure the system clock to 24M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
  258. \param[in] none
  259. \param[out] none
  260. \retval none
  261. */
  262. static void system_clock_24m_hxtal(void)
  263. {
  264. uint32_t timeout = 0U;
  265. uint32_t stab_flag = 0U;
  266. /* enable HXTAL */
  267. RCU_CTL |= RCU_CTL_HXTALEN;
  268. /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
  269. do{
  270. timeout++;
  271. stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
  272. }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
  273. /* if fail */
  274. if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
  275. while(1){
  276. }
  277. }
  278. /* HXTAL is stable */
  279. /* AHB = SYSCLK */
  280. RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
  281. /* APB2 = AHB/1 */
  282. RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
  283. /* APB1 = AHB/2 */
  284. RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
  285. /* CK_PLL = (CK_PREDIV0) * 6 = 24 MHz */
  286. RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
  287. RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL6);
  288. if(HXTAL_VALUE==25000000){
  289. /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
  290. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
  291. RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
  292. /* enable PLL1 */
  293. RCU_CTL |= RCU_CTL_PLL1EN;
  294. /* wait till PLL1 is ready */
  295. while((RCU_CTL & RCU_CTL_PLL1STB) == 0){
  296. }
  297. }else if(HXTAL_VALUE==8000000){
  298. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
  299. RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 );
  300. }
  301. /* enable PLL */
  302. RCU_CTL |= RCU_CTL_PLLEN;
  303. /* wait until PLL is stable */
  304. while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
  305. }
  306. /* select PLL as system clock */
  307. RCU_CFG0 &= ~RCU_CFG0_SCS;
  308. RCU_CFG0 |= RCU_CKSYSSRC_PLL;
  309. /* wait until PLL is selected as system clock */
  310. while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
  311. }
  312. }
  313. #elif defined (__SYSTEM_CLOCK_36M_PLL_HXTAL)
  314. /*!
  315. \brief configure the system clock to 36M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
  316. \param[in] none
  317. \param[out] none
  318. \retval none
  319. */
  320. static void system_clock_36m_hxtal(void)
  321. {
  322. uint32_t timeout = 0U;
  323. uint32_t stab_flag = 0U;
  324. /* enable HXTAL */
  325. RCU_CTL |= RCU_CTL_HXTALEN;
  326. /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
  327. do{
  328. timeout++;
  329. stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
  330. }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
  331. /* if fail */
  332. if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
  333. while(1){
  334. }
  335. }
  336. /* HXTAL is stable */
  337. /* AHB = SYSCLK */
  338. RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
  339. /* APB2 = AHB/1 */
  340. RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
  341. /* APB1 = AHB/2 */
  342. RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
  343. /* CK_PLL = (CK_PREDIV0) * 9 = 36 MHz */
  344. RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
  345. RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL9);
  346. if(HXTAL_VALUE==25000000){
  347. /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
  348. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
  349. RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
  350. /* enable PLL1 */
  351. RCU_CTL |= RCU_CTL_PLL1EN;
  352. /* wait till PLL1 is ready */
  353. while((RCU_CTL & RCU_CTL_PLL1STB) == 0){
  354. }
  355. }else if(HXTAL_VALUE==8000000){
  356. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
  357. RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 );
  358. }
  359. /* enable PLL */
  360. RCU_CTL |= RCU_CTL_PLLEN;
  361. /* wait until PLL is stable */
  362. while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
  363. }
  364. /* select PLL as system clock */
  365. RCU_CFG0 &= ~RCU_CFG0_SCS;
  366. RCU_CFG0 |= RCU_CKSYSSRC_PLL;
  367. /* wait until PLL is selected as system clock */
  368. while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
  369. }
  370. }
  371. #elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL)
  372. /*!
  373. \brief configure the system clock to 48M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
  374. \param[in] none
  375. \param[out] none
  376. \retval none
  377. */
  378. static void system_clock_48m_hxtal(void)
  379. {
  380. uint32_t timeout = 0U;
  381. uint32_t stab_flag = 0U;
  382. /* enable HXTAL */
  383. RCU_CTL |= RCU_CTL_HXTALEN;
  384. /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
  385. do{
  386. timeout++;
  387. stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
  388. }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
  389. /* if fail */
  390. if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
  391. while(1){
  392. }
  393. }
  394. /* HXTAL is stable */
  395. /* AHB = SYSCLK */
  396. RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
  397. /* APB2 = AHB/1 */
  398. RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
  399. /* APB1 = AHB/2 */
  400. RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
  401. /* CK_PLL = (CK_PREDIV0) * 12 = 48 MHz */
  402. RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
  403. RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL12);
  404. if(HXTAL_VALUE==25000000){
  405. /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
  406. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
  407. RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
  408. /* enable PLL1 */
  409. RCU_CTL |= RCU_CTL_PLL1EN;
  410. /* wait till PLL1 is ready */
  411. while((RCU_CTL & RCU_CTL_PLL1STB) == 0){
  412. }
  413. }else if(HXTAL_VALUE==8000000){
  414. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
  415. RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 );
  416. }
  417. /* enable PLL */
  418. RCU_CTL |= RCU_CTL_PLLEN;
  419. /* wait until PLL is stable */
  420. while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
  421. }
  422. /* select PLL as system clock */
  423. RCU_CFG0 &= ~RCU_CFG0_SCS;
  424. RCU_CFG0 |= RCU_CKSYSSRC_PLL;
  425. /* wait until PLL is selected as system clock */
  426. while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
  427. }
  428. }
  429. #elif defined (__SYSTEM_CLOCK_56M_PLL_HXTAL)
  430. /*!
  431. \brief configure the system clock to 56M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
  432. \param[in] none
  433. \param[out] none
  434. \retval none
  435. */
  436. static void system_clock_56m_hxtal(void)
  437. {
  438. uint32_t timeout = 0U;
  439. uint32_t stab_flag = 0U;
  440. /* enable HXTAL */
  441. RCU_CTL |= RCU_CTL_HXTALEN;
  442. /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
  443. do{
  444. timeout++;
  445. stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
  446. }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
  447. /* if fail */
  448. if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
  449. while(1){
  450. }
  451. }
  452. /* HXTAL is stable */
  453. /* AHB = SYSCLK */
  454. RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
  455. /* APB2 = AHB/1 */
  456. RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
  457. /* APB1 = AHB/2 */
  458. RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
  459. /* CK_PLL = (CK_PREDIV0) * 14 = 56 MHz */
  460. RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
  461. RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL14);
  462. if(HXTAL_VALUE==25000000){
  463. /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
  464. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
  465. RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
  466. /* enable PLL1 */
  467. RCU_CTL |= RCU_CTL_PLL1EN;
  468. /* wait till PLL1 is ready */
  469. while((RCU_CTL & RCU_CTL_PLL1STB) == 0){
  470. }
  471. }else if(HXTAL_VALUE==8000000){
  472. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
  473. RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 );
  474. }
  475. /* enable PLL */
  476. RCU_CTL |= RCU_CTL_PLLEN;
  477. /* wait until PLL is stable */
  478. while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
  479. }
  480. /* select PLL as system clock */
  481. RCU_CFG0 &= ~RCU_CFG0_SCS;
  482. RCU_CFG0 |= RCU_CKSYSSRC_PLL;
  483. /* wait until PLL is selected as system clock */
  484. while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
  485. }
  486. }
  487. #elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
  488. /*!
  489. \brief configure the system clock to 72M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
  490. \param[in] none
  491. \param[out] none
  492. \retval none
  493. */
  494. static void system_clock_72m_hxtal(void)
  495. {
  496. uint32_t timeout = 0U;
  497. uint32_t stab_flag = 0U;
  498. /* enable HXTAL */
  499. RCU_CTL |= RCU_CTL_HXTALEN;
  500. /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
  501. do{
  502. timeout++;
  503. stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
  504. }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
  505. /* if fail */
  506. if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
  507. while(1){
  508. }
  509. }
  510. /* HXTAL is stable */
  511. /* AHB = SYSCLK */
  512. RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
  513. /* APB2 = AHB/1 */
  514. RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
  515. /* APB1 = AHB/2 */
  516. RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
  517. /* CK_PLL = (CK_PREDIV0) * 18 = 72 MHz */
  518. RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
  519. RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL18);
  520. if(HXTAL_VALUE==25000000){
  521. /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
  522. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
  523. RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
  524. /* enable PLL1 */
  525. RCU_CTL |= RCU_CTL_PLL1EN;
  526. /* wait till PLL1 is ready */
  527. while((RCU_CTL & RCU_CTL_PLL1STB) == 0){
  528. }
  529. }else if(HXTAL_VALUE==8000000){
  530. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
  531. RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 );
  532. }
  533. /* enable PLL */
  534. RCU_CTL |= RCU_CTL_PLLEN;
  535. /* wait until PLL is stable */
  536. while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
  537. }
  538. /* select PLL as system clock */
  539. RCU_CFG0 &= ~RCU_CFG0_SCS;
  540. RCU_CFG0 |= RCU_CKSYSSRC_PLL;
  541. /* wait until PLL is selected as system clock */
  542. while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
  543. }
  544. }
  545. #elif defined (__SYSTEM_CLOCK_96M_PLL_HXTAL)
  546. /*!
  547. \brief configure the system clock to 96M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
  548. \param[in] none
  549. \param[out] none
  550. \retval none
  551. */
  552. static void system_clock_96m_hxtal(void)
  553. {
  554. uint32_t timeout = 0U;
  555. uint32_t stab_flag = 0U;
  556. /* enable HXTAL */
  557. RCU_CTL |= RCU_CTL_HXTALEN;
  558. /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
  559. do{
  560. timeout++;
  561. stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
  562. }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
  563. /* if fail */
  564. if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
  565. while(1){
  566. }
  567. }
  568. /* HXTAL is stable */
  569. /* AHB = SYSCLK */
  570. RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
  571. /* APB2 = AHB/1 */
  572. RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
  573. /* APB1 = AHB/2 */
  574. RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
  575. if(HXTAL_VALUE==25000000){
  576. /* CK_PLL = (CK_PREDIV0) * 24 = 96 MHz */
  577. RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
  578. RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL24);
  579. /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
  580. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
  581. RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
  582. /* enable PLL1 */
  583. RCU_CTL |= RCU_CTL_PLL1EN;
  584. /* wait till PLL1 is ready */
  585. while((RCU_CTL & RCU_CTL_PLL1STB) == 0){
  586. }
  587. }else if(HXTAL_VALUE==8000000){
  588. /* CK_PLL = (CK_PREDIV0) * 24 = 96 MHz */
  589. RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
  590. RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL24);
  591. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
  592. RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 );
  593. }
  594. /* enable PLL */
  595. RCU_CTL |= RCU_CTL_PLLEN;
  596. /* wait until PLL is stable */
  597. while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
  598. }
  599. /* select PLL as system clock */
  600. RCU_CFG0 &= ~RCU_CFG0_SCS;
  601. RCU_CFG0 |= RCU_CKSYSSRC_PLL;
  602. /* wait until PLL is selected as system clock */
  603. while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
  604. }
  605. }
  606. #elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
  607. /*!
  608. \brief configure the system clock to 108M by PLL which selects HXTAL(MD/HD/XD:8M; CL:25M) as its clock source
  609. \param[in] none
  610. \param[out] none
  611. \retval none
  612. */
  613. static void system_clock_108m_hxtal(void) {
  614. uint32_t timeout = 0U;
  615. uint32_t stab_flag = 0U;
  616. /* enable HXTAL */
  617. RCU_CTL |= RCU_CTL_HXTALEN;
  618. /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
  619. do {
  620. timeout++;
  621. stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
  622. } while ((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
  623. /* if fail */
  624. if (0U == (RCU_CTL & RCU_CTL_HXTALSTB)) {
  625. while (1) {
  626. }
  627. }
  628. /* HXTAL is stable */
  629. /* AHB = SYSCLK */
  630. RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
  631. /* APB2 = AHB/1 */
  632. RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
  633. /* APB1 = AHB/2 */
  634. RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
  635. /* CK_PLL = (CK_PREDIV0) * 27 = 108 MHz */
  636. RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
  637. RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL27);
  638. if (HXTAL_VALUE == 25000000) {
  639. /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
  640. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF
  641. | RCU_CFG1_PREDV0);
  642. RCU_CFG1 |= (RCU_PREDV0SRC_CKPLL1 | RCU_PREDV1_DIV5 | RCU_PLL1_MUL8
  643. | RCU_PREDV0_DIV10);
  644. /* enable PLL1 */
  645. RCU_CTL |= RCU_CTL_PLL1EN;
  646. /* wait till PLL1 is ready */
  647. while (0U == (RCU_CTL & RCU_CTL_PLL1STB)) {
  648. }
  649. /* enable PLL1 */
  650. RCU_CTL |= RCU_CTL_PLL2EN;
  651. /* wait till PLL1 is ready */
  652. while (0U == (RCU_CTL & RCU_CTL_PLL2STB)) {
  653. }
  654. } else if (HXTAL_VALUE == 8000000) {
  655. RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF
  656. | RCU_CFG1_PREDV0);
  657. RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 | RCU_PREDV1_DIV2
  658. | RCU_PLL1_MUL20 | RCU_PLL2_MUL20);
  659. /* enable PLL1 */
  660. RCU_CTL |= RCU_CTL_PLL1EN;
  661. /* wait till PLL1 is ready */
  662. while (0U == (RCU_CTL & RCU_CTL_PLL1STB)) {
  663. }
  664. /* enable PLL2 */
  665. RCU_CTL |= RCU_CTL_PLL2EN;
  666. /* wait till PLL1 is ready */
  667. while (0U == (RCU_CTL & RCU_CTL_PLL2STB)) {
  668. }
  669. }
  670. /* enable PLL */
  671. RCU_CTL |= RCU_CTL_PLLEN;
  672. /* wait until PLL is stable */
  673. while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {
  674. }
  675. /* select PLL as system clock */
  676. RCU_CFG0 &= ~RCU_CFG0_SCS;
  677. RCU_CFG0 |= RCU_CKSYSSRC_PLL;
  678. /* wait until PLL is selected as system clock */
  679. while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {
  680. }
  681. }
  682. #elif defined (__SYSTEM_CLOCK_48M_PLL_IRC8M)
  683. /*!
  684. \brief configure the system clock to 48M by PLL which selects IRC8M as its clock source
  685. \param[in] none
  686. \param[out] none
  687. \retval none
  688. */
  689. static void system_clock_48m_irc8m(void)
  690. {
  691. uint32_t timeout = 0U;
  692. uint32_t stab_flag = 0U;
  693. /* enable IRC8M */
  694. RCU_CTL |= RCU_CTL_IRC8MEN;
  695. /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
  696. do{
  697. timeout++;
  698. stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
  699. }
  700. while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
  701. /* if fail */
  702. if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
  703. while(1){
  704. }
  705. }
  706. /* IRC8M is stable */
  707. /* AHB = SYSCLK */
  708. RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
  709. /* APB2 = AHB/1 */
  710. RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
  711. /* APB1 = AHB/2 */
  712. RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
  713. /* CK_PLL = (CK_IRC8M/2) * 12 = 48 MHz */
  714. RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
  715. RCU_CFG0 |= RCU_PLL_MUL12;
  716. /* enable PLL */
  717. RCU_CTL |= RCU_CTL_PLLEN;
  718. /* wait until PLL is stable */
  719. while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
  720. }
  721. /* select PLL as system clock */
  722. RCU_CFG0 &= ~RCU_CFG0_SCS;
  723. RCU_CFG0 |= RCU_CKSYSSRC_PLL;
  724. /* wait until PLL is selected as system clock */
  725. while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
  726. }
  727. }
  728. #elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M)
  729. /*!
  730. \brief configure the system clock to 72M by PLL which selects IRC8M as its clock source
  731. \param[in] none
  732. \param[out] none
  733. \retval none
  734. */
  735. static void system_clock_72m_irc8m(void)
  736. {
  737. uint32_t timeout = 0U;
  738. uint32_t stab_flag = 0U;
  739. /* enable IRC8M */
  740. RCU_CTL |= RCU_CTL_IRC8MEN;
  741. /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
  742. do{
  743. timeout++;
  744. stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
  745. }
  746. while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
  747. /* if fail */
  748. if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
  749. while(1){
  750. }
  751. }
  752. /* IRC8M is stable */
  753. /* AHB = SYSCLK */
  754. RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
  755. /* APB2 = AHB/1 */
  756. RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
  757. /* APB1 = AHB/2 */
  758. RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
  759. /* CK_PLL = (CK_IRC8M/2) * 18 = 72 MHz */
  760. RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
  761. RCU_CFG0 |= RCU_PLL_MUL18;
  762. /* enable PLL */
  763. RCU_CTL |= RCU_CTL_PLLEN;
  764. /* wait until PLL is stable */
  765. while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
  766. }
  767. /* select PLL as system clock */
  768. RCU_CFG0 &= ~RCU_CFG0_SCS;
  769. RCU_CFG0 |= RCU_CKSYSSRC_PLL;
  770. /* wait until PLL is selected as system clock */
  771. while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
  772. }
  773. }
  774. #elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M)
  775. /*!
  776. \brief configure the system clock to 108M by PLL which selects IRC8M as its clock source
  777. \param[in] none
  778. \param[out] none
  779. \retval none
  780. */
  781. static void system_clock_108m_irc8m(void)
  782. {
  783. uint32_t timeout = 0U;
  784. uint32_t stab_flag = 0U;
  785. /* enable IRC8M */
  786. RCU_CTL |= RCU_CTL_IRC8MEN;
  787. /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
  788. do{
  789. timeout++;
  790. stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
  791. }
  792. while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
  793. /* if fail */
  794. if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
  795. while(1){
  796. }
  797. }
  798. /* IRC8M is stable */
  799. /* AHB = SYSCLK */
  800. RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
  801. /* APB2 = AHB/1 */
  802. RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
  803. /* APB1 = AHB/2 */
  804. RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
  805. /* CK_PLL = (CK_IRC8M/2) * 27 = 108 MHz */
  806. RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4);
  807. RCU_CFG0 |= RCU_PLL_MUL27;
  808. /* enable PLL */
  809. RCU_CTL |= RCU_CTL_PLLEN;
  810. /* wait until PLL is stable */
  811. while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
  812. }
  813. /* select PLL as system clock */
  814. RCU_CFG0 &= ~RCU_CFG0_SCS;
  815. RCU_CFG0 |= RCU_CKSYSSRC_PLL;
  816. /* wait until PLL is selected as system clock */
  817. while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
  818. }
  819. }
  820. #endif