system_ch32v20x.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name : system_ch32v20x.c
  3. * Author : WCH
  4. * Version : V1.0.0
  5. * Date : 2021/06/06
  6. * Description : CH32V20x Device Peripheral Access Layer System Source File.
  7. * For HSE = 32Mhz (CH32V208x/CH32V203RBT6)
  8. * For HSE = 8Mhz (other CH32V203x)
  9. * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
  10. * SPDX-License-Identifier: Apache-2.0
  11. *********************************************************************************/
  12. #include "ch32v20x.h"
  13. /*
  14. * Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after
  15. * reset the HSI is used as SYSCLK source).
  16. * If none of the define below is enabled, the HSI is used as System clock source.
  17. */
  18. //#define SYSCLK_FREQ_HSE HSE_VALUE
  19. //#define SYSCLK_FREQ_48MHz_HSE 48000000
  20. //#define SYSCLK_FREQ_56MHz_HSE 56000000
  21. //#define SYSCLK_FREQ_72MHz_HSE 72000000
  22. //#define SYSCLK_FREQ_96MHz_HSE 96000000
  23. //#define SYSCLK_FREQ_120MHz_HSE 120000000
  24. #define SYSCLK_FREQ_144MHz_HSE 144000000
  25. //#define SYSCLK_FREQ_HSI HSI_VALUE
  26. //#define SYSCLK_FREQ_48MHz_HSI 48000000
  27. //#define SYSCLK_FREQ_56MHz_HSI 56000000
  28. //#define SYSCLK_FREQ_72MHz_HSI 72000000
  29. //#define SYSCLK_FREQ_96MHz_HSI 96000000
  30. //#define SYSCLK_FREQ_120MHz_HSI 120000000
  31. //#define SYSCLK_FREQ_144MHz_HSI 144000000
  32. /* Clock Definitions */
  33. #ifdef SYSCLK_FREQ_HSE
  34. uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */
  35. #elif defined SYSCLK_FREQ_48MHz_HSE
  36. uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */
  37. #elif defined SYSCLK_FREQ_56MHz_HSE
  38. uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */
  39. #elif defined SYSCLK_FREQ_72MHz_HSE
  40. uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */
  41. #elif defined SYSCLK_FREQ_96MHz_HSE
  42. uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSE; /* System Clock Frequency (Core Clock) */
  43. #elif defined SYSCLK_FREQ_120MHz_HSE
  44. uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSE; /* System Clock Frequency (Core Clock) */
  45. #elif defined SYSCLK_FREQ_144MHz_HSE
  46. uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSE; /* System Clock Frequency (Core Clock) */
  47. #elif defined SYSCLK_FREQ_48MHz_HSI
  48. uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */
  49. #elif defined SYSCLK_FREQ_56MHz_HSI
  50. uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */
  51. #elif defined SYSCLK_FREQ_72MHz_HSI
  52. uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */
  53. #elif defined SYSCLK_FREQ_96MHz_HSI
  54. uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSI; /* System Clock Frequency (Core Clock) */
  55. #elif defined SYSCLK_FREQ_120MHz_HSI
  56. uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSI; /* System Clock Frequency (Core Clock) */
  57. #elif defined SYSCLK_FREQ_144MHz_HSI
  58. uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSI; /* System Clock Frequency (Core Clock) */
  59. #else
  60. uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */
  61. #endif
  62. __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
  63. /* system_private_function_proto_types */
  64. static void SetSysClock(void);
  65. #ifdef SYSCLK_FREQ_HSE
  66. static void SetSysClockToHSE( void );
  67. #elif defined SYSCLK_FREQ_48MHz_HSE
  68. static void SetSysClockTo48_HSE( void );
  69. #elif defined SYSCLK_FREQ_56MHz_HSE
  70. static void SetSysClockTo56_HSE( void );
  71. #elif defined SYSCLK_FREQ_72MHz_HSE
  72. static void SetSysClockTo72_HSE( void );
  73. #elif defined SYSCLK_FREQ_96MHz_HSE
  74. static void SetSysClockTo96_HSE( void );
  75. #elif defined SYSCLK_FREQ_120MHz_HSE
  76. static void SetSysClockTo120_HSE( void );
  77. #elif defined SYSCLK_FREQ_144MHz_HSE
  78. static void SetSysClockTo144_HSE( void );
  79. #elif defined SYSCLK_FREQ_48MHz_HSI
  80. static void SetSysClockTo48_HSI( void );
  81. #elif defined SYSCLK_FREQ_56MHz_HSI
  82. static void SetSysClockTo56_HSI( void );
  83. #elif defined SYSCLK_FREQ_72MHz_HSI
  84. static void SetSysClockTo72_HSI( void );
  85. #elif defined SYSCLK_FREQ_96MHz_HSI
  86. static void SetSysClockTo96_HSI( void );
  87. #elif defined SYSCLK_FREQ_120MHz_HSI
  88. static void SetSysClockTo120_HSI( void );
  89. #elif defined SYSCLK_FREQ_144MHz_HSI
  90. static void SetSysClockTo144_HSI( void );
  91. #endif
  92. /*********************************************************************
  93. * @fn SystemInit
  94. *
  95. * @brief Setup the microcontroller system Initialize the Embedded Flash Interface,
  96. * the PLL and update the SystemCoreClock variable.
  97. *
  98. * @return none
  99. */
  100. void SystemInit (void)
  101. {
  102. RCC->CTLR |= (uint32_t)0x00000001;
  103. RCC->CFGR0 &= (uint32_t)0xF8FF0000;
  104. RCC->CTLR &= (uint32_t)0xFEF6FFFF;
  105. RCC->CTLR &= (uint32_t)0xFFFBFFFF;
  106. RCC->CFGR0 &= (uint32_t)0xFF80FFFF;
  107. RCC->INTR = 0x009F0000;
  108. SetSysClock();
  109. }
  110. /*********************************************************************
  111. * @fn SystemCoreClockUpdate
  112. *
  113. * @brief Update SystemCoreClock variable according to Clock Register Values.
  114. *
  115. * @return none
  116. */
  117. void SystemCoreClockUpdate (void)
  118. {
  119. uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0;
  120. tmp = RCC->CFGR0 & RCC_SWS;
  121. switch (tmp)
  122. {
  123. case 0x00:
  124. SystemCoreClock = HSI_VALUE;
  125. break;
  126. case 0x04:
  127. SystemCoreClock = HSE_VALUE;
  128. break;
  129. case 0x08:
  130. pllmull = RCC->CFGR0 & RCC_PLLMULL;
  131. pllsource = RCC->CFGR0 & RCC_PLLSRC;
  132. pllmull = ( pllmull >> 18) + 2;
  133. if(pllmull == 17) pllmull = 18;
  134. if (pllsource == 0x00)
  135. {
  136. if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE){
  137. SystemCoreClock = HSI_VALUE * pllmull;
  138. }
  139. else{
  140. SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
  141. }
  142. }
  143. else
  144. {
  145. #if defined (CH32V20x_D8W)
  146. if((RCC->CFGR0 & (3<<22)) == (3<<22))
  147. {
  148. SystemCoreClock = ((HSE_VALUE>>1)) * pllmull;
  149. }
  150. else
  151. #endif
  152. if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET)
  153. {
  154. #if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
  155. SystemCoreClock = ((HSE_VALUE>>2) >> 1) * pllmull;
  156. #else
  157. SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
  158. #endif
  159. }
  160. else
  161. {
  162. #if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
  163. SystemCoreClock = (HSE_VALUE>>2) * pllmull;
  164. #else
  165. SystemCoreClock = HSE_VALUE * pllmull;
  166. #endif
  167. }
  168. }
  169. if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2);
  170. break;
  171. default:
  172. SystemCoreClock = HSI_VALUE;
  173. break;
  174. }
  175. tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)];
  176. SystemCoreClock >>= tmp;
  177. }
  178. /*********************************************************************
  179. * @fn SetSysClock
  180. *
  181. * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
  182. *
  183. * @return none
  184. */
  185. static void SetSysClock(void)
  186. {
  187. #ifdef SYSCLK_FREQ_HSE
  188. SetSysClockToHSE();
  189. #elif defined SYSCLK_FREQ_48MHz_HSE
  190. SetSysClockTo48_HSE();
  191. #elif defined SYSCLK_FREQ_56MHz_HSE
  192. SetSysClockTo56_HSE();
  193. #elif defined SYSCLK_FREQ_72MHz_HSE
  194. SetSysClockTo72_HSE();
  195. #elif defined SYSCLK_FREQ_96MHz_HSE
  196. SetSysClockTo96_HSE();
  197. #elif defined SYSCLK_FREQ_120MHz_HSE
  198. SetSysClockTo120_HSE();
  199. #elif defined SYSCLK_FREQ_144MHz_HSE
  200. SetSysClockTo144_HSE();
  201. #elif defined SYSCLK_FREQ_48MHz_HSI
  202. SetSysClockTo48_HSI();
  203. #elif defined SYSCLK_FREQ_56MHz_HSI
  204. SetSysClockTo56_HSI();
  205. #elif defined SYSCLK_FREQ_72MHz_HSI
  206. SetSysClockTo72_HSI();
  207. #elif defined SYSCLK_FREQ_96MHz_HSI
  208. SetSysClockTo96_HSI();
  209. #elif defined SYSCLK_FREQ_120MHz_HSI
  210. SetSysClockTo120_HSI();
  211. #elif defined SYSCLK_FREQ_144MHz_HSI
  212. SetSysClockTo144_HSI();
  213. #endif
  214. /* If none of the define above is enabled, the HSI is used as System clock
  215. * source (default after reset)
  216. */
  217. }
  218. #ifdef SYSCLK_FREQ_HSE
  219. /*********************************************************************
  220. * @fn SetSysClockToHSE
  221. *
  222. * @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers.
  223. *
  224. * @return none
  225. */
  226. static void SetSysClockToHSE(void)
  227. {
  228. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  229. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  230. /* Wait till HSE is ready and if Time out is reached exit */
  231. do
  232. {
  233. HSEStatus = RCC->CTLR & RCC_HSERDY;
  234. StartUpCounter++;
  235. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  236. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  237. {
  238. HSEStatus = (uint32_t)0x01;
  239. }
  240. else
  241. {
  242. HSEStatus = (uint32_t)0x00;
  243. }
  244. if (HSEStatus == (uint32_t)0x01)
  245. {
  246. /* HCLK = SYSCLK */
  247. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  248. /* PCLK2 = HCLK */
  249. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  250. /* PCLK1 = HCLK */
  251. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
  252. /* Select HSE as system clock source */
  253. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  254. RCC->CFGR0 |= (uint32_t)RCC_SW_HSE;
  255. /* Wait till HSE is used as system clock source */
  256. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04)
  257. {
  258. }
  259. }
  260. else
  261. {
  262. /* If HSE fails to start-up, the application will have wrong clock
  263. * configuration. User can add here some code to deal with this error
  264. */
  265. }
  266. }
  267. #elif defined SYSCLK_FREQ_48MHz_HSE
  268. /*********************************************************************
  269. * @fn SetSysClockTo48_HSE
  270. *
  271. * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  272. *
  273. * @return none
  274. */
  275. static void SetSysClockTo48_HSE(void)
  276. {
  277. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  278. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  279. /* Wait till HSE is ready and if Time out is reached exit */
  280. do
  281. {
  282. HSEStatus = RCC->CTLR & RCC_HSERDY;
  283. StartUpCounter++;
  284. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  285. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  286. {
  287. HSEStatus = (uint32_t)0x01;
  288. }
  289. else
  290. {
  291. HSEStatus = (uint32_t)0x00;
  292. }
  293. if (HSEStatus == (uint32_t)0x01)
  294. {
  295. /* HCLK = SYSCLK */
  296. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  297. /* PCLK2 = HCLK */
  298. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  299. /* PCLK1 = HCLK */
  300. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  301. /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */
  302. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
  303. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6);
  304. /* Enable PLL */
  305. RCC->CTLR |= RCC_PLLON;
  306. /* Wait till PLL is ready */
  307. while((RCC->CTLR & RCC_PLLRDY) == 0)
  308. {
  309. }
  310. /* Select PLL as system clock source */
  311. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  312. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  313. /* Wait till PLL is used as system clock source */
  314. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  315. {
  316. }
  317. }
  318. else
  319. {
  320. /*
  321. * If HSE fails to start-up, the application will have wrong clock
  322. * configuration. User can add here some code to deal with this error
  323. */
  324. }
  325. }
  326. #elif defined SYSCLK_FREQ_56MHz_HSE
  327. /*********************************************************************
  328. * @fn SetSysClockTo56_HSE
  329. *
  330. * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  331. *
  332. * @return none
  333. */
  334. static void SetSysClockTo56_HSE(void)
  335. {
  336. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  337. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  338. /* Wait till HSE is ready and if Time out is reached exit */
  339. do
  340. {
  341. HSEStatus = RCC->CTLR & RCC_HSERDY;
  342. StartUpCounter++;
  343. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  344. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  345. {
  346. HSEStatus = (uint32_t)0x01;
  347. }
  348. else
  349. {
  350. HSEStatus = (uint32_t)0x00;
  351. }
  352. if (HSEStatus == (uint32_t)0x01)
  353. {
  354. /* HCLK = SYSCLK */
  355. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  356. /* PCLK2 = HCLK */
  357. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  358. /* PCLK1 = HCLK */
  359. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  360. /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */
  361. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
  362. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7);
  363. /* Enable PLL */
  364. RCC->CTLR |= RCC_PLLON;
  365. /* Wait till PLL is ready */
  366. while((RCC->CTLR & RCC_PLLRDY) == 0)
  367. {
  368. }
  369. /* Select PLL as system clock source */
  370. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  371. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  372. /* Wait till PLL is used as system clock source */
  373. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  374. {
  375. }
  376. }
  377. else
  378. {
  379. /*
  380. * If HSE fails to start-up, the application will have wrong clock
  381. * configuration. User can add here some code to deal with this error
  382. */
  383. }
  384. }
  385. #elif defined SYSCLK_FREQ_72MHz_HSE
  386. /*********************************************************************
  387. * @fn SetSysClockTo72_HSE
  388. *
  389. * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  390. *
  391. * @return none
  392. */
  393. static void SetSysClockTo72_HSE(void)
  394. {
  395. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  396. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  397. /* Wait till HSE is ready and if Time out is reached exit */
  398. do
  399. {
  400. HSEStatus = RCC->CTLR & RCC_HSERDY;
  401. StartUpCounter++;
  402. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  403. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  404. {
  405. HSEStatus = (uint32_t)0x01;
  406. }
  407. else
  408. {
  409. HSEStatus = (uint32_t)0x00;
  410. }
  411. if (HSEStatus == (uint32_t)0x01)
  412. {
  413. /* HCLK = SYSCLK */
  414. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  415. /* PCLK2 = HCLK */
  416. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  417. /* PCLK1 = HCLK */
  418. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  419. /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
  420. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
  421. RCC_PLLMULL));
  422. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9);
  423. /* Enable PLL */
  424. RCC->CTLR |= RCC_PLLON;
  425. /* Wait till PLL is ready */
  426. while((RCC->CTLR & RCC_PLLRDY) == 0)
  427. {
  428. }
  429. /* Select PLL as system clock source */
  430. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  431. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  432. /* Wait till PLL is used as system clock source */
  433. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  434. {
  435. }
  436. }
  437. else
  438. {
  439. /*
  440. * If HSE fails to start-up, the application will have wrong clock
  441. * configuration. User can add here some code to deal with this error
  442. */
  443. }
  444. }
  445. #elif defined SYSCLK_FREQ_96MHz_HSE
  446. /*********************************************************************
  447. * @fn SetSysClockTo96_HSE
  448. *
  449. * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  450. *
  451. * @return none
  452. */
  453. static void SetSysClockTo96_HSE(void)
  454. {
  455. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  456. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  457. /* Wait till HSE is ready and if Time out is reached exit */
  458. do
  459. {
  460. HSEStatus = RCC->CTLR & RCC_HSERDY;
  461. StartUpCounter++;
  462. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  463. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  464. {
  465. HSEStatus = (uint32_t)0x01;
  466. }
  467. else
  468. {
  469. HSEStatus = (uint32_t)0x00;
  470. }
  471. if (HSEStatus == (uint32_t)0x01)
  472. {
  473. /* HCLK = SYSCLK */
  474. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  475. /* PCLK2 = HCLK */
  476. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  477. /* PCLK1 = HCLK */
  478. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  479. /* PLL configuration: PLLCLK = HSE * 12 = 96 MHz */
  480. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
  481. RCC_PLLMULL));
  482. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12);
  483. /* Enable PLL */
  484. RCC->CTLR |= RCC_PLLON;
  485. /* Wait till PLL is ready */
  486. while((RCC->CTLR & RCC_PLLRDY) == 0)
  487. {
  488. }
  489. /* Select PLL as system clock source */
  490. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  491. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  492. /* Wait till PLL is used as system clock source */
  493. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  494. {
  495. }
  496. }
  497. else
  498. {
  499. /*
  500. * If HSE fails to start-up, the application will have wrong clock
  501. * configuration. User can add here some code to deal with this error
  502. */
  503. }
  504. }
  505. #elif defined SYSCLK_FREQ_120MHz_HSE
  506. /*********************************************************************
  507. * @fn SetSysClockTo120_HSE
  508. *
  509. * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  510. *
  511. * @return none
  512. */
  513. static void SetSysClockTo120_HSE(void)
  514. {
  515. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  516. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  517. /* Wait till HSE is ready and if Time out is reached exit */
  518. do
  519. {
  520. HSEStatus = RCC->CTLR & RCC_HSERDY;
  521. StartUpCounter++;
  522. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  523. if((RCC->CTLR & RCC_HSERDY) != RESET)
  524. {
  525. HSEStatus = (uint32_t)0x01;
  526. }
  527. else
  528. {
  529. HSEStatus = (uint32_t)0x00;
  530. }
  531. if(HSEStatus == (uint32_t)0x01)
  532. {
  533. #if defined (CH32V20x_D8W)
  534. RCC->CFGR0 |= (uint32_t)(3<<22);
  535. /* HCLK = SYSCLK/2 */
  536. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2;
  537. #else
  538. /* HCLK = SYSCLK */
  539. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  540. #endif
  541. /* PCLK2 = HCLK */
  542. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  543. /* PCLK1 = HCLK */
  544. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  545. /* PLL configuration: PLLCLK = HSE * 15 = 120 MHz */
  546. RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
  547. RCC_PLLMULL));
  548. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15);
  549. /* Enable PLL */
  550. RCC->CTLR |= RCC_PLLON;
  551. /* Wait till PLL is ready */
  552. while((RCC->CTLR & RCC_PLLRDY) == 0)
  553. {
  554. }
  555. /* Select PLL as system clock source */
  556. RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
  557. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  558. /* Wait till PLL is used as system clock source */
  559. while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  560. {
  561. }
  562. }
  563. else
  564. {
  565. /*
  566. * If HSE fails to start-up, the application will have wrong clock
  567. * configuration. User can add here some code to deal with this error
  568. */
  569. }
  570. }
  571. #elif defined SYSCLK_FREQ_144MHz_HSE
  572. /*********************************************************************
  573. * @fn SetSysClockTo144_HSE
  574. *
  575. * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  576. *
  577. * @return none
  578. */
  579. static void SetSysClockTo144_HSE(void)
  580. {
  581. __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  582. RCC->CTLR |= ((uint32_t)RCC_HSEON);
  583. /* Wait till HSE is ready and if Time out is reached exit */
  584. do
  585. {
  586. HSEStatus = RCC->CTLR & RCC_HSERDY;
  587. StartUpCounter++;
  588. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
  589. if ((RCC->CTLR & RCC_HSERDY) != RESET)
  590. {
  591. HSEStatus = (uint32_t)0x01;
  592. }
  593. else
  594. {
  595. HSEStatus = (uint32_t)0x00;
  596. }
  597. if (HSEStatus == (uint32_t)0x01)
  598. {
  599. /* HCLK = SYSCLK */
  600. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  601. /* PCLK2 = HCLK */
  602. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  603. /* PCLK1 = HCLK */
  604. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  605. /* PLL configuration: PLLCLK = HSE * 18 = 144 MHz */
  606. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
  607. RCC_PLLMULL));
  608. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18);
  609. /* Enable PLL */
  610. RCC->CTLR |= RCC_PLLON;
  611. /* Wait till PLL is ready */
  612. while((RCC->CTLR & RCC_PLLRDY) == 0)
  613. {
  614. }
  615. /* Select PLL as system clock source */
  616. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  617. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  618. /* Wait till PLL is used as system clock source */
  619. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  620. {
  621. }
  622. }
  623. else
  624. {
  625. /*
  626. * If HSE fails to start-up, the application will have wrong clock
  627. * configuration. User can add here some code to deal with this error
  628. */
  629. }
  630. }
  631. #elif defined SYSCLK_FREQ_48MHz_HSI
  632. /*********************************************************************
  633. * @fn SetSysClockTo48_HSI
  634. *
  635. * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  636. *
  637. * @return none
  638. */
  639. static void SetSysClockTo48_HSI(void)
  640. {
  641. EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
  642. /* HCLK = SYSCLK */
  643. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  644. /* PCLK2 = HCLK */
  645. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  646. /* PCLK1 = HCLK */
  647. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  648. /* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */
  649. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
  650. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6);
  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. #elif defined SYSCLK_FREQ_56MHz_HSI
  666. /*********************************************************************
  667. * @fn SetSysClockTo56_HSI
  668. *
  669. * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  670. *
  671. * @return none
  672. */
  673. static void SetSysClockTo56_HSI(void)
  674. {
  675. EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
  676. /* HCLK = SYSCLK */
  677. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  678. /* PCLK2 = HCLK */
  679. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  680. /* PCLK1 = HCLK */
  681. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  682. /* PLL configuration: PLLCLK = HSI * 7 = 48 MHz */
  683. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
  684. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7);
  685. /* Enable PLL */
  686. RCC->CTLR |= RCC_PLLON;
  687. /* Wait till PLL is ready */
  688. while((RCC->CTLR & RCC_PLLRDY) == 0)
  689. {
  690. }
  691. /* Select PLL as system clock source */
  692. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  693. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  694. /* Wait till PLL is used as system clock source */
  695. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  696. {
  697. }
  698. }
  699. #elif defined SYSCLK_FREQ_72MHz_HSI
  700. /*********************************************************************
  701. * @fn SetSysClockTo72_HSI
  702. *
  703. * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  704. *
  705. * @return none
  706. */
  707. static void SetSysClockTo72_HSI(void)
  708. {
  709. EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
  710. /* HCLK = SYSCLK */
  711. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  712. /* PCLK2 = HCLK */
  713. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  714. /* PCLK1 = HCLK */
  715. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  716. /* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */
  717. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
  718. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9);
  719. /* Enable PLL */
  720. RCC->CTLR |= RCC_PLLON;
  721. /* Wait till PLL is ready */
  722. while((RCC->CTLR & RCC_PLLRDY) == 0)
  723. {
  724. }
  725. /* Select PLL as system clock source */
  726. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  727. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  728. /* Wait till PLL is used as system clock source */
  729. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  730. {
  731. }
  732. }
  733. #elif defined SYSCLK_FREQ_96MHz_HSI
  734. /*********************************************************************
  735. * @fn SetSysClockTo96_HSI
  736. *
  737. * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  738. *
  739. * @return none
  740. */
  741. static void SetSysClockTo96_HSI(void)
  742. {
  743. EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
  744. /* HCLK = SYSCLK */
  745. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  746. /* PCLK2 = HCLK */
  747. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  748. /* PCLK1 = HCLK */
  749. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  750. /* PLL configuration: PLLCLK = HSI * 12 = 96 MHz */
  751. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
  752. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12);
  753. /* Enable PLL */
  754. RCC->CTLR |= RCC_PLLON;
  755. /* Wait till PLL is ready */
  756. while((RCC->CTLR & RCC_PLLRDY) == 0)
  757. {
  758. }
  759. /* Select PLL as system clock source */
  760. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  761. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  762. /* Wait till PLL is used as system clock source */
  763. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  764. {
  765. }
  766. }
  767. #elif defined SYSCLK_FREQ_120MHz_HSI
  768. /*********************************************************************
  769. * @fn SetSysClockTo120_HSI
  770. *
  771. * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  772. *
  773. * @return none
  774. */
  775. static void SetSysClockTo120_HSI(void)
  776. {
  777. EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
  778. /* HCLK = SYSCLK */
  779. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  780. /* PCLK2 = HCLK */
  781. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  782. /* PCLK1 = HCLK */
  783. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  784. /* PLL configuration: PLLCLK = HSI * 15 = 120 MHz */
  785. RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
  786. RCC_PLLMULL));
  787. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15);
  788. /* Enable PLL */
  789. RCC->CTLR |= RCC_PLLON;
  790. /* Wait till PLL is ready */
  791. while((RCC->CTLR & RCC_PLLRDY) == 0)
  792. {
  793. }
  794. /* Select PLL as system clock source */
  795. RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
  796. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  797. /* Wait till PLL is used as system clock source */
  798. while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  799. {
  800. }
  801. }
  802. #elif defined SYSCLK_FREQ_144MHz_HSI
  803. /*********************************************************************
  804. * @fn SetSysClockTo144_HSI
  805. *
  806. * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
  807. *
  808. * @return none
  809. */
  810. static void SetSysClockTo144_HSI(void)
  811. {
  812. EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
  813. /* HCLK = SYSCLK */
  814. RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
  815. /* PCLK2 = HCLK */
  816. RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
  817. /* PCLK1 = HCLK */
  818. RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
  819. /* PLL configuration: PLLCLK = HSI * 18 = 144 MHz */
  820. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
  821. RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18);
  822. /* Enable PLL */
  823. RCC->CTLR |= RCC_PLLON;
  824. /* Wait till PLL is ready */
  825. while((RCC->CTLR & RCC_PLLRDY) == 0)
  826. {
  827. }
  828. /* Select PLL as system clock source */
  829. RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
  830. RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
  831. /* Wait till PLL is used as system clock source */
  832. while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
  833. {
  834. }
  835. }
  836. #endif