1 /*
2   ******************************************************************************
3   * @file    System_ACM32F0x0.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 RESET_REASON Reset_Reason_Save;
16 
17 /* System count in SysTick_Handler */
18 volatile uint32_t gu32_SystemCount;
19 
20 /************************* Miscellaneous Configuration ************************/
21 /*!< Uncomment the following line if you need to relocate your vector Table in
22      Internal SRAM. */
23 /* #define VECT_TAB_SRAM */
24 #define VECT_TAB_OFFSET  0x0U /*!< Vector Table base offset field.
25                                    This value must be a multiple of 0x200. */
26 /******************************************************************************/
27 #if 0
28 /*********************************************************************************
29 * Function    : HardFault_Handler
30 * Description : Hard Fault handle, while(1) loop, wait for debug
31 * Input       : none
32 * Output      : none
33 * Author      : xwl
34 **********************************************************************************/
35 void HardFault_Handler(void)
36 {
37     while(1);
38 }
39 
40 /*********************************************************************************
41 * Function    : SysTick_Handler
42 * Description : System tick handler
43 * Input       : none
44 * Output      : none
45 * Author      : Chris_Kyle
46 **********************************************************************************/
47 void SysTick_Handler(void)
48 {
49     gu32_SystemCount++;
50 }
51 
52 /*********************************************************************************
53 * Function    : System_SysTick_Init
54 * Description : System Tick Init. Period is 1 ms
55 * Input       : none
56 * Output      : none
57 * Author      : Chris_Kyle
58 **********************************************************************************/
59 void System_SysTick_Init(void)
60 {
61     gu32_SystemCount = 0;
62     SysTick_Config(gu32_SystemClock / 1000);  //1ms/tick
63 }
64 #endif
65 /*********************************************************************************
66 * Function    : System_SysTick_Off
67 * Description : Turn off System Tick
68 * Input       : none
69 * Output      : none
70 * Author      : xwl
71 **********************************************************************************/
System_SysTick_Off(void)72 void System_SysTick_Off(void)
73 {
74     SysTick->CTRL = 0;
75 }
76 /*********************************************************************************
77 * Function    : System_Init
78 * Description : Initialize the system clock
79 * Input       : none
80 * Outpu       : none
81 * Author      : Chris_Kyle                         Date : 2021
82 **********************************************************************************/
System_Init(void)83 void System_Init(void)
84 {
85     SCU->RCR |= SCU_RCR_REMAP_EN;
86     System_Set_Buzzer_Divider(80, FUNC_DISABLE); // disable clock out
87     /* Configure the Vector Table location add offset address ------------------*/
88 #ifdef VECT_TAB_SRAM
89     /* Vector Table Relocation in Internal SRAM */
90     SCU->VECTOROFFSET = SRAM_BASE | VECT_TAB_OFFSET | SCU_VECTOROFFSET_VOFFSETEN;
91 #else
92     /* Vector Table Relocation in Internal FLASH */
93     SCU->VECTOROFFSET = EFLASH_BASE | VECT_TAB_OFFSET | SCU_VECTOROFFSET_VOFFSETEN;
94 #endif
95 
96     /* Initialize the system clock */
97     if (false == System_Clock_Init(DEFAULT_SYSTEM_CLOCK))
98     {
99         while(1);
100     }
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_Clock_Init
109 * Description : Clock init
110 * Input       : fu32_Clock: System core clock
111 * Outpu       : 0: success, other value: fail reason
112 * Author      : xwl                         Date : 2021
113 **********************************************************************************/
System_Clock_Init(uint32_t fu32_Clock)114 bool System_Clock_Init(uint32_t fu32_Clock)
115 {
116     uint32_t lu32_DIV, lu32_system_clk_source, lu32_result, lu32_timeout;
117 
118     lu32_system_clk_source = CLK_SRC_RC64M;
119 
120     SET_EFC_RD_WAIT(RD_WAIT_SET_DEFAULT)
121 
122     switch (fu32_Clock)
123     {
124         /* 64MHz */
125         case 64000000: lu32_DIV = 1; break;
126 
127         /* 32MHz */
128         case 32000000: lu32_DIV = 2; break;
129 
130         /* 16MHz */
131         case 16000000: lu32_DIV = 4; break;
132 
133         /* 8MHz */
134         case 8000000:  lu32_DIV = 8; break;
135 
136         default: return false;
137     }
138 
139     lu32_result = 0;
140 
141     if (lu32_system_clk_source == CLK_SRC_XTH_PLL)
142     {
143         lu32_timeout = 0;
144 
145         SCU->XTHCR = SCU_XTHCR_XTH_EN | SCU_XTHCR_READYTIME_32768;
146         while (0 == (SCU->XTHCR & SCU_XTHCR_XTHRDY))
147         {
148             if (lu32_timeout == SYSTEM_TIMEOUT)
149             {
150                 lu32_result = 1;
151                 break;
152             }
153             lu32_timeout++;
154         }
155 
156         if (0 == lu32_result)
157         {
158             SCU->PLLCR |=  SCU_PLLCR_PLL_EN;
159             SCU->PLLCR &= ~(SCU_PLLCR_PLL_SLEEP);
160             while(!(SCU->PLLCR & (SCU_PLLCR_PLL_FREE_RUN) )) {}
161 
162 #ifdef XTH_8M_CRYSTAL
163             SCU->PLLCR = (SCU->PLLCR &(~(0x1FFFFU << 3))) | (15U << 3) | (1U << 12) | (0U << 16);
164 #endif
165 
166 #ifdef XTH_12M_CRYSTAL
167             SCU->PLLCR = (SCU->PLLCR &(~(0x1FFFFU << 3))) | (15U << 3) | (2U << 12) | (0U << 16);
168 #endif
169 
170             SCU->PLLCR = (SCU->PLLCR & (~(0x3U << 1)) ) | (3 << 1);
171             SCU->PLLCR |= SCU_PLLCR_PLL_UPDATE_EN;
172             while(!(SCU->PLLCR & (SCU_PLLCR_PLL_FREE_RUN) ) );
173 
174             /* Division Config */
175             SCU->CCR2 = (SCU->CCR2 & (~0xFF)) | APB_CLK_DIV_0 | (lu32_DIV - 1);
176             while((SCU->CCR2 & (1UL << 31)) == 0x00);
177 
178             /* Clock Select PLL */
179             SCU->CCR1 = SYS_CLK_SRC_PLLCLK;
180         }
181         else
182         {
183             SCU->XTHCR &= (~SCU_XTHCR_XTH_EN);
184         }
185     }
186 
187     if ( (lu32_system_clk_source == CLK_SRC_RC64M) || (0 != lu32_result) )
188     {
189         /* Division Config */
190         SCU->CCR2 = (SCU->CCR2 & (~0xFF)) | APB_CLK_DIV_0 | (lu32_DIV - 1);
191         while((SCU->CCR2 & (1UL << 31)) == 0x00);
192 
193         /* Clock Select RCH */
194         SCU->CCR1 = SYS_CLK_SRC_RCH;
195     }
196 
197     gu32_SystemClock = fu32_Clock;
198     gu32_APBClock    = fu32_Clock;
199 
200     /* Eflash Config */
201     //HAL_EFlash_Init(gu32_SystemClock);
202 
203     return true;
204 }
205 
206 /*********************************************************************************
207 * Function    : System_Get_SystemClock
208 * Description : get AHB clock frequency
209 * Input       : none
210 * Outpu       : frequency, measured as Hz
211 * Author      : Chris_Kyle                         Date : 2020
212 **********************************************************************************/
System_Get_SystemClock(void)213 uint32_t System_Get_SystemClock(void)
214 {
215     return gu32_SystemClock;
216 }
217 
218 /*********************************************************************************
219 * Function    : System_Get_APBClock
220 * Description : get APB clock frequency
221 * Input       : none
222 * Outpu       : frequency, measured as Hz
223 * Author      : Chris_Kyle                         Date : 2021
224 **********************************************************************************/
System_Get_APBClock(void)225 uint32_t System_Get_APBClock(void)
226 {
227     return gu32_APBClock;
228 }
229 
230 /*********************************************************************************
231 * Function    : System_Module_Reset
232 * Description : reset module
233 * Input       : module id
234 * Outpu       : none
235 * Author      : Chris_Kyle                         Date : 2021
236 **********************************************************************************/
System_Module_Reset(enum_RST_ID_t fe_ID_Index)237 void System_Module_Reset(enum_RST_ID_t fe_ID_Index)
238 {
239     SCU->IPRST &= (~(1 << fe_ID_Index));
240     System_Delay(2);
241     SCU->IPRST |= (1 << fe_ID_Index);
242 }
243 
244 /*********************************************************************************
245 * Function    : System_Module_Enable
246 * Description : enable module clock
247 * Input       : module id
248 * Outpu       : none
249 * Author      : Chris_Kyle                         Date : 2021
250 **********************************************************************************/
System_Module_Enable(enum_Enable_ID_t fe_ID_Index)251 void System_Module_Enable(enum_Enable_ID_t fe_ID_Index)
252 {
253     if (fe_ID_Index > 6)
254     {
255         SCU->IPCKENR1 |= (1U << (fe_ID_Index - 7) );
256     }
257     else
258     {
259         SCU->IPCKENR2 |= (1U << fe_ID_Index);
260     }
261 
262     System_Delay(2);
263 }
264 
265 /*********************************************************************************
266 * Function    : System_Module_Disable
267 * Description : disable module clock
268 * Input       : module id
269 * Outpu       : none
270 * Author      : Chris_Kyle                         Date : 2021
271 **********************************************************************************/
System_Module_Disable(enum_Enable_ID_t fe_ID_Index)272 void System_Module_Disable(enum_Enable_ID_t fe_ID_Index)
273 {
274     if (fe_ID_Index > 6)
275     {
276         SCU->IPCKENR1 &= ~(1U << (fe_ID_Index - 7));
277     }
278     else
279     {
280         SCU->IPCKENR2 &= ~(1U << fe_ID_Index);
281     }
282 }
283 
284 /*********************************************************************************
285 * Function    : System_Delay
286 * Description : NOP delay
287 * Input       : count
288 * Output      : none
289 * Author      : Chris_Kyle
290 **********************************************************************************/
System_Delay(volatile uint32_t fu32_Delay)291 void System_Delay(volatile uint32_t fu32_Delay)
292 {
293     while (fu32_Delay--);
294 }
295 
296 /*********************************************************************************
297 * Function    : System_Delay_MS
298 * Description : ms delay. Use this Function must call System_SysTick_Init()
299 * Input       : delay period, measured as ms
300 * Output      : none
301 * Author      : Chris_Kyle
302 **********************************************************************************/
System_Delay_MS(volatile uint32_t fu32_Delay)303 void System_Delay_MS(volatile uint32_t fu32_Delay)
304 {
305     uint32_t lu32_SystemCountBackup;
306 
307     lu32_SystemCountBackup = gu32_SystemCount;
308 
309     while ( (gu32_SystemCount - lu32_SystemCountBackup) < fu32_Delay);
310 }
311 
312 /*********************************************************************************
313 * Function    : System_Enable_RC32K
314 * Description : Enable RC32K, make sure RTC Domain Access is allowed
315 * Input       : none
316 * Outpu       : none
317 * Author      : Chris_Kyle                         Date : 2021
318 **********************************************************************************/
System_Enable_RC32K(void)319 void System_Enable_RC32K(void)
320 {
321     PMU->ANACR |= RPMU_ANACR_RC32K_EN;
322     while(!(PMU->ANACR & RPMU_ANACR_RC32K_RDY));
323 }
324 
325 /*********************************************************************************
326 * Function    : System_Disable_RC32K
327 * Description : Disable RC32K
328 * Input       : none
329 * Outpu       : none
330 * Author      : CWT                         Date : 2021
331 **********************************************************************************/
System_Disable_RC32K(void)332 void System_Disable_RC32K(void)
333 {
334     PMU->ANACR &= (~RPMU_ANACR_RC32K_EN);
335 }
336 
337 /*********************************************************************************
338 * Function    : System_Enable_XTAL
339 * Description : Enable XTAL, make sure RTC Domain Access is allowed
340 * Input       : none
341 * Outpu       : none
342 * Author      : Chris_Kyle                         Date : 2021
343 **********************************************************************************/
System_Enable_XTAL(void)344 void System_Enable_XTAL(void)
345 {
346     PMU->ANACR = (PMU->ANACR & ~RPMU_ANACR_XTLDRV) | (RPMU_ANACR_XTLDRV_1 | RPMU_ANACR_XTLDRV_0);
347     PMU->ANACR |= RPMU_ANACR_XTLEN;
348     while(!(PMU->ANACR & RPMU_ANACR_XTLRDY));
349     PMU->CR1 |= RTC_CLOCK_XTL;
350 }
351 
352 /*********************************************************************************
353 * Function    : System_Disable_XTAL
354 * Description : Disable XTAL
355 * Input       : none
356 * Output      : none
357 * Author      : CWT
358 **********************************************************************************/
System_Disable_XTAL(void)359 void System_Disable_XTAL(void)
360 {
361     PMU->ANACR &= (~(RPMU_ANACR_XTLEN));
362 }
363 
364 /*********************************************************************************
365 * Function    : System_Enable_Disable_RTC_Domain_Access
366 * Description : Enable or Disable  RTC Domain Access.
367 * Input       : enable or  disable
368 * Output      : none
369 * Author      : CWT
370 **********************************************************************************/
System_Enable_Disable_RTC_Domain_Access(FUNC_DISABLE_ENABLE enable_disable)371 void System_Enable_Disable_RTC_Domain_Access(FUNC_DISABLE_ENABLE enable_disable)
372 {
373     if (FUNC_DISABLE == enable_disable)
374     {
375         SCU->STOPCFG &= (~SCU_STOPCFG_RTC_WE);
376     }
377     else
378     {
379         SCU->STOPCFG |= SCU_STOPCFG_RTC_WE;
380         System_Delay(1);
381         RTC->WP = 0xCA53CA53U;
382     }
383 }
384 
385 /*********************************************************************************
386 * Function    : System_Enable_Disable_Reset
387 * Description : Enable or Disable  System Reset source.
388 * Input       : none
389 * Output      : none
390 * Author      : CWT
391 **********************************************************************************/
System_Enable_Disable_Reset(RESET_ENABLE_SOURCE source,FUNC_DISABLE_ENABLE enable_disable)392 void System_Enable_Disable_Reset(RESET_ENABLE_SOURCE source, FUNC_DISABLE_ENABLE enable_disable)
393 {
394     switch(source)
395     {
396         /* reset source: from bit0 to bit3  */
397         case RESET_ENABLE_SOURCE_LVD:
398         case RESET_ENABLE_SOURCE_WDT:
399         case RESET_ENABLE_SOURCE_IWDT:
400         case RESET_ENABLE_SOURCE_LOCKUP:
401 
402         if (FUNC_DISABLE == enable_disable)
403         {
404             SCU->RCR &= (~(1U << source));
405         }
406         else
407         {
408             SCU->RCR |= (1U << source);
409         }
410         break;
411 
412         default: break;
413     }
414 }
415 
416 /*********************************************************************************
417 * Function    : System_Reset_MCU
418 * Description : reset mcu
419 * Input       : reset source
420 * Output      : none
421 * Author      : xwl
422 **********************************************************************************/
System_Reset_MCU(RESET_SOURCE source)423 void System_Reset_MCU(RESET_SOURCE source)
424 {
425     switch(source)
426     {
427         case RESET_SOURCE_EFC:
428         {
429             SCU->RCR &= (~BIT29);
430             while(1);
431         }
432 
433         case RESET_SOURCE_NVIC_RESET:
434         {
435             NVIC_SystemReset();
436             while(1);
437         }
438 
439         case RESET_SOFT_RESET:
440         {
441             SCU->RCR &= (~BIT30);
442             while(1);
443         }
444 
445         default: break;
446     }
447 }
448 
449 /*********************************************************************************
450 * Function    : System_Enter_Standby_Mode
451 * Description : try to enter standby mode
452 * Input       : none
453 * Output      : none
454 * Author      : xwl                         Date : 2021
455 **********************************************************************************/
System_Enter_Standby_Mode(void)456 void System_Enter_Standby_Mode(void)
457 {
458     __set_PRIMASK(1);    // disable interrupt
459     SysTick->CTRL = 0;   // disable systick
460     SCU->STOPCFG |= BIT11;  // set PDDS=1
461 
462     /* Set SLEEPDEEP bit of Cortex System Control Register */
463     SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
464     __WFI();
465     CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
466     System_Delay(100);
467 
468     printfS("Enter Standby Mode Failed! \n");   // should not go here
469 }
470 
471 /*********************************************************************************
472 * Function    : System_Clear_Stop_Wakeup
473 * Description : clear all stop setting and status
474 * Input       : none
475 * Output      : none
476 * Author      : CWT                         Date : 2021
477 **********************************************************************************/
System_Clear_Stop_Wakeup(void)478 void System_Clear_Stop_Wakeup(void)
479 {
480     EXTI->IENR = 0;
481     EXTI->RTENR = 0;
482     EXTI->FTENR = 0;
483     EXTI->SWIER = 0;
484     EXTI->PDR = 0x7FFFFFU;
485 }
486 
487 /*********************************************************************************
488 * Function    : System_Enter_Stop_Mode
489 * Description : try to enter stop mode
490 * Input       : STOPEntry: STOPENTRY_WFI or STOPENTRY_WFE
491 * Output      : none
492 * Author      : CWT                         Date : 2021
493 **********************************************************************************/
System_Enter_Stop_Mode(uint8_t STOPEntry)494 void System_Enter_Stop_Mode(uint8_t STOPEntry)
495 {
496     /* Set SLEEPDEEP bit of Cortex System Control Register */
497     SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
498 
499     SCU->STOPCFG &= (~BIT11);  // PDDS=0
500 
501     System_SysTick_Off();
502     /* Select Stop mode entry */
503     if(STOPEntry == STOPENTRY_WFI)
504     {
505         /* Wait For Interrupt */
506         __WFI();
507     }
508     else
509     {
510         __SEV();
511         __WFE();
512         __WFE();    /* Wait For Event */
513     }
514 
515     CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
516 
517 #ifdef HAL_SYSTICK_ENABLED  // To activate macro in ACM32Fxx_HAL.h
518     System_SysTick_Init();
519 #endif
520 }
521 
522 /*********************************************************************************
523 * Function    : System_Enter_Sleep_Mode
524 * Description : try to enter sleep mode
525 * Input       : SleepEntry: SLEEPENTRY_WFI or SLEEPENTRY_WFE
526 * Output      : none
527 * Author      : CWT                         Date : 2021
528 **********************************************************************************/
System_Enter_Sleep_Mode(uint8_t SleepEntry)529 void System_Enter_Sleep_Mode(uint8_t SleepEntry)
530 {
531     /* clear SLEEPDEEP bit of Cortex System Control Register */
532     CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
533 
534     /* Select Stop mode entry */
535     if(SleepEntry == SLEEPENTRY_WFI)
536     {
537         /* Wait For Interrupt */
538         __WFI();
539     }
540     else
541     {
542 
543         __SEV();
544         __WFE();
545         __WFE(); /*Wait For Event */
546     }
547 
548 }
549 
550  /*********************************************************************************
551 * Function    : System_Return_Last_Reset_Reason
552 * Description : Get System Last Reset Reason
553 * Input       : none
554 * Output      : RESET_REASON
555 * Author      : CWT                         Date : 2021
556 **********************************************************************************/
System_Return_Last_Reset_Reason(void)557 RESET_REASON System_Return_Last_Reset_Reason(void)
558 {
559     RESET_REASON i = RESET_REASON_POR;
560     Reset_Reason_Save = RESET_REASON_POR;
561 
562     for(i = RESET_REASON_POR; i >= RESET_REASON_POR12; i--)
563     {
564         if ((SCU->RSR) & (1U << i))
565         {
566             SCU->RSR |= SCU_RSR_RSTFLAG_CLR; // clear reset reason flags
567             Reset_Reason_Save = i;
568             return i;
569         }
570     }
571 
572     for(i = RESET_REASON_LOW_VOLTAGE; i <= RESET_REASON_SOFT; i++)
573     {
574         if ((SCU->RSR) & (1U << i))
575         {
576             SCU->RSR |= SCU_RSR_RSTFLAG_CLR; // clear reset reason flags
577             Reset_Reason_Save = i;
578             return i;
579         }
580     }
581 
582     return RESET_REASON_INVALID;  // this should not happen
583 }
584 
585  /*********************************************************************************
586 * Function    : System_Return_Saved_Reset_Reason
587 * Description : Get saved Reset Reason
588 * Input       : none
589 * Output      : RESET_REASON
590 * Author      : CWT                         Date : 2021
591 **********************************************************************************/
System_Return_Saved_Reset_Reason(void)592 RESET_REASON System_Return_Saved_Reset_Reason(void)
593 {
594     return Reset_Reason_Save;
595 }
596  /*********************************************************************************
597 * Function    : System_Set_Buzzer_Divider
598 * Description : set buzzer divide factor
599 * Input       :
600               div: div factor, if div = 80 then output buzzer freq=HCLK/80
601               enable: FUNC_DISABLE and FUNC_ENABLE
602 * Output      : none
603 * Author      : xwl                         Date : 2021
604 **********************************************************************************/
System_Set_Buzzer_Divider(uint32_t div,FUNC_DISABLE_ENABLE enable)605 void System_Set_Buzzer_Divider(uint32_t div, FUNC_DISABLE_ENABLE enable)
606 {
607     if (FUNC_ENABLE == enable)
608     {
609         SCU->CLKOCR = (SCU->CLKOCR & (~(0x1FFFFU << 5) ) ) | (div << 5);
610         SCU->CLKOCR |= BIT23;
611     }
612     else
613     {
614         SCU->CLKOCR &= (~BIT23);
615     }
616 }
617 
618