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-05-09     Zero-Free    Adding multiple configurations for system clock frequency
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_HSE
27                               |RCC_OSCILLATORTYPE_LSE;
28   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
29   RCC_OscInitStruct.LSEState = RCC_LSE_ON;
30   RCC_OscInitStruct.LSIState = RCC_LSI_ON;
31   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
32   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
33   RCC_OscInitStruct.PLL.PLLM = 1;
34   RCC_OscInitStruct.PLL.PLLN = 20;
35   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
36   RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
37   RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
38   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
39   {
40     Error_Handler();
41   }
42   /** Initializes the CPU, AHB and APB busses clocks
43   */
44   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
45                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
46   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
47   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
48   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
49   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
50 
51   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
52   {
53     Error_Handler();
54   }
55   PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART1
56                               |RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_USB
57                               |RCC_PERIPHCLK_ADC;
58   PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
59   PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
60   PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
61   PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
62   PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;
63   PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE;
64   PeriphClkInit.PLLSAI1.PLLSAI1M = 1;
65   PeriphClkInit.PLLSAI1.PLLSAI1N = 12;
66   PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7;
67   PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
68   PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
69   PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK|RCC_PLLSAI1_ADC1CLK;
70   if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
71   {
72     Error_Handler();
73   }
74   /** Configure the main internal regulator output voltage
75   */
76   if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
77   {
78     Error_Handler();
79   }
80 }
81 
82 #ifdef RT_USING_PM
83 
SystemClock_MSI_ON(void)84 void SystemClock_MSI_ON(void)
85 {
86     RCC_OscInitTypeDef RCC_OscInitStruct   = {0};
87     RCC_ClkInitTypeDef RCC_ClkInitStruct   = {0};
88 
89     /* Initializes the CPU, AHB and APB busses clocks */
90     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
91     RCC_OscInitStruct.MSIState = RCC_MSI_ON;
92     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
93     {
94         RT_ASSERT(0);
95     }
96 
97     RCC_ClkInitStruct.ClockType       = RCC_CLOCKTYPE_SYSCLK;
98     RCC_ClkInitStruct.SYSCLKSource    = RCC_SYSCLKSOURCE_MSI;
99     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
100     {
101         Error_Handler();
102     }
103 }
104 
SystemClock_MSI_OFF(void)105 void SystemClock_MSI_OFF(void)
106 {
107     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
108 
109     RCC_OscInitStruct.OscillatorType  = RCC_OSCILLATORTYPE_MSI;
110     RCC_OscInitStruct.HSIState        = RCC_MSI_OFF;
111     RCC_OscInitStruct.PLL.PLLState    = RCC_PLL_NONE;  /* No update on PLL */
112     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
113     {
114         Error_Handler();
115     }
116 }
117 
SystemClock_80M(void)118 void SystemClock_80M(void)
119 {
120     RCC_OscInitTypeDef RCC_OscInitStruct;
121     RCC_ClkInitTypeDef RCC_ClkInitStruct;
122 
123     /**Initializes the CPU, AHB and APB busses clocks */
124     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
125     RCC_OscInitStruct.HSEState = RCC_HSE_ON;
126     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
127     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
128     RCC_OscInitStruct.PLL.PLLM = 1;
129     RCC_OscInitStruct.PLL.PLLN = 20;
130     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
131     RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
132     RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
133     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
134     {
135         Error_Handler();
136     }
137 
138     /**Initializes the CPU, AHB and APB busses clocks
139     */
140     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
141                                   | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
142     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
143     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
144     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
145     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
146 
147     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
148     {
149         Error_Handler();
150     }
151 }
152 
SystemClock_24M(void)153 void SystemClock_24M(void)
154 {
155     RCC_OscInitTypeDef RCC_OscInitStruct;
156     RCC_ClkInitTypeDef RCC_ClkInitStruct;
157 
158     /** Initializes the CPU, AHB and APB busses clocks */
159     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
160     RCC_OscInitStruct.HSEState = RCC_HSE_ON;
161     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
162     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
163     RCC_OscInitStruct.PLL.PLLM = 1;
164     RCC_OscInitStruct.PLL.PLLN = 12;
165     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
166     RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
167     RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4;
168     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
169     {
170         Error_Handler();
171     }
172     /** Initializes the CPU, AHB and APB busses clocks */
173     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
174                                   | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
175     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
176     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
177     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
178     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
179     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
180     {
181         Error_Handler();
182     }
183 }
184 
SystemClock_2M(void)185 void SystemClock_2M(void)
186 {
187     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
188     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
189 
190     /* MSI is enabled after System reset, update MSI to 2Mhz (RCC_MSIRANGE_5) */
191     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
192     RCC_OscInitStruct.MSIState = RCC_MSI_ON;
193     RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
194     RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
195     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
196     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
197     {
198         /* Initialization Error */
199         Error_Handler();
200     }
201 
202     /* Select MSI as system clock source and configure the HCLK, PCLK1 and PCLK2
203        clocks dividers */
204     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
205     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
206     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
207     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
208     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
209     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
210     {
211         /* Initialization Error */
212         Error_Handler();
213     }
214 }
215 
216 /**
217   * @brief  Configures system clock after wake-up from STOP: enable HSI, PLL
218   *         and select PLL as system clock source.
219   * @param  None
220   * @retval None
221   */
SystemClock_ReConfig(uint8_t mode)222 void SystemClock_ReConfig(uint8_t mode)
223 {
224     SystemClock_MSI_ON();
225 
226     switch (mode)
227     {
228     case PM_RUN_MODE_HIGH_SPEED:
229     case PM_RUN_MODE_NORMAL_SPEED:
230         SystemClock_80M();
231         break;
232     case PM_RUN_MODE_MEDIUM_SPEED:
233         SystemClock_24M();
234         break;
235     case PM_RUN_MODE_LOW_SPEED:
236         SystemClock_2M();
237         break;
238     default:
239         break;
240     }
241 
242     // SystemClock_MSI_OFF();
243 }
244 
245 #endif /* RT_USING_PM */
246