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 "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 RCH_CR_TRIM_24M_VAL (*((volatile uint16_t*) (0x00100C00ul)))
85 #define RCH_CR_TRIM_22_12M_VAL (*((volatile uint16_t*) (0x00100C02ul)))
86 #define RCH_CR_TRIM_16M_VAL (*((volatile uint16_t*) (0x00100C04ul)))
87 #define RCH_CR_TRIM_8M_VAL (*((volatile uint16_t*) (0x00100C06ul)))
88 #define RCH_CR_TRIM_4M_VAL (*((volatile uint16_t*) (0x00100C08ul)))
89
90 #define RCL_CR_TRIM_38400_VAL (*((volatile uint16_t*) (0x00100C20ul)))
91 #define RCL_CR_TRIM_32768_VAL (*((volatile uint16_t*) (0x00100C22ul)))
92
93 /*******************************************************************************
94 * Global variable definitions (declared in header file with 'extern')
95 ******************************************************************************/
96 extern uint32_t SystemCoreClock;
97 /*******************************************************************************
98 * Local type definitions ('typedef')
99 ******************************************************************************/
100
101 /*******************************************************************************
102 * Local variable definitions ('static')
103 ******************************************************************************/
104
105 /*******************************************************************************
106 * Local function prototypes ('static')
107 ******************************************************************************/
108
109
110 /*******************************************************************************
111 * Function implementation - global ('extern') and local ('static')
112 ******************************************************************************/
113
114 /**
115 *******************************************************************************
116 ** \brief SYSCTRL0\SYSCTRL1寄存器操作解锁
117 **
118 ** \retval None
119 ******************************************************************************/
_SysctrlUnlock(void)120 static void _SysctrlUnlock(void)
121 {
122 M0P_SYSCTRL->SYSCTRL2 = 0x5A5A;
123 M0P_SYSCTRL->SYSCTRL2 = 0xA5A5;
124 }
125
126 /**
127 *******************************************************************************
128 ** \brief 系统时钟源使能
129 ** \param [in] enSource 目标时钟源
130 ** \param [in] bFlag 使能1-开/0-关
131 ** \retval Ok 设定成功
132 ** 其他 设定失败
133 ******************************************************************************/
Sysctrl_ClkSourceEnable(en_sysctrl_clk_source_t enSource,boolean_t bFlag)134 en_result_t Sysctrl_ClkSourceEnable(en_sysctrl_clk_source_t enSource, boolean_t bFlag)
135 {
136 en_result_t enRet = Ok;
137
138 _SysctrlUnlock();
139 bFlag = !!bFlag;
140
141 switch (enSource)
142 {
143 case SysctrlClkRCH:
144 M0P_SYSCTRL->SYSCTRL0_f.RCH_EN = bFlag;
145 while(bFlag && (1 != M0P_SYSCTRL->RCH_CR_f.STABLE))
146 {
147 ;
148 }
149 break;
150
151 case SysctrlClkXTH:
152 M0P_GPIO->PDADS_f.PD00 = 1;
153 M0P_GPIO->PDADS_f.PD01 = 1;
154 M0P_SYSCTRL->SYSCTRL0_f.XTH_EN = bFlag;
155 while(bFlag && (1 != M0P_SYSCTRL->XTH_CR_f.STABLE))
156 {
157 ;
158 }
159 break;
160
161 case SysctrlClkRCL:
162 M0P_SYSCTRL->SYSCTRL0_f.RCL_EN = bFlag;
163 while(bFlag && (1 != M0P_SYSCTRL->RCL_CR_f.STABLE))
164 {
165 ;
166 }
167 break;
168
169 case SysctrlClkXTL:
170 M0P_GPIO->PCADS_f.PC14 = 1;
171 M0P_GPIO->PCADS_f.PC15 = 1;
172 M0P_SYSCTRL->SYSCTRL0_f.XTL_EN = bFlag;
173 while(bFlag && (1 != M0P_SYSCTRL->XTL_CR_f.STABLE))
174 {
175 ;
176 }
177 break;
178
179 case SysctrlClkPLL:
180 M0P_SYSCTRL->SYSCTRL0_f.PLL_EN = bFlag;
181 while(bFlag && (1 != M0P_SYSCTRL->PLL_CR_f.STABLE))
182 {
183 ;
184 }
185 break;
186
187 default:
188 enRet = ErrorInvalidParameter;
189 break;
190 }
191
192 return enRet;
193 }
194
195 /**
196 *******************************************************************************
197 ** \brief 外部高速晶振驱动配置
198 ** \param [in] enFreq 外部高速晶振频率范围选择
199 ** \param [in] enDriver 外部高速晶振驱动能力选择
200 ** \retval Ok 设定成功
201 ** 其他 设定失败
202 ******************************************************************************/
Sysctrl_XTHDriverConfig(en_sysctrl_xtal_driver_t enDriver)203 en_result_t Sysctrl_XTHDriverConfig(en_sysctrl_xtal_driver_t enDriver)
204 {
205 en_result_t enRet = Ok;
206
207 M0P_SYSCTRL->XTH_CR_f.DRIVER = enDriver;
208
209 return enRet;
210 }
211
212 /**
213 *******************************************************************************
214 ** \brief 外部低速晶振驱动配置
215 ** \param [in] enFreq 外部低速晶振频率范围选择
216 ** \param [in] enDriver 外部低速晶振驱动能力选择
217 ** \retval Ok 设定成功
218 ** 其他 设定失败
219 ******************************************************************************/
Sysctrl_XTLDriverConfig(en_sysctrl_xtl_amp_t enAmp,en_sysctrl_xtal_driver_t enDriver)220 en_result_t Sysctrl_XTLDriverConfig(en_sysctrl_xtl_amp_t enAmp, en_sysctrl_xtal_driver_t enDriver)
221 {
222 en_result_t enRet = Ok;
223
224 M0P_SYSCTRL->XTL_CR_f.AMP_SEL = enAmp;
225 M0P_SYSCTRL->XTL_CR_f.DRIVER = enDriver;
226
227 return enRet;
228 }
229
230 /**
231 *******************************************************************************
232 ** \brief 外部高速时钟稳定周期配置
233 ** \param [in] enCycle 外部高速时钟稳定周期设置
234 ** \retval Ok 设定成功
235 ** 其他 设定失败
236 ******************************************************************************/
Sysctrl_SetXTHStableTime(en_sysctrl_xth_cycle_t enCycle)237 en_result_t Sysctrl_SetXTHStableTime(en_sysctrl_xth_cycle_t enCycle)
238 {
239 en_result_t enRet = Ok;
240 M0P_SYSCTRL->XTH_CR_f.STARTUP = enCycle;
241 return enRet;
242 }
243
244 /**
245 *******************************************************************************
246 ** \brief 内部低速时钟稳定周期配置
247 ** \param [in] enCycle 内部低速时钟稳定周期设置
248 ** \retval Ok 设定成功
249 ** 其他 设定失败
250 ******************************************************************************/
Sysctrl_SetRCLStableTime(en_sysctrl_rcl_cycle_t enCycle)251 en_result_t Sysctrl_SetRCLStableTime(en_sysctrl_rcl_cycle_t enCycle)
252 {
253 en_result_t enRet = Ok;
254 M0P_SYSCTRL->RCL_CR_f.STARTUP = enCycle;
255 return enRet;
256 }
257
258 /**
259 *******************************************************************************
260 ** \brief 外部低速时钟稳定周期配置
261 ** \param [in] enCycle 外部低速时钟稳定周期设置
262 ** \retval Ok 设定成功
263 ** 其他 设定失败
264 ******************************************************************************/
Sysctrl_SetXTLStableTime(en_sysctrl_xtl_cycle_t enCycle)265 en_result_t Sysctrl_SetXTLStableTime(en_sysctrl_xtl_cycle_t enCycle)
266 {
267 en_result_t enRet = Ok;
268 M0P_SYSCTRL->XTL_CR_f.STARTUP = enCycle;
269 return enRet;
270 }
271
272 /**
273 *******************************************************************************
274 ** \brief PLL稳定周期配置
275 ** \param [in] enCycle PLL稳定周期设置
276 ** \retval Ok 设定成功
277 ** 其他 设定失败
278 ******************************************************************************/
Sysctrl_SetPLLStableTime(en_sysctrl_pll_cycle_t enCycle)279 en_result_t Sysctrl_SetPLLStableTime(en_sysctrl_pll_cycle_t enCycle)
280 {
281 en_result_t enRet = Ok;
282 M0P_SYSCTRL->PLL_CR_f.STARTUP = enCycle;
283 return enRet;
284 }
285
286 /**
287 *******************************************************************************
288 ** \brief 时钟源切换,该函数执行后会开启新时钟源
289 ** \note 选择时钟源之前,需根据需要配置目标时钟源的频率/驱动参数/使能时钟源等
290 ** \param [in] enSource 新时钟源
291 **
292 ** \retval Ok 设定成功
293 ** 其他 设定失败
294 ******************************************************************************/
Sysctrl_SysClkSwitch(en_sysctrl_clk_source_t enSource)295 en_result_t Sysctrl_SysClkSwitch(en_sysctrl_clk_source_t enSource)
296 {
297 en_result_t enRet = Ok;
298
299 en_sysctrl_clk_source_t ClkNew = enSource;
300
301 _SysctrlUnlock();
302 M0P_SYSCTRL->SYSCTRL0_f.CLK_SW5_SEL = ClkNew;
303
304 //更新Core时钟(HCLK)
305 SystemCoreClockUpdate();
306
307 return enRet;
308 }
309
310 /**
311 *******************************************************************************
312 ** \brief 获得系统时钟(HCLK)频率值
313 ** \retval uint32_t HCLK频率值
314 **
315 ******************************************************************************/
Sysctrl_GetHClkFreq(void)316 uint32_t Sysctrl_GetHClkFreq(void)
317 {
318 uint32_t u32Val = 0;
319 const uint32_t u32hcr_tbl[] = { 4000000, 8000000, 16000000, 22120000, 24000000};
320 const uint16_t u32lcr_tbl[] = { 32768, 38400};
321 en_sysctrl_clk_source_t enSrc;
322 uint16_t u16Trim[5] = {0};
323 u16Trim[4] = RCH_CR_TRIM_24M_VAL;
324 u16Trim[3] = RCH_CR_TRIM_22_12M_VAL;
325 u16Trim[2] = RCH_CR_TRIM_16M_VAL;
326 u16Trim[1] = RCH_CR_TRIM_8M_VAL;
327 u16Trim[0] = RCL_CR_TRIM_38400_VAL;
328
329 //获取当前系统时钟
330 enSrc = (en_sysctrl_clk_source_t)(M0P_SYSCTRL->SYSCTRL0_f.CLK_SW5_SEL);
331
332 switch (enSrc)
333 {
334 case SysctrlClkRCH:
335 {
336
337 if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[4]))
338 {
339 u32Val = u32hcr_tbl[4];
340 }
341 else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[3]))
342 {
343 u32Val = u32hcr_tbl[3];
344 }
345 else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[2]))
346 {
347 u32Val = u32hcr_tbl[2];
348 }
349 else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[1]))
350 {
351 u32Val = u32hcr_tbl[1];
352 }
353 else
354 {
355 u32Val = u32hcr_tbl[0];
356 }
357 }
358 break;
359 case SysctrlClkXTH:
360 u32Val = SYSTEM_XTH;
361 break;
362 case SysctrlClkRCL:
363 {
364 if(u16Trim[0] == (M0P_SYSCTRL->RCL_CR_f.TRIM))
365 {
366 u32Val = u32lcr_tbl[1];
367 }
368 else
369 {
370 u32Val = u32lcr_tbl[0];
371 }
372 }
373 break;
374 case SysctrlClkXTL:
375 u32Val = SYSTEM_XTL;
376 break;
377 case SysctrlClkPLL:
378 {
379 if (SysctrlPllRch == M0P_SYSCTRL->PLL_CR_f.REFSEL)
380 {
381 if(u16Trim[4] == M0P_SYSCTRL->RCH_CR_f.TRIM)
382 {
383 u32Val = u32hcr_tbl[4];
384 }
385 else if(u16Trim[3] == M0P_SYSCTRL->RCH_CR_f.TRIM)
386 {
387 u32Val = u32hcr_tbl[3];
388 }
389 else if(u16Trim[2] == M0P_SYSCTRL->RCH_CR_f.TRIM)
390 {
391 u32Val = u32hcr_tbl[2];
392 }
393 else if(u16Trim[1] == M0P_SYSCTRL->RCH_CR_f.TRIM)
394 {
395 u32Val = u32hcr_tbl[1];
396 }
397 else
398 {
399 u32Val = u32hcr_tbl[0];
400 }
401 }
402 else
403 {
404 u32Val = SYSTEM_XTH;
405 }
406
407 u32Val = (u32Val * M0P_SYSCTRL->PLL_CR_f.DIVN);
408 }
409 break;
410 default:
411 u32Val = 0u;
412 break;
413 }
414
415 u32Val = (u32Val >> M0P_SYSCTRL->SYSCTRL0_f.HCLK_PRS);
416
417 return u32Val;
418 }
419
420 /**
421 *******************************************************************************
422 ** \brief 获得外设时钟(PCLK)频率值
423 ** \retval uint32_t PCLK频率值(Hz)
424 **
425 ******************************************************************************/
Sysctrl_GetPClkFreq(void)426 uint32_t Sysctrl_GetPClkFreq(void)
427 {
428 uint32_t u32Val = 0;
429
430 u32Val = Sysctrl_GetHClkFreq();
431 u32Val = (u32Val >> (M0P_SYSCTRL->SYSCTRL0_f.PCLK_PRS));
432
433 return u32Val;
434 }
435
436
437 /**
438 *******************************************************************************
439 ** \brief 时钟初始化函数
440 ** \param [in] pstcCfg 初始化配置参数
441 ** \retval Ok 设定成功
442 ** 其他 设定失败
443 ******************************************************************************/
Sysctrl_ClkInit(stc_sysctrl_clk_config_t * pstcCfg)444 en_result_t Sysctrl_ClkInit(stc_sysctrl_clk_config_t *pstcCfg)
445 {
446 en_result_t enRet = Ok;
447
448 //系统时钟参数配置
449 switch(pstcCfg->enClkSrc)
450 {
451 case SysctrlClkRCH:
452
453 break;
454 case SysctrlClkXTH:
455 Sysctrl_XTHDriverConfig(SysctrlXtalDriver3);
456 Sysctrl_SetXTHStableTime(SysctrlXthStableCycle16384);
457 break;
458 case SysctrlClkRCL:
459 Sysctrl_SetRCLStableTime(SysctrlRclStableCycle256);
460 break;
461 case SysctrlClkXTL:
462 Sysctrl_XTLDriverConfig(SysctrlXtlAmp3, SysctrlXtalDriver3);
463 Sysctrl_SetXTLStableTime(SysctrlXtlStableCycle16384);
464 break;
465 case SysctrlClkPLL:
466 Sysctrl_SetPLLStableTime(SysctrlPllStableCycle16384);
467 break;
468 default:
469 enRet = ErrorInvalidParameter;
470 break;
471 }
472
473 //时钟源使能
474 Sysctrl_ClkSourceEnable(pstcCfg->enClkSrc, TRUE);
475
476 //时钟源切换
477 Sysctrl_SysClkSwitch(pstcCfg->enClkSrc);
478
479 //时钟分频设置
480 Sysctrl_SetHCLKDiv(pstcCfg->enHClkDiv);
481 Sysctrl_SetPCLKDiv(pstcCfg->enPClkDiv);
482
483 return enRet;
484 }
485
486 /**
487 *******************************************************************************
488 ** \brief 时钟去初始化函数
489 ** \param [in]
490 ** \retval Ok 设定成功
491 ** 其他 设定失败
492 ******************************************************************************/
Sysctrl_ClkDeInit(void)493 en_result_t Sysctrl_ClkDeInit(void)
494 {
495 en_result_t enRet = Ok;
496
497 //配置RCH为内部4Hz
498 Sysctrl_SetRCHTrim(SysctrlRchFreq4MHz);
499
500 //时钟源使能
501 Sysctrl_ClkSourceEnable(SysctrlClkRCH, TRUE);
502
503 //时钟源切换
504 Sysctrl_SysClkSwitch(SysctrlClkRCH);
505
506 //其它时钟源使能关闭
507 Sysctrl_ClkSourceEnable(SysctrlClkXTH, FALSE);
508 Sysctrl_ClkSourceEnable(SysctrlClkRCL, FALSE);
509 Sysctrl_ClkSourceEnable(SysctrlClkXTL, FALSE);
510 Sysctrl_ClkSourceEnable(SysctrlClkPLL, FALSE);
511
512 //时钟分频设置
513 Sysctrl_SetHCLKDiv(SysctrlHclkDiv1);
514 Sysctrl_SetPCLKDiv(SysctrlPclkDiv1);
515
516 return enRet;
517 }
518
519 /**
520 *******************************************************************************
521 ** \brief 内部高速时钟频率TRIM值加载
522 ** \param [in] enRCHFreq 设定的RCH目标频率值
523 ** \retval Ok 设定成功
524 ** 其他 设定失败或时钟未稳定
525 ******************************************************************************/
Sysctrl_SetRCHTrim(en_sysctrl_rch_freq_t enRCHFreq)526 en_result_t Sysctrl_SetRCHTrim(en_sysctrl_rch_freq_t enRCHFreq)
527 {
528 en_result_t enRet = Ok;
529
530 //加载RCH Trim值
531 switch (enRCHFreq)
532 {
533 case SysctrlRchFreq4MHz:
534 M0P_SYSCTRL->RCH_CR_f.TRIM = RCH_CR_TRIM_4M_VAL;
535 break;
536 case SysctrlRchFreq8MHz:
537 M0P_SYSCTRL->RCH_CR_f.TRIM = RCH_CR_TRIM_8M_VAL;
538 break;
539 case SysctrlRchFreq16MHz:
540 M0P_SYSCTRL->RCH_CR_f.TRIM = RCH_CR_TRIM_16M_VAL;
541 break;
542 case SysctrlRchFreq22_12MHz:
543 M0P_SYSCTRL->RCH_CR_f.TRIM = RCH_CR_TRIM_22_12M_VAL;
544 break;
545 case SysctrlRchFreq24MHz:
546 M0P_SYSCTRL->RCH_CR_f.TRIM = RCH_CR_TRIM_24M_VAL;
547 break;
548 default:
549 enRet = ErrorInvalidParameter;
550 break;
551 }
552
553 return enRet;
554 }
555
556 /**
557 *******************************************************************************
558 ** \brief 外部高速时钟频率范围设定
559 ** \param [in] enXTHFreq 设定的频率值
560 ** \retval Ok 设定成功
561 ** 其他 设定失败或时钟未稳定
562 ******************************************************************************/
Sysctrl_SetXTHFreq(en_sysctrl_xth_freq_t enXTHFreq)563 en_result_t Sysctrl_SetXTHFreq(en_sysctrl_xth_freq_t enXTHFreq)
564 {
565 en_result_t enRet = Ok;
566
567 M0P_SYSCTRL->XTH_CR_f.XTH_FSEL = enXTHFreq;
568
569 return enRet;
570 }
571
572 /**
573 *******************************************************************************
574 ** \brief PLL时钟配置
575 ** \param [in] pstcPLLCfg PLL配置结构体指针
576 ** \retval Ok 设定成功
577 ** 其他 设定失败或参数值不匹配
578 ******************************************************************************/
Sysctrl_SetPLLFreq(stc_sysctrl_pll_config_t * pstcPLLCfg)579 en_result_t Sysctrl_SetPLLFreq(stc_sysctrl_pll_config_t *pstcPLLCfg)
580 {
581 en_result_t enRet = Ok;
582
583 uint16_t u16Trim[5] = {0};
584 u16Trim[4] = RCH_CR_TRIM_24M_VAL;
585 u16Trim[3] = RCH_CR_TRIM_22_12M_VAL;
586 u16Trim[2] = RCH_CR_TRIM_16M_VAL;
587 u16Trim[1] = RCH_CR_TRIM_8M_VAL;
588
589 ////PLL最高时钟不能超过48MHz
590 //RCH作为PLL输入
591 if (SysctrlPllRch == pstcPLLCfg->enPllClkSrc)
592 {
593 if( ((u16Trim[4] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 2)) ||
594 ((u16Trim[3] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 2)) ||
595 ((u16Trim[2] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 3)) ||
596 ((u16Trim[1] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 6)))
597 {
598 return ErrorInvalidMode;
599 }
600 }
601 else //XTH作为PLL输入
602 {
603 if ((SYSTEM_XTH * pstcPLLCfg->enPllMul) > 48*1000*1000)
604 {
605 return ErrorInvalidMode;
606 }
607 }
608
609 M0P_SYSCTRL->PLL_CR_f.FRSEL = pstcPLLCfg->enInFreq;
610 M0P_SYSCTRL->PLL_CR_f.FOSC = pstcPLLCfg->enOutFreq;
611 M0P_SYSCTRL->PLL_CR_f.DIVN = pstcPLLCfg->enPllMul;
612 M0P_SYSCTRL->PLL_CR_f.REFSEL = pstcPLLCfg->enPllClkSrc;
613
614 return enRet;
615 }
616
617 /**
618 *******************************************************************************
619 ** \brief 内部低速时钟频率TRIM值加载
620 ** \param [in] enRCLFreq 设定的RCL目标频率值
621 ** \retval Ok 设定成功
622 ** 其他 设定失败
623 ******************************************************************************/
Sysctrl_SetRCLTrim(en_sysctrl_rcl_freq_t enRCLFreq)624 en_result_t Sysctrl_SetRCLTrim(en_sysctrl_rcl_freq_t enRCLFreq)
625 {
626 en_result_t enRet = Ok;
627
628 switch (enRCLFreq)
629 {
630 case SysctrlRclFreq32768:
631 M0P_SYSCTRL->RCL_CR_f.TRIM = RCL_CR_TRIM_32768_VAL;
632 break;
633 case SysctrlRclFreq38400:
634 M0P_SYSCTRL->RCL_CR_f.TRIM = RCL_CR_TRIM_38400_VAL;
635 break;
636 default:
637 enRet = ErrorInvalidParameter;
638 break;
639 }
640
641 return enRet;
642 }
643
644 /**
645 *******************************************************************************
646 ** \brief 系统时钟(HCLK)分频设定
647 ** \param [in] enHCLKDiv 分频设定值
648 ** \retval Ok 设定成功
649 ** 其他 设定失败
650 ******************************************************************************/
Sysctrl_SetHCLKDiv(en_sysctrl_hclk_div_t enHCLKDiv)651 en_result_t Sysctrl_SetHCLKDiv(en_sysctrl_hclk_div_t enHCLKDiv)
652 {
653 en_result_t enRet = Ok;
654
655 _SysctrlUnlock();
656 M0P_SYSCTRL->SYSCTRL0_f.HCLK_PRS = enHCLKDiv;
657
658 return enRet;
659 }
660
661 /**
662 *******************************************************************************
663 ** \brief 外设时钟(PCLK)分频设定
664 ** \param [in] enPCLKDiv 分频设定值
665 ** \retval Ok 设定成功
666 ** 其他 设定失败
667 ******************************************************************************/
Sysctrl_SetPCLKDiv(en_sysctrl_pclk_div_t enPCLKDiv)668 en_result_t Sysctrl_SetPCLKDiv(en_sysctrl_pclk_div_t enPCLKDiv)
669 {
670 en_result_t enRet = Ok;
671
672 _SysctrlUnlock();
673 M0P_SYSCTRL->SYSCTRL0_f.PCLK_PRS = enPCLKDiv;
674
675 return enRet;
676 }
677
678 /**
679 *******************************************************************************
680 ** \brief 设置外设时钟门控开关
681 ** \param [in] enPeripheral 目标外设
682 ** \param [in] bFlag 使能开关
683 ** \retval Ok 设定成功
684 ** 其他 设定失败
685 ******************************************************************************/
Sysctrl_SetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral,boolean_t bFlag)686 en_result_t Sysctrl_SetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral, boolean_t bFlag)
687 {
688 en_result_t enRet = Ok;
689
690 bFlag = !!bFlag;
691
692 setBit(&(M0P_SYSCTRL->PERI_CLKEN), enPeripheral, bFlag);
693
694 return enRet;
695 }
696
697 /**
698 *******************************************************************************
699 ** \brief 获得外设时钟门控开关状态
700 ** \param [in] enPeripheral 目标外设
701 ** \retval TRUE 开
702 ** FALSE 关
703 ******************************************************************************/
Sysctrl_GetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral)704 boolean_t Sysctrl_GetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral)
705 {
706 return getBit(&(M0P_SYSCTRL->PERI_CLKEN), enPeripheral);
707 }
708
709 /**
710 *******************************************************************************
711 ** \brief 系统功能设定
712 ** \param [in] enFunc 系统功能枚举类型
713 ** \param [in] bFlag 1-开/0-关
714 ** \retval Ok 设定成功
715 ** 其他 设定失败
716 ******************************************************************************/
Sysctrl_SetFunc(en_sysctrl_func_t enFunc,boolean_t bFlag)717 en_result_t Sysctrl_SetFunc(en_sysctrl_func_t enFunc, boolean_t bFlag)
718 {
719 en_result_t enRet = Ok;
720
721 _SysctrlUnlock();
722 bFlag = !!bFlag;
723
724 switch (enFunc)
725 {
726 case SysctrlWkupByRCHEn:
727 M0P_SYSCTRL->SYSCTRL0_f.WAKEUP_BYRCH = bFlag;
728 break;
729 case SysctrlEXTHEn:
730 M0P_SYSCTRL->SYSCTRL1_f.EXTH_EN = bFlag;
731 break;
732 case SysctrlEXTLEn:
733 M0P_SYSCTRL->SYSCTRL1_f.EXTL_EN = bFlag;
734 break;
735 case SysctrlXTLAlwaysOnEn:
736 M0P_SYSCTRL->SYSCTRL1_f.XTL_ALWAYS_ON = bFlag;
737 break;
738 case SysctrlClkFuncRTCLpmEn:
739 M0P_SYSCTRL->SYSCTRL1_f.RTC_LPW = bFlag;
740 break;
741 case SysctrlCMLockUpEn:
742 M0P_SYSCTRL->SYSCTRL1_f.LOCKUP_EN = bFlag;
743 break;
744 case SysctrlSWDUseIOEn:
745 M0P_SYSCTRL->SYSCTRL1_f.SWD_USE_IO = bFlag;
746 break;
747 default:
748 enRet = ErrorInvalidParameter;
749 break;
750 }
751
752 return enRet;
753 }
754
755 /**
756 *******************************************************************************
757 ** \brief 设定RTC校准时钟频率
758 ** \param [in] enRtcAdj 校准频率值
759 ** \retval Ok 设定成功
760 ** 其他 设定失败
761 ******************************************************************************/
Sysctrl_SetRTCAdjustClkFreq(en_sysctrl_rtc_adjust_t enRtcAdj)762 en_result_t Sysctrl_SetRTCAdjustClkFreq(en_sysctrl_rtc_adjust_t enRtcAdj)
763 {
764 en_result_t enRet = Ok;
765
766 _SysctrlUnlock();
767 M0P_SYSCTRL->SYSCTRL1_f.RTC_FREQ_ADJUST = enRtcAdj;
768
769 return enRet;
770 }
771
772 //@} // SysctrlGroup
773
774 /*******************************************************************************
775 * EOF (not truncated)
776 ******************************************************************************/
777