system_gd32f10x.c 31 KB

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