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