system_ch32v30x.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name : system_ch32v30x.c
  3. * Author : WCH
  4. * Version : V1.0.0
  5. * Date : 2021/06/06
  6. * Description : CH32V30x Device Peripheral Access Layer System Source File.
  7. * For HSE = 8Mhz
  8. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
  9. * SPDX-License-Identifier: Apache-2.0
  10. *********************************************************************************/
  11. #include "ch32v30x.h"
  12. /*
  13. * Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after
  14. * reset the HSI is used as SYSCLK source).
  15. * If none of the define below is enabled, the HSI is used as System clock source.
  16. */
  17. // #define SYSCLK_FREQ_HSE HSE_VALUE
  18. /* #define SYSCLK_FREQ_24MHz 24000000 */
  19. //#define SYSCLK_FREQ_48MHz 48000000
  20. /* #define SYSCLK_FREQ_56MHz 56000000 */
  21. //#define SYSCLK_FREQ_72MHz 72000000
  22. //#define SYSCLK_FREQ_96MHz 96000000
  23. //#define SYSCLK_FREQ_120MHz 120000000
  24. #define SYSCLK_FREQ_144MHz 144000000
  25. /* Clock Definitions */
  26. #ifdef SYSCLK_FREQ_HSE
  27. uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */
  28. #elif defined SYSCLK_FREQ_24MHz
  29. uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /* System Clock Frequency (Core Clock) */
  30. #elif defined SYSCLK_FREQ_48MHz
  31. uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /* System Clock Frequency (Core Clock) */
  32. #elif defined SYSCLK_FREQ_56MHz
  33. uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /* System Clock Frequency (Core Clock) */
  34. #elif defined SYSCLK_FREQ_72MHz
  35. uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /* System Clock Frequency (Core Clock) */
  36. #elif defined SYSCLK_FREQ_96MHz
  37. uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz; /* System Clock Frequency (Core Clock) */
  38. #elif defined SYSCLK_FREQ_120MHz
  39. uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz; /* System Clock Frequency (Core Clock) */
  40. #elif defined SYSCLK_FREQ_144MHz
  41. uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz; /* System Clock Frequency (Core Clock) */
  42. #else /* HSI Selected as System Clock source */
  43. uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */
  44. #endif
  45. __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
  46. /* system_private_function_proto_types */
  47. static void SetSysClock(void);
  48. #ifdef SYSCLK_FREQ_HSE
  49. static void SetSysClockToHSE(void);
  50. #elif defined SYSCLK_FREQ_24MHz
  51. static void SetSysClockTo24(void);
  52. #elif defined SYSCLK_FREQ_48MHz
  53. static void SetSysClockTo48(void);
  54. #elif defined SYSCLK_FREQ_56MHz
  55. static void SetSysClockTo56(void);
  56. #elif defined SYSCLK_FREQ_72MHz
  57. static void SetSysClockTo72(void);
  58. #elif defined SYSCLK_FREQ_96MHz
  59. static void SetSysClockTo96(void);
  60. #elif defined SYSCLK_FREQ_120MHz
  61. static void SetSysClockTo120(void);
  62. #elif defined SYSCLK_FREQ_144MHz
  63. static void SetSysClockTo144(void);
  64. #endif
  65. /*********************************************************************
  66. * @fn SystemInit
  67. *
  68. * @brief Setup the microcontroller system Initialize the Embedded Flash Interface,
  69. * the PLL and update the SystemCoreClock variable.
  70. *
  71. * @return none
  72. */
  73. void SystemInit (void)
  74. {
  75. RCC->CTLR |= (uint32_t)0x00000001;
  76. #ifdef CH32V30x_D8C
  77. RCC->CFGR0 &= (uint32_t)0xF8FF0000;
  78. #else
  79. RCC->CFGR0 &= (uint32_t)0xF0FF0000;
  80. #endif
  81. RCC->CTLR &= (uint32_t)0xFEF6FFFF;
  82. RCC->CTLR &= (uint32_t)0xFFFBFFFF;
  83. RCC->CFGR0 &= (uint32_t)0xFF80FFFF;
  84. #ifdef CH32V30x_D8C
  85. RCC->CTLR &= (uint32_t)0xEBFFFFFF;
  86. RCC->INTR = 0x00FF0000;
  87. RCC->CFGR2 = 0x00000000;
  88. #else
  89. RCC->INTR = 0x009F0000;
  90. #endif
  91. SetSysClock();
  92. }
  93. /*********************************************************************
  94. * @fn SystemCoreClockUpdate
  95. *
  96. * @brief Update SystemCoreClock variable according to Clock Register Values.
  97. *
  98. * @return none
  99. */
  100. void SystemCoreClockUpdate (void)
  101. {
  102. uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0;
  103. tmp = RCC->CFGR0 & RCC_SWS;
  104. switch (tmp)
  105. {
  106. case 0x00:
  107. SystemCoreClock = HSI_VALUE;
  108. break;
  109. case 0x04:
  110. SystemCoreClock = HSE_VALUE;
  111. break;
  112. case 0x08:
  113. pllmull = RCC->CFGR0 & RCC_PLLMULL;
  114. pllsource = RCC->CFGR0 & RCC_PLLSRC;
  115. pllmull = ( pllmull >> 18) + 2;
  116. #ifdef CH32V30x_D8
  117. if(pllmull == 17) pllmull = 18;
  118. #else
  119. if(pllmull == 2) pllmull = 18;
  120. if(pllmull == 15){
  121. pllmull = 13; /* *6.5 */
  122. Pll_6_5 = 1;
  123. }
  124. if(pllmull == 16) pllmull = 15;
  125. if(pllmull == 17) pllmull = 16;
  126. #endif
  127. if (pllsource == 0x00)
  128. {
  129. SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
  130. }
  131. else
  132. {
  133. if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET)
  134. {
  135. SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
  136. }
  137. else
  138. {
  139. SystemCoreClock = HSE_VALUE * pllmull;
  140. }
  141. }
  142. if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2);
  143. break;
  144. default:
  145. SystemCoreClock = HSI_VALUE;
  146. break;
  147. }
  148. tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)];
  149. SystemCoreClock >>= tmp;
  150. }
  151. /*********************************************************************
  152. * @fn SetSysClock
  153. *
  154. * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
  155. *
  156. * @return none
  157. */
  158. static void SetSysClock(void)
  159. {
  160. #ifdef SYSCLK_FREQ_HSE
  161. SetSysClockToHSE();
  162. #elif defined SYSCLK_FREQ_24MHz
  163. SetSysClockTo24();
  164. #elif defined SYSCLK_FREQ_48MHz
  165. SetSysClockTo48();
  166. #elif defined SYSCLK_FREQ_56MHz
  167. SetSysClockTo56();
  168. #elif defined SYSCLK_FREQ_72MHz
  169. SetSysClockTo72();
  170. #elif defined SYSCLK_FREQ_96MHz
  171. SetSysClockTo96();
  172. #elif defined SYSCLK_FREQ_120MHz
  173. SetSysClockTo120();
  174. #elif defined SYSCLK_FREQ_144MHz
  175. SetSysClockTo144();
  176. #endif
  177. /* If none of the define above is enabled, the HSI is used as System clock
  178. * source (default after reset)
  179. */
  180. }
  181. #ifdef SYSCLK_FREQ_HSE
  182. /*********************************************************************
  183. * @fn SetSysClockToHSE
  184. *
  185. * @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers.
  186. *
  187. * @return none
  188. */
  189. static void SetSysClockToHSE(void)
  190. {
  191. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  192. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  193. /* Wait till HSE is ready and if Time out is reached exit */
  194. do
  195. {
  196. HSEStatus = RCC->CTLR & RCC_HSERDY;
  197. StartUpCounter++;
  198. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  199. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  200. {
  201. HSEStatus = (uint32_t)0x01;
  202. }
  203. else
  204. {
  205. HSEStatus = (uint32_t)0x00;
  206. }
  207. if (HSEStatus == (uint32_t)0x01)
  208. {
  209. /* HCLK = SYSCLK */
  210. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  211. /* PCLK2 = HCLK */
  212. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  213. /* PCLK1 = HCLK */
  214. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
  215. /* Select HSE as system clock source */
  216. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  217. RCC->CFGR0 |= (uint32_t)RCC_SW_HSE;
  218. /* Wait till HSE is used as system clock source */
  219. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04)
  220. {
  221. }
  222. }
  223. else
  224. {
  225. /* If HSE fails to start-up, the application will have wrong clock
  226. * configuration. User can add here some code to deal with this error
  227. */
  228. }
  229. }
  230. #elif defined SYSCLK_FREQ_24MHz
  231. /*********************************************************************
  232. * @fn SetSysClockTo24
  233. *
  234. * @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  235. *
  236. * @return none
  237. */
  238. static void SetSysClockTo24(void)
  239. {
  240. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  241. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  242. /* Wait till HSE is ready and if Time out is reached exit */
  243. do
  244. {
  245. HSEStatus = RCC->CTLR & RCC_HSERDY;
  246. StartUpCounter++;
  247. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  248. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  249. {
  250. HSEStatus = (uint32_t)0x01;
  251. }
  252. else
  253. {
  254. HSEStatus = (uint32_t)0x00;
  255. }
  256. if (HSEStatus == (uint32_t)0x01)
  257. {
  258. /* HCLK = SYSCLK */
  259. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  260. /* PCLK2 = HCLK */
  261. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  262. /* PCLK1 = HCLK */
  263. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
  264. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
  265. #ifdef CH32V30x_D8
  266. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL3);
  267. #else
  268. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL3_EXTEN);
  269. #endif
  270. /* Enable PLL */
  271. RCC->CTLR |= RCC_PLLON;
  272. /* Wait till PLL is ready */
  273. while((RCC->CTLR & RCC_PLLRDY) == 0)
  274. {
  275. }
  276. /* Select PLL as system clock source */
  277. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  278. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  279. /* Wait till PLL is used as system clock source */
  280. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  281. {
  282. }
  283. }
  284. else
  285. {
  286. /* If HSE fails to start-up, the application will have wrong clock
  287. * configuration. User can add here some code to deal with this error
  288. */
  289. }
  290. }
  291. #elif defined SYSCLK_FREQ_48MHz
  292. /*********************************************************************
  293. * @fn SetSysClockTo48
  294. *
  295. * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  296. *
  297. * @return none
  298. */
  299. static void SetSysClockTo48(void)
  300. {
  301. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  302. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  303. /* Wait till HSE is ready and if Time out is reached exit */
  304. do
  305. {
  306. HSEStatus = RCC->CTLR & RCC_HSERDY;
  307. StartUpCounter++;
  308. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  309. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  310. {
  311. HSEStatus = (uint32_t)0x01;
  312. }
  313. else
  314. {
  315. HSEStatus = (uint32_t)0x00;
  316. }
  317. if (HSEStatus == (uint32_t)0x01)
  318. {
  319. /* HCLK = SYSCLK */
  320. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  321. /* PCLK2 = HCLK */
  322. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  323. /* PCLK1 = HCLK */
  324. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  325. /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */
  326. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
  327. #ifdef CH32V30x_D8
  328. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6);
  329. #else
  330. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6_EXTEN);
  331. #endif
  332. /* Enable PLL */
  333. RCC->CTLR |= RCC_PLLON;
  334. /* Wait till PLL is ready */
  335. while((RCC->CTLR & RCC_PLLRDY) == 0)
  336. {
  337. }
  338. /* Select PLL as system clock source */
  339. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  340. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  341. /* Wait till PLL is used as system clock source */
  342. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  343. {
  344. }
  345. }
  346. else
  347. {
  348. /*
  349. * If HSE fails to start-up, the application will have wrong clock
  350. * configuration. User can add here some code to deal with this error
  351. */
  352. }
  353. }
  354. #elif defined SYSCLK_FREQ_56MHz
  355. /*********************************************************************
  356. * @fn SetSysClockTo56
  357. *
  358. * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  359. *
  360. * @return none
  361. */
  362. static void SetSysClockTo56(void)
  363. {
  364. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  365. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  366. /* Wait till HSE is ready and if Time out is reached exit */
  367. do
  368. {
  369. HSEStatus = RCC->CTLR & RCC_HSERDY;
  370. StartUpCounter++;
  371. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  372. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  373. {
  374. HSEStatus = (uint32_t)0x01;
  375. }
  376. else
  377. {
  378. HSEStatus = (uint32_t)0x00;
  379. }
  380. if (HSEStatus == (uint32_t)0x01)
  381. {
  382. /* HCLK = SYSCLK */
  383. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  384. /* PCLK2 = HCLK */
  385. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  386. /* PCLK1 = HCLK */
  387. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  388. /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */
  389. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
  390. #ifdef CH32V30x_D8
  391. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7);
  392. #else
  393. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7_EXTEN);
  394. #endif
  395. /* Enable PLL */
  396. RCC->CTLR |= RCC_PLLON;
  397. /* Wait till PLL is ready */
  398. while((RCC->CTLR & RCC_PLLRDY) == 0)
  399. {
  400. }
  401. /* Select PLL as system clock source */
  402. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  403. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  404. /* Wait till PLL is used as system clock source */
  405. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  406. {
  407. }
  408. }
  409. else
  410. {
  411. /*
  412. * If HSE fails to start-up, the application will have wrong clock
  413. * configuration. User can add here some code to deal with this error
  414. */
  415. }
  416. }
  417. #elif defined SYSCLK_FREQ_72MHz
  418. /*********************************************************************
  419. * @fn SetSysClockTo72
  420. *
  421. * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  422. *
  423. * @return none
  424. */
  425. static void SetSysClockTo72(void)
  426. {
  427. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  428. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  429. /* Wait till HSE is ready and if Time out is reached exit */
  430. do
  431. {
  432. HSEStatus = RCC->CTLR & RCC_HSERDY;
  433. StartUpCounter++;
  434. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  435. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  436. {
  437. HSEStatus = (uint32_t)0x01;
  438. }
  439. else
  440. {
  441. HSEStatus = (uint32_t)0x00;
  442. }
  443. if (HSEStatus == (uint32_t)0x01)
  444. {
  445. /* HCLK = SYSCLK */
  446. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  447. /* PCLK2 = HCLK */
  448. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  449. /* PCLK1 = HCLK */
  450. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  451. /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
  452. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
  453. RCC_PLLMULL));
  454. #ifdef CH32V30x_D8
  455. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9);
  456. #else
  457. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9_EXTEN);
  458. #endif
  459. /* Enable PLL */
  460. RCC->CTLR |= RCC_PLLON;
  461. /* Wait till PLL is ready */
  462. while((RCC->CTLR & RCC_PLLRDY) == 0)
  463. {
  464. }
  465. /* Select PLL as system clock source */
  466. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  467. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  468. /* Wait till PLL is used as system clock source */
  469. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  470. {
  471. }
  472. }
  473. else
  474. {
  475. /*
  476. * If HSE fails to start-up, the application will have wrong clock
  477. * configuration. User can add here some code to deal with this error
  478. */
  479. }
  480. }
  481. #elif defined SYSCLK_FREQ_96MHz
  482. /*********************************************************************
  483. * @fn SetSysClockTo96
  484. *
  485. * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  486. *
  487. * @return none
  488. */
  489. static void SetSysClockTo96(void)
  490. {
  491. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  492. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  493. /* Wait till HSE is ready and if Time out is reached exit */
  494. do
  495. {
  496. HSEStatus = RCC->CTLR & RCC_HSERDY;
  497. StartUpCounter++;
  498. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  499. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  500. {
  501. HSEStatus = (uint32_t)0x01;
  502. }
  503. else
  504. {
  505. HSEStatus = (uint32_t)0x00;
  506. }
  507. if (HSEStatus == (uint32_t)0x01)
  508. {
  509. /* HCLK = SYSCLK */
  510. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  511. /* PCLK2 = HCLK */
  512. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  513. /* PCLK1 = HCLK */
  514. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  515. /* PLL configuration: PLLCLK = HSE * 12 = 96 MHz */
  516. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
  517. RCC_PLLMULL));
  518. #ifdef CH32V30x_D8
  519. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12);
  520. #else
  521. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12_EXTEN);
  522. #endif
  523. /* Enable PLL */
  524. RCC->CTLR |= RCC_PLLON;
  525. /* Wait till PLL is ready */
  526. while((RCC->CTLR & RCC_PLLRDY) == 0)
  527. {
  528. }
  529. /* Select PLL as system clock source */
  530. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  531. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  532. /* Wait till PLL is used as system clock source */
  533. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  534. {
  535. }
  536. }
  537. else
  538. {
  539. /*
  540. * If HSE fails to start-up, the application will have wrong clock
  541. * configuration. User can add here some code to deal with this error
  542. */
  543. }
  544. }
  545. #elif defined SYSCLK_FREQ_120MHz
  546. /*********************************************************************
  547. * @fn SetSysClockTo120
  548. *
  549. * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  550. *
  551. * @return none
  552. */
  553. static void SetSysClockTo120(void)
  554. {
  555. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  556. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  557. /* Wait till HSE is ready and if Time out is reached exit */
  558. do
  559. {
  560. HSEStatus = RCC->CTLR & RCC_HSERDY;
  561. StartUpCounter++;
  562. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  563. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  564. {
  565. HSEStatus = (uint32_t)0x01;
  566. }
  567. else
  568. {
  569. HSEStatus = (uint32_t)0x00;
  570. }
  571. if (HSEStatus == (uint32_t)0x01)
  572. {
  573. /* HCLK = SYSCLK */
  574. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  575. /* PCLK2 = HCLK */
  576. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  577. /* PCLK1 = HCLK */
  578. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  579. /* PLL configuration: PLLCLK = HSE * 15 = 120 MHz */
  580. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
  581. RCC_PLLMULL));
  582. #ifdef CH32V30x_D8
  583. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15);
  584. #else
  585. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15_EXTEN);
  586. #endif
  587. /* Enable PLL */
  588. RCC->CTLR |= RCC_PLLON;
  589. /* Wait till PLL is ready */
  590. while((RCC->CTLR & RCC_PLLRDY) == 0)
  591. {
  592. }
  593. /* Select PLL as system clock source */
  594. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  595. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  596. /* Wait till PLL is used as system clock source */
  597. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  598. {
  599. }
  600. }
  601. else
  602. {
  603. /*
  604. * If HSE fails to start-up, the application will have wrong clock
  605. * configuration. User can add here some code to deal with this error
  606. */
  607. }
  608. }
  609. #elif defined SYSCLK_FREQ_144MHz
  610. /*********************************************************************
  611. * @fn SetSysClockTo144
  612. *
  613. * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  614. *
  615. * @return none
  616. */
  617. static void SetSysClockTo144(void)
  618. {
  619. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  620. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  621. /* Wait till HSE is ready and if Time out is reached exit */
  622. do
  623. {
  624. HSEStatus = RCC->CTLR & RCC_HSERDY;
  625. StartUpCounter++;
  626. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  627. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  628. {
  629. HSEStatus = (uint32_t)0x01;
  630. }
  631. else
  632. {
  633. HSEStatus = (uint32_t)0x00;
  634. }
  635. if (HSEStatus == (uint32_t)0x01)
  636. {
  637. /* HCLK = SYSCLK */
  638. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  639. /* PCLK2 = HCLK */
  640. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  641. /* PCLK1 = HCLK */
  642. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  643. /* PLL configuration: PLLCLK = HSE * 18 = 144 MHz */
  644. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
  645. RCC_PLLMULL));
  646. #ifdef CH32V30x_D8
  647. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18);
  648. #else
  649. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18_EXTEN);
  650. #endif
  651. /* Enable PLL */
  652. RCC->CTLR |= RCC_PLLON;
  653. /* Wait till PLL is ready */
  654. while((RCC->CTLR & RCC_PLLRDY) == 0)
  655. {
  656. }
  657. /* Select PLL as system clock source */
  658. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  659. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  660. /* Wait till PLL is used as system clock source */
  661. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  662. {
  663. }
  664. }
  665. else
  666. {
  667. /*
  668. * If HSE fails to start-up, the application will have wrong clock
  669. * configuration. User can add here some code to deal with this error
  670. */
  671. }
  672. }
  673. #endif