1 /*!
2 * @file system_apm32f0xx.c
3 *
4 * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File
5 *
6 * @version V1.0.3
7 *
8 * @date 2022-09-20
9 *
10 * @attention
11 *
12 * Copyright (C) 2020-2022 Geehy Semiconductor
13 *
14 * You may not use this file except in compliance with the
15 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16 *
17 * The program is only for reference, which is distributed in the hope
18 * that it will be useful and instructional for customers to develop
19 * their software. Unless required by applicable law or agreed to in
20 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23 * and limitations under the License.
24 */
25
26 /* Includes */
27 #include "apm32f0xx.h"
28
29 /** @addtogroup CMSIS
30 @{
31 */
32
33 /** @addtogroup APM32F0xx_System
34 @{
35 */
36
37 /** @defgroup System_Macros Macros
38 @{
39 */
40
41 /* HSE is used as system clock source */
42 //#define SYSTEM_CLOCK_HSE HSE_VALUE
43
44 /* HSE (8MHz) used to clock the PLL, and the PLL is used as system clock source */
45 //#define SYSTEM_CLOCK_24MHz (24000000)
46 //#define SYSTEM_CLOCK_36MHz (36000000)
47 #define SYSTEM_CLOCK_48MHz (48000000)
48
49 //#define VECT_TAB_SRAM
50 /* Vector Table base offset field. This value must be a multiple of 0x200. */
51 #define VECT_TAB_OFFSET 0x00
52
53 /**@} end of group System_Macros */
54
55 /** @defgroup System_Enumerations Enumerations
56 @{
57 */
58
59 /**@} end of group System_Enumerations */
60
61 /** @defgroup System_Structures Structures
62 @{
63 */
64
65 /**@} end of group System_Structures */
66
67 /** @defgroup System_Variables Variables
68 @{
69 */
70
71 #ifdef SYSTEM_CLOCK_HSE
72 uint32_t SystemCoreClock = SYSTEM_CLOCK_HSE;
73 #elif defined SYSTEM_CLOCK_24MHz
74 uint32_t SystemCoreClock = SYSTEM_CLOCK_24MHz;
75 #elif defined SYSTEM_CLOCK_36MHz
76 uint32_t SystemCoreClock = SYSTEM_CLOCK_36MHz;
77 #elif defined SYSTEM_CLOCK_48MHz
78 uint32_t SystemCoreClock = SYSTEM_CLOCK_48MHz;
79 #else
80 uint32_t SystemCoreClock = HSI_VALUE;
81 #endif
82
83 static void SystemClockConfig(void);
84
85 #ifdef SYSTEM_CLOCK_HSE
86 static void SystemClockHSE(void);
87 #elif defined SYSTEM_CLOCK_24MHz
88 static void SystemClock24M(void);
89 #elif defined SYSTEM_CLOCK_36MHz
90 static void SystemClock36M(void);
91 #elif defined SYSTEM_CLOCK_48MHz
92 static void SystemClock48M(void);
93
94 #endif
95
96 /**@} end of group System_Variables */
97
98 /** @defgroup System_Functions Functions
99 @{
100 */
101
102 /*!
103 * @brief Setup the microcontroller system
104 *
105 * @param None
106 *
107 * @retval None
108 *
109 * @note
110 */
SystemInit(void)111 void SystemInit(void)
112 {
113 /* Set HSIEN bit */
114 RCM->CTRL1_B.HSIEN = BIT_SET;
115 /* Reset SCLKSEL, AHBPSC, APB1PSC, APB2PSC, ADCPSC and COC bits */
116 RCM->CFG1 &= (uint32_t)0x08FFB80CU;
117 /* Reset HSEEN, CSSEN and PLLEN bits */
118 RCM->CTRL1 &= (uint32_t)0xFEF6FFFFU;
119 /* Reset HSEBCFG bit */
120 RCM->CTRL1_B.HSEBCFG = BIT_RESET;
121 /* Reset PLLSRCSEL, PLLHSEPSC, PLLMULCFG bits */
122 RCM->CFG1 &= (uint32_t)0xFFC0FFFFU;
123 /* Reset PREDIV[3:0] bits */
124 RCM->CFG1 &= (uint32_t)0xFFFFFFF0U;
125 /* Reset USARTSW[1:0], I2CSW, CECSW and ADCSW bits */
126 RCM->CFG3 &= (uint32_t)0xFFFFFEAC;
127 /* Reset HSI14 bit */
128 RCM->CTRL2_B.HSI14EN = BIT_RESET;
129 /* Disable all interrupts */
130 RCM->INT = 0x00000000U;
131
132 SystemClockConfig();
133
134 #ifdef VECT_TAB_SRAM
135 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;
136 #else
137 SCB->VTOR = FMC_BASE | VECT_TAB_OFFSET;
138 #endif
139 }
140
141 /*!
142 * @brief Update SystemCoreClock variable according to Clock Register Values
143 * The SystemCoreClock variable contains the core clock (HCLK)
144 *
145 * @param None
146 *
147 * @retval None
148 *
149 * @note
150 */
SystemCoreClockUpdate(void)151 void SystemCoreClockUpdate(void)
152 {
153 uint32_t sysClock, pllMull, pllSource, Prescaler;
154 uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
155
156 /* Get SYSCLK source */
157 sysClock = RCM->CFG1_B.SCLKSWSTS;
158
159 switch (sysClock)
160 {
161 case 0:
162 SystemCoreClock = HSI_VALUE;
163 break;
164
165 /* sys clock is HSE */
166 case 1:
167 SystemCoreClock = HSE_VALUE;
168 break;
169
170 /* sys clock is PLL */
171 case 2:
172 pllMull = RCM->CFG1_B.PLLMULCFG + 2;
173 pllSource = RCM->CFG1_B.PLLSRCSEL;
174
175 /* PLL entry clock source is HSE */
176 if (pllSource == 2)
177 {
178 SystemCoreClock = HSE_VALUE * pllMull;
179
180 /* HSE clock divided by 2 */
181 if (pllSource == RCM->CFG1_B.PLLHSEPSC)
182 {
183 SystemCoreClock >>= 1;
184 }
185 }
186 /* PLL entry clock source is HSI/2 */
187 else
188 {
189 SystemCoreClock = (HSI_VALUE >> 1) * pllMull;
190 }
191
192 break;
193
194 default:
195 SystemCoreClock = HSI_VALUE;
196 break;
197 }
198
199 Prescaler = AHBPrescTable[(RCM->CFG1_B.AHBPSC)];
200 SystemCoreClock >>= Prescaler;
201 }
202 /*!
203 * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers
204 *
205 * @param None
206 *
207 * @retval None
208 *
209 * @note
210 */
SystemClockConfig(void)211 static void SystemClockConfig(void)
212 {
213 #ifdef SYSTEM_CLOCK_HSE
214 SystemClockHSE();
215 #elif defined SYSTEM_CLOCK_24MHz
216 SystemClock24M();
217 #elif defined SYSTEM_CLOCK_36MHz
218 SystemClock36M();
219 #elif defined SYSTEM_CLOCK_48MHz
220 SystemClock48M();
221 #endif
222 }
223
224 #if defined SYSTEM_CLOCK_HSE
225
226 /*!
227 * @brief Selects HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers
228 *
229 * @param None
230 *
231 * @retval None
232 *
233 * @note
234 */
SystemClockHSE(void)235 static void SystemClockHSE(void)
236 {
237 uint32_t i;
238
239 RCM->CTRL1_B.HSEEN = BIT_SET;
240
241 for (i = 0; i < HSE_STARTUP_TIMEOUT; i++)
242 {
243 if (RCM->CTRL1_B.HSERDYFLG)
244 {
245 break;
246 }
247 }
248
249 if (RCM->CTRL1_B.HSERDYFLG)
250 {
251 /* Enable Prefetch Buffer */
252 FMC->CTRL1_B.PBEN = BIT_SET;
253 /* Flash 0 wait state */
254 FMC->CTRL1_B.WS = 0;
255
256 /* HCLK = SYSCLK */
257 RCM->CFG1_B.AHBPSC = 0X00;
258
259 /* PCLK = HCLK */
260 RCM->CFG1_B.APB1PSC = 0X00;
261
262 /* Select HSE as system clock source */
263 RCM->CFG1_B.SCLKSEL = 1;
264
265 /* Wait till HSE is used as system clock source */
266 while (RCM->CFG1_B.SCLKSWSTS != 0x01);
267 }
268 }
269
270 #elif defined SYSTEM_CLOCK_24MHz
271
272 /*!
273 * @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2 and PCLK1 prescalers
274 *
275 * @param None
276 *
277 * @retval None
278 *
279 * @note
280 */
SystemClock24M(void)281 static void SystemClock24M(void)
282 {
283 uint32_t i;
284
285 RCM->CTRL1_B.HSEEN = BIT_SET;
286
287 for (i = 0; i < HSE_STARTUP_TIMEOUT; i++)
288 {
289 if (RCM->CTRL1_B.HSERDYFLG)
290 {
291 break;
292 }
293 }
294
295 if (RCM->CTRL1_B.HSERDYFLG)
296 {
297 /* Enable Prefetch Buffer */
298 FMC->CTRL1_B.PBEN = BIT_SET;
299 /* Flash 1 wait state */
300 FMC->CTRL1_B.WS = 1;
301
302 /* HCLK = SYSCLK */
303 RCM->CFG1_B.AHBPSC = 0X00;
304
305 /* PCLK = HCLK */
306 RCM->CFG1_B.APB1PSC = 0X00;
307
308 /* PLL: (HSE / 2) * 6 */
309 RCM->CFG1_B.PLLSRCSEL = 2;
310 RCM->CFG1_B.PLLHSEPSC = 1;
311 RCM->CFG1_B.PLLMULCFG = 4;
312
313 /* Enable PLL */
314 RCM->CTRL1_B.PLLEN = 1;
315
316 /* Wait PLL Ready */
317 while (RCM->CTRL1_B.PLLRDYFLG == BIT_RESET);
318
319 /* Select PLL as system clock source */
320 RCM->CFG1_B.SCLKSEL = 2;
321
322 /* Wait till PLL is used as system clock source */
323 while (RCM->CFG1_B.SCLKSWSTS != 0x02);
324 }
325 }
326
327 #elif defined SYSTEM_CLOCK_36MHz
328
329 /*!
330 * @brief Sets System clock frequency to 36MHz and configure HCLK, PCLK2 and PCLK1 prescalers
331 *
332 * @param None
333 *
334 * @retval None
335 *
336 * @note
337 */
SystemClock36M(void)338 static void SystemClock36M(void)
339 {
340 uint32_t i;
341
342 RCM->CTRL1_B.HSEEN = BIT_SET;
343
344 for (i = 0; i < HSE_STARTUP_TIMEOUT; i++)
345 {
346 if (RCM->CTRL1_B.HSERDYFLG)
347 {
348 break;
349 }
350 }
351
352 if (RCM->CTRL1_B.HSERDYFLG)
353 {
354 /* Enable Prefetch Buffer */
355 FMC->CTRL1_B.PBEN = BIT_SET;
356 /* Flash 1 wait state */
357 FMC->CTRL1_B.WS = 1;
358
359 /* HCLK = SYSCLK */
360 RCM->CFG1_B.AHBPSC = 0X00;
361
362 /* PCLK = HCLK */
363 RCM->CFG1_B.APB1PSC = 0X00;
364
365 /* PLL: (HSE / 2) * 9 */
366 RCM->CFG1_B.PLLSRCSEL = 2;
367 RCM->CFG1_B.PLLHSEPSC = 1;
368 RCM->CFG1_B.PLLMULCFG = 7;
369
370 /* Enable PLL */
371 RCM->CTRL1_B.PLLEN = 1;
372
373 /* Wait PLL Ready */
374 while (RCM->CTRL1_B.PLLRDYFLG == BIT_RESET);
375
376 /* Select PLL as system clock source */
377 RCM->CFG1_B.SCLKSEL = 2;
378
379 /* Wait till PLL is used as system clock source */
380 while (RCM->CFG1_B.SCLKSWSTS != 0x02);
381 }
382 }
383
384 #elif defined SYSTEM_CLOCK_48MHz
385
386 /*!
387 * @brief Sets System clock frequency to 46MHz and configure HCLK, PCLK2 and PCLK1 prescalers
388 *
389 * @param None
390 *
391 * @retval None
392 *
393 * @note
394 */
SystemClock48M(void)395 static void SystemClock48M(void)
396 {
397 uint32_t i;
398
399 RCM->CTRL1_B.HSEEN = BIT_SET;
400
401 for (i = 0; i < HSE_STARTUP_TIMEOUT; i++)
402 {
403 if (RCM->CTRL1_B.HSERDYFLG)
404 {
405 break;
406 }
407 }
408
409 if (RCM->CTRL1_B.HSERDYFLG)
410 {
411 /* Enable Prefetch Buffer */
412 FMC->CTRL1_B.PBEN = BIT_SET;
413 /* Flash 1 wait state */
414 FMC->CTRL1_B.WS = 1;
415
416 /* HCLK = SYSCLK */
417 RCM->CFG1_B.AHBPSC = 0X00;
418
419 /* PCLK = HCLK */
420 RCM->CFG1_B.APB1PSC = 0X00;
421
422 /* PLL: HSE * 6 */
423 RCM->CFG1_B.PLLSRCSEL = 2;
424 RCM->CFG1_B.PLLMULCFG = 4;
425
426 /* Enable PLL */
427 RCM->CTRL1_B.PLLEN = 1;
428
429 /* Wait PLL Ready */
430 while (RCM->CTRL1_B.PLLRDYFLG == BIT_RESET);
431
432 /* Select PLL as system clock source */
433 RCM->CFG1_B.SCLKSEL = 2;
434
435 /* Wait till PLL is used as system clock source */
436 while (RCM->CFG1_B.SCLKSWSTS != 0x02);
437 }
438 }
439
440 #endif
441
442 /**@} end of group System_Functions */
443 /**@} end of group APM32F0xx_System */
444 /**@} end of group CMSIS */
445