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