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