1 /*
2   ******************************************************************************
3   * @file    System_ACM32F4.c
4   * @version V1.0.0
5   * @date    2021
6   * @brief   System Source File, includes clock management, reset management
7   *          and IO configuration, ...
8   ******************************************************************************
9 */
10 #include "ACM32Fxx_HAL.h"
11 
12 uint32_t gu32_SystemClock;
13 uint32_t gu32_APBClock;
14 
15 /* System count in SysTick_Handler */
16 volatile uint32_t gu32_SystemCount;
17 
18 /************************* Miscellaneous Configuration ************************/
19 /*!< Uncomment the following line if you need to relocate your vector Table in
20      Internal SRAM. */
21 /* #define VECT_TAB_SRAM */
22 #define VECT_TAB_OFFSET  0x0U /*!< Vector Table base offset field.
23                                    This value must be a multiple of 0x200. */
24 /******************************************************************************/
25 
26 /*********************************************************************************
27 * Function    : HardFault_Handler
28 * Description : Hard Fault handle, while(1) loop, wait for debug
29 * Input       : none
30 * Output      : none
31 * Author      : xwl
32 **********************************************************************************/
33 //void HardFault_Handler(void)	//implemented in context_rvds.S
34 //{
35 //    while(1);
36 //}
37 
38 /*********************************************************************************
39 * Function    : SysTick_Handler
40 * Description : System tick handler
41 * Input       : none
42 * Output      : none
43 * Author      : Chris_Kyle
44 **********************************************************************************/
45 //void SysTick_Handler(void)	//implemented in board.c
46 //{
47 //    gu32_SystemCount++;
48 //}
49 
50 /*********************************************************************************
51 * Function    : System_SysTick_Init
52 * Description : System Tick Init. Period is 1 ms
53 * Input       : none
54 * Output      : none
55 * Author      : Chris_Kyle
56 **********************************************************************************/
57 //void System_SysTick_Init(void)	//implemented in board.c/rt_hw_board_init()
58 //{
59 //    gu32_SystemCount = 0;
60 //    SysTick_Config(gu32_SystemClock / 1000);  //1ms/tick
61 //}
62 
63 /*********************************************************************************
64 * Function    : System_SysTick_Off
65 * Description : Turn off System Tick
66 * Input       : none
67 * Output      : none
68 * Author      : xwl
69 **********************************************************************************/
70 //void System_SysTick_Off(void)
71 //{
72 //    SysTick->CTRL = 0;
73 //}
74 /*********************************************************************************
75 * Function    : System_Init
76 * Description : Initialize the system clock, accelerate function and system tick.
77 * Input       : none
78 * Output      : none
79 * Author      : Chris_Kyle
80 **********************************************************************************/
System_Init(void)81 void System_Init(void)
82 {
83     SCU->RCR |= SCU_RCR_REMAP_EN;   // always remap enabled
84     System_Set_Buzzer_Divider(80, FUNC_DISABLE); // disable clock out
85     /* 3 bits for pre-emption priority, 0 bits for subpriority */
86     NVIC_SetPriorityGrouping(NVIC_PRIORITY_GROUP_3);
87 
88     /* Initialize the system clock */
89     if (false == System_Clock_Init(DEFAULT_SYSTEM_CLOCK))
90     {
91         while(1);
92     }
93 
94 #if (__ACCELERATE_PRESENT == 1)
95     System_EnableIAccelerate();
96 #endif
97 
98 #if (__ACCELERATE_EH_PRESENT == 1)
99     System_EnableDAccelerate();
100 #endif
101 
102 #ifdef HAL_SYSTICK_ENABLED  // To activate macro in ACM32Fxx_HAL.h
103     //System_SysTick_Init();
104 #endif
105 }
106 
107 /*********************************************************************************
108 * Function    : System_Core_Config
109 * Description : configure FPU and vector table address
110 * Input       : none
111 * Output      : none
112 * Author      : Chris_Kyle
113 **********************************************************************************/
System_Core_Config(void)114 void System_Core_Config(void)
115 {
116 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
117     /* set CP10 and CP11 Full Access */
118     SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2));
119 #endif
120 
121     /* Configure the Vector Table location add offset address ------------------*/
122 #ifdef VECT_TAB_SRAM
123     SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;    /* Vector Table Relocation in Internal SRAM */
124 #else
125     SCB->VTOR = EFLASH_BASE | VECT_TAB_OFFSET;  /* Vector Table Relocation in Internal FLASH */
126 #endif
127 }
128 
129 
130 /*********************************************************************************
131 * Function    : System_Clock_Init
132 * Description : Clock init
133 * Input       : fu32_Clock: System core clock frequency, measured as Hz
134 * Output      : 0: success, other value: fail reason
135 * Author      : xwl
136 **********************************************************************************/
System_Clock_Init(uint32_t fu32_Clock)137 bool System_Clock_Init(uint32_t fu32_Clock)
138 {
139     volatile uint32_t lu32_sysdiv, lu32_pclkdiv, lu32_timeout, lu32_pll_src, lu32_pclk_div_para, lu32_result;
140 
141     SET_EFC_RD_WAIT(RD_WAIT_ENSURE_OK)
142     lu32_result = 0;
143     lu32_pll_src = PLL_SOURCE_FROM;
144 
145     if(0 == (SCU->RCHCR & SCU_RCHCR_RCHRDY))
146     {
147        SCU->RCHCR |=  SCU_RCHCR_RCH_EN;
148        while(0 == (SCU->RCHCR & SCU_RCHCR_RCHRDY));  // wait RCH ready
149     }
150     SCU->CCR1 = 0;  // select RC64M as default
151 
152     if (fu32_Clock <= 64000000)
153     {
154         if ((SCU->RCHCR) & SCU_RCHCR_RCH_DIV)
155         {
156             SCU->RCHCR &= (~SCU_RCHCR_RCH_DIV);
157             while(0 == (SCU->RCHCR & SCU_RCHCR_RCHRDY));
158         }
159 
160         if (fu32_Clock == 32000000)
161         {
162             gu32_SystemClock = fu32_Clock;
163             lu32_sysdiv = 2;
164             lu32_pclkdiv = 1;  // pclk = hclk
165         }
166         else
167         {
168             gu32_SystemClock = 64000000;
169             lu32_sysdiv = 1;
170             lu32_pclkdiv = 1;
171         }
172 
173         gu32_APBClock = gu32_SystemClock/lu32_pclkdiv;
174     }
175     // select pll as system clock
176     else
177     {
178         if (PLLCLK_SRC_RC4M == lu32_pll_src)
179         {
180             SCU->RCHCR |= SCU_RCHCR_RCH_DIV;
181             while(!(SCU->RCHCR & SCU_RCHCR_RCHRDY));
182 
183             SCU->PLLCR |=  SCU_PLLCR_PLL_EN;
184             SCU->PLLCR &= ~(SCU_PLLCR_PLL_SLEEP);
185             while(!(SCU->PLLCR & SCU_PLLCR_PLL_FREE_RUN));
186 
187             switch(fu32_Clock)
188             {
189                 case 180000000:  // 180M
190                 {
191                     SCU->PLLCR  = (SCU->PLLCR & ~(0xFFFF8)) | (33 << 3);
192                     SCU->PLLCR |= SCU_PLLCR_PLL_UPDATE_EN;
193                     while(!(SCU->PLLCR & (SCU_PLLCR_PLL_FREE_RUN) ) );
194 
195                     lu32_sysdiv = 1;
196                     lu32_pclkdiv = 2; // pclk = hclk/2
197                 }break;
198 
199                 case 120000000:  // 120M
200                 {
201                     SCU->PLLCR  = (SCU->PLLCR & ~(0xFFFF8)) | (18U << 3);
202                     SCU->PLLCR |= SCU_PLLCR_PLL_UPDATE_EN;
203                     while(!(SCU->PLLCR & (SCU_PLLCR_PLL_FREE_RUN) ) );
204 
205                     lu32_sysdiv = 1;
206                     lu32_pclkdiv = 2; // pclk = hclk/2
207                 }break;
208 
209                 default: lu32_result = 1; break;
210             }
211             gu32_SystemClock = fu32_Clock;
212             gu32_APBClock = gu32_SystemClock/lu32_pclkdiv;
213             SCU->CCR1 = SCU_CCR1_SYS_PLL;  // configure system clock as PLL clock
214         }
215         else if (SCU_XTHCR_XTH_EN == lu32_pll_src)
216         {
217             lu32_timeout = 0;
218 
219             SCU->XTHCR = SCU_XTHCR_XTH_EN | SCU_XTHCR_READYTIME_32768;
220             while (0 == (SCU->XTHCR & SCU_XTHCR_XTHRDY))
221             {
222                 if (lu32_timeout == SYSTEM_TIMEOUT)
223                 {
224                     lu32_result = 2;
225                     break;
226                 }
227                 lu32_timeout++;
228             }
229 
230             if  (0 == lu32_result)
231             {
232                 SCU->PLLCR |=  SCU_PLLCR_PLL_EN;
233                 SCU->PLLCR &= ~(SCU_PLLCR_PLL_SLEEP);
234                 while(!(SCU->PLLCR & (SCU_PLLCR_PLL_FREE_RUN) ));
235 
236                 switch(fu32_Clock)
237                 {
238                     case 180000000:  // 180M
239                     {
240                         SCU->PLLCR = (SCU->PLLCR &(~(0x1FFFFU << 3))) | (18U << 3) | (1U << 12) | (0U << 16);
241                         SCU->PLLCR = (SCU->PLLCR & (~(0x3U << 1)) ) | (3 << 1);
242                         SCU->PLLCR |= SCU_PLLCR_PLL_UPDATE_EN;
243                         while(!(SCU->PLLCR & (SCU_PLLCR_PLL_FREE_RUN) ) );
244 
245                         lu32_sysdiv = 1;
246                         lu32_pclkdiv = 2; // pclk = hclk/2
247                     }break;
248 
249                     case 120000000:  // 120M
250                     {
251                         SCU->PLLCR = (SCU->PLLCR &(~(0x1FFFFU << 3))) | (18U << 3) | (2U << 12) | (0U << 16);
252                         SCU->PLLCR = (SCU->PLLCR & (~(0x3U << 1)) ) | (3 << 1); // select XTH
253                         SCU->PLLCR |= SCU_PLLCR_PLL_UPDATE_EN;
254                         while(!(SCU->PLLCR & (SCU_PLLCR_PLL_FREE_RUN) ) );
255 
256                         lu32_sysdiv = 1;
257                         lu32_pclkdiv = 2; // pclk = hclk/2
258                     }break;
259 
260                     default: lu32_result = 1; break;
261                 }
262             }
263             gu32_SystemClock = fu32_Clock;
264             gu32_APBClock = gu32_SystemClock/lu32_pclkdiv;
265             SCU->CCR1 = SCU_CCR1_SYS_PLL;  // configure system clock as PLL clock
266         }
267         else
268         {
269             lu32_result = 3;
270         }
271     }
272 
273     if (0 == lu32_result)
274     {
275         if (1 == lu32_pclkdiv)
276         {
277             lu32_pclk_div_para = 0;
278         }
279         else if (2 == lu32_pclkdiv)
280         {
281             lu32_pclk_div_para = 4;    // pclk = hclk/2
282         }
283         else
284         {
285             lu32_pclk_div_para = 5;    // pclk = hclk/4
286         }
287     }
288     else
289     {
290         lu32_sysdiv = 1;
291         lu32_pclk_div_para = 0;
292     }
293 
294     SCU->CCR2 = (SCU->CCR2 & (~0x7FFU)) | (lu32_sysdiv-1) | (lu32_pclk_div_para << 8);
295     while((SCU->CCR2 & SCU_CCR2_DIVDONE) == 0x00);  // wait divide done
296 
297     HAL_EFlash_Init(gu32_SystemClock);
298 
299     return (lu32_result == 0);
300 }
301 
302 /*********************************************************************************
303 * Function    : System_Get_SystemClock
304 * Description : get AHB clock frequency
305 * Input       : none
306 * Output      : frequency, measured as Hz
307 * Author      : Chris_Kyle
308 **********************************************************************************/
System_Get_SystemClock(void)309 uint32_t System_Get_SystemClock(void)
310 {
311     return gu32_SystemClock;
312 }
313 
314 /*********************************************************************************
315 * Function    : System_Get_APBClock
316 * Description : get APB clock frequency
317 * Input       : none
318 * Output      : frequency, measured as Hz
319 * Author      : Chris_Kyle
320 **********************************************************************************/
System_Get_APBClock(void)321 uint32_t System_Get_APBClock(void)
322 {
323     return gu32_APBClock;
324 }
325 
326 /*********************************************************************************
327 * Function    : System_Module_Reset
328 * Description : reset module
329 * Input       : module id
330 * Output      : none
331 * Author      : Chris_Kyle
332 **********************************************************************************/
System_Module_Reset(enum_RST_ID_t fe_ID_Index)333 void System_Module_Reset(enum_RST_ID_t fe_ID_Index)
334 {
335     if (fe_ID_Index > 31)
336     {
337         SCU->IPRST2 &= ~(1 << (fe_ID_Index - 32));
338         System_Delay(5);
339         SCU->IPRST2 |= 1 << (fe_ID_Index - 32);
340     }
341     else
342     {
343         SCU->IPRST1 &= ~(1 << fe_ID_Index);
344         System_Delay(5);
345         SCU->IPRST1 |= 1 << fe_ID_Index;
346     }
347 }
348 
349 /*********************************************************************************
350 * Function    : System_Module_Enable
351 * Description : enable module clock
352 * Input       : module id
353 * Output      : none
354 * Author      : Chris_Kyle
355 **********************************************************************************/
System_Module_Enable(enum_Enable_ID_t fe_ID_Index)356 void System_Module_Enable(enum_Enable_ID_t fe_ID_Index)
357 {
358     if (fe_ID_Index > 13)
359     {
360         SCU->IPCKENR1 |= 1 << (fe_ID_Index - 14);
361     }
362     else
363     {
364         SCU->IPCKENR2 |= 1 << fe_ID_Index;
365     }
366 
367     System_Delay(2);
368 }
369 
370 /*********************************************************************************
371 * Function    : System_Module_Disable
372 * Description : disable module clock
373 * Input       : module id
374 * Output      : none
375 * Author      : Chris_Kyle
376 **********************************************************************************/
System_Module_Disable(enum_Enable_ID_t fe_ID_Index)377 void System_Module_Disable(enum_Enable_ID_t fe_ID_Index)
378 {
379     if (fe_ID_Index > 13)
380     {
381         SCU->IPCKENR1 &= ~(1 << (fe_ID_Index - 14));
382     }
383     else
384     {
385         SCU->IPCKENR2 &= ~(1 << fe_ID_Index);
386     }
387 }
388 
389 /*********************************************************************************
390 * Function    : System_Delay
391 * Description : NOP delay
392 * Input       : count
393 * Output      : none
394 * Author      : Chris_Kyle
395 **********************************************************************************/
System_Delay(volatile uint32_t fu32_Delay)396 void System_Delay(volatile uint32_t fu32_Delay)
397 {
398     while (fu32_Delay--);
399 }
400 
401 /*********************************************************************************
402 * Function    : System_Delay_MS
403 * Description : ms delay. Use this Function must call System_SysTick_Init()
404 * Input       : delay period, measured as ms
405 * Output      : none
406 * Author      : Chris_Kyle
407 **********************************************************************************/
System_Delay_MS(volatile uint32_t fu32_Delay)408 void System_Delay_MS(volatile uint32_t fu32_Delay)
409 {
410     uint32_t lu32_SystemCountBackup;
411 
412     lu32_SystemCountBackup = gu32_SystemCount;
413 
414     while ( (gu32_SystemCount - lu32_SystemCountBackup) < fu32_Delay);
415 }
416 
417 /*********************************************************************************
418 * Function    : System_Enable_RC32K
419 * Description : Enable RC32K, make sure RTC Domain Access is allowed
420 * Input       : none
421 * Output      : none
422 * Author      : CWT
423 **********************************************************************************/
System_Enable_RC32K(void)424 void System_Enable_RC32K(void)
425 {
426     PMU->ANACR |= (1 << 8);
427     while(0 == ((PMU->ANACR) & (1U << 9)));
428 }
429 
430 /*********************************************************************************
431 * Function    : System_Disable_RC32K
432 * Description : Disable RC32K
433 * Input       : none
434 * Output      : none
435 * Author      : CWT
436 **********************************************************************************/
System_Disable_RC32K(void)437 void System_Disable_RC32K(void)
438 {
439     PMU->ANACR &= (~(1 << 8));
440 }
441 
442 /*********************************************************************************
443 * Function    : System_Enable_XTAL
444 * Description : Enable XTAL, make sure RTC Domain Access is allowed
445 * Input       : none
446 * Output      : none
447 * Author      : CWT
448 **********************************************************************************/
System_Enable_XTAL(void)449 void System_Enable_XTAL(void)
450 {
451     PMU->ANACR = (PMU->ANACR & ~RPMU_ANACR_XTLDRV) | (RPMU_ANACR_XTLDRV_1 | RPMU_ANACR_XTLDRV_0);
452     PMU->ANACR |= RPMU_ANACR_XTLEN;
453     while(!(PMU->ANACR & RPMU_ANACR_XTLRDY));
454     PMU->CR1 |= RTC_CLOCK_XTL;
455 }
456 
457 /*********************************************************************************
458 * Function    : System_Disable_XTAL
459 * Description : Disable XTAL
460 * Input       : none
461 * Output      : none
462 * Author      : CWT
463 **********************************************************************************/
System_Disable_XTAL(void)464 void System_Disable_XTAL(void)
465 {
466     PMU->ANACR &= (~(RPMU_ANACR_XTLEN));
467 }
468 
469 /*********************************************************************************
470 * Function    : System_Enable_Disable_RTC_Domain_Access
471 * Description : Enable or Disable  RTC Domain Access.
472 * Input       : enable or  disable
473 * Output      : none
474 * Author      : CWT
475 **********************************************************************************/
System_Enable_Disable_RTC_Domain_Access(FUNC_DISABLE_ENABLE enable_disable)476 void System_Enable_Disable_RTC_Domain_Access(FUNC_DISABLE_ENABLE enable_disable)
477 {
478     if (FUNC_DISABLE == enable_disable)
479     {
480         SCU->STOPCFG &= (~SCU_STOPCFG_RTC_WE);
481     }
482     else
483     {
484         SCU->STOPCFG |= SCU_STOPCFG_RTC_WE;
485         System_Delay(1);
486         RTC->WP = 0xCA53CA53U;
487     }
488 }
489 
490 /*********************************************************************************
491 * Function    : System_Enable_Disable_Reset
492 * Description : Enable or Disable  System Reset source.
493 * Input       : none
494 * Output      : none
495 * Author      : CWT
496 **********************************************************************************/
System_Enable_Disable_Reset(RESET_ENABLE_SOURCE source,FUNC_DISABLE_ENABLE enable_disable)497 void System_Enable_Disable_Reset(RESET_ENABLE_SOURCE source, FUNC_DISABLE_ENABLE enable_disable)
498 {
499     switch(source)
500     {
501         /* reset source: from bit0 to bit3  */
502         case RESET_ENABLE_SOURCE_LVD:
503         case RESET_ENABLE_SOURCE_WDT:
504         case RESET_ENABLE_SOURCE_IWDT:
505         case RESET_ENABLE_SOURCE_LOCKUP:
506 
507         if (FUNC_DISABLE == enable_disable)
508         {
509             SCU->RCR &= (~(1U << source));
510         }
511         else
512         {
513             SCU->RCR |= (1U << source);
514         }
515         break;
516 
517         default: break;
518     }
519 }
520 
521 /*********************************************************************************
522 * Function    : System_Reset_MCU
523 * Description : reset mcu
524 * Input       : reset source
525 * Output      : none
526 * Author      : xwl
527 **********************************************************************************/
System_Reset_MCU(RESET_SOURCE source)528 void System_Reset_MCU(RESET_SOURCE source)
529 {
530     switch(source)
531     {
532         case RESET_SOURCE_EFC:
533         {
534             SCU->RCR &= (~BIT29);
535             while(1);
536         }break;
537 
538         case RESET_SOURCE_NVIC_RESET:
539         {
540             NVIC_SystemReset();
541             while(1);
542         }break;
543 
544         case RESET_SOFT_RESET:
545         {
546             SCU->RCR &= (~BIT30);
547             while(1);
548         }break;
549 
550         default: break;
551     }
552 }
553 
554 /*********************************************************************************
555 * Function    : System_Enter_Standby_Mode
556 * Description : try to enter standby mode
557 * Input       : none
558 * Output      : none
559 * Author      : xwl                         Date : 2021
560 **********************************************************************************/
System_Enter_Standby_Mode(void)561 void System_Enter_Standby_Mode(void)
562 {
563     __set_PRIMASK(1);    // disable interrupt
564     SysTick->CTRL = 0;   // disable systick
565     SCU->STOPCFG |= BIT11;  // set PDDS=1
566 
567     /* Set SLEEPDEEP bit of Cortex System Control Register */
568     SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
569     __WFI();
570     CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
571     System_Delay(100);
572 
573     printfS("Enter Standby Mode Failed! \n");   // should not go here
574 }
575 
576 /*********************************************************************************
577 * Function    : System_Clear_Stop_Wakeup
578 * Description : clear all stop setting and status
579 * Input       : none
580 * Output      : none
581 * Author      : CWT                         Date : 2021年4月
582 **********************************************************************************/
System_Clear_Stop_Wakeup(void)583 void System_Clear_Stop_Wakeup(void)
584 {
585     EXTI->IENR = 0;
586     EXTI->RTENR = 0;
587     EXTI->FTENR = 0;
588     EXTI->SWIER = 0;
589     EXTI->PDR = 0x7FFFFFU;
590 }
591 
592 /*********************************************************************************
593 * Function    : System_Enter_Stop_Mode
594 * Description : try to enter stop mode
595 * Input       : STOPEntry: STOPENTRY_WFI or STOPENTRY_WFE
596 * Output      : none
597 * Author      : CWT                         Date : 2021
598 **********************************************************************************/
System_Enter_Stop_Mode(uint8_t STOPEntry)599 void System_Enter_Stop_Mode(uint8_t STOPEntry)
600 {
601     /* Set SLEEPDEEP bit of Cortex System Control Register */
602     SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
603 
604     SCU->STOPCFG &= (~BIT11);  // PDDS=0
605 
606     //System_SysTick_Off();
607     /* Select Stop mode entry */
608     if(STOPEntry == STOPENTRY_WFI)
609     {
610         /* Wait For Interrupt */
611         __WFI();
612     }
613     else
614     {
615         __SEV();
616         __WFE();
617         __WFE();    /* Wait For Event */
618     }
619 
620     CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
621 
622 #ifdef HAL_SYSTICK_ENABLED  // To activate macro in ACM32Fxx_HAL.h
623     //System_SysTick_Init();
624 #endif
625 }
626 
627 /*********************************************************************************
628 * Function    : System_Enter_Sleep_Mode
629 * Description : try to enter sleep mode
630 * Input       : SleepEntry: SLEEPENTRY_WFI or SLEEPENTRY_WFE
631 * Output      : none
632 * Author      : CWT                         Date : 2021
633 **********************************************************************************/
System_Enter_Sleep_Mode(uint8_t SleepEntry)634 void System_Enter_Sleep_Mode(uint8_t SleepEntry)
635 {
636     /* clear SLEEPDEEP bit of Cortex System Control Register */
637     CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
638 
639     /* Select Stop mode entry */
640     if(SleepEntry == SLEEPENTRY_WFI)
641     {
642         /* Wait For Interrupt */
643         __WFI();
644     }
645     else
646     {
647 
648         __SEV();
649         __WFE();
650         __WFE(); /*Wait For Event */
651     }
652 
653 }
654 
655 
656  /*********************************************************************************
657 * Function    : System_Return_Last_Reset_Reason
658 * Description : Get System Last Reset Reason
659 * Input       : none
660 * Output      : RESET_REASON
661 * Author      : CWT                         Date : 2021年4月
662 **********************************************************************************/
System_Return_Last_Reset_Reason(void)663 RESET_REASON System_Return_Last_Reset_Reason(void)
664 {
665     RESET_REASON Reset_Reason_Save;
666     RESET_REASON i = RESET_REASON_POR;
667 
668     for(i = RESET_REASON_POR; i >= RESET_REASON_POR12; i--)
669     {
670         if ((SCU->RSR) & (1U << i))
671         {
672             SCU->RSR |= SCU_RSR_RSTFLAG_CLR; // clear reset reason flags
673             Reset_Reason_Save = i;
674             return i;
675         }
676     }
677 
678     for(i = RESET_REASON_LOW_VOLTAGE; i <= RESET_REASON_SOFT; i++)
679     {
680         if ((SCU->RSR) & (1U << i))
681         {
682             SCU->RSR |= SCU_RSR_RSTFLAG_CLR; // clear reset reason flags
683             Reset_Reason_Save = i;
684             return i;
685         }
686     }
687 
688     return RESET_REASON_INVALID;  // this should not happen
689 }
690 
691 /*********************************************************************************
692 * Function    : System_Set_Buzzer_Divider
693 * Description : set buzzer divide factor
694 * Input       :
695               div: div factor, if div = 80 then output buzzer freq=HCLK/80
696               enable: FUNC_DISABLE and FUNC_ENABLE
697 * Output      : none
698 * Author      : xwl                         Date : 2021年4月
699 **********************************************************************************/
System_Set_Buzzer_Divider(uint32_t div,FUNC_DISABLE_ENABLE enable)700 void System_Set_Buzzer_Divider(uint32_t div, FUNC_DISABLE_ENABLE enable)
701 {
702     if (FUNC_ENABLE == enable)
703     {
704         SCU->CLKOCR = (SCU->CLKOCR & (~(0x1FFFFU << 5) ) ) | (div << 5);
705         SCU->CLKOCR |= BIT23;
706     }
707     else
708     {
709         SCU->CLKOCR &= (~BIT23);
710     }
711 }
712 
713 /*********************************************************************************
714 * Function    : System_USB_PHY_Config
715 * Description : Configure USB PHY, such as clock select, pll...
716 * Input       : none
717 * Output      : 0: fail, 1:success
718 * Author      : xwl                         Date : 2021年4月
719 **********************************************************************************/
System_USB_PHY_Config(void)720 uint32_t System_USB_PHY_Config(void)
721 {
722     volatile uint32_t delay_count;
723 
724     SCU->PHYCR &= (~BIT2); // exit power down, auto select clock source
725 
726     delay_count = SYSTEM_TIMEOUT;
727     while(delay_count--)
728     {
729         if (SCU->PHYCR & (BIT19)) // clksel_end flag = 1
730         {
731             break;
732         }
733     }
734 
735     if (delay_count)
736     {
737         return HAL_OK;
738     }
739     else
740     {
741         return HAL_TIMEOUT;
742     }
743 }
744 
745