system_gd32f10x.c 32 KB

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