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 * 2009-01-05 Bernard first implementation
9 */
10
11 #include <board.h>
12 #include <drv_common.h>
13
SystemClock_Config(void)14 void SystemClock_Config(void)
15 {
16 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
17 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
18 RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
19
20 /**Configure LSE Drive Capability
21 */
22 HAL_PWR_EnableBkUpAccess();
23 __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
24 /**Initializes the CPU, AHB and APB busses clocks
25 */
26 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_LSE
27 |RCC_OSCILLATORTYPE_MSI;
28 RCC_OscInitStruct.LSEState = RCC_LSE_ON;
29 RCC_OscInitStruct.LSIState = RCC_LSI_ON;
30 RCC_OscInitStruct.MSIState = RCC_MSI_ON;
31 RCC_OscInitStruct.MSICalibrationValue = 0;
32 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
33 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
34 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
35 RCC_OscInitStruct.PLL.PLLM = 1;
36 RCC_OscInitStruct.PLL.PLLN = 40;
37 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
38 RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
39 RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
40 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
41 {
42 Error_Handler();
43 }
44 /**Initializes the CPU, AHB and APB busses clocks
45 */
46 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
47 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
48 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
49 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
50 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
51 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
52
53 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
54 {
55 Error_Handler();
56 }
57 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART2
58 |RCC_PERIPHCLK_USART3|RCC_PERIPHCLK_LPUART1
59 |RCC_PERIPHCLK_SDMMC1|RCC_PERIPHCLK_ADC;
60 PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
61 PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
62 PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
63 PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
64 PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
65 PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_PLLSAI1;
66 PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_MSI;
67 PeriphClkInit.PLLSAI1.PLLSAI1M = 1;
68 PeriphClkInit.PLLSAI1.PLLSAI1N = 16;
69 PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV2;
70 PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
71 PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
72 PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK|RCC_PLLSAI1_ADC1CLK;
73 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
74 {
75 Error_Handler();
76 }
77 /**Configure the main internal regulator output voltage
78 */
79 if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
80 {
81 Error_Handler();
82 }
83 }
84
85
86 #ifdef RT_USING_PM
87
SystemClock_MSI_ON(void)88 void SystemClock_MSI_ON(void)
89 {
90 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
91 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
92
93 /* Initializes the CPU, AHB and APB busses clocks */
94 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
95 RCC_OscInitStruct.MSIState = RCC_MSI_ON;
96 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
97 {
98 RT_ASSERT(0);
99 }
100
101 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
102 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
103 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
104 {
105 Error_Handler();
106 }
107 }
108
SystemClock_MSI_OFF(void)109 void SystemClock_MSI_OFF(void)
110 {
111 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
112
113 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
114 RCC_OscInitStruct.HSIState = RCC_MSI_OFF;
115 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; /* No update on PLL */
116 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
117 {
118 Error_Handler();
119 }
120 }
121
SystemClock_80M(void)122 void SystemClock_80M(void)
123 {
124 RCC_OscInitTypeDef RCC_OscInitStruct;
125 RCC_ClkInitTypeDef RCC_ClkInitStruct;
126
127 /**Initializes the CPU, AHB and APB busses clocks */
128 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
129 RCC_OscInitStruct.HSEState = RCC_HSE_ON;
130 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
131 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
132 RCC_OscInitStruct.PLL.PLLM = 1;
133 RCC_OscInitStruct.PLL.PLLN = 20;
134 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
135 RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
136 RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
137 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
138 {
139 Error_Handler();
140 }
141
142 /**Initializes the CPU, AHB and APB busses clocks
143 */
144 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
145 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
146 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
147 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
148 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
149 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
150
151 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
152 {
153 Error_Handler();
154 }
155 }
156
SystemClock_Config_fromSTOP(void)157 void SystemClock_Config_fromSTOP(void)
158 {
159 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
160 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
161 uint32_t pFLatency = 0;
162
163 /* Get the Oscillators & PLL configuration according to the internal RCC registers */
164 HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
165
166 /* Wake up on HSI, re-enable MSI and PLL with MSI as source */
167 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
168 RCC_OscInitStruct.MSIState = RCC_MSI_ON;
169 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
170 RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
171 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
172 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
173 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
174 {
175 Error_Handler();
176 }
177
178 /* Get the Clocks configuration according to the internal RCC registers */
179 HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
180
181 /* Select PLL as system clock source */
182 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
183 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
184 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK)
185 {
186 Error_Handler();
187 }
188 }
189
SystemClock_24M(void)190 void SystemClock_24M(void)
191 {
192 RCC_OscInitTypeDef RCC_OscInitStruct;
193 RCC_ClkInitTypeDef RCC_ClkInitStruct;
194
195 /** Initializes the CPU, AHB and APB busses clocks */
196 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
197 RCC_OscInitStruct.HSEState = RCC_HSE_ON;
198 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
199 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
200 RCC_OscInitStruct.PLL.PLLM = 1;
201 RCC_OscInitStruct.PLL.PLLN = 12;
202 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
203 RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
204 RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4;
205 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
206 {
207 Error_Handler();
208 }
209 /** Initializes the CPU, AHB and APB busses clocks */
210 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
211 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
212 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
213 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
214 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
215 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
216 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
217 {
218 Error_Handler();
219 }
220 }
221
SystemClock_2M(void)222 void SystemClock_2M(void)
223 {
224 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
225 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
226
227 /* MSI is enabled after System reset, update MSI to 2Mhz (RCC_MSIRANGE_5) */
228 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
229 RCC_OscInitStruct.MSIState = RCC_MSI_ON;
230 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
231 RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
232 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
233 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
234 {
235 /* Initialization Error */
236 Error_Handler();
237 }
238
239 /* Select MSI as system clock source and configure the HCLK, PCLK1 and PCLK2
240 clocks dividers */
241 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
242 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
243 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
244 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
245 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
246 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
247 {
248 /* Initialization Error */
249 Error_Handler();
250 }
251 }
252
253 /**
254 * @brief Configures system clock after wake-up from STOP: enable HSI, PLL
255 * and select PLL as system clock source.
256 * @param None
257 * @retval None
258 */
SystemClock_ReConfig(uint8_t mode)259 void SystemClock_ReConfig(uint8_t mode)
260 {
261 SystemClock_MSI_ON();
262
263 switch (mode)
264 {
265 case PM_RUN_MODE_HIGH_SPEED:
266 case PM_RUN_MODE_NORMAL_SPEED:
267 SystemClock_80M();
268 break;
269 case PM_RUN_MODE_MEDIUM_SPEED:
270 SystemClock_24M();
271 break;
272 case PM_RUN_MODE_LOW_SPEED:
273 SystemClock_2M();
274 break;
275 default:
276 break;
277 }
278
279 // SystemClock_MSI_OFF();
280 }
281
282 #endif
283