drv_clk.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-08-20 breo.com first version
  9. */
  10. #include "drv_clk.h"
  11. #include "board.h"
  12. void DumpClock(const char *msg)
  13. {
  14. RCC_ClocksType RCC_ClockFreq;
  15. rt_kprintf("--------------------------------\n");
  16. rt_kprintf("%s:\n", msg);
  17. RCC_GetClocksFreqValue(&RCC_ClockFreq);
  18. rt_kprintf("SYSCLK: %d\n", RCC_ClockFreq.SysclkFreq);
  19. rt_kprintf("HCLK: %d\n", RCC_ClockFreq.HclkFreq);
  20. rt_kprintf("PCLK1: %d\n", RCC_ClockFreq.Pclk1Freq);
  21. rt_kprintf("PCLK2: %d\n", RCC_ClockFreq.Pclk2Freq);
  22. }
  23. void SetSysClockToHSI(void)
  24. {
  25. RCC_DeInit();
  26. RCC_EnableHsi(ENABLE);
  27. /* Enable Prefetch Buffer */
  28. FLASH_PrefetchBufSet(FLASH_PrefetchBuf_EN);
  29. /* Flash 0 wait state */
  30. FLASH_SetLatency(FLASH_LATENCY_0);
  31. /* HCLK = SYSCLK */
  32. RCC_ConfigHclk(RCC_SYSCLK_DIV1);
  33. /* PCLK2 = HCLK */
  34. RCC_ConfigPclk2(RCC_HCLK_DIV1);
  35. /* PCLK1 = HCLK */
  36. RCC_ConfigPclk1(RCC_HCLK_DIV1);
  37. /* Select HSE as system clock source */
  38. RCC_ConfigSysclk(RCC_SYSCLK_SRC_HSI);
  39. /* Wait till PLL is used as system clock source */
  40. while (RCC_GetSysclkSrc() != 0x00)
  41. {
  42. }
  43. }
  44. /**
  45. * @brief Selects HSE as System clock source and configure HCLK, PCLK2
  46. * and PCLK1 prescalers.
  47. */
  48. void SetSysClockToHSE(void)
  49. {
  50. ErrorStatus HSEStartUpStatus;
  51. /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration
  52. * -----------------------------*/
  53. /* RCC system reset(for debug purpose) */
  54. RCC_DeInit();
  55. /* Enable HSE */
  56. RCC_ConfigHse(RCC_HSE_ENABLE);
  57. /* Wait till HSE is ready */
  58. HSEStartUpStatus = RCC_WaitHseStable();
  59. if (HSEStartUpStatus == SUCCESS)
  60. {
  61. /* Enable Prefetch Buffer */
  62. FLASH_PrefetchBufSet(FLASH_PrefetchBuf_EN);
  63. if (HSE_Value <= 32000000)
  64. {
  65. /* Flash 0 wait state */
  66. FLASH_SetLatency(FLASH_LATENCY_0);
  67. }
  68. else
  69. {
  70. /* Flash 1 wait state */
  71. FLASH_SetLatency(FLASH_LATENCY_1);
  72. }
  73. /* HCLK = SYSCLK */
  74. RCC_ConfigHclk(RCC_SYSCLK_DIV1);
  75. /* PCLK2 = HCLK */
  76. RCC_ConfigPclk2(RCC_HCLK_DIV1);
  77. /* PCLK1 = HCLK */
  78. RCC_ConfigPclk1(RCC_HCLK_DIV1);
  79. /* Select HSE as system clock source */
  80. RCC_ConfigSysclk(RCC_SYSCLK_SRC_HSE);
  81. /* Wait till HSE is used as system clock source */
  82. while (RCC_GetSysclkSrc() != 0x04)
  83. {
  84. }
  85. }
  86. else
  87. {
  88. /* If HSE fails to start-up, the application will have wrong clock
  89. configuration. User can add here some code to deal with this error */
  90. /* Go to infinite loop */
  91. while (1)
  92. {
  93. }
  94. }
  95. }
  96. void SetSysClockToPLL(uint32_t freq, uint8_t src)
  97. {
  98. uint32_t pllsrc = (src == SYSCLK_PLLSRC_HSI ? RCC_PLL_SRC_HSI_DIV2 : RCC_PLL_SRC_HSE_DIV2);
  99. uint32_t pllmul;
  100. uint32_t latency;
  101. uint32_t pclk1div, pclk2div;
  102. ErrorStatus HSEStartUpStatus;
  103. if (HSE_VALUE != 8000000)
  104. {
  105. /* HSE_VALUE == 8000000 is needed in this project! */
  106. while (1)
  107. ;
  108. }
  109. /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration
  110. * -----------------------------*/
  111. /* RCC system reset(for debug purpose) */
  112. RCC_DeInit();
  113. if (src == SYSCLK_PLLSRC_HSE)
  114. {
  115. /* Enable HSE */
  116. RCC_ConfigHse(RCC_HSE_ENABLE);
  117. /* Wait till HSE is ready */
  118. HSEStartUpStatus = RCC_WaitHseStable();
  119. if (HSEStartUpStatus != SUCCESS)
  120. {
  121. /* If HSE fails to start-up, the application will have wrong clock
  122. configuration. User can add here some code to deal with this
  123. error */
  124. /* Go to infinite loop */
  125. while (1)
  126. ;
  127. }
  128. }
  129. switch (freq)
  130. {
  131. case 24000000:
  132. latency = FLASH_LATENCY_0;
  133. pllmul = RCC_PLL_MUL_6;
  134. pclk1div = RCC_HCLK_DIV1;
  135. pclk2div = RCC_HCLK_DIV1;
  136. break;
  137. case 36000000:
  138. latency = FLASH_LATENCY_1;
  139. pllmul = RCC_PLL_MUL_9;
  140. pclk1div = RCC_HCLK_DIV1;
  141. pclk2div = RCC_HCLK_DIV1;
  142. break;
  143. case 48000000:
  144. latency = FLASH_LATENCY_1;
  145. pllmul = RCC_PLL_MUL_12;
  146. pclk1div = RCC_HCLK_DIV2;
  147. pclk2div = RCC_HCLK_DIV1;
  148. break;
  149. case 56000000:
  150. latency = FLASH_LATENCY_1;
  151. pllmul = RCC_PLL_MUL_14;
  152. pclk1div = RCC_HCLK_DIV2;
  153. pclk2div = RCC_HCLK_DIV1;
  154. break;
  155. case 72000000:
  156. latency = FLASH_LATENCY_2;
  157. pllmul = RCC_PLL_MUL_18;
  158. pclk1div = RCC_HCLK_DIV2;
  159. pclk2div = RCC_HCLK_DIV1;
  160. break;
  161. case 96000000:
  162. latency = FLASH_LATENCY_2;
  163. pllmul = RCC_PLL_MUL_24;
  164. pclk1div = RCC_HCLK_DIV4;
  165. pclk2div = RCC_HCLK_DIV2;
  166. break;
  167. case 128000000:
  168. latency = FLASH_LATENCY_3;
  169. pllmul = RCC_PLL_MUL_32;
  170. pclk1div = RCC_HCLK_DIV4;
  171. pclk2div = RCC_HCLK_DIV2;
  172. break;
  173. case 144000000:
  174. /* must use HSE as PLL source */
  175. latency = FLASH_LATENCY_4;
  176. pllsrc = RCC_PLL_SRC_HSE_DIV1;
  177. pllmul = RCC_PLL_MUL_18;
  178. pclk1div = RCC_HCLK_DIV4;
  179. pclk2div = RCC_HCLK_DIV2;
  180. break;
  181. default:
  182. while (1)
  183. ;
  184. }
  185. FLASH_SetLatency(latency);
  186. /* HCLK = SYSCLK */
  187. RCC_ConfigHclk(RCC_SYSCLK_DIV1);
  188. /* PCLK2 = HCLK */
  189. RCC_ConfigPclk2(pclk2div);
  190. /* PCLK1 = HCLK */
  191. RCC_ConfigPclk1(pclk1div);
  192. RCC_ConfigPll(pllsrc, pllmul);
  193. /* Enable PLL */
  194. RCC_EnablePll(ENABLE);
  195. /* Wait till PLL is ready */
  196. while (RCC_GetFlagStatus(RCC_FLAG_PLLRD) == RESET)
  197. ;
  198. /* Select PLL as system clock source */
  199. RCC_ConfigSysclk(RCC_SYSCLK_SRC_PLLCLK);
  200. /* Wait till PLL is used as system clock source */
  201. while (RCC_GetSysclkSrc() != 0x08)
  202. ;
  203. }