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