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