1 ////////////////////////////////////////////////////////////////////////////////
2 /// @file SYSTEM_MM32.C
3 /// @author AE TEAM
4 /// @brief THIS FILE PROVIDES ALL THE SYSTEM FUNCTIONS.
5 ////////////////////////////////////////////////////////////////////////////////
6 /// @attention
7 ///
8 /// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
9 /// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
10 /// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
11 /// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
12 /// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
13 /// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
14 ///
15 /// <H2><CENTER>© COPYRIGHT MINDMOTION </CENTER></H2>
16 ////////////////////////////////////////////////////////////////////////////////
17
18 // Define to prevent recursive inclusion
19 #define _SYSTEM_MM32_C_
20
21 // Files includes
22
23 /// @addtogroup CMSIS
24 /// @{
25
26 #include "mm32_device.h"
27
28
29 /// @}
30
31
32
33 /// @}
34
35
36 /// Uncomment the line corresponding to the desired System clock (SYSCLK)
37 /// frequency (after reset the HSI is used as SYSCLK source)
38 ///
39 /// IMPORTANT NOTE:
40 /// ==============
41 /// 1. After each device reset the HSI is used as System clock source.
42 ///
43 /// 2. Please make sure that the selected System clock doesn't exceed your device's
44 /// maximum frequency.
45 ///
46 /// 3. If none of the define below is enabled, the HSI is used as System clock
47 /// source.
48 ///
49 /// 4. The System clock configuration functions provided within this file assume that:
50 /// - For Low, Medium and High density Value line devices an external 8MHz
51 /// crystal is used to drive the System clock.
52 /// - For Low, Medium and High density devices an external 8MHz crystal is
53 /// used to drive the System clock.
54 /// - For Connectivity line devices an external 25MHz crystal is used to drive
55 /// the System clock.
56 /// If you are using different crystal you have to adapt those functions accordingly.
57
58 //#define SYSCLK_FREQ_HSE HSE_VALUE //HSE_VALUE is define in reg_common.h
59 //#define SYSCLK_FREQ_24MHz (HSE_VALUE*3) //24000000 based HSE_VALUE = 8000000
60 //#define SYSCLK_FREQ_36MHz (HSE_VALUE*9/2) //36000000 based HSE_VALUE = 8000000
61 //#define SYSCLK_FREQ_48MHz (HSE_VALUE*6) //48000000 based HSE_VALUE = 8000000
62 //#define SYSCLK_FREQ_XXMHz (HSE_VALUE*6) //48000000 based HSE_VALUE = 8000000
63 //#define SYSCLK_FREQ_XXMHz (HSE_VALUE*9) //72000000 based HSE_VALUE = 8000000
64 //#define SYSCLK_FREQ_XXMHz (HSE_VALUE*12) //96000000 based HSE_VALUE = 8000000
65 #define SYSCLK_FREQ_XXMHz (HSE_VALUE*15) //120000000 based HSE_VALUE = 8000000
66
67 #if defined(SYSCLK_FREQ_HSE) || defined(SYSCLK_FREQ_24MHz) || defined(SYSCLK_FREQ_36MHz) || defined(SYSCLK_FREQ_48MHz) || defined(SYSCLK_FREQ_XXMHz)
68
69 #if defined(HSE_VALUE) && (!(HSE_VALUE == 8000000))
70 #warning redefine HSE_VALUE in reg_common.h Line 48 and ignore this warning
71 #endif
72
73 #endif
74
75
76 //#define SYSCLK_HSI_24MHz 24000000
77 //#define SYSCLK_HSI_36MHz 36000000
78 //#define SYSCLK_HSI_48MHz 48000000
79 //#define SYSCLK_HSI_XXMHz 48000000
80 //#define SYSCLK_HSI_XXMHz 72000000
81 //#define SYSCLK_HSI_XXMHz 96000000
82 #define SYSCLK_HSI_XXMHz 120000000
83 /// Uncomment the following line if you need to relocate your vector Table in
84 /// Internal SRAM.
85 ///#define VECT_TAB_SRAM
86 #define VECT_TAB_OFFSET 0x0
87 /// Vector Table base offset field.
88 /// This value must be a multiple of 0x200.
89
90
91 /// @}
92
93
94
95
96 ///////////////////////////////////////////////////////////////
97 ///Clock Definitions
98 ///////////////////////////////////////////////////////////////
99 #if defined SYSCLK_FREQ_HSE
100 u32 SystemCoreClock = SYSCLK_FREQ_HSE;
101 #elif defined SYSCLK_FREQ_24MHz
102 u32 SystemCoreClock = SYSCLK_FREQ_24MHz;
103 #elif defined SYSCLK_FREQ_36MHz
104 u32 SystemCoreClock = SYSCLK_FREQ_36MHz;
105 #elif defined SYSCLK_FREQ_48MHz
106 u32 SystemCoreClock = SYSCLK_FREQ_48MHz;
107 #elif defined SYSCLK_FREQ_XXMHz
108 u32 SystemCoreClock = SYSCLK_FREQ_XXMHz;
109
110
111 #elif defined SYSCLK_HSI_24MHz
112 u32 SystemCoreClock = SYSCLK_HSI_24MHz;
113 #elif defined SYSCLK_HSI_36MHz
114 u32 SystemCoreClock = SYSCLK_HSI_36MHz;
115 #elif defined SYSCLK_HSI_48MHz
116 u32 SystemCoreClock = SYSCLK_HSI_48MHz;
117 #elif defined SYSCLK_HSI_XXMHz
118 u32 SystemCoreClock = SYSCLK_HSI_XXMHz;
119 #else //HSI Selected as System Clock source
120 u32 SystemCoreClock = HSI_VALUE;
121 #endif
122
123 __I u8 AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
124
125 /// @}
126
127
128 static void SetSysClock(void);
129
130 #if defined SYSCLK_FREQ_HSE
131 static void SetSysClockToHSE(void);
132 #elif defined SYSCLK_FREQ_24MHz
133 static void SetSysClockTo24(void);
134 #elif defined SYSCLK_FREQ_36MHz
135 static void SetSysClockTo36(void);
136 #elif defined SYSCLK_FREQ_48MHz
137 static void SetSysClockTo48(void);
138 #elif defined SYSCLK_FREQ_XXMHz
139 static void SetSysClockToXX(void);
140
141 #elif defined SYSCLK_HSI_24MHz
142 static void SetSysClockTo24_HSI(void);
143 #elif defined SYSCLK_HSI_36MHz
144 static void SetSysClockTo36_HSI(void);
145 #elif defined SYSCLK_HSI_48MHz
146 static void SetSysClockTo48_HSI(void);
147 #elif defined SYSCLK_HSI_XXMHz
148 static void SetSysClockToXX_HSI(void);
149 #endif
150
151 #ifdef DATA_IN_ExtSRAM
152 static void SystemInit_ExtMemCtl(void);
153 #endif //DATA_IN_ExtSRAM
154
155
156 /// @}
157
158
159
160 /// @brief Setup the microcontroller system
161 /// Initialize the Embedded Flash Interface, the PLL and update the
162 /// SystemCoreClock variable.
163 /// @note This function should be used only after reset.
164 /// @param None
165 /// @retval None
166
SystemInit(void)167 void SystemInit (void)
168 {
169 //Reset the RCC clock configuration to the default reset state(for debug purpose)
170 //Set HSION bit
171 RCC->CR |= (u32)0x00000001;
172
173 //Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits
174 RCC->CFGR &= (u32)0xF8FFC00C;
175
176 //Reset HSEON, CSSON and PLLON bits
177 RCC->CR &= (u32)0xFEF6FFFF;
178
179 //Reset HSEBYP bit
180 RCC->CR &= (u32)0xFFFBFFFF;
181
182 //Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits
183 RCC->CFGR &= (u32)0xFF3CFFFF;
184 RCC->CR &= (u32)0x008FFFFF;
185
186 //Disable all interrupts and clear pending bits
187 RCC->CIR = 0x009F0000;
188 //Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers
189 //Configure the Flash Latency cycles and enable prefetch buffer
190 SetSysClock();
191 }
192
193
194 /// @brief use to return the pllm&plln.
195 /// @param pllclkSourceFrq : PLL source clock frquency;
196 /// pllclkFrq : Target PLL clock frquency;
197 /// plln : PLL factor PLLN
198 /// pllm : PLL factor PLLM
199 /// @retval amount of error
AutoCalPllFactor(u32 pllclkSourceFrq,u32 pllclkFrq,u8 * plln,u8 * pllm)200 u32 AutoCalPllFactor(u32 pllclkSourceFrq, u32 pllclkFrq, u8* plln, u8* pllm)
201 {
202 u32 n, m;
203 u32 tempFrq;
204 u32 minDiff = pllclkFrq;
205 u8 flag = 0;
206 for(m = 0; m < 4 ; m++) {
207 for(n = 0; n < 64 ; n++) {
208 tempFrq = pllclkSourceFrq * (n + 1) / (m + 1);
209 tempFrq = (tempFrq > pllclkFrq) ? (tempFrq - pllclkFrq) : (pllclkFrq - tempFrq) ;
210
211 if(minDiff > tempFrq) {
212 minDiff = tempFrq;
213 *plln = n;
214 *pllm = m;
215 }
216 if(minDiff == 0) {
217 flag = 1;
218 break;
219 }
220 }
221 if(flag != 0) {
222 break;
223 }
224 }
225 return minDiff;
226 }
DELAY_xUs(u32 count)227 static void DELAY_xUs(u32 count)
228 {
229 u32 temp;
230 SysTick->CTRL = 0x0; //disable systick function
231 SysTick->LOAD = count * 8; //time count for 1us with HSI as SYSCLK
232 SysTick->VAL = 0x00; //clear counter
233 SysTick->CTRL = 0x5; //start discrease with Polling
234 do {
235 temp = SysTick->CTRL;
236 } while((temp & 0x01) && !(temp & (1 << 16))); //wait time count done
237 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //Close Counter
238 SysTick->VAL = 0X00; //clear counter
239 }
240 /// @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
241 /// @param None
242 /// @retval None
243
SetSysClock(void)244 static void SetSysClock(void)
245 {
246 CACHE->CCR &= ~(0x3 << 3);
247 CACHE->CCR |= 1;
248 while((CACHE->SR & 0x3) != 2);
249 #ifdef SYSCLK_FREQ_HSE
250 SetSysClockToHSE();
251 #elif defined SYSCLK_FREQ_24MHz
252 SetSysClockTo24();
253 #elif defined SYSCLK_FREQ_36MHz
254 SetSysClockTo36();
255 #elif defined SYSCLK_FREQ_48MHz
256 SetSysClockTo48();
257 #elif defined SYSCLK_FREQ_XXMHz
258 SetSysClockToXX();
259
260 #elif defined SYSCLK_HSI_24MHz
261 SetSysClockTo24_HSI();
262 #elif defined SYSCLK_HSI_36MHz
263 SetSysClockTo36_HSI();
264 #elif defined SYSCLK_HSI_48MHz
265 SetSysClockTo48_HSI();
266 #elif defined SYSCLK_HSI_XXMHz
267 SetSysClockToXX_HSI();
268 #endif
269
270 //If none of the define above is enabled, the HSI is used as System clock
271 //source (default after reset)
272 }
273
274 #ifdef SYSCLK_FREQ_HSE
275
276 /// @brief Selects HSE as System clock source and configure HCLK, PCLK2
277 /// and PCLK1 prescalers.
278 /// @note This function should be used only after reset.
279 /// @param None
280 /// @retval None
281
SetSysClockToHSE(void)282 static void SetSysClockToHSE(void)
283 {
284 __IO u32 StartUpCounter = 0, HSEStatus = 0;
285 s32 i;
286
287 //SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------
288 //Enable HSE
289 RCC->CR |= ((u32)RCC_CR_HSEON);
290
291 //Wait till HSE is ready and if Time out is reached exit
292 do {
293 HSEStatus = RCC->CR & RCC_CR_HSERDY;
294 StartUpCounter++;
295 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
296
297 if ((RCC->CR & RCC_CR_HSERDY) != RESET) {
298 HSEStatus = (u32)0x01;
299 i = 2000;
300 while(i--);
301 }
302 else {
303 HSEStatus = (u32)0x00;
304 }
305
306 if (HSEStatus == (u32)0x01) {
307 //Enable Prefetch Buffer
308 FLASH->ACR |= FLASH_ACR_PRFTBE;
309
310 //Flash 0 wait state ,bit0~2
311 FLASH->ACR &= ~0x07;
312 //HCLK = SYSCLK
313 RCC->CFGR |= (u32)RCC_CFGR_HPRE_DIV1;
314
315 //PCLK2 = HCLK
316 RCC->CFGR |= (u32)RCC_CFGR_PPRE2_DIV1;
317
318 //PCLK1 = HCLK
319 RCC->CFGR |= (u32)RCC_CFGR_PPRE1_DIV1;
320
321 //Select HSE as system clock source
322 RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
323 RCC->CFGR |= (u32)RCC_CFGR_SW_HSE;
324
325 //Wait till HSE is used as system clock source
326 while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)0x04) {
327 }
328 }
329 else {
330 //If HSE fails to start-up, the application will have wrong clock
331 //configuration. User can add here some code to deal with this error
332 }
333 }
334 #elif defined SYSCLK_FREQ_24MHz
335
336 /// @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2
337 /// and PCLK1 prescalers.
338 /// @note This function should be used only after reset.
339 /// @param None
340 /// @retval None
341
SetSysClockTo24(void)342 static void SetSysClockTo24(void)
343 {
344 __IO u32 StartUpCounter = 0, HSEStatus = 0;
345 s32 i;
346
347 //SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------
348 //Enable HSE
349 RCC->CR |= ((u32)RCC_CR_HSEON);
350
351 //Wait till HSE is ready and if Time out is reached exit
352 do {
353 HSEStatus = RCC->CR & RCC_CR_HSERDY;
354 StartUpCounter++;
355 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
356
357 if ((RCC->CR & RCC_CR_HSERDY) != RESET) {
358 HSEStatus = (u32)0x01;
359 i = 2000;
360 while(i--);
361 }
362 else {
363 HSEStatus = (u32)0x00;
364 }
365
366 if (HSEStatus == (u32)0x01) {
367 //Enable Prefetch Buffer
368 FLASH->ACR |= FLASH_ACR_PRFTBE;
369 //Flash 0 wait state ,bit0~2
370 FLASH->ACR &= ~0x07;
371 FLASH->ACR |= 0x01;
372 //HCLK = SYSCLK
373 RCC->CFGR |= (u32)RCC_CFGR_HPRE_DIV1;
374
375 //PCLK2 = HCLK
376 RCC->CFGR |= (u32)RCC_CFGR_PPRE2_DIV1;
377
378 //PCLK1 = HCLK
379 RCC->CFGR |= (u32)RCC_CFGR_PPRE1_DIV1;
380
381 // PLL configuration: = (HSE ) * (2+1) = 24 MHz
382 RCC->PLLCFGR &= ~((u32 ) RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLXTPRE) ;
383 RCC->PLLCFGR |= (u32 ) RCC_PLLCFGR_PLLSRC ;
384
385 RCC->APB1ENR |= RCC_APB1ENR_PWR;
386 RCC->PLLCFGR &= (u32)((~RCC_PLLCFGR_PLL_DN) & (~RCC_PLLCFGR_PLL_DP));
387 RCC->PLLCFGR |= ((0 << RCC_PLLCFGR_PLL_DN_Pos) | (2 << RCC_PLLCFGR_PLL_DP_Pos));
388 //Enable PLL
389 RCC->CR |= RCC_CR_PLLON;
390
391 //Wait till PLL is ready
392 while((RCC->CR & RCC_CR_PLLRDY) == 0) {
393 }
394
395 //Select PLL as system clock source
396 RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
397 RCC->CFGR |= (u32)RCC_CFGR_SW_PLL;
398
399 //Wait till PLL is used as system clock source
400 while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)0x08) {
401 }
402 }
403 else {
404 //If HSE fails to start-up, the application will have wrong clock
405 //configuration. User can add here some code to deal with this error
406 }
407 }
408 #elif defined SYSCLK_FREQ_36MHz
409
410 /// @brief Sets System clock frequency to 36MHz and configure HCLK, PCLK2
411 /// and PCLK1 prescalers.
412 /// @note This function should be used only after reset.
413 /// @param None
414 /// @retval None
415
SetSysClockTo36(void)416 static void SetSysClockTo36(void)
417 {
418 s32 i;
419 __IO u32 StartUpCounter = 0, HSEStatus = 0;
420
421 //SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------
422 //Enable HSE
423 RCC->CR |= ((u32)RCC_CR_HSEON);
424
425 //Wait till HSE is ready and if Time out is reached exit
426 do {
427 HSEStatus = RCC->CR & RCC_CR_HSERDY;
428 StartUpCounter++;
429 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
430
431 if ((RCC->CR & RCC_CR_HSERDY) != RESET) {
432 HSEStatus = (u32)0x01;
433 i = 2000;
434 while(i--);
435 }
436 else {
437 HSEStatus = (u32)0x00;
438 }
439
440 if (HSEStatus == (u32)0x01) {
441 //Enable Prefetch Buffer
442 FLASH->ACR |= FLASH_ACR_PRFTBE;
443
444 //Flash 0 wait state ,bit0~2
445 FLASH->ACR &= ~0x07;
446 FLASH->ACR |= 0x01;
447 //HCLK = SYSCLK
448 RCC->CFGR |= (u32)RCC_CFGR_HPRE_DIV1;
449
450 //PCLK2 = HCLK
451 RCC->CFGR |= (u32)RCC_CFGR_PPRE2_DIV1;
452
453 //PCLK1 = HCLK
454 RCC->CFGR |= (u32)RCC_CFGR_PPRE1_DIV1;
455 RCC->PLLCFGR &= ~((u32 ) RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLXTPRE) ;
456 RCC->PLLCFGR |= (u32 ) RCC_PLLCFGR_PLLSRC ;
457
458 RCC->APB1ENR |= RCC_APB1ENR_PWR;
459 RCC->PLLCFGR &= (u32)((~RCC_PLLCFGR_PLL_DN) & (~RCC_PLLCFGR_PLL_DP));
460 RCC->PLLCFGR |= ((1 << RCC_PLLCFGR_PLL_DN_Pos) | (8 << RCC_PLLCFGR_PLL_DP_Pos));
461 //Enable PLL
462 RCC->CR |= RCC_CR_PLLON;
463
464 //Wait till PLL is ready
465 while((RCC->CR & RCC_CR_PLLRDY) == 0) {
466 }
467
468 //Select PLL as system clock source
469 RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
470 RCC->CFGR |= (u32)RCC_CFGR_SW_PLL;
471
472 //Wait till PLL is used as system clock source
473 while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)0x08) {
474 }
475 }
476 else {
477 //If HSE fails to start-up, the application will have wrong clock
478 //configuration. User can add here some code to deal with this error
479 }
480 }
481 #elif defined SYSCLK_FREQ_48MHz
482
483 /// @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2
484 /// and PCLK1 prescalers.
485 /// @note This function should be used only after reset.
486 /// @param None
487 /// @retval None
488
SetSysClockTo48(void)489 static void SetSysClockTo48(void)
490 {
491 __IO u32 StartUpCounter = 0, HSEStatus = 0;
492 s32 i;
493 //SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------
494 //Enable HSE
495 RCC->CR |= ((u32)RCC_CR_HSEON);
496
497 //Wait till HSE is ready and if Time out is reached exit
498 do {
499 HSEStatus = RCC->CR & RCC_CR_HSERDY;
500 StartUpCounter++;
501 } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
502
503 if ((RCC->CR & RCC_CR_HSERDY) != RESET) {
504 HSEStatus = (u32)0x01;
505 i = 2000;
506 while(i--);
507 }
508 else {
509 HSEStatus = (u32)0x00;
510 }
511
512 if (HSEStatus == (u32)0x01) {
513 //Enable Prefetch Buffer
514 FLASH->ACR |= FLASH_ACR_PRFTBE;
515 //Flash 0 wait state ,bit0~2
516 FLASH->ACR &= ~0x07;
517 FLASH->ACR |= 0x02;
518 //HCLK = SYSCLK
519 RCC->CFGR |= (u32)RCC_CFGR_HPRE_DIV1;
520
521 //PCLK2 = HCLK
522 RCC->CFGR |= (u32)RCC_CFGR_PPRE2_DIV1;
523
524 //PCLK1 = HCLK
525 RCC->CFGR |= (u32)RCC_CFGR_PPRE1_DIV2;
526
527 // PLL configuration: = (HSE ) * (5+1) = 48MHz
528 RCC->PLLCFGR &= ~((u32 ) RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLXTPRE) ;
529 RCC->PLLCFGR |= (u32 ) RCC_PLLCFGR_PLLSRC ;
530
531 RCC->APB1ENR |= RCC_APB1ENR_PWR;
532 RCC->PLLCFGR &= (u32)((~RCC_PLLCFGR_PLL_DN) & (~RCC_PLLCFGR_PLL_DP));
533 RCC->PLLCFGR |= ((0 << RCC_PLLCFGR_PLL_DN_Pos) | (5 << RCC_PLLCFGR_PLL_DP_Pos));
534 //Enable PLL
535 RCC->CR |= RCC_CR_PLLON;
536
537 //Wait till PLL is ready
538 while((RCC->CR & RCC_CR_PLLRDY) == 0) {
539 }
540
541 //Select PLL as system clock source
542 RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
543 RCC->CFGR |= (u32)RCC_CFGR_SW_PLL;
544
545 //Wait till PLL is used as system clock source
546 while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)0x08) {
547 }
548 }
549 else {
550 //If HSE fails to start-up, the application will have wrong clock
551 //configuration. User can add here some code to deal with this error
552 }
553 }
554 #elif defined SYSCLK_FREQ_XXMHz
555
556 /// @brief Sets System clock frequency to XXMHz and configure HCLK, PCLK2
557 /// and PCLK1 prescalers.
558 /// @note This function should be used only after reset.
559 /// @param None
560 /// @retval None
561
SetSysClockToXX(void)562 static void SetSysClockToXX(void)
563 {
564 __IO u32 temp, tn, tm;//j,
565 __IO u32 StartUpCounter = 0, HSEStatus = 0;
566
567 u8 plln, pllm;
568
569 RCC->CR |= RCC_CR_HSION;
570 while(!(RCC->CR & RCC_CR_HSIRDY));
571 //PLL SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------
572 //Enable HSE
573 RCC->CR |= ((u32)RCC_CR_HSEON);
574
575 DELAY_xUs(5);
576
577 if(SystemCoreClock > 96000000) {
578 RCC->APB1ENR |= RCC_APB1ENR_PWR;
579 PWR->CR &= ~(3 << 14);
580 PWR->CR |= 3 << 14;
581 }
582 //Wait till HSE is ready and if Time out is reached exit
583 while(1) {
584 HSEStatus = RCC->CR & RCC_CR_HSERDY;
585 if(HSEStatus != 0)
586 break;
587 StartUpCounter++;
588 if(StartUpCounter >= (10 * HSE_STARTUP_TIMEOUT))
589 return;
590 }
591
592 if ((RCC->CR & RCC_CR_HSERDY) == RESET) {
593 //If HSE fails to start-up, the application will have wrong clock
594 //configuration. User can add here some code to deal with this error
595 HSEStatus = (u32)0x00;
596 return;
597 }
598
599 HSEStatus = (u32)0x01;
600 DELAY_xUs(5);
601
602 SystemCoreClock = SYSCLK_FREQ_XXMHz;
603 //Enable Prefetch Buffer
604 FLASH->ACR |= FLASH_ACR_PRFTBE;
605 //Flash 0 wait state ,bit0~2
606 FLASH->ACR &= ~FLASH_ACR_LATENCY;
607 temp = (SystemCoreClock - 1) / 24000000;
608 FLASH->ACR |= (temp & FLASH_ACR_LATENCY);
609 RCC->CFGR &= (~RCC_CFGR_HPRE) & ( ~RCC_CFGR_PPRE1) & (~RCC_CFGR_PPRE2);
610
611 //HCLK = AHB = FCLK = SYSCLK divided by 4
612 RCC->CFGR |= (u32)RCC_CFGR_HPRE_DIV4;
613
614 //PCLK2 = APB2 = HCLK divided by 1, APB2 is high APB CLK
615 RCC->CFGR |= (u32)RCC_CFGR_PPRE2_DIV1;
616
617 if(SystemCoreClock > 72000000) {
618 //PCLK1 = APB1 = HCLK divided by 4, APB1 is low APB CLK
619 RCC->CFGR |= (u32)RCC_CFGR_PPRE1_DIV4;
620 }
621 else if(SystemCoreClock > 36000000) {
622 //PCLK1 = APB1 = HCLK divided by 2, APB1 is low APB CLK
623 RCC->CFGR |= (u32)RCC_CFGR_PPRE1_DIV2;
624 }
625
626 AutoCalPllFactor(HSE_VALUE, SystemCoreClock, &plln, &pllm);
627
628 RCC->PLLCFGR &= ~((u32 ) RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLXTPRE) ;
629 RCC->PLLCFGR |= (u32 ) RCC_PLLCFGR_PLLSRC ;
630
631 tm = (((u32)pllm) & 0x07);
632 tn = (((u32)plln) & 0x7F);
633
634 RCC->APB1ENR |= RCC_APB1ENR_PWR;
635 RCC->PLLCFGR &= (u32)((~RCC_PLLCFGR_PLL_DN) & (~RCC_PLLCFGR_PLL_DP));
636 RCC->PLLCFGR |= ((tn << RCC_PLLCFGR_PLL_DN_Pos) | (tm << RCC_PLLCFGR_PLL_DP_Pos));
637 //Enable PLL
638 RCC->CR |= RCC_CR_PLLON;
639 //Wait till PLL is ready
640 while((RCC->CR & RCC_CR_PLLRDY) == 0) {
641 __ASM ("nop") ;//__NOP();
642 }
643 //Select PLL as system clock source
644 RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
645 RCC->CFGR |= (u32)RCC_CFGR_SW_PLL;
646
647 //Wait till PLL is used as system clock source
648 while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)RCC_CFGR_SWS_PLL) {
649 __ASM ("nop") ;//__NOP();
650 }
651
652 DELAY_xUs(1);
653 // set HCLK = AHB = FCLK = SYSCLK divided by 2
654 RCC->CFGR &= (~(RCC_CFGR_PPRE_0));
655 DELAY_xUs(1);
656
657 // set HCLK = AHB = FCLK = SYSCLK divided by 1
658 RCC->CFGR &= (~(RCC_CFGR_PPRE_3));
659
660 DELAY_xUs(1);
661
662 }
663 #elif defined SYSCLK_HSI_24MHz
SetSysClockTo24_HSI(void)664 void SetSysClockTo24_HSI(void)
665 {
666 u8 temp = 0;
667
668 RCC->CR |= RCC_CR_HSION;
669
670 while(!(RCC->CR & RCC_CR_HSIRDY));
671 FLASH->ACR = FLASH_ACR_PRFTBE;
672
673 RCC->CFGR = RCC_CFGR_PPRE1_2;
674 // PLL configuration: = (HSI = 8M ) * (2+1)/(0+1) = 24 MHz
675 RCC->PLLCFGR &= ~((u32 ) RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLXTPRE) ;
676 RCC->PLLCFGR |= (u32 ) RCC_PLLCFGR_PLLSRC ;
677
678 RCC->APB1ENR |= RCC_APB1ENR_PWR;
679 RCC->PLLCFGR &= (u32)((~RCC_PLLCFGR_PLL_DN) & (~RCC_PLLCFGR_PLL_DP));
680 RCC->PLLCFGR |= ((0 << RCC_PLLCFGR_PLL_DN_Pos) | (2 << RCC_PLLCFGR_PLL_DP_Pos));
681
682
683 RCC->CR |= RCC_CR_PLLON;
684
685 while(!(RCC->CR & RCC_CR_PLLRDY));
686
687 RCC->CFGR &= ~RCC_CFGR_SW;
688
689 RCC->CFGR |= RCC_CFGR_SW_PLL;
690
691 while(temp != 0x02) {
692 temp = RCC->CFGR >> 2;
693 temp &= 0x03;
694 }
695 }
696
697 #elif defined SYSCLK_HSI_36MHz
SetSysClockTo36_HSI(void)698 void SetSysClockTo36_HSI(void)
699 {
700 u8 temp = 0;
701
702 RCC->CR |= RCC_CR_HSION;
703
704 while(!(RCC->CR & RCC_CR_HSIRDY));
705 FLASH->ACR = FLASH_ACR_LATENCY_1 | FLASH_ACR_PRFTBE;
706 RCC->CFGR = RCC_CFGR_PPRE1_2;
707 // PLL configuration: = (HSI = 8M ) * (8+1)/(1+1) = 36 MHz
708 RCC->PLLCFGR &= ~((u32 ) RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLXTPRE) ;
709 RCC->PLLCFGR |= (u32 ) RCC_PLLCFGR_PLLSRC ;
710
711 RCC->APB1ENR |= RCC_APB1ENR_PWR;
712 RCC->PLLCFGR &= (u32)((~RCC_PLLCFGR_PLL_DN) & (~RCC_PLLCFGR_PLL_DP));
713 RCC->PLLCFGR |= ((1 << RCC_PLLCFGR_PLL_DN_Pos) | (8 << RCC_PLLCFGR_PLL_DP_Pos));
714
715 RCC->CR |= RCC_CR_PLLON;
716
717 while(!(RCC->CR & RCC_CR_PLLRDY));
718
719 RCC->CFGR &= ~ RCC_CFGR_SW;
720
721 RCC->CFGR |= RCC_CFGR_SW_PLL;
722
723 while(temp != 0x02) {
724 temp = RCC->CFGR >> 2;
725 temp &= 0x03;
726 }
727 }
728
729 #elif defined SYSCLK_HSI_48MHz
SetSysClockTo48_HSI(void)730 void SetSysClockTo48_HSI(void)
731 {
732 u8 temp = 0;
733
734 RCC->CR |= RCC_CR_HSION;
735
736 while(!(RCC->CR & RCC_CR_HSIRDY));
737 FLASH->ACR = FLASH_ACR_LATENCY_1 | FLASH_ACR_PRFTBE;
738 RCC->CFGR = RCC_CFGR_PPRE1_2;
739
740
741
742
743
744 // PLL configuration: = (HSI = 8M ) * (5+1)/(0+1) = 36 MHz
745 RCC->PLLCFGR &= ~((u32 ) RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLXTPRE) ;
746 RCC->PLLCFGR |= (u32 ) RCC_PLLCFGR_PLLSRC ;
747
748 RCC->APB1ENR |= RCC_APB1ENR_PWR;
749 RCC->PLLCFGR &= (u32)((~RCC_PLLCFGR_PLL_DN) & (~RCC_PLLCFGR_PLL_DP));
750 RCC->PLLCFGR |= ((0 << RCC_PLLCFGR_PLL_DN_Pos) | (5 << RCC_PLLCFGR_PLL_DP_Pos));
751
752 RCC->CR |= RCC_CR_PLLON;
753
754 while(!(RCC->CR & RCC_CR_PLLRDY));
755
756 RCC->CFGR &= ~RCC_CFGR_SW;
757
758 RCC->CFGR |= RCC_CFGR_SW_PLL;
759
760 while(temp != 0x02) {
761 temp = RCC->CFGR >> 2;
762 temp &= 0x03;
763 }
764 }
765 #elif defined SYSCLK_HSI_XXMHz
766
767
SetSysClockToXX_HSI(void)768 static void SetSysClockToXX_HSI(void)
769 {
770 __IO u32 temp, tn, tm;
771 u8 plln, pllm;
772
773 RCC->CR |= RCC_CR_HSION;
774 while(!(RCC->CR & RCC_CR_HSIRDY));
775
776 if(SystemCoreClock > 96000000) {
777 RCC->APB1ENR |= RCC_APB1ENR_PWR;
778 PWR->CR &= ~(3 << 14);
779 PWR->CR |= 3 << 14;
780 }
781
782
783
784 SystemCoreClock = SYSCLK_HSI_XXMHz;
785 //Enable Prefetch Buffer
786 FLASH->ACR |= FLASH_ACR_PRFTBE;
787 //Flash 0 wait state ,bit0~2
788 FLASH->ACR &= ~FLASH_ACR_LATENCY;
789
790 temp = (SystemCoreClock - 1) / 24000000;
791
792 FLASH->ACR |= (temp & FLASH_ACR_LATENCY);
793
794
795 RCC->CFGR &= (~RCC_CFGR_HPRE) & ( ~RCC_CFGR_PPRE1) & (~RCC_CFGR_PPRE2);
796 //HCLK = AHB = FCLK = SYSCLK divided by 4
797 RCC->CFGR |= (u32)RCC_CFGR_HPRE_DIV4;
798
799 //PCLK2 = APB2 = HCLK divided by 1, APB2 is high APB CLK
800 RCC->CFGR |= (u32)RCC_CFGR_PPRE2_DIV1;
801
802 if(SystemCoreClock > 72000000) {
803 //PCLK1 = APB1 = HCLK divided by 4, APB1 is low APB CLK
804 RCC->CFGR |= (u32)RCC_CFGR_PPRE1_DIV4;
805 }
806 else if(SystemCoreClock > 36000000) {
807 //PCLK1 = APB1 = HCLK divided by 2, APB1 is low APB CLK
808 RCC->CFGR |= (u32)RCC_CFGR_PPRE1_DIV2;
809 }
810
811
812
813 AutoCalPllFactor(HSI_VALUE_PLL_ON, SystemCoreClock, &plln, &pllm);
814
815 RCC->PLLCFGR &= ~((u32 ) RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLXTPRE) ;
816 RCC->PLLCFGR &= ~((u32 ) RCC_PLLCFGR_PLLSRC);
817
818 tm = (((u32)pllm) & 0x07);
819 tn = (((u32)plln) & 0x7F);
820
821 RCC->APB1ENR |= RCC_APB1ENR_PWR;
822 RCC->PLLCFGR &= (u32)((~RCC_PLLCFGR_PLL_DN) & (~RCC_PLLCFGR_PLL_DP));
823 RCC->PLLCFGR |= ((tn << RCC_PLLCFGR_PLL_DN_Pos) | (tm << RCC_PLLCFGR_PLL_DP_Pos));
824 //Enable PLL
825 RCC->CR |= RCC_CR_PLLON;
826 //Wait till PLL is ready
827 while((RCC->CR & RCC_CR_PLLRDY) == 0) {
828 __ASM ("nop") ;//__NOP();
829 }
830 //Select PLL as system clock source
831 RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
832 RCC->CFGR |= (u32)RCC_CFGR_SW_PLL;
833
834 //Wait till PLL is used as system clock source
835 while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)RCC_CFGR_SWS_PLL) {
836 __ASM ("nop") ;//__NOP();
837 }
838
839 DELAY_xUs(1);
840 // set HCLK = AHB = FCLK = SYSCLK divided by 2
841 RCC->CFGR &= (~(RCC_CFGR_PPRE_0));
842 DELAY_xUs(1);
843
844 // set HCLK = AHB = FCLK = SYSCLK divided by 1
845 RCC->CFGR &= (~(RCC_CFGR_PPRE_3));
846
847 DELAY_xUs(1);
848
849 }
850
851 #endif
852
853
854
855 /// @}
856
857
858
859 /// @}
860
861
862
863 /// @}
864
865
866
867