1 /**************************************************************************//**
2  * @file    library/Device/Holtek/HT32F5xxxx/Source/system_ht32f5xxxx_07.c
3  * @brief   CMSIS Cortex-M0+ Device Peripheral Access Layer Source File
4  *          for the Holtek HT32F5xxxx Device Series
5  * @version $Rev:: 6597         $
6  * @date    $Date:: 2022-12-27 #$
7  *
8  * @note
9  * Copyright (C) Holtek Semiconductor Inc. All rights reserved.
10  *
11  * @par
12  * ARM Limited (ARM) supplies this software for Cortex-M processor-based
13  * microcontrollers. This file can be freely distributed within development
14  * tools that are supporting such ARM based processors.
15  *
16  * @par
17  * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
18  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
20  * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
21  * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
22  *
23  ******************************************************************************/
24 
25 // Supported Device
26 // ========================================
27 //   HT32F0006
28 //   HT32F61352
29 //   HT32F61355
30 //   HT32F61356
31 //   HT32F61357
32 
33 //#define USE_HT32F0006
34 //#define USE_HT32F61352
35 //#define USE_HT32F61355_56_57
36 
37 /** @addtogroup CMSIS
38   * @{
39   */
40 
41 /** @addtogroup HT32F5xxxx_system HT32F5xxxx System
42   * @{
43   */
44 
45 
46 #include "ht32f5xxxx_01.h"
47 
48 /** @addtogroup HT32F5xxxx_System_Private_Defines
49   * @{
50   */
51 /*
52 //-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
53 */
54 
55 /*--------------------- Clock Configuration ----------------------------------
56 //
57 //    <q1> Enable High Speed External Crystal Oscillator (HSE)
58 //          <i> Default HSE = DISABLE
59 //
60 //    <q3> Enable Low Speed External Crystal Oscillator (LSE)
61 //          <i> Default LSE = DISABLE
62 //
63 //    <e4> Enable PLL
64 //                <i> Default PLL = DISABLE
65 //        <o5>  PLL Clock Source
66 //                <0=> CK_HSE
67 //                <1=> CK_HSI
68 //                <i> Default PLL clock source = CK_HSI
69 //                <i> PLL source clock must be in the range of 4 MHz to 16 MHz
70 //        <o6>  PLL Feedback Clock Divider (NF2): 1 ~ 16
71 //                <1-16:1>
72 //                <i> PLL feedback clock = PLL clock source x NF2
73 //                <i> PLL feedback clock must be in the range of 24 MHz to 48 MHz
74 //        <o7>  PLL Output Clock Divider (NO2)
75 //                <0=> 1
76 //                <1=> 2
77 //                <2=> 4
78 //                <3=> 8
79 //                <i> PLL output clock = PLL feedback clock / NO2
80 //                <i> PLL output clock must be in the range of 4 MHz to 48 MHz
81 //      </e>
82 //
83 //    <h> SystemCoreClock Configuration (CK_AHB)
84 //      <o8>    SystemCoreClock Source
85 //                <1=> CK_PLL
86 //                <2=> CK_HSE
87 //                <3=> CK_HSI
88 //                <6=> CK_LSE
89 //                <7=> CK_LSI
90 //                <i> Default SystemCoreClock source = CK_HSI
91 //      <o9>    SystemCoreClock Source Divider
92 //                <0=> 1
93 //                <1=> 2
94 //                <2=> 4
95 //                <3=> 8
96 //                <4=> 16
97 //                <5=> 32
98 //                <i> Default SystemCoreClock source divider = 1
99 //    </h>
100 //
101 //    <h> FLASH Configuration
102 //      <o10>   Wait state
103 //                <0=> 0 WS
104 //                <1=> 1 WS
105 //                <9=> AUTO
106 //                <i>   0 WS:  1 kHz <= CK_AHB <= 24 MHz
107 //                <i>   1 WS: 24 MHz <  CK_AHB <= 48 MHz
108 //      <q11>   Pre-fetch Buffer Enable
109 //                <i> Default pre-fetch buffer = ENABLE
110 //      <q12>   Branch cache Enable
111 //                <i> Default branch cache = ENABLE
112 //    </h>
113 */
114 
115 /* !!! NOTICE !!!
116    HSI must keep turn on when doing the Flash operation (Erase/Program).
117 */
118 
119 /* !!! NOTICE !!!
120  * How to adjust the value of High Speed External oscillator (HSE)?
121    The default value of HSE is define by "HSE_VALUE" in "ht32fxxxxx_nn.h".
122    If your board uses a different HSE speed, please add a new compiler preprocessor
123    C define, "HSE_VALUE=n000000" ("n" represents n MHz) in the toolchain/IDE,
124    or edit the "HSE_VALUE" in the "ht32f5xxxx_conf.h" file.
125    Take Keil MDK-ARM for instance, to set HSE as 16 MHz:
126    "Option of Taret -> C/C++ > Preprocessor Symbols"
127       Define: USE_HT32_DRIVER, USE_HT32Fxxxxx_SK, USE_HT32Fxxxxx_xx, USE_MEM_HT32Fxxxxx, HSE_VALUE=16000000
128                                                                                          ^^ Add "HSE_VALUE"
129                                                                                             define as above.
130 */
131 #define HSI_ENABLE        (1)     /*!< 0: DISABLE,  1: ENABLE                                               */
132 #define HSE_ENABLE        (1)     /*!< 0: DISABLE,  1: ENABLE                                               */
133 #define LSI_ENABLE        (1)     /*!< 0: DISABLE,  1: ENABLE                                               */
134 #define LSE_ENABLE        (0)     /*!< 0: DISABLE,  1: ENABLE                                               */
135 #define PLL_ENABLE        (1)     /*!< 0: DISABLE,  1: ENABLE                                               */
136 #define PLL_CLK_SRC       (0)     /*!< 0: HSE,      1: HSI                                                  */
137 #define PLL_NF2_DIV       (4)     /*!< 1~16: DIV1~DIV16                                                     */
138 #define PLL_NO2_DIV       (0)     /*!< 0: DIV1,     1: DIV2,   2: DIV4,   3: DIV8                           */
139 #define HCLK_SRC          (1)     /*!< 0: PLL,      1: PLL,    2: HSE,    3: HSI     6: LSE,    7: LSI      */
140 #define HCLK_DIV          (0)     /*!< 0: DIV1,     1: DIV2,   2: DIV4,   3: DIV8,   4: DIV16,  5: DIV32    */
141 #define WAIT_STATE        (9)     /*!< 0: WS = 0,   1: WS = 1,                       9: WS = AUTO           */
142 #define PRE_FETCH_ENABLE  (1)     /*!< 0: DISABLE,  1: ENABLE                                               */
143 #define BCACHE_ENABLE     (1)     /*!< 0: DISABLE,  1: ENABLE                                               */
144 #define DEINIT_ENABLE     (1)     /* Set 0 for reduce code size                                             */
145 
146 /*----------------------------------------------------------------------------------------------------------*/
147 /* PLL Out = ((HSE or HSI) x PLL_NF2) / PLL_NO2                                                             */
148 /*----------------------------------------------------------------------------------------------------------*/
149 
150 
151 /*--------------------- WDT Configuration ----------------------------------
152 //
153 //    <e0> Enable WDT Configuration
154 //      <o1> WDT Prescaler Selection
155 //           <0=> CK_WDT / 1
156 //           <1=> CK_WDT / 2
157 //           <2=> CK_WDT / 4
158 //           <3=> CK_WDT / 8
159 //           <4=> CK_WDT / 16
160 //           <5=> CK_WDT / 32
161 //           <6=> CK_WDT / 64
162 //           <7=> CK_WDT / 128
163 //      <o2> WDT Reload Value <1-4095:1>
164 //      <q3> Enable WDT Reset function
165 //      <o4> WDT Sleep Halt mode
166 //           <0=> No halt
167 //           <1=> Halt in DeepSleep1
168 //           <2=> Halt in Sleep & DeepSleep1
169 //   </e>
170 */
171 #define WDT_ENABLE        (0)     /*!< 0: DISABLE,  1: ENABLE                                               */
172 #define WDT_PRESCALER     (5)     /*!< 0: 1/1, 1: 1/2, 2: 1/4, 3: 1/8, 4: 1/16, 5: 1/32, 6: 1/64, 7: 1/128  */
173 #define WDT_RELOAD        (2000)  /*!< 0 ~ 4095, 12 bit                                                     */
174 #define WDT_RESET_ENABLE  (1)     /*!< 0: No Reset, 1: Reset when WDT over flow                             */
175 #define WDT_SLEEP_HALT    (2)     /*!< 0: No halt,  1: Halt in DeepSleep1, 2: Halt in Sleep & DeepSleep1    */
176 
177 /**
178  * @brief Check HSI frequency
179  */
180 #if (HSI_VALUE != 8000000UL)
181   #error "CK_HSI clock issue: must be 8 MHz!"
182 #endif
183 
184 /**
185  * @brief Check HSE frequency
186  */
187 #if ((HSE_VALUE < 4000000UL) || (HSE_VALUE > 16000000UL))
188   #error "CK_HSE clock issue: must be in the range of 4 MHz to 16 MHz!"
189 #endif
190 
191 /**
192  * @brief Check LSI frequency
193  */
194 #if (LSI_VALUE != 32000UL)
195   #error "CK_LSI clock issue: must be 32 kHz!"
196 #endif
197 
198 /**
199  * @brief Check LSE frequency
200  */
201 #if (LSE_VALUE != 32768UL)
202   #error "CK_LSE clock issue: must be 32.768 kHz!"
203 #endif
204 
205 /**
206  * @brief CK_PLL definition
207  */
208 #if (PLL_ENABLE == 1)
209   /* Get CK_VCO frequency                                                                                   */
210   #if (PLL_CLK_SRC == 1)
211     #if (HSI_ENABLE == 0)
212       #error "CK_PLL clock source issue: HSI has not been enabled"
213     #else
214       #define __CK_VCO    (HSI_VALUE * PLL_NF2_DIV)             /*!< Select HSI as PLL source               */
215     #endif
216   #else
217     #if (HSE_ENABLE == 0)
218       #error "CK_PLL clock source issue: HSE has not been enabled!"
219     #else
220       #define __CK_VCO    (HSE_VALUE * PLL_NF2_DIV)             /*!< Select HSE as PLL source               */
221     #endif
222   #endif
223 
224   #define VCO_MIN 24000000UL
225   #define VCO_MAX 48000000UL
226   #define PLL_MIN  4000000UL
227   #define PLL_MAX 48000000UL
228 
229   /* Check CK_VCO frequency                                                                                 */
230   #if ((__CK_VCO < VCO_MIN) || (__CK_VCO > VCO_MAX))
231     #error "CK_VCO clock issue: must be in the range!"
232   #endif
233 
234   #define __CK_PLL    (__CK_VCO >> PLL_NO2_DIV)                 /*!< Get CK_PLL frequency                   */
235 
236   /* Check CK_PLL frequency                                                                                 */
237   #if ((__CK_PLL < PLL_MIN) || (__CK_PLL > PLL_MAX))
238     #error "CK_PLL clock issue: must be in the range!"
239   #endif
240 #endif
241 
242 /**
243  * @brief CK_SYS definition
244  */
245 #if (HCLK_SRC == 1)
246   #if (PLL_ENABLE == 1)
247     #define __CK_SYS    __CK_PLL              /*!< Select PLL as CK_SYS source                              */
248   #else
249     #error "CK_SYS clock source issue: PLL is not enable!"
250   #endif
251 #elif (HCLK_SRC == 2)
252   #if (HSE_ENABLE == 1)
253     #define __CK_SYS    HSE_VALUE             /*!< Select HSE as CK_SYS source                              */
254   #else
255     #error "CK_SYS clock source issue: HSE is not enable!"
256   #endif
257 #elif (HCLK_SRC == 3)
258   #if (HSI_ENABLE == 1)
259     #define __CK_SYS    HSI_VALUE             /*!< Select HSI as CK_SYS source                              */
260   #else
261     #error "CK_SYS clock source issue: HSI is not enable!"
262   #endif
263 #elif (HCLK_SRC == 6)
264   #if (LSE_ENABLE == 1)
265     #define __CK_SYS    LSE_VALUE             /*!< Select LSE as CK_SYS source                              */
266   #else
267     #error "CK_SYS clock source issue: LSE is not enable!"
268   #endif
269 #elif (HCLK_SRC == 7)
270   #if (LSI_ENABLE == 1)
271     #define __CK_SYS    LSI_VALUE             /*!< Select LSI as CK_SYS source                              */
272   #else
273     #error "CK_SYS clock source issue: LSI is not enable!"
274   #endif
275 #else
276   #error "CK_SYS clock source issue: No clock source is selected!"
277 #endif
278 
279 /**
280  * @brief CK_AHB definition
281  */
282 #define __CK_AHB    (__CK_SYS >> HCLK_DIV)    /*!< Get CK_AHB frequency                                     */
283 
284 #define CKAHB_MIN 1000UL
285 #define CKAHB_MAX 48000000UL
286 #define WS0_CLK   24000000UL
287 
288 /* Check CK_AHB frequency                                                                                   */
289 #if ((__CK_AHB < CKAHB_MIN) || (__CK_AHB > CKAHB_MAX))
290   #error "CK_AHB clock issue: must be in the range!"
291 #endif
292 
293 /* Check FLASH wait-state setting                                                                           */
294 #if ((__CK_AHB > WS0_CLK) && (WAIT_STATE < 1))
295   #error "FLASH wait state configuration issue!"
296 #endif
297 /**
298   * @}
299   */
300 
301 /** @addtogroup HT32F5xxxx_System_Private_Variables
302   * @{
303   */
304 __IO uint32_t SystemCoreClock = __CK_AHB;   /*!< SystemCoreClock = CK_AHB                                   */
305 /**
306   * @}
307   */
308 
309 /** @addtogroup HT32F5xxxx_System_Private_Functions
310   * @{
311   */
312 
313 /**
314   * @brief  Setup the microcontroller system.
315   *         Initializes the system clocks and the embedded Flash.
316   * @note   This function should be used after reset.
317   * @retval None
318   */
SystemInit(void)319 void SystemInit(void)
320 {
321 #if (WDT_ENABLE == 1)
322   HT_CKCU->APBCCR1 |= (0x1 << 4);
323   HT_WDT->PR = 0x35CA;
324   HT_WDT->MR0 = 0;
325   HT_WDT->MR1 = ((HT_WDT->MR1 & 0xFFF) | (WDT_PRESCALER << 12));
326   HT_WDT->MR0 = WDT_RELOAD | (WDT_RESET_ENABLE << 13) | (WDT_SLEEP_HALT << 14) | (0x1 << 16);
327   HT_WDT->CR = 0x5FA00001;
328 #else
329   #if (DEINIT_ENABLE == 1)
330   HT_RSTCU->APBPRST1 = (1 << 4);
331   #endif
332 #endif
333 
334   HT_CKCU->LPCR = 1;                                            /* configure Backup domain isolation        */
335   SetBit_BB((u32)(&HT_CKCU->APBCCR1), 6);                       /* enable Backup domain register clock      */
336   while (HT_PWRCU->TEST != 0x27);                               /* wait for Backup domain register ready    */
337 
338   #if (DEINIT_ENABLE == 1)
339   /* De-init the setting                                                                                    */
340   HT_CKCU->AHBCCR &= ~(0x3 << 10);                              /* disable IP who may use PLL as source     */
341   SetBit_BB((u32)(&HT_CKCU->GCCR), 11);                         /* enable HSI                               */
342   while (!GetBit_BB((u32)(&HT_CKCU->GCSR), 3));                 /* wait for HSI ready                       */
343   HT_CKCU->GCCR = ((HT_CKCU->GCCR & ~7UL) | 3UL);               /* select CK_SYS source                     */
344   while ((HT_CKCU->CKST & 7UL) != 3UL);                         /* wait for clock switch complete           */
345   HT_FLASH->CFCR = (((HT_FLASH->CFCR) & ~7UL) | 1UL);           /* set Wait State as 0 WS                   */
346   HT_CKCU->AHBCFGR = 0;                                         /* set CK_AHB prescaler                     */
347   ResetBit_BB((u32)(&HT_CKCU->GCCR), 9);                        /* disable PLL                              */
348   SetBit_BB((u32)(&HT_CKCU->GCFGR), 8);                         /* select PLL source as HSI                 */
349   #endif
350 
351   /* HSE initiation                                                                                         */
352 #if (HSE_ENABLE == 1)
353   SetBit_BB((u32)(&HT_CKCU->GCCR), 10);                         /* enable HSE                               */
354   while (!GetBit_BB((u32)(&HT_CKCU->GCSR), 2)){};               /* wait for HSE ready                       */
355 #endif
356 
357   /* LSE initiation                                                                                         */
358 #if (LSE_ENABLE == 1)
359   do {
360     SetBit_BB((u32)(&HT_RTC->CR), 3);                           /* enable LSE                               */
361   } while (!GetBit_BB((u32)(&HT_RTC->CR), 3));
362   while (!GetBit_BB((u32)(&HT_CKCU->GCSR), 4));                 /* wait for LSE ready                       */
363 #endif
364 
365   ResetBit_BB((u32)(&HT_CKCU->APBCCR1), 6);                     /* disable Backup domain register clock     */
366 
367   /* LSI initiation                                                                                         */
368 #if (HCLK_SRC == 7)
369   while (!GetBit_BB((u32)(&HT_CKCU->GCSR), 5)){};               /* wait for LSI ready                       */
370 #endif
371 
372   /* PLL initiation                                                                                         */
373 #if (PLL_ENABLE == 1)
374   #if (PLL_CLK_SRC == 0)
375     ResetBit_BB((u32)(&HT_CKCU->GCFGR), 8);                     /* select PLL source as HSE                 */
376   #else
377     SetBit_BB((u32)(&HT_CKCU->GCFGR), 8);                       /* select PLL source as HSI                 */
378   #endif
379   HT_CKCU->PLLCFGR = ((PLL_NF2_DIV & 0x0F) << 23) | (PLL_NO2_DIV << 21);  /* set PLL divider                */
380   SetBit_BB((u32)(&HT_CKCU->GCCR), 9);                                    /* enable PLL                     */
381   while (!GetBit_BB((u32)(&HT_CKCU->GCSR), 1)){};                         /* wait for PLL ready             */
382 #endif
383 
384   /* CK_AHB initiation                                                                                      */
385 #if (WAIT_STATE == 9)
386   #if (__CK_AHB > WS0_CLK)
387     HT_FLASH->CFCR = (((HT_FLASH->CFCR) & ~7UL) | 2UL);         /* auto-select wait state                   */
388   #endif
389 #else
390   HT_FLASH->CFCR = (((HT_FLASH->CFCR) & ~7UL) | (WAIT_STATE + 1));        /* manual wait state              */
391 #endif
392 
393   HT_CKCU->AHBCFGR = HCLK_DIV;                                  /* set CK_AHB prescaler                     */
394   HT_CKCU->GCCR = ((HT_CKCU->GCCR & ~7UL) | HCLK_SRC);          /* select CK_SYS source                     */
395   while ((HT_CKCU->CKST & 7UL) != HCLK_SRC);                    /* wait for clock switch complete           */
396 
397   /* Pre-fetch buffer configuration                                                                         */
398 #if (PRE_FETCH_ENABLE == 0)
399   ResetBit_BB((u32)(&HT_FLASH->CFCR), 4);               /* 0: pre-fetch disable, 1: pre-fetch enable        */
400 #else
401   SetBit_BB((u32)(&HT_FLASH->CFCR), 4);                 /* 0: pre-fetch disable, 1: pre-fetch enable        */
402 #endif
403 
404   /* Branch cache configuration                                                                             */
405 #if (BCACHE_ENABLE == 0)
406   ResetBit_BB((u32)(&HT_FLASH->CFCR), 12);              /* 0: branch cache disable, 1: branch cache enable  */
407 #else
408   SetBit_BB((u32)(&HT_FLASH->CFCR), 12);                /* 0: branch cache disable, 1: branch cache enable  */
409 #endif
410 
411   /* HSE power down                                                                                         */
412 #if ((HSE_ENABLE == 0) && (HCLK_SRC != 2) && ((PLL_ENABLE == 0) || (PLL_CLK_SRC == 1)))
413   ResetBit_BB((u32)(&HT_CKCU->GCCR), 10);
414 #endif
415 
416   /* HSI power down                                                                                         */
417 #if ((HSI_ENABLE == 0) && (HCLK_SRC != 3) && ((PLL_ENABLE == 0) || (PLL_CLK_SRC == 0)))
418   ResetBit_BB((u32)(&HT_CKCU->GCCR), 11);
419 #endif
420 }
421 
422 /**
423   * @brief  Update SystemCoreClock
424   * @retval None
425   */
SystemCoreClockUpdate(void)426 void SystemCoreClockUpdate(void)
427 {
428   u32 SystemCoreClockDiv = HT_CKCU->AHBCFGR & 7UL;
429   u32 PllFeedbackClockDiv = ((HT_CKCU->PLLCFGR >> 23) == 0) ? (16) : (HT_CKCU->PLLCFGR >> 23);
430   u32 PllOutputClockDiv = (HT_CKCU->PLLCFGR >> 21) & 3UL;
431   u32 SystemCoreClockSrc = HT_CKCU->CKST & 7UL;
432 
433   /* Get system core clock according to global clock control & configuration registers                      */
434   if (SystemCoreClockSrc == 1)
435   {
436     if (GetBit_BB((u32)(&HT_CKCU->PLLCR), 31))
437     {
438       PllFeedbackClockDiv = 1;
439       PllOutputClockDiv = 0;
440     }
441 
442     if (GetBit_BB((u32)(&HT_CKCU->GCFGR), 8))
443     {
444       SystemCoreClock = ((HSI_VALUE * PllFeedbackClockDiv) >> PllOutputClockDiv) >> SystemCoreClockDiv;
445     }
446     else
447     {
448       SystemCoreClock = ((HSE_VALUE * PllFeedbackClockDiv) >> PllOutputClockDiv) >> SystemCoreClockDiv;
449     }
450   }
451   else if (SystemCoreClockSrc == 2)
452   {
453     SystemCoreClock = HSE_VALUE >> SystemCoreClockDiv;
454   }
455   else if (SystemCoreClockSrc == 3)
456   {
457     SystemCoreClock = HSI_VALUE >> SystemCoreClockDiv;
458   }
459   else if (SystemCoreClockSrc == 6)
460   {
461     SystemCoreClock = LSE_VALUE >> SystemCoreClockDiv;
462   }
463   else if (SystemCoreClockSrc == 7)
464   {
465     SystemCoreClock = LSI_VALUE >> SystemCoreClockDiv;
466   }
467 }
468 
469 /**
470   * @}
471   */
472 
473 
474 /**
475   * @}
476   */
477 
478 /**
479   * @}
480   */
481 
482 /******************* (C) COPYRIGHT Holtek Semiconductor Inc. *****END OF FILE***                            */
483