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  * 2019-02-05     gw           first version
9  * 2019-05-05     Zero-Free    Adding multiple  configurations for system clock frequency
10  */
11 
12 #include <board.h>
13 #include <rtconfig.h>
14 #include <drv_common.h>
15 
SystemClock_Config(void)16 void SystemClock_Config(void)
17 {
18     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
19     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
20     RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
21 
22 #ifdef BSP_USING_ONCHIP_RTC
23     /**Configure LSE Drive Capability
24     */
25     HAL_PWR_EnableBkUpAccess();
26     __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
27 #endif
28     /**Initializes the CPU, AHB and APB busses clocks
29     */
30     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
31     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
32     RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
33     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
34     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
35     RCC_OscInitStruct.PLL.PLLM = 1;
36     RCC_OscInitStruct.PLL.PLLN = 10;
37     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
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_USART2;
58     PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
59     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
60     {
61         Error_Handler();
62     }
63     /**Configure the main internal regulator output voltage
64     */
65     if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
66     {
67         Error_Handler();
68     }
69 }
70 
71 #ifdef RT_USING_PM
72 
SystemClock_MSI_ON(void)73 void SystemClock_MSI_ON(void)
74 {
75     RCC_OscInitTypeDef RCC_OscInitStruct   = {0};
76     RCC_ClkInitTypeDef RCC_ClkInitStruct   = {0};
77 
78     /* Initializes the CPU, AHB and APB busses clocks */
79     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
80     RCC_OscInitStruct.MSIState = RCC_MSI_ON;
81     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
82     {
83         RT_ASSERT(0);
84     }
85 
86     RCC_ClkInitStruct.ClockType       = RCC_CLOCKTYPE_SYSCLK;
87     RCC_ClkInitStruct.SYSCLKSource    = RCC_SYSCLKSOURCE_MSI;
88     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
89     {
90         Error_Handler();
91     }
92 }
93 
SystemClock_MSI_OFF(void)94 void SystemClock_MSI_OFF(void)
95 {
96     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
97 
98     RCC_OscInitStruct.OscillatorType  = RCC_OSCILLATORTYPE_MSI;
99     RCC_OscInitStruct.HSIState        = RCC_MSI_OFF;
100     RCC_OscInitStruct.PLL.PLLState    = RCC_PLL_NONE;  /* No update on PLL */
101     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
102     {
103         Error_Handler();
104     }
105 }
106 
SystemClock_80M(void)107 void SystemClock_80M(void)
108 {
109     RCC_OscInitTypeDef RCC_OscInitStruct;
110     RCC_ClkInitTypeDef RCC_ClkInitStruct;
111 
112     /**Initializes the CPU, AHB and APB busses clocks */
113     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
114     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
115     RCC_OscInitStruct.HSICalibrationValue = 16;
116     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
117     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
118     RCC_OscInitStruct.PLL.PLLM = 1;
119     RCC_OscInitStruct.PLL.PLLN = 10;
120     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
121     RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
122     RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
123     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
124     {
125         Error_Handler();
126     }
127 
128     /**Initializes the CPU, AHB and APB busses clocks
129     */
130     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
131                                   | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
132     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
133     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
134     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
135     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
136 
137     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
138     {
139         Error_Handler();
140     }
141 }
142 
SystemClock_24M(void)143 void SystemClock_24M(void)
144 {
145     RCC_OscInitTypeDef RCC_OscInitStruct;
146     RCC_ClkInitTypeDef RCC_ClkInitStruct;
147     RCC_PeriphCLKInitTypeDef PeriphClkInit;
148 
149     /** Initializes the CPU, AHB and APB busses clocks */
150     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
151     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
152     RCC_OscInitStruct.HSICalibrationValue = 16;
153     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
154     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
155     RCC_OscInitStruct.PLL.PLLM = 1;
156     RCC_OscInitStruct.PLL.PLLN = 12;
157     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
158     RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
159     RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV8;
160     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
161     {
162         Error_Handler();
163     }
164     /** Initializes the CPU, AHB and APB busses clocks */
165     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
166                                   | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
167     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
168     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
169     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
170     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
171     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
172     {
173         Error_Handler();
174     }
175     PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
176     PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
177     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
178     {
179         Error_Handler();
180     }
181 }
182 
SystemClock_2M(void)183 void SystemClock_2M(void)
184 {
185     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
186     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
187 
188     /* MSI is enabled after System reset, update MSI to 2Mhz (RCC_MSIRANGE_5) */
189     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
190     RCC_OscInitStruct.MSIState = RCC_MSI_ON;
191     RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
192     RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
193     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
194     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
195     {
196         /* Initialization Error */
197         Error_Handler();
198     }
199 
200     /* Select MSI as system clock source and configure the HCLK, PCLK1 and PCLK2
201        clocks dividers */
202     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
203     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
204     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
205     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
206     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
207     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
208     {
209         /* Initialization Error */
210         Error_Handler();
211     }
212 }
213 
214 /**
215   * @brief  Configures system clock after wake-up from STOP: enable HSI, PLL
216   *         and select PLL as system clock source.
217   * @param  None
218   * @retval None
219   */
SystemClock_ReConfig(uint8_t mode)220 void SystemClock_ReConfig(uint8_t mode)
221 {
222     SystemClock_MSI_ON();
223 
224     switch (mode)
225     {
226     case PM_RUN_MODE_HIGH_SPEED:
227     case PM_RUN_MODE_NORMAL_SPEED:
228         SystemClock_80M();
229         break;
230     case PM_RUN_MODE_MEDIUM_SPEED:
231         SystemClock_24M();
232         break;
233     case PM_RUN_MODE_LOW_SPEED:
234         SystemClock_2M();
235         break;
236     default:
237         break;
238     }
239 
240     // SystemClock_MSI_OFF();
241 }
242 
243 #endif
244