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