sysctrl.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. /******************************************************************************
  2. * Copyright (C) 2021, Xiaohua Semiconductor Co., Ltd. All rights reserved.
  3. *
  4. * This software component is licensed by XHSC under BSD 3-Clause license
  5. * (the "License"); You may not use this file except in compliance with the
  6. * License. You may obtain a copy of the License at:
  7. * opensource.org/licenses/BSD-3-Clause
  8. *
  9. ******************************************************************************/
  10. /******************************************************************************
  11. * @file sysctrl.c
  12. *
  13. * @brief Source file for SYSCTRL functions
  14. *
  15. * @author MADS Team
  16. *
  17. ******************************************************************************/
  18. /*******************************************************************************
  19. * Include files
  20. ******************************************************************************/
  21. #include "sysctrl.h"
  22. /**
  23. *******************************************************************************
  24. ** \addtogroup SysctrlGroup
  25. ******************************************************************************/
  26. //@{
  27. /*******************************************************************************
  28. * Local pre-processor symbols/macros ('#define')
  29. ******************************************************************************/
  30. #define CLK_TIMEOUT (1000000u)
  31. #define IS_VALID_SRC(x) ( ClkRCH == (x)||\
  32. ClkXTH == (x)||\
  33. ClkRCL == (x)||\
  34. ClkXTL == (x) )
  35. #define IS_VALID_FUNC(x) ( ClkFuncWkupRCH == (x)||\
  36. ClkFuncXTHEn == (x)||\
  37. ClkFuncXTLEn == (x)||\
  38. ClkFuncXTLAWSON == (x)||\
  39. ClkFuncFaultEn == (x)||\
  40. ClkFuncRtcLPWEn == (x)||\
  41. ClkFuncLockUpEn == (x)||\
  42. ClkFuncRstPinIOEn == (x)||\
  43. ClkFuncSwdPinIOEn == (x) )
  44. #define RC_TRIM_BASE_ADDR ((volatile uint16_t*) (0x00100C00ul))
  45. #define RCH_CR_TRIM_24M_VAL (*((volatile uint16_t*) (0x00100C00ul)))
  46. #define RCH_CR_TRIM_22_12M_VAL (*((volatile uint16_t*) (0x00100C02ul)))
  47. #define RCH_CR_TRIM_16M_VAL (*((volatile uint16_t*) (0x00100C04ul)))
  48. #define RCH_CR_TRIM_8M_VAL (*((volatile uint16_t*) (0x00100C06ul)))
  49. #define RCH_CR_TRIM_4M_VAL (*((volatile uint16_t*) (0x00100C08ul)))
  50. #define RCL_CR_TRIM_38400_VAL (*((volatile uint16_t*) (0x00100C20ul)))
  51. #define RCL_CR_TRIM_32768_VAL (*((volatile uint16_t*) (0x00100C22ul)))
  52. /*******************************************************************************
  53. * Global variable definitions (declared in header file with 'extern')
  54. ******************************************************************************/
  55. extern uint32_t SystemCoreClock;
  56. /*******************************************************************************
  57. * Local type definitions ('typedef')
  58. ******************************************************************************/
  59. /*******************************************************************************
  60. * Local variable definitions ('static')
  61. ******************************************************************************/
  62. /*******************************************************************************
  63. * Local function prototypes ('static')
  64. ******************************************************************************/
  65. /*******************************************************************************
  66. * Function implementation - global ('extern') and local ('static')
  67. ******************************************************************************/
  68. /**
  69. *******************************************************************************
  70. ** \brief SYSCTRL0\SYSCTRL1寄存器操作解锁
  71. **
  72. ** \retval None
  73. ******************************************************************************/
  74. static void _SysctrlUnlock(void)
  75. {
  76. M0P_SYSCTRL->SYSCTRL2 = 0x5A5A;
  77. M0P_SYSCTRL->SYSCTRL2 = 0xA5A5;
  78. }
  79. /**
  80. *******************************************************************************
  81. ** \brief 系统时钟源使能
  82. ** \param [in] enSource 目标时钟源
  83. ** \param [in] bFlag 使能1-开/0-关
  84. ** \retval Ok 设定成功
  85. ** 其他 设定失败
  86. ******************************************************************************/
  87. en_result_t Sysctrl_ClkSourceEnable(en_sysctrl_clk_source_t enSource, boolean_t bFlag)
  88. {
  89. en_result_t enRet = Ok;
  90. uint32_t u32Temp;
  91. _SysctrlUnlock();
  92. bFlag = !!bFlag;
  93. u32Temp = M0P_SYSCTRL->PERI_CLKEN0;
  94. switch (enSource)
  95. {
  96. case SysctrlClkRCH:
  97. M0P_SYSCTRL->SYSCTRL0_f.RCH_EN = bFlag;
  98. while(bFlag && (1 != M0P_SYSCTRL->RCH_CR_f.STABLE))
  99. {
  100. ;
  101. }
  102. break;
  103. case SysctrlClkXTH:
  104. M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = TRUE;
  105. M0P_GPIO->PFADS |= 3u;
  106. M0P_SYSCTRL->SYSCTRL0_f.XTH_EN = bFlag;
  107. while(bFlag && (1 != M0P_SYSCTRL->XTH_CR_f.STABLE))
  108. {
  109. ;
  110. }
  111. break;
  112. case SysctrlClkRCL:
  113. M0P_SYSCTRL->SYSCTRL0_f.RCL_EN = bFlag;
  114. while(bFlag && (1 != M0P_SYSCTRL->RCL_CR_f.STABLE))
  115. {
  116. ;
  117. }
  118. break;
  119. case SysctrlClkXTL:
  120. M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = TRUE;
  121. M0P_GPIO->PCADS |= 0xC000;
  122. M0P_SYSCTRL->SYSCTRL0_f.XTL_EN = bFlag;
  123. while(bFlag && (1 != M0P_SYSCTRL->XTL_CR_f.STABLE))
  124. {
  125. ;
  126. }
  127. break;
  128. case SysctrlClkPLL:
  129. M0P_SYSCTRL->PERI_CLKEN0_f.ADC = TRUE;
  130. M0P_BGR->CR_f.BGR_EN = TRUE;
  131. delay10us(20);
  132. M0P_SYSCTRL->SYSCTRL0_f.PLL_EN = bFlag;
  133. while(bFlag && (1 != M0P_SYSCTRL->PLL_CR_f.STABLE))
  134. {
  135. ;
  136. }
  137. break;
  138. default:
  139. enRet = ErrorInvalidParameter;
  140. break;
  141. }
  142. M0P_SYSCTRL->PERI_CLKEN0 = u32Temp;
  143. return enRet;
  144. }
  145. /**
  146. *******************************************************************************
  147. ** \brief 外部高速晶振驱动配置
  148. ** \param [in] enFreq 外部高速晶振频率范围选择
  149. ** \param [in] enDriver 外部高速晶振驱动能力选择
  150. ** \retval Ok 设定成功
  151. ** 其他 设定失败
  152. ******************************************************************************/
  153. en_result_t Sysctrl_XTHDriverCfg(en_sysctrl_xtal_driver_t enDriver)
  154. {
  155. en_result_t enRet = Ok;
  156. M0P_SYSCTRL->XTH_CR_f.DRIVER = enDriver;
  157. return enRet;
  158. }
  159. /**
  160. *******************************************************************************
  161. ** \brief 外部低速晶振驱动配置
  162. ** \param [in] enFreq 外部低速晶振频率范围选择
  163. ** \param [in] enDriver 外部低速晶振驱动能力选择
  164. ** \retval Ok 设定成功
  165. ** 其他 设定失败
  166. ******************************************************************************/
  167. en_result_t Sysctrl_XTLDriverCfg(en_sysctrl_xtl_amp_t enAmp, en_sysctrl_xtal_driver_t enDriver)
  168. {
  169. en_result_t enRet = Ok;
  170. M0P_SYSCTRL->XTL_CR_f.AMP_SEL = enAmp;
  171. M0P_SYSCTRL->XTL_CR_f.DRIVER = enDriver;
  172. return enRet;
  173. }
  174. /**
  175. *******************************************************************************
  176. ** \brief 外部高速时钟稳定周期配置
  177. ** \param [in] enCycle 外部高速时钟稳定周期设置
  178. ** \retval Ok 设定成功
  179. ** 其他 设定失败
  180. ******************************************************************************/
  181. en_result_t Sysctrl_SetXTHStableTime(en_sysctrl_xth_cycle_t enCycle)
  182. {
  183. en_result_t enRet = Ok;
  184. M0P_SYSCTRL->XTH_CR_f.STARTUP = enCycle;
  185. return enRet;
  186. }
  187. /**
  188. *******************************************************************************
  189. ** \brief 内部低速时钟稳定周期配置
  190. ** \param [in] enCycle 内部低速时钟稳定周期设置
  191. ** \retval Ok 设定成功
  192. ** 其他 设定失败
  193. ******************************************************************************/
  194. en_result_t Sysctrl_SetRCLStableTime(en_sysctrl_rcl_cycle_t enCycle)
  195. {
  196. en_result_t enRet = Ok;
  197. M0P_SYSCTRL->RCL_CR_f.STARTUP = enCycle;
  198. return enRet;
  199. }
  200. /**
  201. *******************************************************************************
  202. ** \brief 外部低速时钟稳定周期配置
  203. ** \param [in] enCycle 外部低速时钟稳定周期设置
  204. ** \retval Ok 设定成功
  205. ** 其他 设定失败
  206. ******************************************************************************/
  207. en_result_t Sysctrl_SetXTLStableTime(en_sysctrl_xtl_cycle_t enCycle)
  208. {
  209. en_result_t enRet = Ok;
  210. M0P_SYSCTRL->XTL_CR_f.STARTUP = enCycle;
  211. return enRet;
  212. }
  213. /**
  214. *******************************************************************************
  215. ** \brief PLL稳定周期配置
  216. ** \param [in] enCycle PLL稳定周期设置
  217. ** \retval Ok 设定成功
  218. ** 其他 设定失败
  219. ******************************************************************************/
  220. en_result_t Sysctrl_SetPLLStableTime(en_sysctrl_pll_cycle_t enCycle)
  221. {
  222. en_result_t enRet = Ok;
  223. M0P_SYSCTRL->PLL_CR_f.STARTUP = enCycle;
  224. return enRet;
  225. }
  226. /**
  227. *******************************************************************************
  228. ** \brief 时钟源切换,该函数执行后会开启新时钟源
  229. ** \note 选择时钟源之前,需根据需要配置目标时钟源的频率/驱动参数/使能时钟源等
  230. ** \param [in] enSource 新时钟源
  231. **
  232. ** \retval Ok 设定成功
  233. ** 其他 设定失败
  234. ******************************************************************************/
  235. en_result_t Sysctrl_SysClkSwitch(en_sysctrl_clk_source_t enSource)
  236. {
  237. en_result_t enRet = Ok;
  238. en_sysctrl_clk_source_t ClkNew = enSource;
  239. _SysctrlUnlock();
  240. M0P_SYSCTRL->SYSCTRL0_f.CLKSW = ClkNew;
  241. //更新Core时钟(HCLK)
  242. SystemCoreClockUpdate();
  243. return enRet;
  244. }
  245. /**
  246. *******************************************************************************
  247. ** \brief 获得系统时钟(HCLK)频率值
  248. ** \retval uint32_t HCLK频率值
  249. **
  250. ******************************************************************************/
  251. uint32_t Sysctrl_GetHClkFreq(void)
  252. {
  253. uint32_t u32Val = 0;
  254. const uint32_t u32hcr_tbl[] = { 4000000, 8000000, 16000000, 22120000, 24000000};
  255. const uint16_t u32lcr_tbl[] = { 32768, 38400};
  256. en_sysctrl_clk_source_t enSrc;
  257. uint16_t u16Trim[5] = {0};
  258. u16Trim[4] = RCH_CR_TRIM_24M_VAL;
  259. u16Trim[3] = RCH_CR_TRIM_22_12M_VAL;
  260. u16Trim[2] = RCH_CR_TRIM_16M_VAL;
  261. u16Trim[1] = RCH_CR_TRIM_8M_VAL;
  262. u16Trim[0] = RCL_CR_TRIM_38400_VAL;
  263. //获取当前系统时钟
  264. enSrc = (en_sysctrl_clk_source_t)(M0P_SYSCTRL->SYSCTRL0_f.CLKSW);
  265. switch (enSrc)
  266. {
  267. case SysctrlClkRCH:
  268. {
  269. if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[4]))
  270. {
  271. u32Val = u32hcr_tbl[4];
  272. }
  273. else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[3]))
  274. {
  275. u32Val = u32hcr_tbl[3];
  276. }
  277. else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[2]))
  278. {
  279. u32Val = u32hcr_tbl[2];
  280. }
  281. else if((M0P_SYSCTRL->RCH_CR_f.TRIM) == (u16Trim[1]))
  282. {
  283. u32Val = u32hcr_tbl[1];
  284. }
  285. else
  286. {
  287. u32Val = u32hcr_tbl[0];
  288. }
  289. }
  290. break;
  291. case SysctrlClkXTH:
  292. u32Val = SYSTEM_XTH;
  293. break;
  294. case SysctrlClkRCL:
  295. {
  296. if(u16Trim[0] == (M0P_SYSCTRL->RCL_CR_f.TRIM))
  297. {
  298. u32Val = u32lcr_tbl[1];
  299. }
  300. else
  301. {
  302. u32Val = u32lcr_tbl[0];
  303. }
  304. }
  305. break;
  306. case SysctrlClkXTL:
  307. u32Val = SYSTEM_XTL;
  308. break;
  309. case SysctrlClkPLL:
  310. {
  311. if (SysctrlPllRch == M0P_SYSCTRL->PLL_CR_f.REFSEL)
  312. {
  313. if(u16Trim[4] == M0P_SYSCTRL->RCH_CR_f.TRIM)
  314. {
  315. u32Val = u32hcr_tbl[4];
  316. }
  317. else if(u16Trim[3] == M0P_SYSCTRL->RCH_CR_f.TRIM)
  318. {
  319. u32Val = u32hcr_tbl[3];
  320. }
  321. else if(u16Trim[2] == M0P_SYSCTRL->RCH_CR_f.TRIM)
  322. {
  323. u32Val = u32hcr_tbl[2];
  324. }
  325. else if(u16Trim[1] == M0P_SYSCTRL->RCH_CR_f.TRIM)
  326. {
  327. u32Val = u32hcr_tbl[1];
  328. }
  329. else
  330. {
  331. u32Val = u32hcr_tbl[0];
  332. }
  333. }
  334. else
  335. {
  336. u32Val = SYSTEM_XTH;
  337. }
  338. u32Val = (u32Val * M0P_SYSCTRL->PLL_CR_f.DIVN);
  339. }
  340. break;
  341. default:
  342. u32Val = 0u;
  343. break;
  344. }
  345. u32Val = (u32Val >> M0P_SYSCTRL->SYSCTRL0_f.HCLK_PRS);
  346. return u32Val;
  347. }
  348. /**
  349. *******************************************************************************
  350. ** \brief 获得外设时钟(PCLK)频率值
  351. ** \retval uint32_t PCLK频率值(Hz)
  352. **
  353. ******************************************************************************/
  354. uint32_t Sysctrl_GetPClkFreq(void)
  355. {
  356. uint32_t u32Val = 0;
  357. u32Val = Sysctrl_GetHClkFreq();
  358. u32Val = (u32Val >> (M0P_SYSCTRL->SYSCTRL0_f.PCLK_PRS));
  359. return u32Val;
  360. }
  361. /**
  362. *******************************************************************************
  363. ** \brief 时钟初始化函数
  364. ** \param [in] pstcCfg 初始化配置参数
  365. ** \retval Ok 设定成功
  366. ** 其他 设定失败
  367. ******************************************************************************/
  368. en_result_t Sysctrl_ClkInit(stc_sysctrl_clk_cfg_t *pstcCfg)
  369. {
  370. en_result_t enRet = Ok;
  371. //系统时钟参数配置
  372. switch(pstcCfg->enClkSrc)
  373. {
  374. case SysctrlClkRCH:
  375. break;
  376. case SysctrlClkXTH:
  377. Sysctrl_XTHDriverCfg(SysctrlXtalDriver3);
  378. Sysctrl_SetXTHStableTime(SysctrlXthStableCycle16384);
  379. break;
  380. case SysctrlClkRCL:
  381. Sysctrl_SetRCLStableTime(SysctrlRclStableCycle256);
  382. break;
  383. case SysctrlClkXTL:
  384. Sysctrl_XTLDriverCfg(SysctrlXtlAmp3, SysctrlXtalDriver3);
  385. Sysctrl_SetXTLStableTime(SysctrlXtlStableCycle16384);
  386. break;
  387. case SysctrlClkPLL:
  388. Sysctrl_SetPLLStableTime(SysctrlPllStableCycle16384);
  389. break;
  390. default:
  391. enRet = ErrorInvalidParameter;
  392. break;
  393. }
  394. //时钟源使能
  395. Sysctrl_ClkSourceEnable(pstcCfg->enClkSrc, TRUE);
  396. //时钟源切换
  397. Sysctrl_SysClkSwitch(pstcCfg->enClkSrc);
  398. //时钟分频设置
  399. Sysctrl_SetHCLKDiv(pstcCfg->enHClkDiv);
  400. Sysctrl_SetPCLKDiv(pstcCfg->enPClkDiv);
  401. return enRet;
  402. }
  403. /**
  404. *******************************************************************************
  405. ** \brief 时钟去初始化函数
  406. ** \param [in]
  407. ** \retval Ok 设定成功
  408. ** 其他 设定失败
  409. ******************************************************************************/
  410. en_result_t Sysctrl_ClkDeInit(void)
  411. {
  412. en_result_t enRet = Ok;
  413. //配置RCH为内部4Hz
  414. Sysctrl_SetRCHTrim(SysctrlRchFreq4MHz);
  415. //时钟源使能
  416. Sysctrl_ClkSourceEnable(SysctrlClkRCH, TRUE);
  417. //时钟源切换
  418. Sysctrl_SysClkSwitch(SysctrlClkRCH);
  419. //其它时钟源使能关闭
  420. Sysctrl_ClkSourceEnable(SysctrlClkXTH, FALSE);
  421. Sysctrl_ClkSourceEnable(SysctrlClkRCL, FALSE);
  422. Sysctrl_ClkSourceEnable(SysctrlClkXTL, FALSE);
  423. Sysctrl_ClkSourceEnable(SysctrlClkPLL, FALSE);
  424. //时钟分频设置
  425. Sysctrl_SetHCLKDiv(SysctrlHclkDiv1);
  426. Sysctrl_SetPCLKDiv(SysctrlPclkDiv1);
  427. return enRet;
  428. }
  429. /**
  430. *******************************************************************************
  431. ** \brief 内部高速时钟频率TRIM值加载
  432. ** \param [in] enRCHFreq 设定的RCH目标频率值
  433. ** \retval Ok 设定成功
  434. ** 其他 设定失败或时钟未稳定
  435. ******************************************************************************/
  436. en_result_t Sysctrl_SetRCHTrim(en_sysctrl_rch_freq_t enRCHFreq)
  437. {
  438. //加载RCH Trim值
  439. M0P_SYSCTRL->RCH_CR_f.TRIM = *(RC_TRIM_BASE_ADDR + enRCHFreq);
  440. return Ok;
  441. }
  442. /**
  443. *******************************************************************************
  444. ** \brief 外部高速时钟频率范围设定
  445. ** \param [in] enXTHFreq 设定的频率值
  446. ** \retval Ok 设定成功
  447. ** 其他 设定失败或时钟未稳定
  448. ******************************************************************************/
  449. en_result_t Sysctrl_SetXTHFreq(en_sysctrl_xth_freq_t enXTHFreq)
  450. {
  451. en_result_t enRet = Ok;
  452. M0P_SYSCTRL->XTH_CR_f.XTH_FSEL = enXTHFreq;
  453. return enRet;
  454. }
  455. /**
  456. *******************************************************************************
  457. ** \brief PLL时钟配置
  458. ** \param [in] pstcPLLCfg PLL配置结构体指针
  459. ** \retval Ok 设定成功
  460. ** 其他 设定失败或参数值不匹配
  461. ******************************************************************************/
  462. en_result_t Sysctrl_SetPLLFreq(stc_sysctrl_pll_cfg_t *pstcPLLCfg)
  463. {
  464. en_result_t enRet = Ok;
  465. uint16_t u16Trim[5] = {0};
  466. u16Trim[4] = RCH_CR_TRIM_24M_VAL;
  467. u16Trim[3] = RCH_CR_TRIM_22_12M_VAL;
  468. u16Trim[2] = RCH_CR_TRIM_16M_VAL;
  469. u16Trim[1] = RCH_CR_TRIM_8M_VAL;
  470. ////PLL最高时钟不能超过48MHz
  471. //RCH作为PLL输入
  472. if (SysctrlPllRch == pstcPLLCfg->enPllClkSrc)
  473. {
  474. if( ((u16Trim[4] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 2)) ||
  475. ((u16Trim[3] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 2)) ||
  476. ((u16Trim[2] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 3)) ||
  477. ((u16Trim[1] == M0P_SYSCTRL->RCH_CR_f.TRIM) && (pstcPLLCfg->enPllMul > 6)))
  478. {
  479. return ErrorInvalidMode;
  480. }
  481. }
  482. else //XTH作为PLL输入
  483. {
  484. if ((SYSTEM_XTH * pstcPLLCfg->enPllMul) > 48*1000*1000)
  485. {
  486. return ErrorInvalidMode;
  487. }
  488. }
  489. M0P_SYSCTRL->PLL_CR_f.FRSEL = pstcPLLCfg->enInFreq;
  490. M0P_SYSCTRL->PLL_CR_f.FOSC = pstcPLLCfg->enOutFreq;
  491. M0P_SYSCTRL->PLL_CR_f.DIVN = pstcPLLCfg->enPllMul;
  492. M0P_SYSCTRL->PLL_CR_f.REFSEL = pstcPLLCfg->enPllClkSrc;
  493. return enRet;
  494. }
  495. /**
  496. *******************************************************************************
  497. ** \brief 内部低速时钟频率TRIM值加载
  498. ** \param [in] enRCLFreq 设定的RCL目标频率值
  499. ** \retval Ok 设定成功
  500. ** 其他 设定失败
  501. ******************************************************************************/
  502. en_result_t Sysctrl_SetRCLTrim(en_sysctrl_rcl_freq_t enRCLFreq)
  503. {
  504. M0P_SYSCTRL->RCL_CR_f.TRIM = *(RC_TRIM_BASE_ADDR + enRCLFreq);
  505. return Ok;
  506. }
  507. /**
  508. *******************************************************************************
  509. ** \brief 系统时钟(HCLK)分频设定
  510. ** \param [in] enHCLKDiv 分频设定值
  511. ** \retval Ok 设定成功
  512. ** 其他 设定失败
  513. ******************************************************************************/
  514. en_result_t Sysctrl_SetHCLKDiv(en_sysctrl_hclk_div_t enHCLKDiv)
  515. {
  516. _SysctrlUnlock();
  517. M0P_SYSCTRL->SYSCTRL0_f.HCLK_PRS = enHCLKDiv;
  518. return Ok;
  519. }
  520. /**
  521. *******************************************************************************
  522. ** \brief 外设时钟(PCLK)分频设定
  523. ** \param [in] enPCLKDiv 分频设定值
  524. ** \retval Ok 设定成功
  525. ** 其他 设定失败
  526. ******************************************************************************/
  527. en_result_t Sysctrl_SetPCLKDiv(en_sysctrl_pclk_div_t enPCLKDiv)
  528. {
  529. _SysctrlUnlock();
  530. M0P_SYSCTRL->SYSCTRL0_f.PCLK_PRS = enPCLKDiv;
  531. return Ok;
  532. }
  533. ///<< for Sysctrl_SetPeripheralGate() & Sysctrl_GetPeripheralGate()
  534. static volatile boolean_t bDacPeriBac = FALSE;
  535. /**
  536. *******************************************************************************
  537. ** \brief 设置外设时钟门控开关
  538. ** \param [in] enPeripheral 目标外设
  539. ** \param [in] bFlag 使能开关
  540. ** \retval Ok 设定成功
  541. ** 其他 设定失败
  542. ******************************************************************************/
  543. en_result_t Sysctrl_SetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral, boolean_t bFlag)
  544. {
  545. if(enPeripheral&0x20u)
  546. {
  547. enPeripheral &= ~0x20u;
  548. SetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN1)), enPeripheral, bFlag);
  549. if((SysctrlPeripheralDac & ~0x20u) == enPeripheral)
  550. {
  551. bDacPeriBac = bFlag;
  552. }
  553. else
  554. {
  555. SetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN1)), (SysctrlPeripheralDac & ~0x20u), bDacPeriBac);
  556. }
  557. }
  558. else
  559. {
  560. SetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN0)), enPeripheral, bFlag);
  561. }
  562. return Ok;
  563. }
  564. /**
  565. *******************************************************************************
  566. ** \brief 获得外设时钟门控开关状态
  567. ** \param [in] enPeripheral 目标外设
  568. ** \retval TRUE 开
  569. ** FALSE 关
  570. ******************************************************************************/
  571. boolean_t Sysctrl_GetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral)
  572. {
  573. if(enPeripheral&0x20u)
  574. {
  575. if(SysctrlPeripheralDac == enPeripheral)
  576. {
  577. return bDacPeriBac;
  578. }
  579. else
  580. {
  581. enPeripheral &= ~0x20u;
  582. return GetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN1)), enPeripheral);
  583. }
  584. }
  585. else
  586. {
  587. return GetBit((uint32_t)(&(M0P_SYSCTRL->PERI_CLKEN0)), enPeripheral);
  588. }
  589. }
  590. /**
  591. *******************************************************************************
  592. ** \brief 系统功能设定
  593. ** \param [in] enFunc 系统功能枚举类型
  594. ** \param [in] bFlag 1-开/0-关
  595. ** \retval Ok 设定成功
  596. ** 其他 设定失败
  597. ******************************************************************************/
  598. en_result_t Sysctrl_SetFunc(en_sysctrl_func_t enFunc, boolean_t bFlag)
  599. {
  600. _SysctrlUnlock();
  601. SetBit((uint32_t)(&(M0P_SYSCTRL->SYSCTRL1)), enFunc, bFlag);
  602. return Ok;
  603. }
  604. /**
  605. *******************************************************************************
  606. ** \brief 设定RTC校准时钟频率
  607. ** \param [in] enRtcAdj 校准频率值
  608. ** \retval Ok 设定成功
  609. ** 其他 设定失败
  610. ******************************************************************************/
  611. en_result_t Sysctrl_SetRTCAdjustClkFreq(en_sysctrl_rtc_adjust_t enRtcAdj)
  612. {
  613. _SysctrlUnlock();
  614. M0P_SYSCTRL->SYSCTRL1_f.RTC_FREQ_ADJUST = enRtcAdj;
  615. return Ok;
  616. }
  617. //@} // SysctrlGroup
  618. /*******************************************************************************
  619. * EOF (not truncated)
  620. ******************************************************************************/