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