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>&COPY; 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