1 /******************************************************************************
2 *Copyright(C)2018, Huada Semiconductor Co.,Ltd All rights reserved.
3 *
4 * This software is owned and published by:
5 * Huada Semiconductor Co.,Ltd("HDSC").
6 *
7 * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
8 * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
9 *
10 * This software contains source code for use with HDSC
11 * components. This software is licensed by HDSC to be adapted only
12 * for use in systems utilizing HDSC components. HDSC shall not be
13 * responsible for misuse or illegal use of this software for devices not
14 * supported herein. HDSC is providing this software "AS IS" and will
15 * not be responsible for issues arising from incorrect user implementation
16 * of the software.
17 *
18 * Disclaimer:
19 * HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
20 * REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
21 * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
22 * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
23 * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
24 * WARRANTY OF NONINFRINGEMENT.
25 * HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
26 * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
27 * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
28 * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
29 * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
30 * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
31 * SAVINGS OR PROFITS,
32 * EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
33 * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
34 * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
35 * FROM, THE SOFTWARE.
36 *
37 * This software may be replicated in part or whole for the licensed use,
38 * with the restriction that this Disclaimer and Copyright notice must be
39 * included with each copy of this software, whether used in part or whole,
40 * at all times.
41 */
42
43 /** \file sysctrl.c
44 **
45 ** Common API of sysctrl.
46 ** @link SysctrlGroup Some description @endlink
47 **
48 ** - 2018-04-22 Lux
49 **
50 ******************************************************************************/
51
52 /*******************************************************************************
53 * Include files
54 ******************************************************************************/
55 #include "hc32l196_sysctrl.h"
56
57 /**
58 *******************************************************************************
59 ** \addtogroup SysctrlGroup
60 ******************************************************************************/
61 //@{
62
63 /*******************************************************************************
64 * Local pre-processor symbols/macros ('#define')
65 ******************************************************************************/
66 #define CLK_TIMEOUT (1000000u)
67
68 #define IS_VALID_SRC(x) ( ClkRCH == (x)||\
69 ClkXTH == (x)||\
70 ClkRCL == (x)||\
71 ClkXTL == (x) )
72
73
74 #define IS_VALID_FUNC(x) ( ClkFuncWkupRCH == (x)||\
75 ClkFuncXTHEn == (x)||\
76 ClkFuncXTLEn == (x)||\
77 ClkFuncXTLAWSON == (x)||\
78 ClkFuncFaultEn == (x)||\
79 ClkFuncRtcLPWEn == (x)||\
80 ClkFuncLockUpEn == (x)||\
81 ClkFuncRstPinIOEn == (x)||\
82 ClkFuncSwdPinIOEn == (x) )
83
84 #define RC_TRIM_BASE_ADDR ((volatile uint16_t*) (0x00100C00ul))
85 #define RCH_CR_TRIM_24M_VAL (*((volatile uint16_t*) (0x00100C00ul)))
86 #define RCH_CR_TRIM_22_12M_VAL (*((volatile uint16_t*) (0x00100C02ul)))
87 #define RCH_CR_TRIM_16M_VAL (*((volatile uint16_t*) (0x00100C04ul)))
88 #define RCH_CR_TRIM_8M_VAL (*((volatile uint16_t*) (0x00100C06ul)))
89 #define RCH_CR_TRIM_4M_VAL (*((volatile uint16_t*) (0x00100C08ul)))
90
91 #define RCL_CR_TRIM_38400_VAL (*((volatile uint16_t*) (0x00100C20ul)))
92 #define RCL_CR_TRIM_32768_VAL (*((volatile uint16_t*) (0x00100C22ul)))
93
94 /*******************************************************************************
95 * Global variable definitions (declared in header file with 'extern')
96 ******************************************************************************/
97 extern uint32_t SystemCoreClock;
98 /*******************************************************************************
99 * Local type definitions ('typedef')
100 ******************************************************************************/
101
102 /*******************************************************************************
103 * Local variable definitions ('static')
104 ******************************************************************************/
105
106 /*******************************************************************************
107 * Local function prototypes ('static')
108 ******************************************************************************/
109
110
111 /*******************************************************************************
112 * Function implementation - global ('extern') and local ('static')
113 ******************************************************************************/
114
115 /**
116 *******************************************************************************
117 ** \brief SYSCTRL0\SYSCTRL1寄存器操作解锁
118 **
119 ** \retval None
120 ******************************************************************************/
_SysctrlUnlock(void)121 static void _SysctrlUnlock(void)
122 {
123 M0P_SYSCTRL->SYSCTRL2 = 0x5A5A;
124 M0P_SYSCTRL->SYSCTRL2 = 0xA5A5;
125 }
126
127 /**
128 *******************************************************************************
129 ** \brief 系统时钟源使能
130 ** \param [in] enSource 目标时钟源
131 ** \param [in] bFlag 使能1-开/0-关
132 ** \retval Ok 设定成功
133 ** 其他 设定失败
134 ******************************************************************************/
Sysctrl_ClkSourceEnable(en_sysctrl_clk_source_t enSource,boolean_t bFlag)135 en_result_t Sysctrl_ClkSourceEnable(en_sysctrl_clk_source_t enSource, boolean_t bFlag)
136 {
137 en_result_t enRet = Ok;
138 uint32_t u32Temp;
139
140 _SysctrlUnlock();
141 bFlag = !!bFlag;
142
143 u32Temp = M0P_SYSCTRL->PERI_CLKEN0;
144 switch (enSource)
145 {
146 case SysctrlClkRCH:
147 M0P_SYSCTRL->SYSCTRL0_f.RCH_EN = bFlag;
148 while(bFlag && (1 != M0P_SYSCTRL->RCH_CR_f.STABLE))
149 {
150 ;
151 }
152 break;
153
154 case SysctrlClkXTH:
155 M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = TRUE;
156 M0P_GPIO->PFADS |= 3u;
157 M0P_SYSCTRL->SYSCTRL0_f.XTH_EN = bFlag;
158 while(bFlag && (1 != M0P_SYSCTRL->XTH_CR_f.STABLE))
159 {
160 ;
161 }
162 break;
163
164 case SysctrlClkRCL:
165
166 M0P_SYSCTRL->SYSCTRL0_f.RCL_EN = bFlag;
167 while(bFlag && (1 != M0P_SYSCTRL->RCL_CR_f.STABLE))
168 {
169 ;
170 }
171 break;
172
173 case SysctrlClkXTL:
174 M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = TRUE;
175 M0P_GPIO->PCADS |= 0xC000;
176 M0P_SYSCTRL->SYSCTRL0_f.XTL_EN = bFlag;
177 while(bFlag && (1 != M0P_SYSCTRL->XTL_CR_f.STABLE))
178 {
179 ;
180 }
181 break;
182
183 case SysctrlClkPLL:
184 M0P_SYSCTRL->PERI_CLKEN0_f.ADC = TRUE;
185 M0P_BGR->CR_f.BGR_EN = TRUE;
186 delay10us(20);
187 M0P_SYSCTRL->SYSCTRL0_f.PLL_EN = bFlag;
188 while(bFlag && (1 != M0P_SYSCTRL->PLL_CR_f.STABLE))
189 {
190 ;
191 }
192 break;
193
194 default:
195 enRet = ErrorInvalidParameter;
196 break;
197 }
198 M0P_SYSCTRL->PERI_CLKEN0 = u32Temp;
199
200 return enRet;
201 }
202
203 /**
204 *******************************************************************************
205 ** \brief 外部高速晶振驱动配置
206 ** \param [in] enFreq 外部高速晶振频率范围选择
207 ** \param [in] enDriver 外部高速晶振驱动能力选择
208 ** \retval Ok 设定成功
209 ** 其他 设定失败
210 ******************************************************************************/
Sysctrl_XTHDriverCfg(en_sysctrl_xtal_driver_t enDriver)211 en_result_t Sysctrl_XTHDriverCfg(en_sysctrl_xtal_driver_t enDriver)
212 {
213 en_result_t enRet = Ok;
214
215 M0P_SYSCTRL->XTH_CR_f.DRIVER = enDriver;
216
217 return enRet;
218 }
219
220 /**
221 *******************************************************************************
222 ** \brief 外部低速晶振驱动配置
223 ** \param [in] enFreq 外部低速晶振频率范围选择
224 ** \param [in] enDriver 外部低速晶振驱动能力选择
225 ** \retval Ok 设定成功
226 ** 其他 设定失败
227 ******************************************************************************/
Sysctrl_XTLDriverCfg(en_sysctrl_xtl_amp_t enAmp,en_sysctrl_xtal_driver_t enDriver)228 en_result_t Sysctrl_XTLDriverCfg(en_sysctrl_xtl_amp_t enAmp, en_sysctrl_xtal_driver_t enDriver)
229 {
230 en_result_t enRet = Ok;
231
232 M0P_SYSCTRL->XTL_CR_f.AMP_SEL = enAmp;
233 M0P_SYSCTRL->XTL_CR_f.DRIVER = enDriver;
234
235 return enRet;
236 }
237
238 /**
239 *******************************************************************************
240 ** \brief 外部高速时钟稳定周期配置
241 ** \param [in] enCycle 外部高速时钟稳定周期设置
242 ** \retval Ok 设定成功
243 ** 其他 设定失败
244 ******************************************************************************/
Sysctrl_SetXTHStableTime(en_sysctrl_xth_cycle_t enCycle)245 en_result_t Sysctrl_SetXTHStableTime(en_sysctrl_xth_cycle_t enCycle)
246 {
247 en_result_t enRet = Ok;
248 M0P_SYSCTRL->XTH_CR_f.STARTUP = enCycle;
249 return enRet;
250 }
251
252 /**
253 *******************************************************************************
254 ** \brief 内部低速时钟稳定周期配置
255 ** \param [in] enCycle 内部低速时钟稳定周期设置
256 ** \retval Ok 设定成功
257 ** 其他 设定失败
258 ******************************************************************************/
Sysctrl_SetRCLStableTime(en_sysctrl_rcl_cycle_t enCycle)259 en_result_t Sysctrl_SetRCLStableTime(en_sysctrl_rcl_cycle_t enCycle)
260 {
261 en_result_t enRet = Ok;
262 M0P_SYSCTRL->RCL_CR_f.STARTUP = enCycle;
263 return enRet;
264 }
265
266 /**
267 *******************************************************************************
268 ** \brief 外部低速时钟稳定周期配置
269 ** \param [in] enCycle 外部低速时钟稳定周期设置
270 ** \retval Ok 设定成功
271 ** 其他 设定失败
272 ******************************************************************************/
Sysctrl_SetXTLStableTime(en_sysctrl_xtl_cycle_t enCycle)273 en_result_t Sysctrl_SetXTLStableTime(en_sysctrl_xtl_cycle_t enCycle)
274 {
275 en_result_t enRet = Ok;
276 M0P_SYSCTRL->XTL_CR_f.STARTUP = enCycle;
277 return enRet;
278 }
279
280 /**
281 *******************************************************************************
282 ** \brief PLL稳定周期配置
283 ** \param [in] enCycle PLL稳定周期设置
284 ** \retval Ok 设定成功
285 ** 其他 设定失败
286 ******************************************************************************/
Sysctrl_SetPLLStableTime(en_sysctrl_pll_cycle_t enCycle)287 en_result_t Sysctrl_SetPLLStableTime(en_sysctrl_pll_cycle_t enCycle)
288 {
289 en_result_t enRet = Ok;
290 M0P_SYSCTRL->PLL_CR_f.STARTUP = enCycle;
291 return enRet;
292 }
293
294 /**
295 *******************************************************************************
296 ** \brief 时钟源切换,该函数执行后会开启新时钟源
297 ** \note 选择时钟源之前,需根据需要配置目标时钟源的频率/驱动参数/使能时钟源等
298 ** \param [in] enSource 新时钟源
299 **
300 ** \retval Ok 设定成功
301 ** 其他 设定失败
302 ******************************************************************************/
Sysctrl_SysClkSwitch(en_sysctrl_clk_source_t enSource)303 en_result_t Sysctrl_SysClkSwitch(en_sysctrl_clk_source_t enSource)
304 {
305 en_result_t enRet = Ok;
306
307 en_sysctrl_clk_source_t ClkNew = enSource;
308
309 _SysctrlUnlock();
310 M0P_SYSCTRL->SYSCTRL0_f.CLKSW = ClkNew;
311
312 //更新Core时钟(HCLK)
313 SystemCoreClockUpdate();
314
315 return enRet;
316 }
317
318 /**
319 *******************************************************************************
320 ** \brief 获得系统时钟(HCLK)频率值
321 ** \retval uint32_t HCLK频率值
322 **
323 ******************************************************************************/
Sysctrl_GetHClkFreq(void)324 uint32_t Sysctrl_GetHClkFreq(void)
325 {
326 uint32_t u32Val = 0;
327 const uint32_t u32hcr_tbl[] = { 4000000, 8000000, 16000000, 22120000, 24000000};
328 const uint16_t u32lcr_tbl[] = { 32768, 38400};
329 en_sysctrl_clk_source_t enSrc;
330 uint16_t u16Trim[5] = {0};
331 u16Trim[4] = RCH_CR_TRIM_24M_VAL;
332 u16Trim[3] = RCH_CR_TRIM_22_12M_VAL;
333 u16Trim[2] = RCH_CR_TRIM_16M_VAL;
334 u16Trim[1] = RCH_CR_TRIM_8M_VAL;
335 u16Trim[0] = RCL_CR_TRIM_38400_VAL;
336
337 //获取当前系统时钟
338 enSrc = (en_sysctrl_clk_source_t)(M0P_SYSCTRL->SYSCTRL0_f.CLKSW);
339
340 switch (enSrc)
341 {
342 case SysctrlClkRCH:
343 {
344
345 if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[4]))
346 {
347 u32Val = u32hcr_tbl[4];
348 }
349 else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[3]))
350 {
351 u32Val = u32hcr_tbl[3];
352 }
353 else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[2]))
354 {
355 u32Val = u32hcr_tbl[2];
356 }
357 else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[1]))
358 {
359 u32Val = u32hcr_tbl[1];
360 }
361 else
362 {
363 u32Val = u32hcr_tbl[0];
364 }
365 }
366 break;
367 case SysctrlClkXTH:
368 u32Val = SYSTEM_XTH;
369 break;
370 case SysctrlClkRCL:
371 {
372 if(u16Trim[0] == (M0P_SYSCTRL->RCL_CR_f.TRIM))
373 {
374 u32Val = u32lcr_tbl[1];
375 }
376 else
377 {
378 u32Val = u32lcr_tbl[0];
379 }
380 }
381 break;
382 case SysctrlClkXTL:
383 u32Val = SYSTEM_XTL;
384 break;
385 case SysctrlClkPLL:
386 {
387 if (SysctrlPllRch == M0P_SYSCTRL->PLL_CR_f.REFSEL)
388 {
389 if(u16Trim[4] == M0P_SYSCTRL->RCH_CR_f.TRIM)
390 {
391 u32Val = u32hcr_tbl[4];
392 }
393 else if(u16Trim[3] == M0P_SYSCTRL->RCH_CR_f.TRIM)
394 {
395 u32Val = u32hcr_tbl[3];
396 }
397 else if(u16Trim[2] == M0P_SYSCTRL->RCH_CR_f.TRIM)
398 {
399 u32Val = u32hcr_tbl[2];
400 }
401 else if(u16Trim[1] == M0P_SYSCTRL->RCH_CR_f.TRIM)
402 {
403 u32Val = u32hcr_tbl[1];
404 }
405 else
406 {
407 u32Val = u32hcr_tbl[0];
408 }
409 }
410 else
411 {
412 u32Val = SYSTEM_XTH;
413 }
414
415 u32Val = (u32Val * M0P_SYSCTRL->PLL_CR_f.DIVN);
416 }
417 break;
418 default:
419 u32Val = 0u;
420 break;
421 }
422
423 u32Val = (u32Val >> M0P_SYSCTRL->SYSCTRL0_f.HCLK_PRS);
424
425 return u32Val;
426 }
427
428 /**
429 *******************************************************************************
430 ** \brief 获得外设时钟(PCLK)频率值
431 ** \retval uint32_t PCLK频率值(Hz)
432 **
433 ******************************************************************************/
Sysctrl_GetPClkFreq(void)434 uint32_t Sysctrl_GetPClkFreq(void)
435 {
436 uint32_t u32Val = 0;
437
438 u32Val = Sysctrl_GetHClkFreq();
439 u32Val = (u32Val >> (M0P_SYSCTRL->SYSCTRL0_f.PCLK_PRS));
440
441 return u32Val;
442 }
443
444
445 /**
446 *******************************************************************************
447 ** \brief 时钟初始化函数
448 ** \param [in] pstcCfg 初始化配置参数
449 ** \retval Ok 设定成功
450 ** 其他 设定失败
451 ******************************************************************************/
Sysctrl_ClkInit(stc_sysctrl_clk_cfg_t * pstcCfg)452 en_result_t Sysctrl_ClkInit(stc_sysctrl_clk_cfg_t *pstcCfg)
453 {
454 en_result_t enRet = Ok;
455
456 //系统时钟参数配置
457 switch(pstcCfg->enClkSrc)
458 {
459 case SysctrlClkRCH:
460
461 break;
462 case SysctrlClkXTH:
463 Sysctrl_XTHDriverCfg(SysctrlXtalDriver3);
464 Sysctrl_SetXTHStableTime(SysctrlXthStableCycle16384);
465 break;
466 case SysctrlClkRCL:
467 Sysctrl_SetRCLStableTime(SysctrlRclStableCycle256);
468 break;
469 case SysctrlClkXTL:
470 Sysctrl_XTLDriverCfg(SysctrlXtlAmp3, SysctrlXtalDriver3);
471 Sysctrl_SetXTLStableTime(SysctrlXtlStableCycle16384);
472 break;
473 case SysctrlClkPLL:
474 Sysctrl_SetPLLStableTime(SysctrlPllStableCycle16384);
475 break;
476 default:
477 enRet = ErrorInvalidParameter;
478 break;
479 }
480
481 //时钟源使能
482 Sysctrl_ClkSourceEnable(pstcCfg->enClkSrc, TRUE);
483
484 //时钟源切换
485 Sysctrl_SysClkSwitch(pstcCfg->enClkSrc);
486
487 //时钟分频设置
488 Sysctrl_SetHCLKDiv(pstcCfg->enHClkDiv);
489 Sysctrl_SetPCLKDiv(pstcCfg->enPClkDiv);
490
491 return enRet;
492 }
493
494 /**
495 *******************************************************************************
496 ** \brief 时钟去初始化函数
497 ** \param [in]
498 ** \retval Ok 设定成功
499 ** 其他 设定失败
500 ******************************************************************************/
Sysctrl_ClkDeInit(void)501 en_result_t Sysctrl_ClkDeInit(void)
502 {
503 en_result_t enRet = Ok;
504
505 //配置RCH为内部4Hz
506 Sysctrl_SetRCHTrim(SysctrlRchFreq4MHz);
507
508 //时钟源使能
509 Sysctrl_ClkSourceEnable(SysctrlClkRCH, TRUE);
510
511 //时钟源切换
512 Sysctrl_SysClkSwitch(SysctrlClkRCH);
513
514 //其它时钟源使能关闭
515 Sysctrl_ClkSourceEnable(SysctrlClkXTH, FALSE);
516 Sysctrl_ClkSourceEnable(SysctrlClkRCL, FALSE);
517 Sysctrl_ClkSourceEnable(SysctrlClkXTL, FALSE);
518 Sysctrl_ClkSourceEnable(SysctrlClkPLL, FALSE);
519
520 //时钟分频设置
521 Sysctrl_SetHCLKDiv(SysctrlHclkDiv1);
522 Sysctrl_SetPCLKDiv(SysctrlPclkDiv1);
523
524 return enRet;
525 }
526
527 /**
528 *******************************************************************************
529 ** \brief 内部高速时钟频率TRIM值加载
530 ** \param [in] enRCHFreq 设定的RCH目标频率值
531 ** \retval Ok 设定成功
532 ** 其他 设定失败或时钟未稳定
533 ******************************************************************************/
Sysctrl_SetRCHTrim(en_sysctrl_rch_freq_t enRCHFreq)534 en_result_t Sysctrl_SetRCHTrim(en_sysctrl_rch_freq_t enRCHFreq)
535 {
536 //加载RCH Trim值
537 M0P_SYSCTRL->RCH_CR_f.TRIM = *(RC_TRIM_BASE_ADDR + enRCHFreq);
538
539 return Ok;
540 }
541
542 /**
543 *******************************************************************************
544 ** \brief 外部高速时钟频率范围设定
545 ** \param [in] enXTHFreq 设定的频率值
546 ** \retval Ok 设定成功
547 ** 其他 设定失败或时钟未稳定
548 ******************************************************************************/
Sysctrl_SetXTHFreq(en_sysctrl_xth_freq_t enXTHFreq)549 en_result_t Sysctrl_SetXTHFreq(en_sysctrl_xth_freq_t enXTHFreq)
550 {
551 en_result_t enRet = Ok;
552
553 M0P_SYSCTRL->XTH_CR_f.XTH_FSEL = enXTHFreq;
554
555 return enRet;
556 }
557
558 /**
559 *******************************************************************************
560 ** \brief PLL时钟配置
561 ** \param [in] pstcPLLCfg PLL配置结构体指针
562 ** \retval Ok 设定成功
563 ** 其他 设定失败或参数值不匹配
564 ******************************************************************************/
Sysctrl_SetPLLFreq(stc_sysctrl_pll_cfg_t * pstcPLLCfg)565 en_result_t Sysctrl_SetPLLFreq(stc_sysctrl_pll_cfg_t *pstcPLLCfg)
566 {
567 en_result_t enRet = Ok;
568
569 uint16_t u16Trim[5] = {0};
570 u16Trim[4] = RCH_CR_TRIM_24M_VAL;
571 u16Trim[3] = RCH_CR_TRIM_22_12M_VAL;
572 u16Trim[2] = RCH_CR_TRIM_16M_VAL;
573 u16Trim[1] = RCH_CR_TRIM_8M_VAL;
574
575 ////PLL最高时钟不能超过48MHz
576 //RCH作为PLL输入
577 if (SysctrlPllRch == pstcPLLCfg->enPllClkSrc)
578 {
579 if( ((u16Trim[4] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 2)) ||
580 ((u16Trim[3] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 2)) ||
581 ((u16Trim[2] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 3)) ||
582 ((u16Trim[1] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 6)))
583 {
584 return ErrorInvalidMode;
585 }
586 }
587 else //XTH作为PLL输入
588 {
589 if ((SYSTEM_XTH * pstcPLLCfg->enPllMul) > 48*1000*1000)
590 {
591 return ErrorInvalidMode;
592 }
593 }
594
595 M0P_SYSCTRL->PLL_CR_f.FRSEL = pstcPLLCfg->enInFreq;
596 M0P_SYSCTRL->PLL_CR_f.FOSC = pstcPLLCfg->enOutFreq;
597 M0P_SYSCTRL->PLL_CR_f.DIVN = pstcPLLCfg->enPllMul;
598 M0P_SYSCTRL->PLL_CR_f.REFSEL = pstcPLLCfg->enPllClkSrc;
599
600 return enRet;
601 }
602
603 /**
604 *******************************************************************************
605 ** \brief 内部低速时钟频率TRIM值加载
606 ** \param [in] enRCLFreq 设定的RCL目标频率值
607 ** \retval Ok 设定成功
608 ** 其他 设定失败
609 ******************************************************************************/
Sysctrl_SetRCLTrim(en_sysctrl_rcl_freq_t enRCLFreq)610 en_result_t Sysctrl_SetRCLTrim(en_sysctrl_rcl_freq_t enRCLFreq)
611 {
612 M0P_SYSCTRL->RCL_CR_f.TRIM = *(RC_TRIM_BASE_ADDR + enRCLFreq);
613
614 return Ok;
615 }
616
617 /**
618 *******************************************************************************
619 ** \brief 系统时钟(HCLK)分频设定
620 ** \param [in] enHCLKDiv 分频设定值
621 ** \retval Ok 设定成功
622 ** 其他 设定失败
623 ******************************************************************************/
Sysctrl_SetHCLKDiv(en_sysctrl_hclk_div_t enHCLKDiv)624 en_result_t Sysctrl_SetHCLKDiv(en_sysctrl_hclk_div_t enHCLKDiv)
625 {
626 _SysctrlUnlock();
627 M0P_SYSCTRL->SYSCTRL0_f.HCLK_PRS = enHCLKDiv;
628
629 return Ok;
630 }
631
632 /**
633 *******************************************************************************
634 ** \brief 外设时钟(PCLK)分频设定
635 ** \param [in] enPCLKDiv 分频设定值
636 ** \retval Ok 设定成功
637 ** 其他 设定失败
638 ******************************************************************************/
Sysctrl_SetPCLKDiv(en_sysctrl_pclk_div_t enPCLKDiv)639 en_result_t Sysctrl_SetPCLKDiv(en_sysctrl_pclk_div_t enPCLKDiv)
640 {
641 _SysctrlUnlock();
642 M0P_SYSCTRL->SYSCTRL0_f.PCLK_PRS = enPCLKDiv;
643
644 return Ok;
645 }
646
647 ///<< for Sysctrl_SetPeripheralGate() & Sysctrl_GetPeripheralGate()
648 static volatile boolean_t bDacPeriBac = FALSE;
649
650 /**
651 *******************************************************************************
652 ** \brief 设置外设时钟门控开关
653 ** \param [in] enPeripheral 目标外设
654 ** \param [in] bFlag 使能开关
655 ** \retval Ok 设定成功
656 ** 其他 设定失败
657 ******************************************************************************/
Sysctrl_SetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral,boolean_t bFlag)658 en_result_t Sysctrl_SetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral, boolean_t bFlag)
659 {
660 if(enPeripheral&0x20u)
661 {
662 enPeripheral &= ~0x20u;
663 SetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN1)), enPeripheral, bFlag);
664
665 if((SysctrlPeripheralDac & ~0x20u) == enPeripheral)
666 {
667 bDacPeriBac = bFlag;
668 }
669 else
670 {
671 SetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN1)), (SysctrlPeripheralDac & ~0x20u), bDacPeriBac);
672 }
673 }
674 else
675 {
676 SetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN0)), enPeripheral, bFlag);
677 }
678
679 return Ok;
680 }
681
682 /**
683 *******************************************************************************
684 ** \brief 获得外设时钟门控开关状态
685 ** \param [in] enPeripheral 目标外设
686 ** \retval TRUE 开
687 ** FALSE 关
688 ******************************************************************************/
Sysctrl_GetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral)689 boolean_t Sysctrl_GetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral)
690 {
691 if(enPeripheral&0x20u)
692 {
693 if(SysctrlPeripheralDac == enPeripheral)
694 {
695 return bDacPeriBac;
696 }
697 else
698 {
699 enPeripheral &= ~0x20u;
700 return GetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN1)), enPeripheral);
701 }
702
703 }
704 else
705 {
706 return GetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN0)), enPeripheral);
707 }
708
709 }
710
711 /**
712 *******************************************************************************
713 ** \brief 系统功能设定
714 ** \param [in] enFunc 系统功能枚举类型
715 ** \param [in] bFlag 1-开/0-关
716 ** \retval Ok 设定成功
717 ** 其他 设定失败
718 ******************************************************************************/
Sysctrl_SetFunc(en_sysctrl_func_t enFunc,boolean_t bFlag)719 en_result_t Sysctrl_SetFunc(en_sysctrl_func_t enFunc, boolean_t bFlag)
720 {
721 _SysctrlUnlock();
722 SetBit((uint32_t)(&(M0P_SYSCTRL->SYSCTRL1)), enFunc, bFlag);
723
724 return Ok;
725 }
726
727 /**
728 *******************************************************************************
729 ** \brief 设定RTC校准时钟频率
730 ** \param [in] enRtcAdj 校准频率值
731 ** \retval Ok 设定成功
732 ** 其他 设定失败
733 ******************************************************************************/
Sysctrl_SetRTCAdjustClkFreq(en_sysctrl_rtc_adjust_t enRtcAdj)734 en_result_t Sysctrl_SetRTCAdjustClkFreq(en_sysctrl_rtc_adjust_t enRtcAdj)
735 {
736 _SysctrlUnlock();
737 M0P_SYSCTRL->SYSCTRL1_f.RTC_FREQ_ADJUST = enRtcAdj;
738
739 return Ok;
740 }
741
742 //@} // SysctrlGroup
743
744 /*******************************************************************************
745 * EOF (not truncated)
746 ******************************************************************************/
747