1 /**************************************************************************//**
2  * @file    library/Device/Holtek/HT32F5xxxx/Source/system_ht32f5xxxx_04.c
3  * @brief   CMSIS Cortex-M0+ Device Peripheral Access Layer Source File
4  *          for the Holtek HT32F5xxxx Device Series
5  * @version $Rev:: 7704         $
6  * @date    $Date:: 2024-05-10 #$
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 //   HT32F50220, HT32F50230
28 //   HT32F50231, HT32F50241
29 //   HT50F32002
30 //   HT32F59041
31 //   HF5032
32 //   HT32F61641
33 //   HT32F61041
34 //   HT32F61741
35 
36 //#define USE_HT32F50220_30
37 //#define USE_HT32F50231_41
38 //#define USE_HT50F32002
39 //#define USE_HT32F59041
40 //#define USE_HF5032
41 //#define USE_HT32F61641
42 //#define USE_HT32F61041
43 //#define USE_HT32F61741
44 
45 /** @addtogroup CMSIS
46   * @{
47   */
48 
49 /** @addtogroup HT32F5xxxx_system HT32F5xxxx System
50   * @{
51   */
52 
53 
54 #include "ht32f5xxxx_01.h"
55 
56 /** @addtogroup HT32F5xxxx_System_Private_Defines
57   * @{
58   */
59 /*
60 //-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
61 */
62 
63 /*--------------------- Clock Configuration ----------------------------------
64 //
65 //    <q1> Enable High Speed External Crystal Oscillator (HSE)
66 //          <i> Default HSE = DISABLE
67 //
68 //    <q3> Enable Low Speed External Crystal Oscillator (LSE)
69 //          <i> Default LSE = DISABLE
70 //
71 //    <h> SystemCoreClock Configuration (CK_AHB)
72 //      <o4>    SystemCoreClock Source
73 //                <2=> CK_HSE
74 //                <3=> CK_HSI
75 //                <6=> CK_LSE
76 //                <7=> CK_LSI
77 //                <i> Default SystemCoreClock source = CK_HSI
78 //      <o5>    SystemCoreClock Source Divider
79 //                <0=> 1
80 //                <1=> 2
81 //                <2=> 4
82 //                <3=> 8
83 //                <4=> 16
84 //                <5=> 32
85 //                <i> Default SystemCoreClock source divider = 2
86 //    </h>
87 */
88 
89 /* !!! NOTICE !!!
90    HSI must keep turn on when doing the Flash operation (Erase/Program).
91 */
92 
93 /* !!! NOTICE !!!
94  * How to adjust the value of High Speed External oscillator (HSE)?
95    The default value of HSE is define by "HSE_VALUE" in "ht32fxxxxx_nn.h".
96    If your board uses a different HSE speed, please add a new compiler preprocessor
97    C define, "HSE_VALUE=n000000" ("n" represents n MHz) in the toolchain/IDE,
98    or edit the "HSE_VALUE" in the "ht32f5xxxx_conf.h" file.
99    Take Keil MDK-ARM for instance, to set HSE as 16 MHz:
100    "Option of Taret -> C/C++ > Preprocessor Symbols"
101       Define: USE_HT32_DRIVER, USE_HT32Fxxxxx_SK, USE_HT32Fxxxxx_xx, USE_MEM_HT32Fxxxxx, HSE_VALUE=16000000
102                                                                                          ^^ Add "HSE_VALUE"
103                                                                                             define as above.
104 */
105 #define HSI_ENABLE        (1)     /*!< 0: DISABLE,  1: ENABLE                                               */
106 #define HSE_ENABLE        (1)     /*!< 0: DISABLE,  1: ENABLE                                               */
107 #define LSI_ENABLE        (1)     /*!< 0: DISABLE,  1: ENABLE                                               */
108 #define LSE_ENABLE        (0)     /*!< 0: DISABLE,  1: ENABLE                                               */
109 #define HCLK_SRC          (2)     /*!< 0: N/A       1: N/A     2: HSE,    3: HSI     6: LSE,    7: LSI      */
110 #define HCLK_DIV          (0)     /*!< 0: DIV1,     1: DIV2,   2: DIV4,   3: DIV8,   4: DIV16,  5: DIV32    */
111 #define DEINIT_ENABLE     (1)     /* Set 0 for reduce code size                                             */
112 
113 /*--------------------- WDT Configuration ----------------------------------
114 //
115 //    <e0> Enable WDT Configuration
116 //      <o1> WDT Prescaler Selection
117 //           <0=> CK_WDT / 1
118 //           <1=> CK_WDT / 2
119 //           <2=> CK_WDT / 4
120 //           <3=> CK_WDT / 8
121 //           <4=> CK_WDT / 16
122 //           <5=> CK_WDT / 32
123 //           <6=> CK_WDT / 64
124 //           <7=> CK_WDT / 128
125 //      <o2> WDT Reload Value <1-4095:1>
126 //      <q3> Enable WDT Reset function
127 //      <o4> WDT Sleep Halt mode
128 //           <0=> No halt
129 //           <1=> Halt in DeepSleep1
130 //           <2=> Halt in Sleep & DeepSleep1
131 //   </e>
132 */
133 #define WDT_ENABLE        (0)     /*!< 0: DISABLE,  1: ENABLE                                               */
134 #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  */
135 #define WDT_RELOAD        (2000)  /*!< 0 ~ 4095, 12 bit                                                     */
136 #define WDT_RESET_ENABLE  (1)     /*!< 0: No Reset, 1: Reset when WDT over flow                             */
137 #define WDT_SLEEP_HALT    (2)     /*!< 0: No halt,  1: Halt in DeepSleep1, 2: Halt in Sleep & DeepSleep1    */
138 
139 /**
140  * @brief Check HSI frequency
141  */
142 #if (HSI_VALUE != 20000000UL)
143   #error "CK_HSI clock issue: must be 20 MHz!"
144 #endif
145 
146 /**
147  * @brief Check HSE frequency
148  */
149 #if ((HSE_VALUE < 4000000UL) || (HSE_VALUE > 20000000UL))
150   #error "CK_HSE clock issue: must be in the range of 4 MHz to 20 MHz!"
151 #endif
152 
153 /**
154  * @brief Check LSI frequency
155  */
156 #if (LSI_VALUE != 32000UL)
157   #error "CK_LSI clock issue: must be 32 kHz!"
158 #endif
159 
160 /**
161  * @brief Check LSE frequency
162  */
163 #if (LSE_VALUE != 32768UL)
164   #error "CK_LSE clock issue: must be 32.768 kHz!"
165 #endif
166 
167 /**
168  * @brief CK_SYS definition
169  */
170 #if (HCLK_SRC == 2)
171   #if (HSE_ENABLE == 1)
172     #define __CK_SYS    HSE_VALUE             /*!< Select HSE as CK_SYS source                              */
173   #else
174     #error "CK_SYS clock source issue: HSE is not enable!"
175   #endif
176 #elif (HCLK_SRC == 3)
177   #if (HSI_ENABLE == 1)
178     #define __CK_SYS    HSI_VALUE             /*!< Select HSI as CK_SYS source                              */
179   #else
180     #error "CK_SYS clock source issue: HSI is not enable!"
181   #endif
182 #elif (HCLK_SRC == 6)
183   #if (LSE_ENABLE == 1)
184     #define __CK_SYS    LSE_VALUE             /*!< Select LSE as CK_SYS source                              */
185   #else
186     #error "CK_SYS clock source issue: LSE is not enable!"
187   #endif
188 #elif (HCLK_SRC == 7)
189   #if (LSI_ENABLE == 1)
190     #define __CK_SYS    LSI_VALUE             /*!< Select LSI as CK_SYS source                              */
191   #else
192     #error "CK_SYS clock source issue: LSI is not enable!"
193   #endif
194 #else
195   #error "CK_SYS clock source issue: No clock source is selected!"
196 #endif
197 
198 /**
199  * @brief CK_AHB definition
200  */
201 #define __CK_AHB    (__CK_SYS >> HCLK_DIV)    /*!< Get CK_AHB frequency                                     */
202 
203 #define CKAHB_MIN 1000UL
204 #define CKAHB_MAX 20000000UL
205 
206 /* Check CK_AHB frequency                                                                                   */
207 #if ((__CK_AHB < CKAHB_MIN) || (__CK_AHB > CKAHB_MAX))
208   #error "CK_AHB clock issue: must be in the range!"
209 #endif
210 /**
211   * @}
212   */
213 
214 /** @addtogroup HT32F5xxxx_System_Private_Variables
215   * @{
216   */
217 __IO uint32_t SystemCoreClock = __CK_AHB;   /*!< SystemCoreClock = CK_AHB                                   */
218 /**
219   * @}
220   */
221 
222 /** @addtogroup HT32F5xxxx_System_Private_Functions
223   * @{
224   */
225 
226 /**
227   * @brief  Setup the microcontroller system.
228   *         Initializes the system clocks and the embedded Flash.
229   * @note   This function should be used after reset.
230   * @retval None
231   */
SystemInit(void)232 void SystemInit(void)
233 {
234 #if (WDT_ENABLE == 1)
235   HT_CKCU->APBCCR1 |= (0x1 << 4);
236   HT_WDT->PR = 0x35CA;
237   HT_WDT->MR0 = 0;
238   HT_WDT->MR1 = ((HT_WDT->MR1 & 0xFFF) | (WDT_PRESCALER << 12));
239   HT_WDT->MR0 = WDT_RELOAD | (WDT_RESET_ENABLE << 13) | (WDT_SLEEP_HALT << 14) | (0x1 << 16);
240   HT_WDT->CR = 0x5FA00001;
241 #else
242   #if (DEINIT_ENABLE == 1)
243   HT_RSTCU->APBPRST1 = (1 << 4);
244   #endif
245 #endif
246 
247   SetBit_BB((u32)(&HT_CKCU->APBCCR1), 6);                       /* enable VDD power domain register clock   */
248 
249   #if (DEINIT_ENABLE == 1)
250   /* De-init the setting                                                                                    */
251   SetBit_BB((u32)(&HT_CKCU->GCCR), 11);                         /* enable HSI                               */
252   while (!GetBit_BB((u32)(&HT_CKCU->GCSR), 3));                 /* wait for HSI ready                       */
253   HT_CKCU->GCCR = ((HT_CKCU->GCCR & ~7UL) | 3UL);               /* select CK_SYS source                     */
254   while ((HT_CKCU->CKST & 7UL) != 3UL);                         /* wait for clock switch complete           */
255   HT_CKCU->AHBCFGR = 1;                                         /* set CK_AHB prescaler                     */
256   #endif
257 
258   /* HSE initiation                                                                                         */
259 #if (HSE_ENABLE == 1)
260   SetBit_BB((u32)(&HT_CKCU->GCCR), 10);                         /* enable HSE                               */
261   while (!GetBit_BB((u32)(&HT_CKCU->GCSR), 2)){};               /* wait for HSE ready                       */
262 #endif
263 
264   /* LSE initiation                                                                                         */
265 #if (LSE_ENABLE == 1)
266   do {
267     SetBit_BB((u32)(&HT_RTC->CR), 3);                           /* enable LSE                               */
268   } while (!GetBit_BB((u32)(&HT_RTC->CR), 3));
269   while (!GetBit_BB((u32)(&HT_CKCU->GCSR), 4));                 /* wait for LSE ready                       */
270 #endif
271 
272   ResetBit_BB((u32)(&HT_CKCU->APBCCR1), 6);                     /* disable Backup domain register clock     */
273 
274   /* LSI initiation                                                                                         */
275 #if (HCLK_SRC == 7)
276   while (!GetBit_BB((u32)(&HT_CKCU->GCSR), 5)){};               /* wait for LSI ready                       */
277 #endif
278 
279   HT_CKCU->AHBCFGR = HCLK_DIV;                                  /* set CK_AHB prescaler                     */
280   HT_CKCU->GCCR = ((HT_CKCU->GCCR & ~7UL) | HCLK_SRC);          /* select CK_SYS source                     */
281   while ((HT_CKCU->CKST & 7UL) != HCLK_SRC);                    /* wait for clock switch complete           */
282 
283   /* HSE power down                                                                                         */
284 #if ((HSE_ENABLE == 0) && (HCLK_SRC != 2))
285   ResetBit_BB((u32)(&HT_CKCU->GCCR), 10);
286 #endif
287 
288   /* HSI power down                                                                                         */
289 #if ((HSI_ENABLE == 0) && (HCLK_SRC != 3))
290   ResetBit_BB((u32)(&HT_CKCU->GCCR), 11);
291 #endif
292 }
293 
294 /**
295   * @brief  Update SystemCoreClock
296   * @retval None
297   */
SystemCoreClockUpdate(void)298 void SystemCoreClockUpdate(void)
299 {
300   u32 SystemCoreClockDiv = HT_CKCU->AHBCFGR & 7UL;
301   u32 SystemCoreClockSrc = HT_CKCU->CKST & 7UL;
302 
303   /* Get system core clock according to global clock control & configuration registers                      */
304   if (SystemCoreClockSrc == 2)
305   {
306     SystemCoreClock = HSE_VALUE >> SystemCoreClockDiv;
307   }
308   else if (SystemCoreClockSrc == 3)
309   {
310     SystemCoreClock = HSI_VALUE >> SystemCoreClockDiv;
311   }
312   else if (SystemCoreClockSrc == 6)
313   {
314     SystemCoreClock = LSE_VALUE >> SystemCoreClockDiv;
315   }
316   else if (SystemCoreClockSrc == 7)
317   {
318     SystemCoreClock = LSI_VALUE >> SystemCoreClockDiv;
319   }
320 }
321 
322 /**
323   * @}
324   */
325 
326 
327 /**
328   * @}
329   */
330 
331 /**
332   * @}
333   */
334 
335 /******************* (C) COPYRIGHT Holtek Semiconductor Inc. *****END OF FILE***                            */
336